栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Android驱动-霍尔摁键hall

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android驱动-霍尔摁键hall

第一步移植.c文件

将修改好的hall_sensor.c文件放到input路径下

如 drivers/input/hall_sensor.c

第二步Kconfig配置

路径在 drivers/input/Kconfig

第三步Makefile配置

路径在:drivers/input/Makefile

第四步deconfig配置

路径arch/arm/configs/msm8937go_defconfig

第五步设备树配置

路径在arch/arm64/boot/dts/qcom/qm215-qrd.dtsi

第六步(如果上图注释中pinctrl需要配置则需要配置)

第七步 检查是否生效

adb shell 进入后 getevent 事件可以查看是否有设备生效

第八步 新增加hall_sensor.kl文件

新增方法,跳转到查看matrix_keypad.kl的增加

第九步 功能测试

翻盖看是否亮灭(注意是否有磁性)
还可以看cat proc/interrupts 中断是否有产生

hall_sensor.c代码
 
 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
#define	LID_DEV_NAME	"hall_sensor"
#define HALL_INPUT	"/dev/input/hall_dev"
 
struct hall_data {
	int gpio;	
	int irq;	
	int active_low;	
	bool wakeup;	
	struct input_dev *hall_dev;
    struct device *dev;
};
 
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_SLEEP, 1);
		//input_sync(data->hall_dev);
		//input_report_key(data->hall_dev, KEY_SLEEP, 0);
		//input_sync(data->hall_dev);
		input_report_key(data->hall_dev, FLIP, 0);
	        input_sync(data->hall_dev);
		dev_info(&data->hall_dev->dev, "nearn");
	} else {
		
		//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);
		input_report_key(data->hall_dev, FLIP, 1);
	        input_sync(data->hall_dev);
		dev_info(&data->hall_dev->dev, "farn");
	}
	//input_report_key(data->hall_dev, KEY_FLIP, 1);
   	//input_sync(data->hall_dev);
    	//input_report_key(data->hall_dev, KEY_FLIP, 0);
	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 failedn");
		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);
        set_bit(FLIP,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 %sn",
				LID_DEV_NAME);
		return err;
	}
 
	return 0;
}
 
#ifdef CONFIG_OF
static int hall_parse_dt(struct device *dev, struct hall_data *data)
{
	unsigned int tmp;

	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 validn");
		return -EINVAL;
	}
	data->active_low = tmp & OF_GPIO_ACTIVE_LOW ? 0 : 1;
 
	data->wakeup = of_property_read_bool(np, "linux,wakeup");
 
	return 0;
}
#else
static int hall_parse_dt(struct device *dev, struct hall_data *data)
{
	return -EINVAL;
}
#endif

// Begin: add by hyangde for hall status show on 220516 
static ssize_t hall_status_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct hall_data *pdata = dev_get_drvdata(dev);
	int value;

	value = (gpio_get_value_cansleep(pdata->gpio) ? 1 : 0) ^ pdata->active_low;

	return snprintf(buf, PAGE_SIZE, "%dn", value);
}

static DEVICE_ATTR(hall_status, 0664, hall_status_show, NULL);

static struct attribute *hall_attrs[] = {
	&dev_attr_hall_status.attr,
	NULL,
};

static struct attribute_group hall_attr_group = {
	.attrs = hall_attrs,
};
// End: add by hyangde for hall status show on 220516 

static int hall_driver_probe(struct platform_device *dev)
{
	struct hall_data *data;
	int err = 0;
	int irq_flags;
 	printk("guh hall probe start");
	dev_info(&dev->dev, "hall_driver proben");
	data = devm_kzalloc(&dev->dev, sizeof(struct hall_data), GFP_KERNEL);
	if (data == NULL) {
		err = -ENOMEM;
		dev_err(&dev->dev,
				"failed to allocate memory %dn", err);
		goto exit;
	}

	data->dev = &dev->dev;
	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 treen");
			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 failedn");
		goto exit;
	}
 
	if (!gpio_is_valid(data->gpio)) {
		dev_err(&dev->dev, "gpio is not validn");
		err = -EINVAL;
		goto free_gpio;
	}
 
	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 %dn", 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 : %dn", data->irq);
		goto free_irq;
	}

	err = sysfs_create_group(&data->dev->kobj, &hall_attr_group);
	if (err) {
		printk(KERN_ERR "%s sysfs_create_group failn", __func__);
		return err;
	}

	device_init_wakeup(&dev->dev, data->wakeup);
	enable_irq_wake(data->irq);
 	printk("guh hall probe end");
	return 0;
 
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);
 
	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", },
	{ },
};
#endif
 
static 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");
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/939748.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号