要移植hall sensor的驱动,但手上没有源码,只能自己写了,但能不能偷懒呢。在github上搜索一番,还真找到了,分享下。

https://github.com/Myself5/android_kernel_sony_msm8994_OM5Z_old/blob/master/drivers/input/hall_sensor.c

dts参考配置

hall {compatible = "hall-switch";linux,gpio-int=<&ap_gpio 45 1>;linux,wakeup;vddio=<&vddcama>;linux,max-uv=<2800>;linux,min-uv=<2800>;
};

如果sensor的电源是常供的,去掉vddiio,找不到该电源,系统会默认拿一路dummy的电源。

源码(原始代码只能亮屏不能灭屏,做了一下修改)

/*** Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 and* only version 2 as published by the Free Software Foundation.** 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.  See the* GNU General Public License for more details.**/#include <linux/err.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>#define LID_DEV_NAME    "hall_sensor"
#define HALL_INPUT  "/dev/input/hall_dev"struct hall_data {int gpio;  /* device use gpio number */int irq;    /* device request irq number */int active_low;  /* gpio active high or low for valid value */bool wakeup;   /* device can wakeup system or not */struct input_dev *hall_dev;struct regulator *vddio;u32 min_uv; /* device allow minimum voltage */u32 max_uv;   /* device allow max voltage */
};static irqreturn_t hall_interrupt_handler(int irq, void *dev)
{int value;struct hall_data *data = dev;value = (gpio_get_value_cansleep(data->gpio) ? 1 : 0) ^data->active_low;if (value) {input_report_key(data->hall_dev, KEY_WAKEUP, 1);input_sync(data->hall_dev);input_report_key(data->hall_dev, KEY_WAKEUP, 0);input_sync(data->hall_dev);dev_info(&data->hall_dev->dev, "far\n");} else {input_report_key(data->hall_dev, KEY_SLEEP, 1);input_sync(data->hall_dev);input_report_key(data->hall_dev, KEY_SLEEP, 0);input_sync(data->hall_dev);dev_info(&data->hall_dev->dev, "near\n");}input_sync(data->hall_dev);return IRQ_HANDLED;
}static int hall_input_init(struct platform_device *pdev,struct hall_data *data)
{int err = -1;data->hall_dev = devm_input_allocate_device(&pdev->dev);if (!data->hall_dev) {dev_err(&data->hall_dev->dev,"input device allocation failed\n");return -EINVAL;}data->hall_dev->name = LID_DEV_NAME;data->hall_dev->phys = HALL_INPUT;set_bit(EV_KEY, data->hall_dev->evbit);set_bit(KEY_WAKEUP, data->hall_dev->keybit);set_bit(KEY_SLEEP, data->hall_dev->keybit);err = input_register_device(data->hall_dev);if (err < 0) {dev_err(&data->hall_dev->dev,"unable to register input device %s\n",LID_DEV_NAME);return err;}return 0;
}static int hall_config_regulator(struct platform_device *dev, bool on)
{struct hall_data *data = dev_get_drvdata(&dev->dev);int rc = 0;if (on) {data->vddio = devm_regulator_get(&dev->dev, "vddio");if (IS_ERR(data->vddio)) {rc = PTR_ERR(data->vddio);dev_err(&dev->dev, "Regulator vddio get failed rc=%d\n",rc);data->vddio = NULL;return rc;}if (regulator_count_voltages(data->vddio) > 0) {rc = regulator_set_voltage(data->vddio,data->min_uv,data->max_uv);if (rc) {dev_err(&dev->dev, "Regulator vddio Set voltage failed rc=%d\n",rc);goto deinit_vregs;}}return rc;} else {goto deinit_vregs;}deinit_vregs:if (regulator_count_voltages(data->vddio) > 0)regulator_set_voltage(data->vddio, 0, data->max_uv);return rc;
}static int hall_set_regulator(struct platform_device *dev, bool on)
{struct hall_data *data = dev_get_drvdata(&dev->dev);int rc = 0;if (on) {if (!IS_ERR_OR_NULL(data->vddio)) {rc = regulator_enable(data->vddio);if (rc) {dev_err(&dev->dev, "Enable regulator vddio failed rc=%d\n",rc);goto disable_regulator;}}return rc;} else {if (!IS_ERR_OR_NULL(data->vddio)) {rc = regulator_disable(data->vddio);if (rc)dev_err(&dev->dev, "Disable regulator vddio failed rc=%d\n",rc);}return 0;}disable_regulator:if (!IS_ERR_OR_NULL(data->vddio))regulator_disable(data->vddio);return rc;
}#ifdef CONFIG_OF
static int hall_parse_dt(struct device *dev, struct hall_data *data)
{unsigned int tmp;u32 tempval;int rc;struct device_node *np = dev->of_node;data->gpio = of_get_named_gpio_flags(dev->of_node,"linux,gpio-int", 0, &tmp);if (!gpio_is_valid(data->gpio)) {dev_err(dev, "hall gpio is not valid\n");return -EINVAL;}data->active_low = tmp & OF_GPIO_ACTIVE_LOW ? 0 : 1;data->wakeup = of_property_read_bool(np, "linux,wakeup");rc = of_property_read_u32(np, "linux,max-uv", &tempval);if (rc) {dev_err(dev, "unable to read max-uv\n");return -EINVAL;}data->max_uv = tempval;rc = of_property_read_u32(np, "linux,min-uv", &tempval);if (rc) {dev_err(dev, "unable to read min-uv\n");return -EINVAL;}data->min_uv = tempval;return 0;
}
#else
static int hall_parse_dt(struct device *dev, struct hall_data *data)
{return -EINVAL;
}
#endifstatic int hall_driver_probe(struct platform_device *dev)
{struct hall_data *data;int err = 0;int irq_flags;dev_info(&dev->dev, "hall_driver probe\n");data = devm_kzalloc(&dev->dev, sizeof(struct hall_data), GFP_KERNEL);if (data == NULL) {err = -ENOMEM;dev_err(&dev->dev,"failed to allocate memory %d\n", err);goto exit;}dev_set_drvdata(&dev->dev, data);if (dev->dev.of_node) {err = hall_parse_dt(&dev->dev, data);if (err < 0) {dev_err(&dev->dev, "Failed to parse device tree\n");goto exit;}} else if (dev->dev.platform_data != NULL) {memcpy(data, dev->dev.platform_data, sizeof(*data));} else {dev_err(&dev->dev, "No valid platform data.\n");err = -ENODEV;goto exit;}err = hall_input_init(dev, data);if (err < 0) {dev_err(&dev->dev, "input init failed\n");goto exit;}if (!gpio_is_valid(data->gpio)) {dev_err(&dev->dev, "gpio is not valid\n");err = -EINVAL;goto exit;}irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING| IRQF_ONESHOT;err = gpio_request_one(data->gpio, GPIOF_DIR_IN, "hall_sensor_irq");if (err) {dev_err(&dev->dev, "unable to request gpio %d\n", data->gpio);goto exit;}data->irq = gpio_to_irq(data->gpio);err = devm_request_threaded_irq(&dev->dev, data->irq, NULL,hall_interrupt_handler,irq_flags, "hall_sensor", data);if (err < 0) {dev_err(&dev->dev, "request irq failed : %d\n", data->irq);goto free_gpio;}device_init_wakeup(&dev->dev, data->wakeup);enable_irq_wake(data->irq);err = hall_config_regulator(dev, true);if (err < 0) {dev_err(&dev->dev, "Configure power failed: %d\n", err);goto free_irq;}err = hall_set_regulator(dev, true);if (err < 0) {dev_err(&dev->dev, "power on failed: %d\n", err);goto err_regulator_init;}return 0;err_regulator_init:hall_config_regulator(dev, false);
free_irq:disable_irq_wake(data->irq);device_init_wakeup(&dev->dev, 0);
free_gpio:gpio_free(data->gpio);
exit:return err;
}static int hall_driver_remove(struct platform_device *dev)
{struct hall_data *data = dev_get_drvdata(&dev->dev);disable_irq_wake(data->irq);device_init_wakeup(&dev->dev, 0);if (data->gpio)gpio_free(data->gpio);hall_set_regulator(dev, false);hall_config_regulator(dev, false);return 0;
}static struct platform_device_id hall_id[] = {{LID_DEV_NAME, 0 },{ },
};#ifdef CONFIG_OF
static struct of_device_id hall_match_table[] = {{.compatible = "hall-switch", },{ },
};
#endifstatic struct platform_driver hall_driver = {.driver = {.name = LID_DEV_NAME,.owner = THIS_MODULE,.of_match_table = of_match_ptr(hall_match_table),},.probe = hall_driver_probe,.remove = hall_driver_remove,.id_table = hall_id,
};static int __init hall_init(void)
{return platform_driver_register(&hall_driver);
}static void __exit hall_exit(void)
{platform_driver_unregister(&hall_driver);
}module_init(hall_init);
module_exit(hall_exit);
MODULE_DESCRIPTION("Hall sensor driver");
MODULE_LICENSE("GPL v2");

