mtk kcolrehs 接地 dws怎么配置

PMIC:MT6323 1.
侧按键硬件设计我们设备左边侧按键定义为F7,连接到PMIC MT6323的FCHR_ENB引脚,右边1个电源按键直接接到PMIC的PWRKEY,右边的另一个按键(我们定义为F6)连接到CPU的KCOL0和KROW0引脚 2.
DrvGen配置codegen.dws文件mediatek\dct\DrvGen.exemediatek\custom\itek82_wet_kk\kernel\dct\dct\codegen.dws图1实际上F7是连接到PMIC的FCHR_ENB,而这里的KEYPAD setting是属于CPU键盘矩阵的配置的,但如果这里不配置F7,那DownloadKey、Mode Key就不能选择F7,而且这里F7我们选择在Row7和Column2交叉处,对应的HW keycode=65,恰好就是KEY_F7对应的scan code值(linux驱动和内核用到) 上图配置好后选择“确定”,然后选择Gen Code,再选择Save,如下图:图2更新的文件有mediatek\custom\itek82_wet_kk\kernel\dct\dct\pmic_drv.h和cust_kpd.h。 然后编译./mk r lk k./mk bootimage跟新lk.bin和boot.img即可。 3.
遇到的问题3.1
无法进入recovery mode问题更新后,开机同时按下power+F7无法进入recovery mode,而是normal mode,根据MTK_on_line_FAQ_SW_ALPS文档给出的方法,如下:[FAQ11302][keypad]使用FCHR_ENB为VOLUMEDOWNKEY,如何进工厂模式[DESCRIPTION]使用FCHR_ENB为VOLUMEDOWNKEY,如何进工厂模式[SOLUTION](1)
在“mediatek\custom\$(Project_Name)\kernel\kpd\kpd\mtk_kpd.h” 內的下列定义“#define KPD_PMIC_RSTKEY_MAPKEY_VOLUMEDOWN//客制化的按键”
“#define MT65XX_PMIC_RST_KEYKEY_VOLUMEDOWN//客制化的按键”(2)
alps\mediatek\platform\mt65XX\lk\mtk_key.cBOOL mtk_detect_key(unsigned short key) /*key: HW keycode */
unsigned short idx, bit,
// if (key &= KPD_NUM_KEYS)
// return FALSE;
if (key % 9 == 8)
}我的修改如下:(1)
mtk_kpd.h#define KPD_PMIC_RSTKEY_MAP KEY_F7
#define MT65XX_PMIC_RST_KEY KEY_F7(2)
如上面 但还是无法进入,下面先来看坚持启动模式的流程图3图4虽然在mediatek\custom\itek82_wet_kk\kernel\kpd\kpd\mtk_kpd.h#define KPD_PMIC_RSTKEY_MAP KEY_F7
#define MT65XX_PMIC_RST_KEY KEY_F7但是经过验证mtk_detect_key()的第112行是不知道定义了MT65XX_PMIC_RST_KEY的,我们看到mtk_key.c下有#include&target/cust_key.h&此文件位于mediatek\custom\itek82_wet_kk\lk\include\target目录下,恰好看到这里有注释掉MT65XX_PMIC_RST_KEY的定义,重新打开并修改为KEY_F7就可以了。 3.2
进入recovery mode只看到图标,没有看到显示的recovery菜单 [Description]目前在JB2版本上,关机状态的手机按(PowerOn + Volume Up)键进入Recovery Mode时,出现的画面是机器人倒地,不会直接显示主菜单。对于一些客户来说,机器人倒地意味着什么他们并不清楚,导致无从下手。所以,就有了『直接显示主菜单』的需求。[Solution]待修改文件路径:alps/bootable/recovery/recovery.cpp修改处:main(){
if (status != INSTALL_SUCCESS ||ui-&IsTextVisible()) {
prompt_and_wait(device, status);
if (status != INSTALL_SUCCESS &&!(ui-&WasTextEverVisible()) || ui-
&IsTextVisible()) {
ui-&ShowText(true); //Added
prompt_and_wait(device, status);
}编译命令./mk recoveryimage然后更新recovery.img即可。 3.3
recovery mode后F6和F7无效问题(1)
根据帮忙文档,查找到到相关的解决办法 [FAQ07808][keypad]进入recover模式后音量按键功能失效[DESCRIPTION]在正常开机或者Factory mode下开机音量键是正常的,在使用LK作为boot loader,且打开LK_H***E_TEXT_MENU宏后(默认打开)时,Power key+Vol up后进入recovery模式会出现的多模式选择菜单:recoveryfactory normalnormal+ftrace等,提示Select Boot Mode:[Volume_Up to select,Volume Down is OK.]此时音量按键失效的问题。[SOLUTION]客制化修改mediatek\custom\$(project)\lk\include\target\cust_key.h1.如果音量键是用的矩阵键盘:根据DCT tool在矩阵键盘里设置的Vol+是rowX1,colY1;Vol-是rowX2,colY2.设定对应的HW scan codeexample:#define MT65xx_PMIC_RST_KEY 1000 //invalidkey
#define MT65XX_BOOT_MENU_KEY 0 //Vol+ (row0,col0时)//修改成您自己的row col
#define MT65XX_MENU_OK_KEY 1 //Vol- (row0,col1时)//修改成您自己的row col2.如果音量键中有使用到了PMIC的homekeyexample:vol-用PMIC homekey,vol+还是矩阵键盘里的#define MT65xx_PMIC_RST_KEYMT65XX_FACTORY_KEY//或者具体的HW scan code
#define MT65XX_BOOT_MENU_KEY 0 //Vol+ (row0,col0)//修改成您自己的row col
#define MT65XX_MENU_OK_KEY MT65xx_PMIC_RST_KEY//Vol
//#define MT65XX_PMIC_RST_KEY
#define MT65XX_MENU_OK_KEY
2 /* KEY_VOLUMEDOWN */
#define MT65XX_PMIC_RST_KEY (KEY_F7)
#define MT65XX_MENU_OK_KEY
MT65XX_PMIC_RST_KEY /* KEY_VOLUMEDOWN*/
修改验证还是无效(2)
mediatek\custom\itek82_wet_kk\recovery\inc\cust_keys.h修改cust_keys.h文件//修改之前
#define RECOVERY_KEY_DOWN
KEY_VOLUMEDOWN
#define RECOVERY_KEY_UP
KEY_VOLUMEDOWN
#define RECOVERY_KEY_ENTER
KEY_VOLUMEUP
//修改之后
#define RECOVERY_KEY_DOWN
#define RECOVERY_KEY_UP
#define RECOVERY_KEY_ENTER
#define RECOVERY_KEY_MENU
KEY_POWER然后编译和更新./mk r k./mk recoveryimage更新recovery.img就解决了此问题 3.4
进入recovery mode后power按键响应不正常问题 上面的问题解决了,但是按power按键要调用对应的功能时,本来是可以看到recovery菜单的,按一下power按键就隐藏起来,再按一下就重新显示,而不是执行对应的功能, 修改
mediatek\custom\itek82_wet_kk\recovery\inc\cust_keys.h解决了此问题修改前
#define RECOVERY_KEY_MENU
#define RECOVERY_KEY_MENU
KEY_MENU//KEY_POWER3.5
进入factory mode后F7按键问题修改mediatek\custom\itek82_wet_kk\factory\inc\cust_keys.h修改前:
#define CUST_KEY_UP
#define CUST_KEY_UP
KEY_F7//KEY_UP./mk mm mediate/factory./mk snod这会生成生成system.img 更新system.img即可
如果您想留下此文,您可以将其发送至您的邮箱(将同时以邮件内容&PDF形式发送)
相关文章推荐
(Ctrl+Enter提交) &&
已有0人在此发表见解
&在& 08:49收藏到了
&&在信息爆炸的时代,您的知识需要整理,沉淀,积累!Lai18为您提供一个简单实用的文章整理收藏工具,在这里您可以收藏对您有用的技术文章,自由分门别类,在整理的过程中,用心梳理自己的知识!相信,用不了多久,您收藏整理的文章将是您一生的知识宝库!
· 蜀ICP备号-12667人阅读
android(36)
1 一、配置GPIO
2 二、配置emmc
3 三、配置LCM
3.1 1、增加LCM驱动文件
3.2 2、配置驱动文件
3.3 3、配置背光
4 四、配置touch panel
4.1 1、通过dct配置gipo及其对应的别名
4.2 2、配置mediatek/config/bbk15_td_ics/ProjectConfig.mk
4.3 3、增加 tp 驱动目录及驱动文件
4.4 4、配置刚刚添加的驱动文件
4.5 5、配置pmic供电
5 五、注意事项
6 六、附录
一、配置GPIO
通过工具:
mediatek/source/dct/DrvGen.exe
配置并替换dws文件:
mediatek/custom/bbk75_emmc_gb2/kernel/dct/dct/codegen.dws
配置GPIO的主要目的是使系统在uboot,甚至preloader阶段时保持BB管脚的状态;在kernel启动阶段加载驱动模块时,不少驱动是会重新设置其用的gpio功能的,所以这一阶段并不要求非常严格,然而同时也必须要保证gpio所配置的初始状态不会影响到系统的启动,如死机、复位等等。
二、配置emmc
1、在下面文件的MTK6575标签栏添加对应的flash芯片型号信息:
mediatek/build/tools/emigen/MT6575/MemoryDeviceList_MT6575.xls
2、从以下文件获取flash芯片对应的序号(从第1列为0,开始数,如到第L列则为11): mediatek/build/tools/ptgen/emmc_region.xls
3、mediatek/custom/bbk15_td_ics/preloader/inc/custom_MemoryDevice.h
#define BOARD_ID&&&&&&&&&&&&&&&&LENOVO75
#define CS_PART_NUMBER[0]&&&&&& KMSJS000KM_B308
将上面的宏更改为MemoryDeviceList_MT6575.xls中对应的内容
4,mediatek/config/bbk15_td_ics/ProjectConfig.mk
将EMMC_CHIP更改为第2步获取的数值,如EMMC_CHIP = 11。
三、配置LCM
1、增加LCM驱动文件
(1)、配置mediatek/config/bbk15_td_ics/ProjectConfig.mk
CUSTOM_KERNEL_LCM = sharp_S6D05A1X12_mcu
CUSTOM_UBOOT_LCM = sharp_S6D05A1X12_mcu
LCM_WIDTH = 320
LCM_HEIGHT = 480
BOOT_LOGO = cmcc_hvga
(2)、增加 lcm 驱动目录及文件
mediatek/custom/common/kernel/lcm/sharp_S6D05A1X12_mcu/
ps.如果是从其他平台拷贝而来,注意更改包含对应的头文件:&
#ifdef BUILD_UBOOT
#define print(x...) printf(x)
#define print(x...) printk(x)
#ifdef BUILD_UBOOT
#define print(x...) printf(x)
#define print(x...) printk(x)
(3)、修改 mt65xx_lcm_list.c 使支持刚添加的驱动
mediatek/custom/common/kernel/lcm/mt65xx_lcm_list.c
extern LCM_DRIVER sharp_S6D05A1X12_mcu_
#if defined(SHARP_S6D05A1X12_MCU)
&&sharp_S6D05A1X12_mcu_drv,
ps.对于2、3步,uboot lcm驱动对应的驱动目录mediatek/custom/common/uboot/lcm/本也要添加,不过现在我们这一版本uboot/lcm/就是link到kernel/lcm/的,故省去这一步
2、配置驱动文件
打开 mediatek/custom/common/kernel/lcm/sharp_S6D05A1X12_mcu/sharp_S6D05A1X12_mcu.c,根据BB管脚定义和实际硬件连接,更改如下GPIO宏定义:
#define LSA0_GPIO_PIN (GPIO49)
#define LSCE_GPIO_PIN (GPIO47)
#define LSCK_GPIO_PIN (GPIO51)
#define LSDA_GPIO_PIN (GPIO52)
#define DPICK_GPIO_PIN (GPIO41)
#define DPIDE_GPIO_PIN (GPIO30)
#define DPIVSYNC_GPIO_PIN (GPIO21)
#define DPIHSYNC_GPIO_PIN (GPIO19)
3、配置背光
背光配置包括uboot和kernal中的文件:
mediatek/custom/bbk15_td_ics/kernel/leds/mt65xx/cust_leds.c
mediatek/custom/bbk15_td_ics/uboot/cust_leds.c
{&lcd-backlight&,&&&& MT65XX_LED_MODE_CUST, (int)Cust_SetBacklight},
中的响应函数&Cust_SetBacklight&,在其中要保证背光能亮,由于是打版软件,这里只先配置成gpio让其保持最亮。
查背光IC datasheet可知,只需设置VFB为低、CE为高即可:
//GPIO162-&BL_EN-&CE
mt_set_gpio_mode(GPIO162,GPIO_MODE_00);
mt_set_gpio_dir(GPIO162,GPIO_DIR_OUT);
mt_set_gpio_out(GPIO162,GPIO_OUT_ONE);
//GPIO67-&PWM1-&VFB
mt_set_gpio_mode(GPIO67,GPIO_MODE_00);
mt_set_gpio_dir(GPIO67,GPIO_DIR_OUT);
mt_set_gpio_out(GPIO67,GPIO_OUT_ZERO);
ps.uboot/cust_leds.c中还要包含头文件&#include&&,否则编译会出错
6.1 1、i2C配置的两种方法
6.2 2、将触屏配置成点触模式
四、配置touch panel
1、通过dct配置gipo及其对应的别名
#define GPIO_CTP_RST_PIN&&&&&&&& GPIO100
#define GPIO_CTP_RST_PIN_M_GPIO&&GPIO_MODE_00
#define GPIO_CTP_EINT_PIN&&&&&&&& GPIO75
#define GPIO_CTP_EINT_PIN_M_GPIO&&GPIO_MODE_00
#define GPIO_CTP_EINT_PIN_M_EINT&&GPIO_MODE_01
#define GPIO_CTP_EINT_PIN_M_PWM&&GPIO_MODE_02
2、配置mediatek/config/bbk15_td_ics/ProjectConfig.mk
CUSTOM_KERNEL_TOUCHPANEL = qt602240
3、增加 tp 驱动目录及驱动文件
添加头文件:
mediatek/custom/bbk15_td_ics/kernel/touchpanel/qt602240/
添加C文件:
mediatek/custom/common/kernel/touchpanel/qt602240/
4、配置刚刚添加的驱动文件
mediatek/custom/bbk15_td_ics/kernel/touchpanel/qt602240/
更改以下宏定义为对应平台:
#define TPD_POWER_SOURCE&&&&&&&& MT6575_POWER_VGP2
check触摸屏驱动ic的i2c地址,确保代码与datasheet中保持一致:
static unsigned short force[] = {3, 0x4a, I2C_CLIENT_END,I2C_CLIENT_END}; //0x4a则为i2c地址
ps: 在mtk6575_dev.c中的地址必须是除去读写位后的地址,而force里的则里的从机地址则需包含读写位的8位标志,如0x94(即mtk对i2c地址的规定和其他地方不一样,一般情况下说i2c的地址都是不包含读写位的,但mtk则将最后一位读写标志算进去了,这点要注意一下).
另外注意check一下此头文件中的其他宏定义信息,确保触屏与LCM适配,如:
//#define TPD_RES_X&&&&&&&&&&&&&&&&480
//#define TPD_RES_Y&&&&&&&&&&&&&&&&800
//#define TPD_CALIBRATION_MATRIX&&{962,0,0,0,,0};
#define TPD_CALIBRATION_MATRIX&&{320*2,0,0,0,480*2,0,0,0};
5、配置pmic供电
一般在对应的.detect(重新供电操作), .suspend(关闭供电操作), .resume(打开供电操作)中添加进行相关操作,供电功能函数如下:
hwPowerDown(TPD_POWER_SOURCE,&TP&); //停止供电
hwPowerOn(TPD_POWER_SOURCE,VOL_2800,&TP&);& //开始供电
另外也可直接在pmic的probe函数中配置(注意找对对应的pm电压输出口和电压大小):
mediatek/platform/mt6575/kernel/drivers/power/pmic_mt6329.c
static int mt6329_driver_probe(struct i2c_client *client, const struct i2c_device_id *id) {&&&&&&&&&&&&&
&&&&pmic_ldo_enable(MT65XX_POWER_LDO_VGP2,KAL_TRUE);
&&&&pmic_ldo_vol_sel(MT65XX_POWER_LDO_VGP2,UPMU_VOLT_2_8_0_0_V);
五、注意事项
在配置完音量键后,每次开机都会进入recovery mode(这一点在显示屏无显示时可通过串口抓打印消息验证,显示屏能显示时当然就一目了然了)。
刚开始怀疑是硬件上的有问题,是不是哪里将音量键拉低了,因为我们是配置成开机时按住音量键才会进入recovery的,但电子的同事测试波形之后反馈说只有开机一小段时间输出低,后续便输出高了,于是再次将目光转到软件上来,后来我们查看dct得知连接volume的输入线芯片默认是内部拉低的,于是用dct将其配置成pull up,再开机,一切ok.
1、i2C配置的两种方法
方法一:在force中进行i2c id的指定,然后用i2c_add_driver挂载到对应的i2c总线上去:
static unsigned short force[] = {3, 0x4a, I2C_CLIENT_END,I2C_CLIENT_END};
注意:若使用mtk的硬件i2c注意上面的i2c地址要包括读写标志位,如上述的0x4a应改为0x94.
方法二:在mtk6575_dev.c中进行设置:
static struct i2c_board_info __initdata i2c_devs0[]={
&&{ I2C_BOARD_INFO(&fan5405&, (0xd4&&1)),},&&
&&{ I2C_BOARD_INFO(&qt602240ts&, (0x94&&1)),},&
2、将触屏配置成点触模式
qt602240ts在配置完成时默认是使用鼠标模式,此时可将以下文件push到 /system/usr/idc/ 即可设置为点触模式:
out/target/product/bbk15_td_ics/system/usr/idc/qt602240ts.idc
# Basic Parameters
touch.deviceType = touchScreen
touch.orientationAware = 1
touch.size.calibration = diameter
touch.size.scale = 10
touch.size.bias = 0
touch.size.isSummed = 0
# Pressure
# Driver reports signal strength as pressure.
# A normal thumb touch typically registers about 200 signal strength
# units although we don\'t expect these values to be accurate.
touch.pressure.calibration = amplitude
touch.pressure.scale = 0.005
# Orientation
touch.orientation.calibration = none
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:186301次
积分:2134
积分:2134
排名:第17811名
原创:41篇
转载:19篇
评论:45条
(1)(2)(1)(1)(1)(3)(3)(2)(5)(1)(1)(12)(12)(3)(4)(4)(2)(2)后使用快捷导航没有帐号?
查看: 1514|回复: 11
请教按如下参考设计,按图中DWS配置,音量加减键反了;按键该如何配置 ?
(41.01 KB, 下载次数: 0)
17:40 上传
(19.64 KB, 下载次数: 0)
17:41 上传
是GND与COL吗?
你这个配置错了吧。
是GND与COL吗?
你这个配置错了吧。
那该如何配 ? 现在这样配音量加减按键反了。
那该如何配 ? 现在这样配音量加减按键反了。
DWS中需要将KEY_TYPE中设置为EXTEND_TYPE
然后在对应配置按键就行了。
你是用COL加地还是PMIC上的KEY?
本帖最后由 Nil 于
18:15 编辑
你是用COL加地还是PMIC上的KEY?
+ GND;8312平台DWS没有extend type选项
+ GND;8312平台DWS没有extend type选项
哦。。你下拉里面应当有吧?
MTK的实现方式应当是一样的。
哦。。你下拉里面应当有吧?
MTK的实现方式应当是一样的。
目前定义成这样如下图,音量上下键依然是反向的。
(5.64 KB, 下载次数: 1)
11:15 上传
PMIC RSTKEY
目前定义成这样如下图,音量上下键依然是反向的。
你这是用PMIC上的按键。。。
你只需要将DWS里配一个按键,另一个就用这个就行了。DWS里不要配了。
你这是用PMIC上的按键。。。
你只需要将DWS里配一个按键,另一个就用这个就行了。DWS里不要配了。
不配编译会出现问题,fctory mode模块报错找不到音量下键。
论坛资料为网友自由上传,与本论坛无关。
Powered by
关注一牛微信
获取手机验证码3268人阅读
mtkandroid(10)
按键没有hal层
设备中断-------驱动------&内核按键码(SCANCODE)-------*.kl--------& android keycode(char*)--------- KeycodeLabels.h ------&android keyevent(int, KeyEvent.java)
B:android keycode(char*)--------------- *.kcm/*.kcm.bin ------------&显示字符(char)
\alps\frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
if (!mSystemBooted) {
// If we have not yet booted, don't let key events do anything.
// Handle special keys.
switch (keyCode) {
//add by //SCAN_123
case KeyEvent.KEYCODE_FN:
if (down){
fnflag = (!fnflag);
Log.i(TAG, &fn status is & + fnflag);
result &= ~ACTION_PASS_TO_USER;
//add fn icon
Intent intent = new Intent(Intent.ACTION_FN_STATUS);
intent.putExtra(&fn_status&, fnflag);
mContext.sendBroadcast(intent);
case KeyEvent.KEYCODE_F1:
case KeyEvent.KEYCODE_F2:
case KeyEvent.KEYCODE_F3:
case KeyEvent.KEYCODE_F4:
if (!down){
handleFKeys(keyCode);
result &= ~ACTION_PASS_TO_USER;
//add end//SCAN_123 ---
event hub &alps\frameworks\base\services\input\
event read
------------- alps\frameworks\base\core\java\android\view\KeyEvent.java 上层
public class KeyEvent extends InputEvent implements Parcelable {
/** Key code constant: Unknown key code. */
public static final int KEYCODE_UNKNOWN
/** Key code constant: Soft Left key.
* Usually situated below the display on phones and used as a multi-function
* feature key for selecting a software defined function shown on the bottom left
* of the display. */
public static final int KEYCODE_SOFT_LEFT
/** Key code constant: Soft Right key.
* Usually situated below the display on phones and used as a multi-function
* feature key for selecting a software defined function shown on the bottom right
* of the display. */
public static final int KEYCODE_SOFT_RIGHT
/** Key code constant: Home key.
* This key is handled by the framework and is never delivered to applications. */
public static final int KEYCODE_HOME
/** Key code constant: Back key. */
public static final int KEYCODE_BACK
/** Key code constant: Call key. */
public static final int KEYCODE_CALL
= 5;    public static final int KEYCODE_KANA            = 218;
    /** Key code constant: Assist key.
     * Launches the global assist activity.  Not delivered to applications. */
    public static final int KEYCODE_ASSIST          = 219;
    public static final int KEYCODE_SCAN          = 220;//sam add 
    public static final int KEYCODE_SCAN_LEFT          = 221;
    public static final int KEYCODE_SCAN_RIGHT          = 222;
    public static final int KEYCODE_FN             = 223;
    private static final int LAST_KEYCODE           = KEYCODE_FN;//KEYCODE_ASSIST;////
private static void populateKeycodeSymbolicNames() {
SparseArray&String& names = KEYCODE_SYMBOLIC_NAMES;
names.append(KEYCODE_UNKNOWN, &KEYCODE_UNKNOWN&);
names.append(KEYCODE_SOFT_LEFT, &KEYCODE_SOFT_LEFT&);
names.append(KEYCODE_SOFT_RIGHT, &KEYCODE_SOFT_RIGHT&);
names.append(KEYCODE_HOME, &KEYCODE_HOME&);
names.append(KEYCODE_BACK, &KEYCODE_BACK&);
names.append(KEYCODE_CALL, &KEYCODE_CALL&);
names.append(KEYCODE_ENDCALL, &KEYCODE_ENDCALL&);
names.append(KEYCODE_0, &KEYCODE_0&);
alps\frameworks\base\api\17.txt & // android API 17 = android4.2 //找到 17.txt文件改 &//可能需要使用命令:./make update-api
field public static final int KEYCODE_HOME = 3; // 0x3
//与上面的数字值要一样。
field public static final int META_SHIFT_RIGHT_ON = 128; // 0x80
field public static final int META_SYM_ON = 4; // 0x4
field public static final int KEYCODE_SCAN = 220; // 0xdc
field public static final int KEYCODE_SCAN_LEFT = 221; // 0xdd
field public static final int KEYCODE_SCAN_RIGHT = 221; // 0xde
alpsAteam\frameworks\native\include\android\keycodes.h
AKEYCODE_KANA
AKEYCODE_ASSIST
AKEYCODE_SCAN
= 220,//sam add
AKEYCODE_SCAN_LEFT
AKEYCODE_SCAN_RIGHT
AKEYCODE_FN
// NOTE: If you add a new keycode here you must also add it to several other files.
Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
\alps\frameworks\base\libs\androidfw\Input.cpp
bool KeyEvent::isSystemKey(int32_t keyCode) {
switch (keyCode) {
case AKEYCODE_MENU:
case AKEYCODE_SOFT_RIGHT:
case AKEYCODE_HOME:
case AKEYCODE_BACK:
case AKEYCODE_CALL:
case AKEYCODE_SEARCH:
case AKEYCODE_SCAN://sam add --below...
case AKEYCODE_SCAN_LEFT:
case AKEYCODE_SCAN_RIGHT:
case AKEYCODE_FN:
case AKEYCODE_F1:
case AKEYCODE_F2:
case AKEYCODE_F3:
case AKEYCODE_F4:
alps\frameworks\native\include\input\KeycodeLabels.h
static const KeycodeLabel KEYCODES[] = {//下层与上层的对照,能过字符串把两个数字来找的。
{ &SOFT_LEFT&, 1 },
{ &SOFT_RIGHT&, 2 },
{ &HOME&, 3 },
{ &BACK&, 4 },
{ &KANA&, 218 },
{ &ASSIST&, 219 },
{ &SCAN&, 220 },//sam add
{ &SCAN_LEFT&, 221 },
{ &SCAN_RIGHT&, 222 },
{ &FN&, 223 },
// NOTE: If you add a new keycode here you must also add it to several other files.
Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
{ NULL, 0 }
mtk-kpd.kl //底层
SCAN_RIGHT
//mt6571/72可以做18个的扩展键盘(3个row pin和3个col pin),但做不了更多,
3*3*2 =power , volume , &&
更多keypad需要做8*8 (8 row pin 和8 col pin)
也可以外挂一个键盘ic来做。
//mtk默认pmic有两个key ,一个是 power key,另一个是 vlume down key/home key/&
在codegen.dws中
[KEYPAD Setting]页面,有一个PowerKey use EINT ,选中,则会打开了这个开关 &KPD_PWRKEY_USE_EINT在mediatek\kernel\drivers\keypad\kpd.c中使用到.一般我们不用EINT做power key,而是默认使用pmic做power key.&/pre&&pre code_snippet_id=&378654& snippet_file_name=&blog__3325559& name=&code& class=&cpp&&alps\mediatek\platform\mt6572\kernel\drivers\keypad\kpd.c
* Copyright (C) 2010 MediaTek, Inc.
* Author: Terry Chang &terry.&
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* GNU General Public License for more details.
#include &linux/init.h&
#include &linux/module.h&
#include &linux/kernel.h&
#include &linux/input.h&
#include &linux/workqueue.h&
#include &linux/timer.h&
#include &linux/interrupt.h&
#include &linux/fs.h&
#include &linux/miscdevice.h&
#include &linux/platform_device.h&
#include &linux/earlysuspend.h&
#include &linux/spinlock.h&
#include &asm/atomic.h&
#include &asm/uaccess.h&
#include &mach/mt_reg_base.h&
#include &mach/mt_boot.h&
#include &mtk_kpd.h&
/* custom file */
#include &mach/irqs.h&
#include &mach/eint.h&
#include &mach/mt_gpio.h&
#include &mach/mt_pmic_wrap.h&
#include &mach/mt_sleep.h&
#include &mach/kpd.h&
#include &mach/sync_write.h&
#include &linux/aee.h&
#if 1 //ATA_TEST
#define KPD_AUTOTEST_BY_KP
#define KPD_NAME &mtk-kpd&
/* Keypad registers */
#define KP_STA
(KP_BASE + 0x0000)
#define KP_MEM1
(KP_BASE + 0x0004)
#define KP_MEM2
(KP_BASE + 0x0008)
#define KP_MEM3
(KP_BASE + 0x000c)
#define KP_MEM4
(KP_BASE + 0x0010)
#define KP_MEM5
(KP_BASE + 0x0014)
#define KP_DEBOUNCE
(KP_BASE + 0x0018)
#define KP_SCAN_TIMING
(KP_BASE + 0x001C)
#define KP_SEL
(KP_BASE + 0x0020)
#define KP_EN
(KP_BASE + 0x0024)
#define KPD_NUM_MEMS 5
#define KPD_MEM5_BITS 8
#define KPD_NUM_KEYS 72 /* 4 * 16 + KPD_MEM5_BITS */
#define KPD_DEBOUNCE_MASK ((1U && 14) - 1)
#define KPD_SAY
#if KPD_DEBUG
#define kpd_print(fmt, arg...) printk(KPD_SAY fmt, ##arg)
#define kpd_print(fmt, arg...) do {} while (0)
static struct input_dev *kpd_input_
static bool kpd_suspend =
static int kpd_show_hw_keycode = 1;
static int kpd_show_register = 1;
static int kpd_enable_lprst = 1;
/* for AEE manual dump */
static bool kpd_volumn_down_flag =
static bool kpd_volumn_up_flag =
static inline void check_aee_dump()
if( (kpd_volumn_down_flag == true) && (kpd_volumn_up_flag == true))
printk(KPD_SAY &kpd_volumn_up+ volumn_down,will trige DB\n&);
aee_kernel_reminding(&manual dump &, &Triggered by press KEY_VOLUMEUP+KEY_VOLUMEDOWN&);
/* for backlight control */
#if KPD_DRV_CTRL_BACKLIGHT
static void kpd_switch_backlight(struct work_struct *work);
static void kpd_backlight_timeout(unsigned long data);
static DECLARE_WORK(kpd_backlight_work, kpd_switch_backlight);
static DEFINE_TIMER(kpd_backlight_timer, kpd_backlight_timeout, 0, 0);
static unsigned long kpd_wake_keybit[BITS_TO_LONGS(KEY_CNT)];
static u16 kpd_wake_key[] __initdata = KPD_BACKLIGHT_WAKE_KEY;
static volatile bool kpd_backlight_
static atomic_t kpd_key_pressed = ATOMIC_INIT(0);
/* for slide QWERTY */
#if KPD_HAS_SLIDE_QWERTY
static void kpd_slide_handler(unsigned long data);
static DECLARE_TASKLET(kpd_slide_tasklet, kpd_slide_handler, 0);
static u8 kpd_slide_state = !KPD_SLIDE_POLARITY;
/* for Power key using EINT */
#if KPD_PWRKEY_USE_EINT
static void kpd_pwrkey_handler(unsigned long data);
static DECLARE_TASKLET(kpd_pwrkey_tasklet, kpd_pwrkey_handler, 0);
static u8 kpd_pwrkey_state = !KPD_PWRKEY_POLARITY;
/* for Power key using PMIC */
/*********************************************************************/
#if 0//KPD_PWRKEY_USE_PMIC //for 77 chip and earlier version
power key bug, has fixed on 89 chip
static void kpd_pwrkey_handler(struct work_struct *work);
static DECLARE_WORK(pwrkey_pmic_work, kpd_pwrkey_handler);
/*********************************************************************/
/* for keymap handling */
static DEFINE_SPINLOCK(keymap_handler_spinlock);
static void kpd_keymap_handler(unsigned long data);
static DECLARE_TASKLET(kpd_keymap_tasklet, kpd_keymap_handler, 0);
#define KPD_INIT_KEYMAP_FULL() \
[0] = KEY_1,
[1] = KEY_2,
[2] = KEY_3,
[3] = KEY_4,
[4] = KEY_5,
[5] = KEY_6,
[6] = KEY_7,
[7] = KEY_8,
[8] = KEY_9,
[9] = KEY_VOLUMEDOWN,
[10] = KEY_VOLUMEUP,
[11] = KEY_0,
[12] = KEY_ENTER,
[13] = KEY_TAB,
[14] = KEY_BACKSPACE,
[15] = KEY_STAR,
[16] = KEY_POUND,
[17] = KEY_SYM,
[18] = KEY_DOT,
[19] = KEY_FN,
[20] = KEY_F1,
[21] = KEY_F2,
[22] = KEY_F3,
[23] = KEY_F4,
[24] = KEY_DEL,
[25] = KEY_S,
[25] = KEY_OK,
//static u16 kpd_keymap[KPD_NUM_KEYS] = KPD_INIT_KEYMAP_FULL(); //KPD_INIT_KEYMAP();
static u16 kpd_keymap[KPD_NUM_KEYS] = KPD_INIT_KEYMAP();
static u16 kpd_keymap_state[KPD_NUM_MEMS] = {
0xffff, 0xffff, 0xffff, 0xffff, 0x00ff
/*********************************************************************/
/*************************kpd function decleare***************************/
/*********************************************************************/
static int kpd_pdrv_probe(struct platform_device *pdev);
static int kpd_pdrv_remove(struct platform_device *pdev);
#ifndef CONFIG_HAS_EARLYSUSPEND
static int kpd_pdrv_suspend(struct platform_device *pdev, pm_message_t state);
static int kpd_pdrv_resume(struct platform_device *pdev);
void mtk_kpd_get_gpio_col(unsigned int COL_REG[], unsigned int GPIO_MODE[]);
void kpd_auto_test_for_factorymode(void);
static struct platform_driver kpd_pdrv = {
= kpd_pdrv_probe,
= kpd_pdrv_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
.suspend = kpd_pdrv_suspend,
= kpd_pdrv_resume,
.name = KPD_NAME,
.owner = THIS_MODULE,
/********************************************************************/
void mtk_kpd_get_gpio_col(unsigned int COL_REG[], unsigned int GPIO_MODE[])
for(i = 0; i& 8; i++)
COL_REG[i] = 0;
GPIO_MODE[i] = 0;
kpd_print(&Enter mtk_kpd_get_gpio_col! \n&);
#ifdef GPIO_KPD_KCOL0_PIN
kpd_print(&checking GPIO_KPD_KCOL0_PIN! \n&);
COL_REG[0] = GPIO_KPD_KCOL0_PIN;
GPIO_MODE[0] |= (GPIO_KPD_KCOL0_PIN_M_KCOL && 4);
#ifdef GPIO_KPD_KCOL1_PIN
kpd_print(&checking GPIO_KPD_KCOL1_PIN! \n&);
COL_REG[1] = GPIO_KPD_KCOL1_PIN;
GPIO_MODE[1] |= (GPIO_KPD_KCOL1_PIN_M_KCOL && 4);
#ifdef GPIO_KPD_KCOL2_PIN
kpd_print(&checking GPIO_KPD_KCOL2_PIN! \n&);
COL_REG[2] = GPIO_KPD_KCOL2_PIN;
GPIO_MODE[2] |= (GPIO_KPD_KCOL2_PIN_M_KCOL && 4);
#ifdef GPIO_KPD_KCOL3_PIN
kpd_print(&checking GPIO_KPD_KCOL3_PIN! \n&);
COL_REG[3] = GPIO_KPD_KCOL3_PIN;
GPIO_MODE[3] |= (GPIO_KPD_KCOL3_PIN_M_KCOL && 4);
#ifdef GPIO_KPD_KCOL4_PIN
kpd_print(&checking GPIO_KPD_KCOL4_PIN! \n&);
COL_REG[4] = GPIO_KPD_KCOL4_PIN;
GPIO_MODE[4] |= (GPIO_KPD_KCOL4_PIN_M_KCOL && 4);
#ifdef GPIO_KPD_KCOL5_PIN
kpd_print(&checking GPIO_KPD_KCOL5_PIN! \n&);
COL_REG[5] = GPIO_KPD_KCOL5_PIN;
GPIO_MODE[5] |= (GPIO_KPD_KCOL5_PIN_M_KCOL && 4);
#ifdef GPIO_KPD_KCOL6_PIN
kpd_print(&checking GPIO_KPD_KCOL6_PIN! \n&);
COL_REG[6] = GPIO_KPD_KCOL6_PIN;
GPIO_MODE[6] |= (GPIO_KPD_KCOL6_PIN_M_KCOL && 4);
#ifdef GPIO_KPD_KCOL7_PIN
kpd_print(&checking GPIO_KPD_KCOL7_PIN! \n&);
COL_REG[7] = GPIO_KPD_KCOL7_PIN;
GPIO_MODE[7] |= (GPIO_KPD_KCOL7_PIN_M_KCOL && 4);
#ifdef KPD_AUTOTEST_BY_KP
void kpd_reset_keymap_state(u16 state[])
for(i = 0; i & (KPD_NUM_MEMS - 1); i++)
state[i] = 0
state[(KPD_NUM_MEMS - 1)] = 0x00
void kpd_kcol_scan_for_factorymode(void)
unsigned int COL_REG[8], COL_LAST = 0;
unsigned int GPIO_MODE[8];
int i, col_
#if !KPD_USE_EXTEND_TYPE
kpd_print(&Enter kpd_kcol_scan_for_factorymode on single keypad! \n&);
col_num = 8;
kpd_print(&Enter kpd_kcol_scan_for_factorymode on double keypad! \n&);
col_num = 3;
disable_irq_nosync(MT_KP_IRQ_ID);
*(volatile u16 *)KP_EN = 0;
kpd_keymap_handler(1);
msleep(100);
mtk_kpd_get_gpio_col(COL_REG, GPIO_MODE);
for(i = 0; i & col_ i++)
if (COL_REG[i] != 0)
mt_set_gpio_mode(COL_REG[i], GPIO_MODE_GPIO);
for(i = 0; i & col_ i++)
if (COL_REG[i] != 0)
mt_set_gpio_mode(COL_REG[i], ((GPIO_MODE[i] && 4) & 0x0f));
kpd_reset_keymap_state(kpd_keymap_state);
COL_LAST = COL_REG[i];
*(volatile u16 *)KP_EN = 0x1;
kpd_print(&kpd_kcol_scan_for_factorymode:
KP enable KCOL=%d \n&, i);
msleep(100);
if(*(volatile u16 *)KP_STA & 0x01)
kpd_keymap_handler(2);
if(0 != COL_LAST)
msleep(100);
kpd_keymap_handler(1);
*(volatile u16 *)KP_EN = 0;
mt_set_gpio_mode(COL_LAST, GPIO_MODE_GPIO);
kpd_print(&kpd_kcol_scan_for_factorymode:
KP disable KCOL=%d \n&, i);
COL_LAST = 0;
for(i = 0; i & col_ i++)
if (COL_REG[i] != 0)
mt_set_gpio_mode(COL_REG[i], ((GPIO_MODE[i] && 4) & 0x0f));
kpd_reset_keymap_state(kpd_keymap_state);
*(volatile u16 *)KP_EN = 0x1;
if(upmu_get_pwrkey_deb()!=1)
kpd_pwrkey_pmic_handler(0);
msleep(100);
kpd_pwrkey_pmic_handler(1);
enable_irq(MT_KP_IRQ_ID);
//KPD_AUTOTEST_BY_KP
void kpd_auto_test_for_factorymode(void)
unsigned int COL_REG[8];
unsigned int GPIO_MODE[8];
kpd_pwrkey_pmic_handler(1);
msleep(100);
kpd_pwrkey_pmic_handler(0);
#ifdef KPD_PMIC_RSTKEY_MAP
kpd_pmic_rstkey_handler(1);
msleep(100);
kpd_pmic_rstkey_handler(0);
kpd_print(&Enter kpd_auto_test_for_factorymode! \n&);
mtk_kpd_get_gpio_col(COL_REG, GPIO_MODE);
for(i = 0; i & 8; i++)
if (COL_REG[i] != 0)
msleep(100);
kpd_print(&kpd kcolumn %d pull down!\n&, COL_REG[i]);
mt_set_gpio_pull_select(COL_REG[i], 0);
msleep(100);
kpd_print(&kpd kcolumn %d pull up!\n&, COL_REG[i]);
mt_set_gpio_pull_select(COL_REG[i], 1);
//KPD_AUTOTEST_BY_KP
/********************************************************************/
/********************************************************************/
/*****************for kpd auto set wake up source*************************/
/********************************************************************/
static volatile int call_status = 0;
static ssize_t kpd_store_call_state(struct device_driver *ddri, const char *buf, size_t count)
if (sscanf(buf, &%u&, &call_status) != 1) {
kpd_print(&kpd call state: Invalid values\n&);
return -EINVAL;
switch(call_status)
kpd_print(&kpd call state: Idle state!\n&);
kpd_print(&kpd call state: ringing state!\n&);
kpd_print(&kpd call state: active or hold state!\n&);
kpd_print(&kpd call state: Invalid values\n&);
static ssize_t kpd_show_call_state(struct device_driver *ddri, char *buf)
res = snprintf(buf, PAGE_SIZE, &%d\n&, call_status);
static DRIVER_ATTR(kpd_call_state, S_IWUSR | S_IRUGO, kpd_show_call_state, kpd_store_call_state);
static struct driver_attribute *kpd_attr_list[] = {
&driver_attr_kpd_call_state,
/*----------------------------------------------------------------------------*/
static int kpd_create_attr(struct device_driver *driver)
int idx, err = 0;
int num = (int)(sizeof(kpd_attr_list)/sizeof(kpd_attr_list[0]));
if (driver == NULL)
return -EINVAL;
for(idx = 0; idx & idx++)
if((err = driver_create_file(driver, kpd_attr_list[idx])))
kpd_print(&driver_create_file (%s) = %d\n&, kpd_attr_list[idx]-&attr.name, err);
/*----------------------------------------------------------------------------*/
static int kpd_delete_attr(struct device_driver *driver)
int idx ,err = 0;
int num = (int)(sizeof(kpd_attr_list)/sizeof(kpd_attr_list[0]));
if (!driver)
return -EINVAL;
for (idx = 0; idx & idx++)
driver_remove_file(driver, kpd_attr_list[idx]);
/*----------------------------------------------------------------------------*/
/********************************************************************/
/********************************************************************/
/********************************************************************/
/* for autotest */
#if KPD_AUTOTEST
static const u16 kpd_auto_keymap[] = {
KEY_OK, KEY_MENU,
KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,
KEY_HOME, KEY_BACK,
KEY_CALL, KEY_ENDCALL,
KEY_VOLUMEUP, KEY_VOLUMEDOWN,
KEY_FOCUS, KEY_CAMERA,
/* for AEE manual dump */
#define AEE_VOLUMEUP_BIT 0
#define AEE_VOLUMEDOWN_BIT 1
#define AEE_DELAY_TIME
/* enable volup + voldown was pressed 5~15 s Trigger aee manual dump */
#define AEE_ENABLE_5_15
static struct hrtimer aee_
static unsigned long
aee_pressed_
static bool aee_timer_
#if AEE_ENABLE_5_15
#define AEE_DELAY_TIME_5S 5
static struct hrtimer aee_timer_5s;
static bool aee_timer_5s_
static bool flags_5s;
static inline void kpd_update_aee_state(void) {
if(aee_pressed_keys == ((1&&AEE_VOLUMEUP_BIT) | (1&&AEE_VOLUMEDOWN_BIT))) {
/* if volumeup and volumedown was pressed the same time then start the time of ten seconds */
aee_timer_started =
#if AEE_ENABLE_5_15
aee_timer_5s_started =
hrtimer_start(&aee_timer_5s,
ktime_set(AEE_DELAY_TIME_5S, 0),
HRTIMER_MODE_REL);
hrtimer_start(&aee_timer,
ktime_set(AEE_DELAY_TIME, 0),
HRTIMER_MODE_REL);
kpd_print(&aee_timer started\n&);
if(aee_timer_started) {
* hrtimer_cancel - cancel a timer and wait for the handler to finish.
* Returns:
* 0 when the timer was not active.
* 1 when the timer was active.
if(hrtimer_cancel(&aee_timer))
kpd_print(&try to cancel hrtimer \n&);
#if AEE_ENABLE_5_15
if(flags_5s)
printk(&Pressed Volup + Voldown5s~15s then trigger aee manual dump.\n&);
aee_kernel_reminding(&manual dump&, &Trigger Vol Up +Vol Down 5s&);
#if AEE_ENABLE_5_15
flags_5s =
aee_timer_started =
kpd_print(&aee_timer canceled\n&);
#if AEE_ENABLE_5_15
if(aee_timer_5s_started) {
* hrtimer_cancel - cancel a timer and wait for the handler to finish.
* Returns:
* 0 when the timer was not active.
* 1 when the timer was active.
if(hrtimer_cancel(&aee_timer_5s))
kpd_print(&try to cancel hrtimer (5s) \n&);
aee_timer_5s_started =
kpd_print(&aee_timer canceled (5s)\n&);
static void kpd_aee_handler(u32 keycode, u16 pressed) {
if(pressed) {
if(keycode == KEY_VOLUMEUP) {
__set_bit(AEE_VOLUMEUP_BIT, &aee_pressed_keys);
} else if(keycode == KEY_VOLUMEDOWN) {
__set_bit(AEE_VOLUMEDOWN_BIT, &aee_pressed_keys);
kpd_update_aee_state();
if(keycode == KEY_VOLUMEUP) {
__clear_bit(AEE_VOLUMEUP_BIT, &aee_pressed_keys);
} else if(keycode == KEY_VOLUMEDOWN) {
__clear_bit(AEE_VOLUMEDOWN_BIT, &aee_pressed_keys);
kpd_update_aee_state();
static enum hrtimer_restart aee_timer_func(struct hrtimer *timer) {
//printk(&kpd: vol up+vol down AEE manual dump!\n&);
//aee_kernel_reminding(&manual dump &, &Triggered by press KEY_VOLUMEUP+KEY_VOLUMEDOWN&);
aee_trigger_kdb();
return HRTIMER_NORESTART;
#if AEE_ENABLE_5_15
static enum hrtimer_restart aee_timer_5s_func(struct hrtimer *timer) {
//printk(&kpd: vol up+vol down AEE manual dump timer 5s !\n&);
flags_5s =
return HRTIMER_NORESTART;
static inline void kpd_get_keymap_state(u16 state[])
state[0] = *(volatile u16 *)KP_MEM1;
state[1] = *(volatile u16 *)KP_MEM2;
state[2] = *(volatile u16 *)KP_MEM3;
state[3] = *(volatile u16 *)KP_MEM4;
state[4] = *(volatile u16 *)KP_MEM5;
if (kpd_show_register) {
printk(KPD_SAY &register = %x %x %x %x %x\n&,
state[0], state[1], state[2], state[3], state[4]);
static inline void kpd_set_debounce(u16 val)
mt65xx_reg_sync_writew((u16)(val & KPD_DEBOUNCE_MASK), KP_DEBOUNCE);
#if KPD_DRV_CTRL_BACKLIGHT
static void kpd_switch_backlight(struct work_struct *work)
if (kpd_backlight_on) {
kpd_enable_backlight();
kpd_print(&backlight is on\n&);
kpd_disable_backlight();
kpd_print(&backlight is off\n&);
static void kpd_backlight_timeout(unsigned long data)
if (!atomic_read(&kpd_key_pressed)) {
kpd_backlight_on = !!atomic_read(&kpd_key_pressed);
schedule_work(&kpd_backlight_work);
kpd_print(&backlight timeout%s\n&,
data ? &: schedule backlight work& : &&);
void kpd_backlight_handler(bool pressed, u16 linux_keycode)
if (kpd_suspend && !test_bit(linux_keycode, kpd_wake_keybit)) {
kpd_print(&Linux keycode %u is not WAKE key\n&, linux_keycode);
/* not in suspend or the key pressed is WAKE key */
if (pressed) {
atomic_inc(&kpd_key_pressed);
kpd_backlight_on = !!atomic_read(&kpd_key_pressed);
schedule_work(&kpd_backlight_work);
kpd_print(&switch backlight on\n&);
atomic_dec(&kpd_key_pressed);
mod_timer(&kpd_backlight_timer,
jiffies + KPD_BACKLIGHT_TIME * HZ);
kpd_print(&activate backlight timer\n&);
#if KPD_HAS_SLIDE_QWERTY
static void kpd_slide_handler(unsigned long data)
u8 old_state = kpd_slide_
kpd_slide_state = !kpd_slide_
slid = (kpd_slide_state == !!KPD_SLIDE_POLARITY);
/* for SW_LID, 1: lid open =& slid, 0: lid shut =& closed */
input_report_switch(kpd_input_dev, SW_LID, slid);
input_sync(kpd_input_dev);
kpd_print(&report QWERTY = %s\n&, slid ? &slid& : &closed&);
if(old_state) {
mt_set_gpio_pull_select(GPIO_QWERTYSLIDE_EINT_PIN, 0);
mt_set_gpio_pull_select(GPIO_QWERTYSLIDE_EINT_PIN, 1);
/* for detecting the return to old_state */
mt65xx_eint_set_polarity(KPD_SLIDE_EINT, old_state);
mt65xx_eint_unmask(KPD_SLIDE_EINT);
static void kpd_slide_eint_handler(void)
tasklet_schedule(&kpd_slide_tasklet);
#if KPD_PWRKEY_USE_EINT
static void kpd_pwrkey_handler(unsigned long data)
u8 old_state = kpd_pwrkey_
kpd_pwrkey_state = !kpd_pwrkey_
pressed = (kpd_pwrkey_state == !!KPD_PWRKEY_POLARITY);
if (kpd_show_hw_keycode) {
printk(KPD_SAY &(%s) HW keycode = using EINT\n&,
pressed ? &pressed& : &released&);
kpd_backlight_handler(pressed, KPD_PWRKEY_MAP);
input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
input_sync(kpd_input_dev);
kpd_print(&report Linux keycode = %u\n&, KPD_PWRKEY_MAP);
/* for detecting the return to old_state */
mt65xx_eint_set_polarity(KPD_PWRKEY_EINT, old_state);
mt65xx_eint_unmask(KPD_PWRKEY_EINT);
static void kpd_pwrkey_eint_handler(void)
tasklet_schedule(&kpd_pwrkey_tasklet);
/*********************************************************************/
#if 0//KPD_PWRKEY_USE_PMIC //for 77 chip and earlier version
power key bug, has fixed on 89 chip
static void kpd_pwrkey_handler(struct work_struct *work)
int pressed = 1;
input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
input_sync(kpd_input_dev);
if (kpd_show_hw_keycode) {
printk(KPD_SAY &(%s) HW keycode = using PMIC\n&,
pressed ? &pressed& : &released&);
if(upmu_get_pwrkey_deb() == 1)
pressed = 0;
/* Report Release */
input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
input_sync(kpd_input_dev);
if (kpd_show_hw_keycode) {
printk(KPD_SAY &(%s) HW keycode = using PMIC\n&,
pressed ? &pressed& : &released&);
msleep(10);
void kpd_pwrkey_pmic_handler(unsigned long pressed)
printk(KPD_SAY &Power Key generate, pressed=%ld\n&, pressed);
if(!kpd_input_dev) {
printk(&KPD input device not ready\n&);
if(get_chip_eco_ver() == CHIP_E2) {
input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
input_sync(kpd_input_dev);
if (kpd_show_hw_keycode) {
printk(KPD_SAY &(%s) HW keycode =%d using PMIC\n&,
pressed ? &pressed& : &released&, KPD_PWRKEY_MAP);
schedule_work(&pwrkey_pmic_work);
/*********************************************************************/
#if KPD_PWRKEY_USE_PMIC
void kpd_pwrkey_pmic_handler(unsigned long pressed)
printk(KPD_SAY &Power Key generate, pressed=%ld\n&, pressed);
if(!kpd_input_dev) {
printk(&KPD input device not ready\n&);
input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
input_sync(kpd_input_dev);
if (kpd_show_hw_keycode) {
printk(KPD_SAY &(%s) HW keycode =%d using PMIC\n&,
pressed ? &pressed& : &released&, KPD_PWRKEY_MAP);
/*********************************************************************/
void kpd_pmic_rstkey_handler(unsigned long pressed)
printk(KPD_SAY &PMIC reset Key generate, pressed=%ld\n&, pressed);
if(!kpd_input_dev) {
printk(&KPD input device not ready\n&);
#ifdef KPD_PMIC_RSTKEY_MAP
input_report_key(kpd_input_dev, KPD_PMIC_RSTKEY_MAP, pressed);
input_sync(kpd_input_dev);
if (kpd_show_hw_keycode) {
printk(KPD_SAY &(%s) HW keycode =%d using PMIC\n&,
pressed ? &pressed& : &released&, KPD_PMIC_RSTKEY_MAP);
kpd_aee_handler(KPD_PMIC_RSTKEY_MAP, pressed);
static void kpd_keymap_handler(unsigned long data)
u16 new_state[KPD_NUM_MEMS], change,
u16 hw_keycode, linux_
spin_lock(&keymap_handler_spinlock);
kpd_get_keymap_state(new_state);
#ifdef KPD_AUTOTEST_BY_KP
if(data == 1)
kpd_reset_keymap_state(new_state);
kpd_print(&kpd_keymap_handler:
data=%d, new_state = %x %x %x %x %x \n&,
data, new_state[0], new_state[1], new_state[2], new_state[3], new_state[4]);
for (i = 0; i & KPD_NUM_MEMS; i++) {
change = new_state[i] ^ kpd_keymap_state[i];
if (!change)
for (j = 0; j & 16; j++) {
mask = 1U &&
if (!(change & mask))
hw_keycode = (i && 4) +
/* bit is 1: not pressed, 0: pressed */
pressed = !(new_state[i] & mask);
if (kpd_show_hw_keycode) {
printk(KPD_SAY &(%s) HW keycode = %u\n&,
pressed ? &pressed& : &released&,
hw_keycode);
BUG_ON(hw_keycode &= KPD_NUM_KEYS);
linux_keycode = kpd_keymap[hw_keycode];
if (unlikely(linux_keycode == 0)) {
kpd_print(&Linux keycode = 0\n&);
#ifdef KPD_AUTOTEST_BY_KP
if((get_boot_mode() != FACTORY_BOOT) && (get_boot_mode() != ATE_FACTORY_BOOT))
kpd_aee_handler(linux_keycode, pressed);
kpd_backlight_handler(pressed, linux_keycode);
input_report_key(kpd_input_dev, linux_keycode, pressed);
input_sync(kpd_input_dev);
kpd_print(&report Linux keycode = %u\n&, linux_keycode);
memcpy(kpd_keymap_state, new_state, sizeof(new_state));
//kpd_print(&save new keymap state\n&);
#ifdef KPD_AUTOTEST_BY_KP
if(data == 0)
enable_irq(MT_KP_IRQ_ID);
spin_unlock(&keymap_handler_spinlock);
static irqreturn_t kpd_irq_handler(int irq, void *dev_id)
/* use _nosync to avoid deadlock */
disable_irq_nosync(MT_KP_IRQ_ID);
tasklet_schedule(&kpd_keymap_tasklet);
return IRQ_HANDLED;
static long kpd_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
void __user *uarg = (void __user *)
struct kpd_
switch (cmd) {
#if KPD_AUTOTEST
case PRESS_OK_KEY://KPD_AUTOTEST disable auto test setting to resolve CR ALPS
if(test_bit(KEY_OK, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS OK KEY!!\n&);
input_report_key(kpd_input_dev, KEY_OK, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support OK KEY!!\n&);
case RELEASE_OK_KEY:
if(test_bit(KEY_OK, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE OK KEY!!\n&);
input_report_key(kpd_input_dev, KEY_OK, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support OK KEY!!\n&);
case PRESS_MENU_KEY:
if(test_bit(KEY_MENU, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS MENU KEY!!\n&);
input_report_key(kpd_input_dev, KEY_MENU, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support MENU KEY!!\n&);
case RELEASE_MENU_KEY:
if(test_bit(KEY_MENU, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE MENU KEY!!\n&);
input_report_key(kpd_input_dev, KEY_MENU, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support MENU KEY!!\n&);
case PRESS_UP_KEY:
if(test_bit(KEY_UP, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS UP KEY!!\n&);
input_report_key(kpd_input_dev, KEY_UP, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support UP KEY!!\n&);
case RELEASE_UP_KEY:
if(test_bit(KEY_UP, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE UP KEY!!\n&);
input_report_key(kpd_input_dev, KEY_UP, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support UP KEY!!\n&);
case PRESS_DOWN_KEY:
if(test_bit(KEY_DOWN, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS DOWN KEY!!\n&);
input_report_key(kpd_input_dev, KEY_DOWN, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support DOWN KEY!!\n&);
case RELEASE_DOWN_KEY:
if(test_bit(KEY_DOWN, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE DOWN KEY!!\n&);
input_report_key(kpd_input_dev, KEY_DOWN, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support DOWN KEY!!\n&);
case PRESS_LEFT_KEY:
if(test_bit(KEY_LEFT, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS LEFT KEY!!\n&);
input_report_key(kpd_input_dev, KEY_LEFT, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support LEFT KEY!!\n&);
case RELEASE_LEFT_KEY:
if(test_bit(KEY_LEFT, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE LEFT KEY!!\n&);
input_report_key(kpd_input_dev, KEY_LEFT, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support LEFT KEY!!\n&);
case PRESS_RIGHT_KEY:
if(test_bit(KEY_RIGHT, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS RIGHT KEY!!\n&);
input_report_key(kpd_input_dev, KEY_RIGHT, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support RIGHT KEY!!\n&);
case RELEASE_RIGHT_KEY:
if(test_bit(KEY_RIGHT, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE RIGHT KEY!!\n&);
input_report_key(kpd_input_dev, KEY_RIGHT, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support RIGHT KEY!!\n&);
case PRESS_HOME_KEY:
if(test_bit(KEY_HOME, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS HOME KEY!!\n&);
input_report_key(kpd_input_dev, KEY_HOME, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support HOME KEY!!\n&);
case RELEASE_HOME_KEY:
if(test_bit(KEY_HOME, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE HOME KEY!!\n&);
input_report_key(kpd_input_dev, KEY_HOME, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support HOME KEY!!\n&);
case PRESS_BACK_KEY:
if(test_bit(KEY_BACK, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS BACK KEY!!\n&);
input_report_key(kpd_input_dev, KEY_BACK, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support BACK KEY!!\n&);
case RELEASE_BACK_KEY:
if(test_bit(KEY_BACK, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE BACK KEY!!\n&);
input_report_key(kpd_input_dev, KEY_BACK, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support BACK KEY!!\n&);
case PRESS_CALL_KEY:
if(test_bit(KEY_CALL, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS CALL KEY!!\n&);
input_report_key(kpd_input_dev, KEY_CALL, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support CALL KEY!!\n&);
case RELEASE_CALL_KEY:
if(test_bit(KEY_CALL, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE CALL KEY!!\n&);
input_report_key(kpd_input_dev, KEY_CALL, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support CALL KEY!!\n&);
case PRESS_ENDCALL_KEY:
if(test_bit(KEY_ENDCALL, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS ENDCALL KEY!!\n&);
input_report_key(kpd_input_dev, KEY_ENDCALL, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support ENDCALL KEY!!\n&);
case RELEASE_ENDCALL_KEY:
if(test_bit(KEY_ENDCALL, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE ENDCALL KEY!!\n&);
input_report_key(kpd_input_dev, KEY_ENDCALL, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support ENDCALL KEY!!\n&);
case PRESS_VLUP_KEY:
if(test_bit(KEY_VOLUMEUP, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS VOLUMEUP KEY!!\n&);
input_report_key(kpd_input_dev, KEY_VOLUMEUP, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support VOLUMEUP KEY!!\n&);
case RELEASE_VLUP_KEY:
if(test_bit(KEY_VOLUMEUP, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE VOLUMEUP KEY!!\n&);
input_report_key(kpd_input_dev, KEY_VOLUMEUP, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support VOLUMEUP KEY!!\n&);
case PRESS_VLDOWN_KEY:
if(test_bit(KEY_VOLUMEDOWN, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS VOLUMEDOWN KEY!!\n&);
input_report_key(kpd_input_dev, KEY_VOLUMEDOWN, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support VOLUMEDOWN KEY!!\n&);
case RELEASE_VLDOWN_KEY:
if(test_bit(KEY_VOLUMEDOWN, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE VOLUMEDOWN KEY!!\n&);
input_report_key(kpd_input_dev, KEY_VOLUMEDOWN, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support VOLUMEDOWN KEY!!\n&);
case PRESS_FOCUS_KEY:
if(test_bit(KEY_FOCUS, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS FOCUS KEY!!\n&);
input_report_key(kpd_input_dev, KEY_FOCUS, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support FOCUS KEY!!\n&);
case RELEASE_FOCUS_KEY:
if(test_bit(KEY_FOCUS, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE FOCUS KEY!!\n&);
input_report_key(kpd_input_dev, KEY_FOCUS, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support RELEASE KEY!!\n&);
case PRESS_CAMERA_KEY:
if(test_bit(KEY_CAMERA, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] PRESS CAMERA KEY!!\n&);
input_report_key(kpd_input_dev, KEY_CAMERA, 1);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support CAMERA KEY!!\n&);
case RELEASE_CAMERA_KEY:
if(test_bit(KEY_CAMERA, kpd_input_dev-&keybit)){
printk(&[AUTOTEST] RELEASE CAMERA KEY!!\n&);
input_report_key(kpd_input_dev, KEY_CAMERA, 0);
input_sync(kpd_input_dev);
printk(&[AUTOTEST] Not Support CAMERA KEY!!\n&);
case SET_KPD_BACKLIGHT:
if (copy_from_user(&ledctl, uarg, sizeof(struct kpd_ledctl)))
return -EFAULT;
//kpd_set_backlight(ledctl.onoff, &ledctl.div, &ledctl.duty);
case SET_KPD_KCOL:
#ifndef KPD_AUTOTEST_BY_KP
kpd_auto_test_for_factorymode();
kpd_kcol_scan_for_factorymode();
printk(&[kpd_auto_test_for_factorymode] test performed!!\n&);
return -EINVAL;
static int kpd_dev_open(struct inode *inode, struct file *file)
static struct file_operations kpd_dev_fops = {
= THIS_MODULE,
.unlocked_ioctl = kpd_dev_ioctl,
= kpd_dev_open,
static struct miscdevice kpd_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = KPD_NAME,
.fops = &kpd_dev_fops,
static int kpd_open(struct input_dev *dev)
#if KPD_HAS_SLIDE_QWERTY
bool evdev_flag=
bool power_op=
struct input_handler *
struct input_handle *
handle = rcu_dereference(dev-&grab);
if (handle)
handler = handle-&
if(strcmp(handler-&name, &evdev&)==0)
return -1;
list_for_each_entry_rcu(handle, &dev-&h_list, d_node) {
handler = handle-&
if(strcmp(handler-&name, &evdev&)==0)
evdev_flag=
if(evdev_flag==false)
return -1;
power_op = powerOn_slidePin_interface();
if(!power_op) {
printk(KPD_SAY &Qwerty slide pin interface power on fail\n&);
kpd_print(&Qwerty slide pin interface power on success\n&);
mt65xx_eint_set_sens(KPD_SLIDE_EINT, KPD_SLIDE_SENSITIVE);
mt65xx_eint_set_hw_debounce(KPD_SLIDE_EINT, KPD_SLIDE_DEBOUNCE);
mt65xx_eint_registration(KPD_SLIDE_EINT, true, KPD_SLIDE_POLARITY,
kpd_slide_eint_handler, false);
power_op = powerOff_slidePin_interface();
if(!power_op) {
printk(KPD_SAY &Qwerty slide pin interface power off fail\n&);
kpd_print(&Qwerty slide pin interface power off success\n&);
/*qwerty slide: GPIO 214. input, mode=EINT, pull enbale, pull select high*/
mt_set_gpio_mode(214, 2);
mt_set_gpio_dir(214, 0);
mt_set_gpio_pull_enable(214, 1);
mt_set_gpio_pull_select(214, 0);
#if 1 // AW9523
扩展键盘IC:
#define GPIO_SIMULATE_I2C
#define AW9523_EINT_GPIO
#define AW9523_EINT_NO
//CUST_EINT_MHALL_NUM
#define AW9523_RESET_PIN GPIO128
#define KPD_AW9523_SWITCH_DEBOUNCE
#define KPD_AW9523_SWITCH_POLARITY
CUST_EINT_MHALL_POLARITY
#define KPD_AW9523_SWITCH_SENSITIVE
CUST_EINT_EDGE_SENSITIVE
// CUST_EINT_MHALL_SENSITIVE
static void kpd_aw9523_handler(unsigned long data);
static DECLARE_TASKLET(kpd_aw9523_tasklet, kpd_aw9523_handler, 0);
static u8 kpd_aw9523_state = !CUST_EINT_POLARITY_LOW;
#define LED_SLAVE_ADDR
0xb0//0xB6
//#if defined(GPIO_SIMULATE_I2C)
#define I2C_SDA_GPIO
GPIO114 //GPIO111
#define I2C_SCL_GPIO
GPIO113 //GPIO108
typedef enum {
typedef enum {
#define AW9523_I2C_MAX_LOOP 50
#define Y_NUM
#define X_NUM
// has pullup resistor
P0 ---& X_NUM ---& col
P1 ---& Y_NUM ---& line(row)
const P0_Enum COL[X_NUM] =
{P0_0, P0_1, P0_2, P0_3, P0_4, P0_5};
//const P1_Enum Line[Y_NUM] = {P1_2, P1_3, P1_4, P1_5, P1_6, P1_7};
const P1_Enum Line[Y_NUM] = {P1_0, P1_1, P1_2, P1_3, P1_4, P1_5};
aw9523_key[Y_NUM][X_NUM]={
KEY_9, KEY_POUND,
KEY_BACK},
{KEY_LEFT,
KEY_RIGHT,
KEY_HOME},
{KEY_A, KEY_0,
KEY_B, KEY_C,
//SCAN here
KEY_F3, KEY_F4,
KEY_ENTER},
KEY_POUND,
KEY_BACK},
{KEY_4, KEY_5,
KEY_6, KEY_STAR,
{KEY_LEFT,
KEY_RIGHT,
KEY_HOME},
u8 P0_kbd_used[8]={1, 1, 1, 1, 1, 1, 0, 0};
u8 P1_kbd_used[8]={0, 0, 1, 1, 1, 1, 1, 1};
KEY_STATE_PRESSED=0,
KEY_STATE_RELEASED,
KEY_STATE_LONGPRESS,
KEY_STATE_REPEATED,
KEY_STATE_NULL
}TOUCHKEY_STATE;
P0_INT_STATE=0x0;
P1_INT_STATE=0x0;
P0_IN_OUT_STATE=0x0;
P1_IN_OUT_STATE=0x0;
P0_kbd_used_temp=0x0;
pre_x=0x00;
pre_y=0x00;
P0_X[X_NUM];
P1_Y[Y_NUM];
P1_VALUE=0;
u8 KeyBoard_Key=0xFF;
u8 KeyBoard_Key_Previous=0xFF;
TOUCHKEY_STATE KeyBoardKey_State=KEY_STATE_NULL;
u8 DELAY_TIMES=2;
//extern void kpled_ctrl_open(u8 enable);
#define AW9523_delay_1us(ms)
udelay(ms*DELAY_TIMES)
#define GPIO_ModeSetup(x, y)
mt_set_gpio_mode(x, y);
#define GPIO_InitIO(x, y)
mt_set_gpio_dir(y, x)
#define GPIO_WriteIO(x, y)
mt_set_gpio_out(y, x)
#define GPIO_ReadIO(x)
mt_get_gpio_in(x)
#define I2C_SDA_MODE
mt_set_gpio_mode(I2C_SDA_GPIO, GPIO_MODE_GPIO)
#define I2C_SCL_MODE
mt_set_gpio_mode(I2C_SCL_GPIO, GPIO_MODE_GPIO)
#define I2C_SDA_OUTPUT
mt_set_gpio_dir(I2C_SDA_GPIO, GPIO_DIR_OUT)
#define I2C_SDA_INPUT
mt_set_gpio_dir(I2C_SDA_GPIO, GPIO_DIR_IN)
#define I2C_SCL_OUTPUT
mt_set_gpio_dir(I2C_SCL_GPIO, GPIO_DIR_OUT)
#define I2C_SDA_HIGH
mt_set_gpio_out(I2C_SDA_GPIO, GPIO_OUT_ONE)
#define I2C_SDA_LOW
mt_set_gpio_out(I2C_SDA_GPIO, GPIO_OUT_ZERO)
#define I2C_SCL_HIGH
mt_set_gpio_out(I2C_SCL_GPIO, GPIO_OUT_ONE)
#define I2C_SCL_LOW
mt_set_gpio_out(I2C_SCL_GPIO, GPIO_OUT_ZERO)
#define I2C_SDA_READ
mt_get_gpio_in(I2C_SDA_GPIO)
#define NEW_I2C_TIMING
void AW9523_i2c_initial(void)
#if NEW_I2C_TIMING
I2C_SDA_MODE;
I2C_SCL_MODE;
I2C_SDA_OUTPUT;
I2C_SCL_OUTPUT;
mt_set_gpio_pull_enable(I2C_SDA_GPIO, GPIO_PULL_ENABLE);
mt_set_gpio_pull_enable(I2C_SCL_GPIO, GPIO_PULL_ENABLE);
I2C_SDA_HIGH;
I2C_SCL_HIGH;
GPIO_ModeSetup(I2C_SCL_GPIO, 0);
GPIO_InitIO(1, I2C_SCL_GPIO);
mt_set_gpio_pull_enable(I2C_SCL_GPIO, GPIO_PULL_ENABLE);
GPIO_WriteIO(1, I2C_SCL_GPIO);
GPIO_ModeSetup(I2C_SDA_GPIO, 0);
GPIO_InitIO(1,I2C_SDA_GPIO);
mt_set_gpio_pull_enable(I2C_SDA_GPIO, GPIO_PULL_ENABLE);
GPIO_WriteIO(0, I2C_SDA_GPIO);
AW9523_delay_1us(5);
GPIO_WriteIO(1, I2C_SDA_GPIO);//脦陋卤脺脙芒i2c initial 脢卤虏煤脡煤\u017d铆脦贸碌脛脳\u017d脤卢拢卢脧脠路垄脪禄\u017e枚脥拢脰鹿脤玫\u0152镁
void AW9523_Hw_reset(void)
GPIO_ModeSetup(GPIO74, 0);
GPIO_InitIO(0, AW9523_RESET_PIN);
AW9523_delay_1us(50);
GPIO_ModeSetup(AW9523_RESET_PIN, 0);
GPIO_InitIO(1, AW9523_RESET_PIN);
GPIO_WriteIO(0, AW9523_RESET_PIN);
//kpled_ctrl_open(1);
// Kpled on , then reset be pulled down
AW9523_delay_1us(200); //\u017e\u017d脦禄脨脜潞脜脦陋碌脥碌莽脝\u0153碌脛鲁脰脨酶脢卤\u0152盲卤脴脨毛脰脕脡脵20us虏脜脛脺脮媒鲁拢\u017e\u017d脦禄
GPIO_WriteIO(1, AW9523_RESET_PIN);
//kpled_ctrl_open(0);
// Kpled off, then reset be pulled up by VIO18
//AW9523_delay_1us(30);
mdelay(30);
static void AW9523_i2c_start(void)
#if NEW_I2C_TIMING
I2C_SDA_MODE;
I2C_SCL_MODE;
I2C_SDA_OUTPUT;
I2C_SCL_OUTPUT;
//spin_lock_irqsave(&gpio_i2c_spinLock, flags_spin);
I2C_SDA_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SCL_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SDA_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
GPIO_InitIO(1,I2C_SDA_GPIO);
GPIO_InitIO(1,I2C_SCL_GPIO);
GPIO_WriteIO(1, I2C_SDA_GPIO);
GPIO_WriteIO(1, I2C_SCL_GPIO);
AW9523_delay_1us(2);
GPIO_WriteIO(0, I2C_SDA_GPIO);
AW9523_delay_1us(2);
GPIO_WriteIO(0, I2C_SCL_GPIO);
AW9523_delay_1us(2);
static void AW9523_i2c_stop(void)
#if NEW_I2C_TIMING
I2C_SDA_OUTPUT;
I2C_SCL_OUTPUT;
//spin_lock_irqsave(&gpio_i2c_spinLock, flags_spin);
I2C_SCL_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SDA_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SCL_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SDA_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
GPIO_InitIO(1,I2C_SDA_GPIO);
GPIO_InitIO(1,I2C_SCL_GPIO);
GPIO_WriteIO(0, I2C_SCL_GPIO);
AW9523_delay_1us(2);
GPIO_WriteIO(0, I2C_SDA_GPIO);
GPIO_WriteIO(1, I2C_SCL_GPIO);
AW9523_delay_1us(2);
GPIO_WriteIO(1, I2C_SDA_GPIO);
static char AW9523_i2c_write_byte(unsigned char data)
#if NEW_I2C_TIMING
char times = 0;
//unsigned long flags_
//spin_lock_irqsave(&gpio_i2c_spinLock, flags_spin);
I2C_SCL_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SDA_OUTPUT;
for(i=0;i&8;i++)
if((data&&i)&0x80)
I2C_SDA_HIGH;
I2C_SDA_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SCL_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SCL_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SDA_INPUT;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SCL_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
//spin_unlock_irqrestore(&gpio_i2c_spinLock, flags_spin);
(I2C_SDA_READ==1)
AW9523_delay_1us(5);
//udelay(10);//return 1;
if (times==10)
I2C_SCL_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
GPIO_InitIO(1,I2C_SDA_GPIO);
for (i=0; i&8; i++)
if (data & 0x80)
GPIO_WriteIO(1,I2C_SDA_GPIO);
GPIO_WriteIO(0,I2C_SDA_GPIO);
data &&= 1;
AW9523_delay_1us(1);
GPIO_WriteIO(1,I2C_SCL_GPIO);
AW9523_delay_1us(1);
GPIO_WriteIO(0,I2C_SCL_GPIO);
AW9523_delay_1us(1);
GPIO_InitIO(0,I2C_SDA_GPIO);
AW9523_delay_1us(6);
GPIO_WriteIO(1,I2C_SCL_GPIO);
ack = GPIO_ReadIO(I2C_SDA_GPIO); /// ack
AW9523_delay_1us(1);
GPIO_WriteIO(0,I2C_SCL_GPIO);
static u8 AW9523_i2c_read_byte(void)
#if NEW_I2C_TIMING
u8 rec_byte = 0x00;
//I2C_SCL_LOW;
//mdelay(1);
for (i=0; i&8; i++)
rec_byte &&=1;
//I2C_SCL_LOW;
//mdelay(1);
I2C_SCL_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
rec_byte |= I2C_SDA_READ;
I2C_SCL_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SDA_OUTPUT;
I2C_SDA_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SCL_HIGH;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
I2C_SCL_LOW;
AW9523_delay_1us(5);
//udelay(10); //udelay(100); //mdelay(1);
return rec_
GPIO_InitIO(0, I2C_SDA_GPIO);
//脢媒\u0178脻露脕鲁枚
bData = 0x00;
for (i=0;i&8;i++) {
bData &&= 1;
AW9523_delay_1us(4);
GPIO_WriteIO(1, I2C_SCL_GPIO);
if (GPIO_ReadIO(I2C_SDA_GPIO)) {
bData |= 0x01;
bData &= 0
AW9523_delay_1us(1);
GPIO_WriteIO(0, I2C_SCL_GPIO);
AW9523_delay_1us(1);
GPIO_WriteIO(1, I2C_SCL_GPIO);
AW9523_delay_1us(1);
GPIO_WriteIO(0, I2C_SCL_GPIO);
static char AW9523_i2c_write_reg_org(unsigned char reg,unsigned char data)
#if NEW_I2C_TIMING
AW9523_i2c_start();
AW9523_i2c_write_byte(LED_SLAVE_ADDR);
AW9523_i2c_write_byte(reg);
AW9523_i2c_write_byte(data);
AW9523_i2c_stop();
char ack=0;
AW9523_i2c_start();
ack|=AW9523_i2c_write_byte(LED_SLAVE_ADDR);
//write device address
ack|=AW9523_i2c_write_byte(reg);
// reg address
ack|= AW9523_i2c_write_byte(data); // data
AW9523_i2c_stop();
static char AW9523_i2c_write_reg(unsigned char reg,unsigned char data)
#if NEW_I2C_TIMING
AW9523_i2c_start();
AW9523_i2c_write_byte(LED_SLAVE_ADDR);
AW9523_i2c_write_byte(reg);
AW9523_i2c_write_byte(data);
AW9523_i2c_stop();
char ack=0;
for (i=0;i&AW9523_I2C_MAX_LOOP;i++)
ack=AW9523_i2c_write_reg_org(reg,data);
if(ack==0) // ack success
u8 AW9523_i2c_read_reg(u8 regaddr)
#if NEW_I2C_TIMING
u8 read_byte = 0;
AW9523_i2c_start();
AW9523_i2c_write_byte(LED_SLAVE_ADDR);
AW9523_i2c_write_byte(regaddr);
AW9523_i2c_stop();
/////////////////////
AW9523_i2c_start();
//restart signal
AW9523_i2c_write_byte(LED_SLAVE_ADDR|0x01);
read_byte = AW9523_i2c_read_byte();
AW9523_i2c_stop();
return read_
u8 mask,i, bD
char ack1,ack2,ack3;
for (i=0;i&AW9523_I2C_MAX_LOOP;i++)
AW9523_i2c_start();
ack1=AW9523_i2c_write_byte(LED_SLAVE_ADDR);
//write device address
ack2=AW9523_i2c_write_byte(regaddr);
// reg address
AW9523_i2c_stop();
AW9523_i2c_start();
ack3=AW9523_i2c_write_byte((LED_SLAVE_ADDR|0x01));
//write device address
if((ack1 || ack2 || ack3)==0) // ack success
bData=AW9523_i2c_read_byte();
AW9523_i2c_stop();
static void AW9523_SDA_Change(void)
u8 SDA_index = 0;
GPIO_WriteIO(0,I2C_SDA_GPIO);
AW9523_delay_1us(80);
for (SDA_index=0;SDA_index&50;SDA_index++)
GPIO_InitIO(0, I2C_SDA_GPIO);
AW9523_delay_1us(420);
//SDA碌脛脰脺脝脷拢卢\u017e脽碌莽脝\u0153420us拢卢 脭脷\u017e梅脝\u0153脤\u0161脧脗脟毛\u017e霉\u0178脻脰梅脝碌脌\u017d碌梅脮没拢卢卤拢鲁脰脪禄脰脗
GPIO_InitIO(1, I2C_SDA_GPIO);//SDA碌脛脰脺脝脷拢卢碌脥碌莽脝\u015380us拢卢 脭脷\u017e梅脝\u0153脤\u0161脧脗脟毛\u017e霉\u0178脻脰梅脝碌脌\u017d碌梅脮没拢卢卤拢鲁脰脪禄脰脗
AW9523_delay_1us(80); //SDA碌脥碌莽脝\u015380us
GPIO_InitIO(1, I2C_SDA_GPIO);
GPIO_WriteIO(1,I2C_SDA_GPIO);
AW9523_delay_1us(420);
char AW9523_POWER_ON(void)
// AW9523 POWER-ON拢卢 脟毛驴脥禄搂虏禄脪陋\u017e脛露炉\u017d脣潞炉脢媒
// 脭脷aw9523_init()脰脨拢卢脧脠\u0153酶脨脨POWER-ON拢卢脭脵\u0153酶脨脨驴脥禄搂脳脭脡铆碌脛脧脿鹿脴虏脵脳梅
char ack=0;
u8 count=0;
AW9523_i2c_initial();
AW9523_Hw_reset();
while(count++ & 120)
if(AW9523_i2c_write_reg_org(0x55,0x55))
//脜脨露脧脫\ud冒脛拢脢\u0153隆拢0x55脦陋驴脮\u0152脛\u017d忙脝梅拢卢虏禄禄谩露脭驴脥禄搂脫\u0160脫脙虏煤脡煤脫掳脧矛
AW9523_SDA_Change();
if(AW9523_i2c_write_reg_org(0xaa,0xaa))
AW9523_SDA_Change();
if(AW9523_i2c_write_reg_org(0x55,0xaa))
AW9523_SDA_Change();
if(AW9523_i2c_write_reg_org(0xaa,0x55))
AW9523_SDA_Change();
ack |= AW9523_i2c_write_reg_org(0x55,0x55);
ack |= AW9523_i2c_write_reg_org(0xaa,0xaa);
//SCI_TRACE_LOW(&----AW9523 POWER ON -----end =%d\r\n&, count);
/*=======================================i2c driver end =================================*/
/*===========================aw脛\u017d忙脝梅碌脛虏脵脳梅\u0153脫驴脷 begin ================================*/
void aw_in_out_setting(void)
/* 脡猫脰脙 p0 p1 脢盲脠毛脢盲鲁枚脳\u017d脤卢*/
P0_IN_OUT_STATE=0xFF;
AW9523_i2c_write_reg(0x04,P0_IN_OUT_STATE);//脡猫脰脙脣霉脫脨P0_\u0153脜脦陋脢盲脠毛脳\u017d脤卢
P1_IN_OUT_STATE=0x0;
AW9523_i2c_write_reg(0x05,P1_IN_OUT_STATE);//脡猫脰脙脣霉脫脨P1_\u0153脜脦陋脢盲鲁枚脳\u017d脤卢
void aw_interrupt_setting(void)
/* 脡猫脰脙 p0 p1 脭脢脨铆脰脨露脧脳\u017d脤卢*/
P0_INT_STATE=0x0;
for (i=0;i&X_NUM;i++) {
P0_INT_STATE=P0_INT_STATE|(1&&COL[i]);//\u017e霉\u0178脻掳\u017d\u0152眉脜脜虏\u0152脌\u017d脡猫脰脙脰脨露脧
P0_INT_STATE=~P0_INT_STATE;
AW9523_i2c_write_reg(0x06,P0_INT_STATE);//潞脥掳\u017d\u0152眉脕脨露脭脫\u0160碌脛P0_\u0153脜脭脢脨铆脰脨露脧
P1_INT_STATE=0xFF;
AW9523_i2c_write_reg(0x07,P1_INT_STATE);//p1\u0153脜露\u0152虏禄脛脺脰脨露脧
void aw9523_p0_int_restore(void)
AW9523_i2c_write_reg(0x06,P0_INT_STATE);
void aw9523_P1_int_restore()
AW9523_i2c_write_reg(0x07,P1_INT_STATE);
void aw9523_p0_int_disable()
AW9523_i2c_write_reg(0x06, 0xff);
void aw9523_p1_int_disable()
AW9523_i2c_write_reg(0x07, 0xff);
u8 aw9523_get_p0(void)
//AW9523_i2c_read_reg(0x01);
//just for test
return AW9523_i2c_read_reg(0x00);
u8 aw9523_get_p1(void)
return AW9523_i2c_read_reg(0x01);
void aw9523_set_p0(u8 data)
AW9523_i2c_write_reg(0x02,data);
void aw9523_set_p1(u8 data)
AW9523_i2c_write_reg(0x03,data);
void RE_P0_WRITE(u8 P0,u8 data)
tmp_value = AW9523_i2c_read_reg(0x02);
if(data==1)
AW9523_i2c_write_reg(0x02,(tmp_value|(1&&P0)));
AW9523_i2c_write_reg(0x02,(tmp_value&(~(1&&P0))));
void RE_P1_WRITE(u8 P1,u8 data)
tmp_value = AW9523_i2c_read_reg(0x03);
if(data==1)
AW9523_i2c_write_reg(0x03,(tmp_value|(1&&P1)));
AW9523_i2c_write_reg(0x03,(tmp_value&(~(1&&P1))));
void aw9523_keylight_open(u8 enable)
if (enable)
AW9523_i2c_write_reg(0x20, 0x40);
// led current P1_0
AW9523_i2c_write_reg(0x21, 0x40);
// led current P1_1
AW9523_i2c_write_reg(0x13, 0xFf);
// P1_0, P1_1 working mode
AW9523_i2c_write_reg(0x20, 0x00);
// led current P1_0
AW9523_i2c_write_reg(0x21, 0x00);
// led current P1_1
AW9523_i2c_write_reg(0x13, 0xFf);
// P1_0, P1_1 working mode
#include &mach/mt_pm_ldo.h&
#define SCAN_GPIO
#define SCAN_POWER_GPIO
#define SCAN_POWER2_GPIO
void SCAN_init(void)
GPIO_ModeSetup(SCAN_POWER_GPIO, 0);
GPIO_InitIO(1, SCAN_POWER_GPIO);
GPIO_WriteIO(1, SCAN_POWER_GPIO);
GPIO_ModeSetup(SCAN_POWER2_GPIO, 0);
GPIO_InitIO(1, SCAN_POWER2_GPIO);
GPIO_WriteIO(1, SCAN_POWER2_GPIO);
hwPowerDown(MT6323_POWER_LDO_VGP2, &TP&);
hwPowerOn(MT6323_POWER_LDO_VGP2, VOL_1800, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerOn(MT6323_POWER_LDO_VGP1, VOL_3300, &TP&);
GPIO_ModeSetup(SCAN_GPIO, 0);
GPIO_InitIO(1, SCAN_GPIO);
GPIO_WriteIO(1, SCAN_GPIO);
void SCAN_test(void)
printk(&\===== SCAN_test\r\n&);
GPIO_ModeSetup(SCAN_GPIO, 0);
GPIO_InitIO(1, SCAN_GPIO);
GPIO_WriteIO(1, SCAN_GPIO);
mdelay(20);
GPIO_ModeSetup(SCAN_POWER_GPIO, 0);
GPIO_InitIO(1, SCAN_POWER_GPIO);
GPIO_WriteIO(1, SCAN_POWER_GPIO);
GPIO_ModeSetup(SCAN_POWER2_GPIO, 0);
GPIO_InitIO(1, SCAN_POWER2_GPIO);
GPIO_WriteIO(1, SCAN_POWER2_GPIO);
hwPowerDown(MT6323_POWER_LDO_VGP2, &TP&);
hwPowerOn(MT6323_POWER_LDO_VGP2, VOL_1800, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerOn(MT6323_POWER_LDO_VGP1, VOL_3300, &TP&);
mdelay(100);
GPIO_WriteIO(0, SCAN_GPIO);
mdelay(1500);
GPIO_WriteIO(1, SCAN_GPIO);
mdelay(100);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
//GPIO_WriteIO(1, SCAN_GPIO);
EXPORT_SYMBOL(SCAN_init);
EXPORT_SYMBOL(SCAN_test);
void trig_scan_evel(int level)
SCAN_test();
printk(&\===== SCAN_test\r\n&);
GPIO_ModeSetup(SCAN_GPIO, 0);
GPIO_InitIO(1, SCAN_GPIO);
GPIO_WriteIO(1, SCAN_GPIO);
mdelay(20);
GPIO_ModeSetup(SCAN_POWER_GPIO, 0);
GPIO_InitIO(1, SCAN_POWER_GPIO);
GPIO_WriteIO(1, SCAN_POWER_GPIO);
GPIO_ModeSetup(SCAN_POWER2_GPIO, 0);
GPIO_InitIO(1, SCAN_POWER2_GPIO);
GPIO_WriteIO(1, SCAN_POWER2_GPIO);
if(level & 0)
hwPowerDown(MT6323_POWER_LDO_VGP2, &TP&);
hwPowerOn(MT6323_POWER_LDO_VGP2, VOL_1800, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerOn(MT6323_POWER_LDO_VGP1, VOL_3300, &TP&);
mdelay(200);
GPIO_WriteIO(0, SCAN_GPIO);
mdelay(100);
GPIO_WriteIO(1, SCAN_GPIO);
mdelay(100);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
hwPowerDown(MT6323_POWER_LDO_VGP1, &TP&);
void aw9523_test(void)
// i2c_initial();
AW9523_Hw_reset();
AW9523_i2c_initial();
printk(&\===== naw9523_test_entry=\r\n&);
printk(&\===== naw9523_i2c_read_reg_0x00=0x%x\r\n&,AW9523_i2c_read_reg(0x00));
printk(&\===== naw9523_i2c_read_reg_0x01=0x%x\r\n&,AW9523_i2c_read_reg(0x01));
printk(&\===== naw9523_i2c_read_reg_0x02=0x%x\r\n&,AW9523_i2c_read_reg(0x02));
printk(&\===== naw9523_i2c_read_reg_0x03=0x%x\r\n&,AW9523_i2c_read_reg(0x03));
printk(&\===== naw9523_i2c_read_reg_0x04=0x%x\r\n&,AW9523_i2c_read_reg(0x04));
printk(&\===== naw9523_i2c_read_reg_0x05=0x%x\r\n&,AW9523_i2c_read_reg(0x05));
printk(&\===== naw9523_i2c_read_reg_0x06=0x%x\r\n&,AW9523_i2c_read_reg(0x06));
printk(&\===== naw9523_i2c_read_reg_0x07=0x%x\r\n&,AW9523_i2c_read_reg(0x07));
printk(&\===== naw9523_i2c_read_reg_0x10=0x%x\r\n&,AW9523_i2c_read_reg(0x10));
printk(&\===== naw9523_i2c_read_reg_0x11=0x%x\r\n&,AW9523_i2c_read_reg(0x11));
printk(&\===== naw9523_i2c_read_reg_0x12=0x%x\r\n&,AW9523_i2c_read_reg(0x12));
printk(&\===== naw9523_i2c_read_reg_0x13=0x%x\r\n&,AW9523_i2c_read_reg(0x13));
void aw9523_set_p1_gpio_mode(void)
AW9523_i2c_write_reg(0x13,0xff);
void aw9523_init()
//AW9523_POWER_ON();
// test new i2

我要回帖

更多关于 接地线 的文章

 

随机推荐