MSM8953 ACC状态上报
说明
acc状态通过发送键值的方式上报给应用,点火发送F12,熄火发送F11.
1.添加键值:
device/qcom/msm8953_64/gpio-keys.kl
key 167 DVR
key 139 MENU
key 28 ENTER
+key 88 F12
+key 87 F11
2.添加ACC驱动设备树节点,acc用的是gpio90
kernel/msm-3.18/arch/arm/boot/dts/qcom/sc826-cn-01-evk/msm8953.dtsi
+ acc {
+ compatible = "qcom,acc";
+ dev_name = "acc";
+ status = "okay";
+ gpio_acc = <&tlmm 90 0x0>;
+ };
3.编译成模块
kernel/msm-3.18/drivers/Makefile
obj-$(CONFIG_MOBICORE_DRIVER) += gud/obj-y += gpio106-5vd-control/
+obj-m += acc_control/
4.添加驱动文件
在kernel/msm-3.18/drivers/目录下面创建一个文件夹acc_control,然后添加Makefile和acc_drv.c文件
Makefile文件内容:
obj-m += acc_drv.o
acc_drv.c文件:
#include <linux/init.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>#include <linux/gpio.h>
#include <linux/of_gpio.h>#include <linux/delay.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/of.h>//#include <linux/time.h>
#include <linux/timer.h>
#include <linux/time.h>#include <linux/timex.h>
#include <linux/kthread.h>#include <linux/input.h>
#include <linux/syscalls.h>
#include <linux/workqueue.h>struct input_dev *acc_input_dev;
//struct work_struct acc_wq;
static struct delayed_work acc_wq;
void aac_do_work(struct work_struct *work);
int acc_detect_gpio = -1;
int old_gpio_value = -1;//从低电平到高电平
static void report_acc_rising(void)
{printk(" zjy_______________________________report_acc_rising \n");input_report_key(acc_input_dev, KEY_F11, 1);input_sync(acc_input_dev);udelay(10);input_report_key(acc_input_dev, KEY_F11, 0);input_sync(acc_input_dev);}//从高电平到低电平
static void report_acc_falling(void)
{printk(" zjy_______________________________report_acc_falling \n");input_report_key(acc_input_dev, KEY_F12, 1);input_sync(acc_input_dev);udelay(10);input_report_key(acc_input_dev, KEY_F12, 0);input_sync(acc_input_dev);
}//static int irq_enum;
//中断处理上半部
static irqreturn_t acc_interrupt(int irq, void *dev_id)
{//int irq_enum = gpio_to_irq(acc_detect_gpio);printk(" zjy_____________acc_interrupt__________________ 中断上半部 \n");//disable_irq_nosync(irq_enum); //进入中断时,屏蔽中断做防抖//schedule_work(&acc_wq);schedule_delayed_work(&acc_wq, msecs_to_jiffies(1000)); //schedule_delayed_work(&acc_wq, msecs_to_jiffies(3000));//3s//disable_irq(irq_enum); //进入中断时,屏蔽中断做防抖return IRQ_HANDLED;
}/*中断处理底半部*/
void acc_do_work(struct work_struct *work)
{int g_value;int irq_enum = gpio_to_irq(acc_detect_gpio);g_value = gpio_get_value(acc_detect_gpio);disable_irq_nosync(irq_enum); //进入中断时,屏蔽中断做防抖if(old_gpio_value != g_value) { old_gpio_value = g_value;if(0 == g_value){report_acc_falling();//上报按键printk(" zjy_____________acc_do_work__________________ g_value = %d \n",g_value);}else if(1==g_value){report_acc_rising();//上报按键printk(" zjy_____________acc_do_work__________________ g_value = %d \n",g_value);}}printk(" zjy_____________acc_do_work__________________ before_enable_irq\n");enable_irq(irq_enum); //使能中断时
}static int setup_acc_detect(struct device_node *np)
{int ret =0;/*根据dtsi文件查找名为acc-detect的gpio号*/acc_detect_gpio = of_get_named_gpio(np,"gpio_acc",0);printk(" zjy_______________________________setup_acc_detect acc_detect_gpio = %d \n",acc_detect_gpio);if(gpio_is_valid(acc_detect_gpio)){ //判断gpio是否有效ret = gpio_request(acc_detect_gpio,"gpio_acc");}printk(" zjy_______________________________gpio_request acc_detect_gpio=ret = %d \n",ret);/*if(ret)input_set_capability{printk(" zjy_______________________________gpio_acc 1 \n");return -EINVAL;}*/gpio_direction_input(acc_detect_gpio); //设置为输入gpio_set_debounce(acc_detect_gpio,20);//gpio管脚防抖//ret =request_threaded_irq(gpio_to_irq(acc_detect_gpio),NULL,acc_detect_irq,IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING| IRQF_ONESHOT,"acc_detect",NULL);ret =request_irq(gpio_to_irq(acc_detect_gpio),acc_interrupt,IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING| IRQF_ONESHOT,"acc_detect",NULL);INIT_DELAYED_WORK(&acc_wq,acc_do_work);//schedule_delayed_work(&acc_wq, msecs_to_jiffies(3000));//NIT_WORK(&acc_wq,acc_do_work);printk(" zjy_______________________________setup_acc_detect request_threaded_irq 中断返回 = %d \n",ret);if(ret){return ret;}return 0;
}static int acc_probe(struct platform_device *pdev)
{int ret = 0;struct device_node *node = pdev->dev.of_node;setup_acc_detect(node); //初始化中断 // 1, 构建一个struct input_device对象 acc_input_dev = input_allocate_device();// 2,初始化struct input_device对象acc_input_dev->evbit[0] = BIT_MASK(EV_KEY);acc_input_dev->name = "venus_gpio_fibocom";acc_input_dev->phys = "venus/input0";input_set_capability(acc_input_dev, EV_KEY, KEY_F12);input_set_capability(acc_input_dev, EV_KEY, KEY_F11);// 3, 注册struct input_device对象ret = input_register_device(acc_input_dev);printk(" zjy_____________acc_probe \n");return 0;
}static int acc_remove(struct platform_device *pdev)
{// int ret =gpio_to_irq(acc_detect_gpio);// gpio_free(acc_detect_gpio);// free_irq(ret,acc_interrupt);printk(" zjy_______________________________ acc_remove\n");return 0;
}static const struct of_device_id acc_dt_match[] = {{.compatible = "qcom,acc",},{},
};//device tree
static struct platform_driver acc_driver = {.probe = acc_probe,.remove = acc_remove,.driver = {.name = "acc",.owner = THIS_MODULE,.of_match_table = acc_dt_match,},
};static int __init acc_init(void)
{printk(" zjy______________acc_init_________________ %s() \n",__func__);if (platform_driver_register(&acc_driver)) {printk("failed to register led driver module\n");return -ENODEV;}return 0;
}static void __exit acc_exit(void)
{//int ret =gpio_to_irq(acc_detect_gpio);// gpio_free(acc_detect_gpio);//free_irq(ret,acc_interrupt);platform_driver_unregister(&acc_driver);printk(" zjy__________________acc_exit_____________ %s() \n",__func__);}
subsys_initcall(acc_init);
module_exit(acc_exit);MODULE_DESCRIPTION("Meson acc Driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhou764219923@qq.com");
5.加载驱动:
在system/core/rootdir/init.rc中添加:
chmod 0777 /dev/ttysWK1chmod 0777 /dev/ttysWK2chmod 0777 /dev/ttysWK3
+ chmod 0666 /system/lib/modules/acc_drv.ko
+ insmod /system/lib/modules/acc_drv.ko
注意:
1》.如果编译到内核修改方式是:obj-m改为obj-y(两个Makefile里面),去掉init.rc中修改权限和insmod驱动即可。
MSM8953 ACC状态上报相关推荐
- linux云服务器状态上报解决方案:外发个人邮箱
linux云服务器状态上报解决方案:外发个人邮箱 需求如下: #### 将一些服务器的关键日志实时发送到手机上 一些案例: CPU状态检测 解决方案: #### 利用mailx命令外发邮件 方法如下: ...
- 浅析Kubelet如何上报状态
浅析Kubelet如何上报状态 1 kubelet上报节点状态 在K8S集群中,由运行在每个节点的Kubelet定期上报心跳到ApiServer,以此来判断Node是否存活,若Node超过一定时间没有 ...
- 错误上报_PCIe错误的上报方式
按Spec定义的原则和内容,前面讲的所有错误类型,包括不可修复错误(Uncorrectable Errors)和可修复错误(Correctable Errors).这些错误的错误检测,都是由各个硬件设 ...
- android停止蓝牙音乐服务,蓝牙音乐播放状态一直为暂停态
安卓源码避坑指南7--蓝牙音乐播放状态一直为暂停态 蓝牙音乐的播放状态是蓝牙音乐等相关应用重点关心的变量,应用根据该状态值(播放.暂停)实时更新界面图标显示.本期就和大家简单分享下蓝牙音乐播放状态上报 ...
- 涂鸦模组开发(压力传感器HX711)——4. 上报传感器数据给涂鸦模块
涂鸦模组开发_压力传感器HX711--4. 上报传感器数据给涂鸦模块 概述 视频演示 资料下载 涂鸦智能 涂鸦功能修改 压力值上报 压力状态上报 增值服务 最后 概述 涂鸦智能 (NYSE:TUYA) ...
- 井盖智能监测终端——井盖状态监测仪
一.产品概述 井盖智能监测终端是一款用于监测城市窨井井盖状态的设备,安装于井盖背面,当井盖发生异动或窨井液位达到报警条件时,将触发井盖监测仪报警,将井盖状态.经纬度.设备参数等数据通过无线传输方式发送 ...
- 车载系统的电源状态及迁移
车载系统的电源状态及迁移 在车载系统开发过程中,无论是软件开发还是硬件开发,都会涉及到"电源状态迁移",这个是一个最基础的知识,但是往往在实际工作中,即使有过几年车载开发经验的人, ...
- 整车电源的几种模式:OFF/ACC/RUN/CRANK
本文框架 1.前言 2. 四种电源模式 2.1 OFF模式 2.2 ACC模式 2.3 ON模式 2.4 CRANK模式 3. KL15/KL30 1.前言 在诊断或者网络管理相关模块开发对客户的需求 ...
- 汽车的OFF档,ACC档,ON档,START档
off:对应lock档 acc:acc档 on:on档 start:发动档: 1.ACC是钥匙门开关,ACC状态就是钥匙门的开关状态. 2.一般的汽车钥匙有4个档位,一个是"OFF" ...
最新文章
- Visual Studio 2013编译Mozilla NPAPI 示例注意事项
- 表贴光电池 FU-NJL6402R-2 的特性
- 计算机二叉树讲解ppt,数据结构二叉树.ppt
- AB1601开机运行后死机
- linux模拟主机宕机,AIX HA模拟宕机--维护磁带机
- Javascript Array和String的互转换。
- mysql json 创建索引_MySQL · 最佳实践 · 如何索引JSON字段
- python最简分数_592. 分数加减法运算(Python)
- Flask实现图片的上传、下载及展示
- 【机器学习】鸢尾花数据探索
- 你对NLP的迁移学习爱的有多深?21个问题弄懂最新的NLP进展。
- NOIP2017错题
- Tomcat优化详细教程
- VMware的XP虚拟机联网
- 多源异构数据库实时同步解决方案
- Ninth season eighth episode,Rachel‘s another sister,how is she???
- 计算机主机英语怎么说,电脑里的 属性 英语怎么说
- deepin20.7隐藏分区
- 创建数据库的相关命令与字符类型
- 上海青少年算法竞赛-6月月赛参考代码