2. dws配中断脚和使能脚

(根据原理图中“09_CAMERA_SENSOR”页中, “HALL”部分【OUT】引脚所连接 - 使能脚GPIO12)

v666为例

dws配置pin脚: - 由于硬件上拉-》dws也要配成上拉

EintMode|Def.Mode M0|M1|M2|M3|M4|M5|M6|M7|InPull En|InPull SelHigh|Def.Dir|In|Out|OutHigh|VarName1

GPIO12 1 0:GPIO12 1 1 IN GPIO_HALL_1_PIN

dws配置EINT:

EINTVar|Debounce Time(ms)|Polarity|Sensitive_Level|Debounce En

EINT12 HALL_1 0 Low Level Disable

dts:

* HALL GPIO standardization */

&pio {

hall_pin_default: halldefaultcfg {

};

hall_pin_as_int: hallint@12 {

pins_cmd_dat {

pins = 《PINMUX_GPIO12__FUNC_GPIO12》;

slew-rate = 《0》;

bias-pull-up = 《00》;

};

};

};

&keypad {

pinctrl-names = “default”, “hall_pin_as_int”;

pinctrl-0 = 《&hall_pin_default》;

pinctrl-1 = 《&hall_pin_as_int》;

status = “okay”;

};

/* HALL GPIO end */

一、 查看是否有键值上报

getevent -i

add device 8: /dev/input/event1

bus: 0019

vendor 2454

product 6500

version 0010

name: “mtk-kpd” // 与音量加减键、电源键、hall同一个event

location: “”

id: “”

version: 1.0.1

getevent -t /dev/input/event1 // 打印出来的是16进制

[70.169911] 0001 0085 00000001 // 85 -》 133 远离

[70.169911] 0000 0000 00000000

[70.352126] 0001 0085 00000000

[70.352126] 0000 0000 00000000

二、查看代码确定上报键值

1. alps\kernel-3.18\drivers\input\keyboard\mediatek\kpd.c

#define KEY_HALL_F3 133 //for hall eint report key far // 磁铁远离

#define KEY_HALL_F4 134 //for hall eint report key close // 磁铁靠近

2. alps/device/magcomm/magc6580_we_c_m/mtk-kpd.kl , 映射给上层

key 114 0x72 VOLUME_DOWN // 侧键

key 115 0x73 VOLUME_UP

key 116 0x74 POWER

+ key 133 F3 // 霍尔

+ key 134 F4

注:修改此文件,可以用push的方式先试验

find /system -name mtk-kpd.kl

/system/usr/keylayout/mtk-kpd.kl

adb push 。.. /system/usr/keylayout/

三、添加权限

alps/device/mediatek/common/sepolicy/basic/system_app.te

# add permission for hall

allow system_app sysfs_keypad_file:dir { search read write };

allow system_app sysfs_keypad_file:file { read write getattr setattr open create };

alps/device/mediatek/common/sepolicy/full/platform_app.te

# add permission for hall

allow platform_app sysfs_keypad_file:dir { search read write };

allow platform_app sysfs_keypad_file:file { read write getattr setattr open create };

alps/device/mediatek/common/sepolicy/full/priv_app.te

# add permission for hall

allow priv_app sysfs_keypad_file:dir { search read write };

allow priv_app sysfs_keypad_file:file { read write getattr setattr open create };

四、手写笔插入与拔出 - 用hall来实现,手写笔尖有磁性(以80 5.1为例)

1. 修改alps/device/haocheng/hct6580_weg_a_l/mtk-kpd.kl ,映射给上层

key 133 F3

key 134 F4

+ key 136 F6

+ key 137 F7

2. 修改alps\kernel-3.10\drivers\misc\mediatek\keypad\kpd.c,仿造hall_1添加hall_2的代码:

+ #ifdef GPIO_HALL_2_PIN

#define CUSTOM_HALL_2_SUPPORT

#define GPIO_HALL_2_EINT_PIN GPIO_HALL_2_PIN

#define GPIO_HALL_2_EINT_PIN_M_EINT GPIO_HALL_2_PIN_M_EINT

