-
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中断脚短地(平常上拉为高电平,低电平为中断) - 有键值上报
MTK hall霍尔传感器
最新推荐文章于 2025-09-11 03:30:41 发布
本文详细介绍了MTK平台下霍尔传感器的配置流程,包括dws配置、dts配置、驱动代码修改等内容,并提供了三个实际的调试案例。
1172

被折叠的 条评论
为什么被折叠?



