当前位置:   article > 正文

嵌入式Linux设备驱动程序开发指南15(Linux输入子系统、I2C设备驱动)——读书笔记_linux i2c input

linux i2c input

十五、Linux输入子系统、I2C设备驱动

15.1 简介

许多驱动程序不是从一个字符设备开始写的,而是使用固定框架实现,该框架专门针对特定设备类型,如网络设备、串口设备、内存设备)(MTD)、实时时钟、工业IO等。框架的作用是把同类设备驱动程序的公共代码分离出来,以减少代码重复度。框架为每种类型设备提供与驱动无关的一致的用户接口。
驱动如何与框架交互并向用户应用程序,使用硬件资源的功能,如下:
在这里插入图片描述

15.2 input_event

输入设备常见的有鼠标、键盘、操作杆、触摸屏等。
输入设备驱动程序统一的格式——input_event数据结构捕获硬件信息,并报告给核心层,核心层对数据进行分类上报事件,最后通过事件层上报给用户态。
输入子系统可分两部分:驱动程序、事件处理程序。
输入子系统划分:event应用程序、输入子系统核心、输入事件驱动、输入轮询设备驱动、I2C驱动;
轮询输入设备头文件定义:

/include/linux/input-polldev.h

struct input_polled_dev;
  • 1
  • 2
  • 3

input_polled_dev数据结构由poll()回调函数来处理,这个函数轮询设备并产生输入事件。poll()函数内部,驱动程序调用input_event()函数把事件发送到事件处理函数。

15.3设备树

					adxl345@1c {
						compatible = "arrow,adxl345";
						reg = <0x1d>;
					};
  • 1
  • 2
  • 3
  • 4

15.4 驱动代码

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/input-polldev.h>

/* create private structure */
struct ioaccel_dev {
	struct i2c_client * i2c_client;
	struct input_polled_dev * polled_input;
};

#define POWER_CTL	0x2D
#define PCTL_MEASURE	(1 << 3)
#define OUT_X_MSB	0x33

/* poll function */
static void ioaccel_poll(struct input_polled_dev * pl_dev)
{
	struct ioaccel_dev * ioaccel = pl_dev->private;
	int val = 0;
	val = i2c_smbus_read_byte_data(ioaccel->i2c_client, OUT_X_MSB);


	if ( (val > 0xc0) && (val < 0xff) ) {
		input_event(ioaccel->polled_input->input, EV_KEY, KEY_1, 1);
	} else {
		input_event(ioaccel->polled_input->input, EV_KEY, KEY_1, 0);
	}

	input_sync(ioaccel->polled_input->input);
}

static int ioaccel_probe(struct i2c_client * client,
		const struct i2c_device_id * id)
{
	/* declare an instance of the private structure */
	struct ioaccel_dev * ioaccel;
	
	dev_info(&client->dev, "my_probe() function is called.\n");

	/* allocate private structure for new device */
	ioaccel = devm_kzalloc(&client->dev, sizeof(struct ioaccel_dev), GFP_KERNEL);  //声明一个私有数据结构体、并分配空间

	/* associate client->dev with ioaccel private structure */
	i2c_set_clientdata(client, ioaccel);

	/* enter measurement mode */
	i2c_smbus_write_byte_data(client, POWER_CTL, PCTL_MEASURE);

	/* allocate the struct input_polled_dev */
	ioaccel->polled_input = devm_input_allocate_polled_device(&client->dev);

	/* initialize polled input */
	ioaccel->i2c_client = client;
	ioaccel->polled_input->private = ioaccel;

	ioaccel->polled_input->poll_interval = 50;
	ioaccel->polled_input->poll = ioaccel_poll;

	ioaccel->polled_input->input->dev.parent = &client->dev;

	ioaccel->polled_input->input->name = "IOACCEL keyboard";
	ioaccel->polled_input->input->id.bustype = BUS_I2C;

	/* set event types */
	set_bit(EV_KEY, ioaccel->polled_input->input->evbit);
	set_bit(KEY_1, ioaccel->polled_input->input->keybit);

	/* register the device, now the device is global until being unregistered*/
	input_register_polled_device(ioaccel->polled_input);

	return 0;
}

static int ioaccel_remove(struct i2c_client * client)
{
	struct ioaccel_dev * ioaccel;
	ioaccel = i2c_get_clientdata(client);
	input_unregister_polled_device(ioaccel->polled_input);
	dev_info(&client->dev, "ioaccel_remove()\n");
	return 0;
}

/* add entries to device tree */
static const struct of_device_id ioaccel_dt_ids[] = {
	{ .compatible = "arrow,adxl345", },
	{ }
};
MODULE_DEVICE_TABLE(of, ioaccel_dt_ids);

static const struct i2c_device_id i2c_ids[] = {
	{ "adxl345", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, i2c_ids);

/* create struct i2c_driver */
static struct i2c_driver ioaccel_driver = {
	.driver = {
		. = "adxl345",
		.owner = THIS_MODULE,
		.of_match_table = ioaccel_dt_ids,
	},
	.probe = ioaccel_probe,
	.remove = ioaccel_remove,
	.id_table = i2c_ids,
};

/* register to i2c bus as a driver */
module_i2c_driver(ioaccel_driver);  //把驱动程序注册到I2C总线上

MODULE_LICENSE("GPL");
MODULE_AUTHOR(" ");
MODULE_DESCRIPTION("This is an accelerometer INPUT framework platform driver");

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

感谢阅读,祝君成功!
-by aiziyou

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/586202
推荐阅读
相关标签
  

闽ICP备14008679号