static unsigned int hall_2_irq;

#define HALL_2_TAG “hall: ”

#define HALL_2_DBG(fmt, args.。.) printk(HALL_2_TAG fmt, ##args)

struct work_struct hall_2_eint_work;

static int hall_2_state_flag = 0;

static bool hall_2_state = 1; //0: close 1:far

#define KEY_HALL_F6 136 //for hall eint report key far

#define KEY_HALL_F7 137 //for hall eint report key close

+ #endif

+ #ifdef CUSTOM_HALL_2_SUPPORT // 提供给上层调用接口: /sys/bus/。..

static volatile int hall_2_status = 0;

static ssize_t store_hall_2_state(struct device_driver *ddri, const char *buf, size_t count)

{

if (sscanf(buf, “%u”, &hall_2_status) != 1) {

kpd_print(“kpd call state: Invalid values\n”);

return -EINVAL;

}

hall_2_state = (bool)hall_2_status;

return count;

}

static ssize_t show_hall_2_state(struct device_driver *ddri, char *buf)

{

ssize_t res;

res = snprintf(buf, PAGE_SIZE, “%d\n”, hall_2_state);

return res;

}

static DRIVER_ATTR(hall_2_state, S_IWUSR | S_IALLUGO, show_hall_2_state, store_hall_2_state);

+ #endif

static struct driver_attribute *kpd_attr_list[] = {

&driver_attr_kpd_call_state,

#ifdef CUSTOM_HALL_SUPPORT

&driver_attr_hall_state,

#endif

+ #ifdef CUSTOM_HALL_2_SUPPORT // 提供给上层调用接口: /sys/bus/。..

+ &driver_attr_hall_2_state,

+ #endif

};

+ #ifdef CUSTOM_HALL_2_SUPPORT

+ void kpd_hall_2_key_handler(unsigned long pressed, u16 linux_keycode)

{

if(!kpd_input_dev) {

printk(“KPD input device not ready\n”);

return;

}

input_report_key(kpd_input_dev, linux_keycode, pressed);

input_sync(kpd_input_dev);

if (kpd_show_hw_keycode) {

printk(KPD_SAY “(%s) KEY_HALL keycode =%d \n”, pressed ? “pressed” : “released”, linux_keycode);

}

}

static void hall_2_work_func(struct work_struct *work)

{

if(hall_2_state == 1) {

kpd_hall_key_handler(1, KEY_HALL_F6);

kpd_hall_key_handler(0, KEY_HALL_F6);

} else if(hall_2_state == 0) {

kpd_hall_key_handler(1, KEY_HALL_F7);

kpd_hall_key_handler(0, KEY_HALL_F7);

}

}

bool get_hall_2_state()

{

return hall_2_state;

}

EXPORT_SYMBOL(get_hall_2_state);

void hall_2_eint_func(void)

{

disable_irq_nosync(hall_2_irq);

if(hall_2_state_flag)

{

hall_2_state_flag = 0;

hall_2_state = 1;

irq_set_irq_type(hall_2_irq,IRQ_TYPE_LEVEL_LOW);

}

else{

hall_2_state_flag = 1;

hall_2_state = 0;

irq_set_irq_type(hall_2_irq,IRQ_TYPE_LEVEL_HIGH);

}

enable_irq(hall_2_irq);

schedule_work(&hall_2_eint_work);

}

static irqreturn_t hall_2_irq_handler(int irq, void *dev_id)

{

hall_2_eint_func();

return IRQ_HANDLED;

}

int hall_2_setup_eint(void)