Linux下的Hall sensor驱动相关推荐

  1. Linux下的USB总线驱动 mouse

    Linux下的USB总线驱动(03)--USB鼠标驱动 usbmouse.c USB鼠标驱动 usbmouse.c 原文链接:http://www.linuxidc.com/Linux/2012-12 ...

  2. 南京邮电大学嵌入式系统开发实验5:嵌入式Linux下LED报警灯驱动设计及编程

    实验5  嵌入式Linux下LED报警灯驱动设计及编程 一.实验目的 理解驱动本质,掌握嵌入式Linux系统下驱动开发相关知识,包括端口寄存器访问.接口函数编写.和文件系统挂接.注册及相关应用编程等知 ...

  3. *Linux下的USB总线驱动 u盘驱动分析*

    Linux下的USB总线驱动(三) u盘驱动分析 版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127 https://www.xuebuyuan.com/13 ...

  4. 在Fedora 16 linux下安装USB无线网卡驱动88x2bu

    在Fedora 16 linux下安装USB无线网卡驱动88x2bu USB无线网卡翼联EP-AC1610兼容linux系统 我之前已经买了一个USB无线网卡是水星mw150us,但是没有linux驱 ...

  5. linux 安装水星无线网卡驱动,Linux下安装RTL8188CE网卡驱动(Mercury MW150U)

    先说明下我的系统: kernel: 3.0.0-32-generic 今天买了个无线网卡Mercury 150Mbps MW150U系列,我发现在我的笔记本的Ubuntu 12.10下不用安装驱动就能 ...

  6. 如何编写Linux 下的 USB 键盘驱动

     如何编写Linux 下的 USB 键盘驱动 1. 指定 USB 键盘驱动所需的头文件: #include <linux/kernel.h>/*内核头文件,含有内核一些常用函数的原型定 ...

  7. 什么是 Linux 下的 platform 设备驱动

    Linux下的字符设备驱动一般都比较简单,只是对IO进行简单的读写操作.但是I2C.SPI.LCD.USB等外设的驱动就比较复杂了,需要考虑到驱动的可重用性,以避免内核中存在大量重复代码,为此人们提出 ...

  8. Linux下PCI转串口卡驱动安装方法

    Linux下PCI转串口卡驱动安装方法 ----------------------------------- 由于公司产品要做行业市场,而产品与行业用户间PC的通讯为RS232串口方式.而行业用户那 ...

  9. usb hub 要驱动 linux,Linux下的USB HUB驱动

    Linux下的USB HUB驱动 [日期:2012-07-29] 来源:Linux社区 作者:zhengmeifu [字体:大 中 小] 五:hub接口驱动分析 5.1:接口驱动架构 是时候来分析接口 ...