{

struct device_node *hall_node;

u32 ints[2] = {0, 0};

mt_set_gpio_dir(GPIO_HALL_2_EINT_PIN, GPIO_DIR_IN);

mt_set_gpio_mode(GPIO_HALL_2_EINT_PIN, GPIO_HALL_2_EINT_PIN_M_EINT);

mt_set_gpio_pull_enable(GPIO_HALL_2_EINT_PIN, 0);

hall_node = of_find_compatible_node(NULL,NULL,“mediatek, HALL_2-eint”);

if(hall_node){

printk(“hall_irq has find!\n”);

of_property_read_u32_array(hall_node, “debounce”, ints, ARRAY_SIZE(ints));

mt_gpio_set_debounce(ints[0], ints[1]);

hall_2_irq= irq_of_parse_and_map(hall_node, 0);

if (!hall_2_irq)

{

printk(“irq_of_parse_and_map hall fail!!\n”);

return -EINVAL;

}

if(request_irq(hall_2_irq, hall_2_irq_handler, IRQF_TRIGGER_NONE, “HALL_2-eint”, NULL)) {

printk(“HALL IRQ NOT AVAILABLE!!\n”);

return -EINVAL;

}

}

else{

printk(“null hall_irq node!\n”);

return -EINVAL;

}

return 0;

}

#endif

static int kpd_pdrv_probe(struct platform_device *pdev)

{

#ifdef CUSTOM_HALL_SUPPORT

__set_bit(KEY_HALL_F3, kpd_input_dev-》keybit);

__set_bit(KEY_HALL_F4, kpd_input_dev-》keybit);

#endif

+ #ifdef CUSTOM_HALL_2_SUPPORT

+ __set_bit(KEY_HALL_F6, kpd_input_dev-》keybit); // 使能input上报键值

+ __set_bit(KEY_HALL_F7, kpd_input_dev-》keybit);

+ #endif

。..

#ifdef CUSTOM_HALL_SUPPORT

INIT_WORK(&hall_eint_work, hall_work_func);

hall_setup_eint();

#endif

+ #ifdef CUSTOM_HALL_2_SUPPORT

+ INIT_WORK(&hall_2_eint_work, hall_2_work_func); // 中断中唤醒工作,工作中上报key

+ hall_2_setup_eint(); // 设置GPIO口状态,从dts获取中断信息,注册中断

+ #endif

。..

}

3. 修改dws,配置GPIO口为中断模式,配置中断的触发方式(电平or边沿)

五、39平台:

1. device/mediateksample/k39tv1_bsp_1g/mtk-kpd.kl

+ key 133 F3

+ key 134 F4

2. mt6739.dts

+ hall_1: hall_1 {

+ compatible = “mediatek, hall_1-eint”;

+ status = “disabled”;

+ };

3. k39tv1_bsp_1g.dts

+ /* HALL GPIO standardization */

+ &keypad {

pinctrl-names = “default”, “hall_pin_as_int”;

pinctrl-0 = 《&hall_pin_default》;

pinctrl-1 = 《&hall_pin_as_int》;

status = “okay”;

};

&pio {

hall_pin_default: halldefaultcfg {

};

hall_pin_as_int: hallint@14 {

pins_cmd_dat {

pins = 《PINMUX_GPIO14__FUNC_GPIO14》;

slew-rate = 《0》;

bias-pull-up = 《00》;

};

};

+ };

+ /* HALL GPIO end */

4. codegen.dws

EINT:

ID EINTVar|Debounce Time(ms)|Polarity|Sensitive_Level|Debounce En

EINT14 HALL_1 0 Low Level Disable

GPIO:

ID EintMode|Def.Mode M0|M1|M2|M3|M4|M5|M6|M7|InPull En|InPull SelHigh|Def.Dir|In|Out|OutHigh|VarName1

GPIO14 1 0:GPIO14 1 1 1 IN 1 GPIO_HALL_1_PIN

5. kernel-4.4/drivers/input/keyboard/mediatek/kpd.c

+ #ifdef CONFIG_KST_HALL_SUPPORT

+ #define CUSTOM_HALL_SUPPORT

#define GPIO_HALL_EINT_PIN GPIO_HALL_1_PIN

#define GPIO_HALL_EINT_PIN_M_EINT GPIO_HALL_1_PIN_M_EINT

static unsigned int hall_irq;

#define HALL_TAG “hall: ”

#define HALL_DBG(fmt, args.。.) printk(HALL_TAG fmt, ##args)

struct work_struct hall_eint_work;

static int hall_state_flag = 0;

static bool hall_state = 1; //0: close 1:far

#define KEY_HALL_F3 133 //116 //for hall eint report key far

#define KEY_HALL_F4 134 //62 //for hall eint report key close

struct pinctrl *hallpinctrl;

+ struct pinctrl_state *hall_pin_as_int;

+ #endif

+ #ifdef CUSTOM_HALL_SUPPORT

+ static volatile int hall_status = 0;

static ssize_t store_hall_state(struct device_driver *ddri, const char *buf, size_t count)

{

if (sscanf(buf, “%u”, &hall_status) != 1) {

kpd_print(“kpd call state: Invalid values\n”);

return -EINVAL;

}

hall_state = (bool)hall_status;

return count;

}

static ssize_t show_hall_state(struct device_driver *ddri, char *buf)

{

ssize_t res;

res = snprintf(buf, PAGE_SIZE, “%d\n”, hall_state);

return res;

}

+ static DRIVER_ATTR(hall_state, S_IWUSR | S_IRUGO, show_hall_state, store_hall_state);

+ #endif

static struct driver_attribute *kpd_attr_list[] = {

&driver_attr_kpd_call_state,

+ #ifdef CUSTOM_HALL_SUPPORT

+ &driver_attr_hall_state,

+ #endif

};

+ #ifdef CUSTOM_HALL_SUPPORT

+ void kpd_hall_key_handler(unsigned long pressed, u16 linux_keycode)

{

if(!kpd_input_dev) {

printk(“KPD input device not ready\n”);

return;

}

input_report_key(kpd_input_dev, linux_keycode, pressed);

input_sync(kpd_input_dev);

if (kpd_show_hw_keycode) {

printk(KPD_SAY “(%s) KEY_HALL keycode =%d \n”, pressed ? “pressed” : “released”, linux_keycode);

}

}

static void hall_work_func(struct work_struct *work)

{

printk(“key hall_work_func not ready\n”); //add

if(hall_state == 1) {

kpd_hall_key_handler(1, KEY_HALL_F3);

kpd_hall_key_handler(0, KEY_HALL_F3);

}

else if(hall_state == 0) {

kpd_hall_key_handler(1, KEY_HALL_F4);

kpd_hall_key_handler(0, KEY_HALL_F4);

}

}

void hall_eint_func(void)

{

disable_irq_nosync(hall_irq);

if(hall_state_flag)

{

hall_state_flag = 0;

hall_state = 1;

irq_set_irq_type(hall_irq,IRQ_TYPE_LEVEL_LOW);

}

else

{

hall_state_flag = 1;

hall_state = 0;

irq_set_irq_type(hall_irq,IRQ_TYPE_LEVEL_HIGH);

}

enable_irq(hall_irq);

schedule_work(&hall_eint_work);

}

static irqreturn_t hall_irq_handler(int irq, void *dev_id)

{

hall_eint_func();

return IRQ_HANDLED;

}

int hall_setup_eint(void)

{

struct device_node *hall_node;

u32 ints[2] = {0, 0};

hall_node = of_find_compatible_node(NULL,NULL,“mediatek, hall_1-eint”);

if(hall_node){

printk(“hall_irq has find!\n”);

of_property_read_u32_array(hall_node, “debounce”, ints, ARRAY_SIZE(ints));

gpio_set_debounce(ints[0], ints[1]);

hall_irq= irq_of_parse_and_map(hall_node, 0);

if (!hall_irq)

{

printk(“irq_of_parse_and_map hall fail!!\n”);

return -EINVAL;

}

if(request_irq(hall_irq, hall_irq_handler, IRQF_TRIGGER_NONE, “hall_1-eint”, NULL)) {

printk(“HALL IRQ NOT AVAILABLE!!\n”);

return -EINVAL;

}

}

else

{

printk(“null hall_irq node!\n”);

return -EINVAL;

}

return 0;

+ }

+ #endif

+ #ifdef CUSTOM_HALL_SUPPORT

+ int hall_get_gpio_info(struct platform_device *pdev)