最新文章

  1. Slackware网卡配置文件和配置工具
  2. 可降阶的高阶微分方程
  3. [Bootstrap]全局样式(四)
  4. MFC socket网络编程(流程示例)
  5. 专属海报小程序_剑3泡泡 | 小程序给你一份专属的账号海报!
  6. php dos命令用不了,windows下如何使用DOS命令强制复制文件
  7. Scala 语言学习之泛型(7)
  8. TCP/IP协议详解内容总结(怒喷一口老血)
  9. Java 25天基础-DAY 05-面向对象-构造函数
  10. 博弈论——战略式博弈
  11. C#操作十六进制数据以及十进制与十六进制互相转换
  12. Java多线程及锁相关面试题
  13. 高中数学建模优秀论文_数学建模优秀论文范文
  14. 解决360抢票王刷票0.1秒停顿问题,思考抢票软件和IT行业
  15. python 实现 n 次方_python实现pow函数(求n次幂,求n次方)
  16. python-生成xlsx表格
  17. phpmail通过qq发邮箱失败_PHPMailer使用QQ邮箱实现邮件发送功能
  18. 通俗地讲一下Web是什么意思。
  19. steam计算机游戏,steam五款免费游戏推荐  整体品质不输付费游戏 千万不要错过...
  20. 从0到1构建一个电商平台 – 开发篇(转)

热门文章

  1. css隐藏滚动条兼容IE,火狐,chrom
  2. 从代理模式再出发!Proxy.newProxyInstance的秘密
  3. 1.综合能源系统优化运行(碳交易机制下考虑需求响应的综合能源系统优化运行)
  4. CentOS 7系统安装Ghost
  5. [转帖]老狼:你知道哪些关于 Windows 10 的骚操作?
  6. 小程序毕设作品之微信积分商城小程序毕业设计成品(1)开发概要
  7. php 图片处理羽化,ps中羽化是什么意思
  8. 简介:cs224n 2022 winter [Chris Manning]
  9. springboot整合netty实现tcp通信
  10. 怎样搜索计算机文档,怎么样快速搜索电脑文件 Windows系统秒搜电脑文件