{

int ret;

hallpinctrl = devm_pinctrl_get(&pdev-》dev);

if (IS_ERR(hallpinctrl)) {

ret = PTR_ERR(hallpinctrl);

dev_err(&pdev-》dev, “hallpinctrl err!\n”);

return ret;

}

hall_pin_as_int = pinctrl_lookup_state(hallpinctrl, “hall_pin_as_int”);

if (IS_ERR(hall_pin_as_int)) {

ret = PTR_ERR(hall_pin_as_int);

dev_err(&pdev-》dev, “hall_pin_as_int err!\n”);

return ret;

}

pinctrl_select_state(hallpinctrl, hall_pin_as_int);

return 0;

+ }

+ #endif

static int kpd_pdrv_probe(struct platform_device *pdev)

{

__set_bit(KPD_KEY_MAP, kpd_input_dev-》keybit);

+ #ifdef CUSTOM_HALL_SUPPORT

+ __set_bit(KEY_HALL_F3, kpd_input_dev-》keybit);

+ __set_bit(KEY_HALL_F4, kpd_input_dev-》keybit);

+ #endif

。..

hrtimer_init(&aee_timer_5s, CLOCK_MONOTONIC, HRTIMER_MODE_REL);

aee_timer_5s.function = aee_timer_5s_func;

+ #ifdef CUSTOM_HALL_SUPPORT

+ INIT_WORK(&hall_eint_work, hall_work_func);

+ hall_get_gpio_info(pdev);

+ hall_setup_eint();

+ #endif

err = kpd_create_attr(&kpd_pdrv.driver);

。..

}

调试案例

案例一 : hall不通 - 电容贴错

现象 :

平台 : androidN,MTK6737

排查过程: 1. 查看是否有键值上报 - 拿磁铁靠近

getevent -t /dev/input/event1 - 无键值上报

2. 检查dws中的gpio口配置&中断配置、dts中断配置均ok(根据原理图得知EINT12 即 GPIO12)

3. 接示波器量中断脚 - 磁铁靠近时 中断脚无高低电平变化

4. 交给硬件同事检查 -》 一个电容贴错,替换后ok

处理方案: 换料 改bom

案例二 : hall不通 - hall芯片贴反

现象 :

平台 : androidN,MTK6737

排查过程: 1. 查看是否有键值上报 - 拿磁铁靠近

getevent -t /dev/input/event1 - 无键值上报

2. 检查dws中的gpio口配置&中断配置、dts中断配置均ok

3. hall芯片贴反了 -》 改正ok

案例三 : hall不通 - 硬件短路

现象 :

平台 : androidN,MTK6737

排查过程: 1. 查看是否有键值上报 - 拿磁铁靠近

getevent -t /dev/input/event1 - 无键值上报

2. 用镊子将hall中断脚短地(平常上拉为高电平,低电平为中断) - 有键值上报

android 霍尔传感器,浅析MTK hall霍尔传感器之原理相关推荐

  1. linux直流电机测试,带霍尔传感器编码器的直流减速电机测速原理讲解(附源码)...

    查看: 14294|回复: 83 带霍尔传感器编码器的直流减速电机测速原理讲解(附源码) 高级会员, 积分 891, 距离下一级还需 109 积分 积分金钱891 注册时间2019-4-22 在线时间 ...

  2. MTK hall霍尔传感器

    2. dws配中断脚和使能脚 (根据原理图中"09_CAMERA_SENSOR"页中, "HALL"部分[OUT]引脚所连接 - 使能脚GPIO12) v666 ...

  3. 传感器和Android平台的开放性结合在一起-传感器之家文章 - 传感器知识博客 - yuyangsensor - 和讯博客

        Android是以Google为首的开放手机联盟于2007年推出的基于Linux平台开源手机操作系统的名称,目前最新版本为Android4.2以上.为什么Android如今非常的流行,这主要是 ...

  4. 玩转 ESP32 + Arduino (四) 电容按键 霍尔传感器 外部中断 延时 脉冲检测

    一. 电容输入 touchRead(pin) 及电容输入中断touchAttachInterrupt(pin, TSR , threshold) ESP32专门提供了电容触摸传感器的功能, 共有T0, ...

  5. 霍尔传感器在汽车电子、工业控制、电力与新能源、家电及消费类产品中的应用

    霍尔传感器,依据霍尔效应来制作的.霍尔效应是研究半导体材料性能的基本方法,通过霍尔效应实验测定的霍尔系数,能够判断半导体材料的导电类型.载流子浓度及载流子迁移率等重要参数. 霍尔传感器分为线性型霍尔传 ...

  6. FOC中有感--霍尔传感器角度判定的理解

    FOC中有感–霍尔传感器角度判定的理解 记录一下FOC 关于霍尔传感器的角度判定问题 霍尔传感器对于角度的判定不是非常精细的,由于只有3个霍尔传感器,最小的分辨角度也只是30度,所以对于SVPWM高频 ...

  7. esp32外部中断_玩转 ESP32 + Arduino (四) 电容按键 霍尔传感器 外部中断 延时 脉冲检测...

    一. 电容输入 touchRead(pin) 及电容输入中断touchAttachInterrupt(pin, TSR , threshold) ESP32专门提供了电容触摸传感器的功能, 共有T0, ...

  8. 传感器技术—霍尔传感器(学习笔记九 补充)

    霍尔传感器 7.4 霍尔传感器的应用 7.4.1 霍尔压力传感器 7.4.2 霍尔加速度传感器 7.4.3 霍尔转速传感器 7.4.4 霍尔计数器 7.4.5 霍尔无触点开关 7.5 霍尔传感器实际应 ...

  9. 霍尔传感器工作原理简介

    范围 此文档适用于扫地机的霍尔传感器参考使用. 霍尔传感器概述 霍尔传感器分为线性型霍尔传感器和开关型霍尔传感器两种.线性霍尔一般用于检测位移量,电流大小:开关霍尔一般用于检测转速,磁场有无的变化. ...

最新文章

  1. Iframe上传文件
  2. php无限极分类实例,PHP实例:PHP无限极分类
  3. Mac系统的终端显示git当前分支
  4. 2016年Web前端面试题
  5. 代言男科、站台微商、变身神棍....这些科学家被捧了几十年,黑历史曝光后,让人三观尽毁......
  6. Android 事件处理
  7. 【CodeForces - 518D】Ilya and Escalator(概率dp,数学期望)
  8. 【洛谷 - P3376 】【模板】网络最大流
  9. 计蒜客 2019 蓝桥杯省赛 B 组模拟赛(一)
  10. coreldraw水涟漪怎么做_不懂怎么挑选水处理设备?跟贝斯沃了解这3点再做决定,轻松挑出适合自己的...
  11. 在注册表里删除没用的服务
  12. 2017年北京共享单车数据(订单数据)
  13. SPSS 性别卡方分析
  14. 腾讯内部转岗_重点扶植微视,火锅视频项目裁撤?腾讯澄清:团队已并入腾讯视频...
  15. 【IOS】模仿抽屉新热榜动态启动页YFSplashScreen
  16. Typora设置标题自动标号
  17. HTTP协议——URL
  18. 鼠标悬浮触发事件(onmouseover)实现
  19. IT码农哥放弃50万年薪:辞职卖咖喱凉皮(背后深藏功与名)_互联网的一些事...
  20. 直流伺服支持绝对值编码器SSI,SPI低压大电流伺服AGV驱动器外骨骼驱动机器人关节驱动智能直流伺服小体积大功率直流伺服

热门文章

  1. consistent hash
  2. JMP指令寻址方式总结,JMP BX指令寻址方式是什么
  3. CCIE知识点总结——三层技术
  4. 赛马比赛:25匹马,5个赛道,选出跑的快的前几匹
  5. SkeyeVSS安防视频云解决方案助力解决幼儿园安全系统防护问题
  6. 好东西——计算机原理学习(序)
  7. python处理Jenkins Job配置文件config.xml
  8. 最新美团代付源码+支持多模板/多支付通道/全开源
  9. Python中的切片
  10. 黑马程序员_java基础笔记(08)...GUI,网络编程,正则表达式