一步一步教你构建一个MPU6050(I2C类)驱动(二)

今天我们先来把驱动的框架搭好

首先是i2c_driver的数据结构

struct i2c_driver {
	unsigned int class;

	/* Notifies the driver that a new bus has appeared. You should avoid
	 * using this, it will be removed in a near future.
	 */
	int (*attach_adapter)(struct i2c_adapter *) __deprecated;

	/* Standard driver model interfaces */
	int (*probe)(struct i2c_client *, const struct i2c_device_id *);
	int (*remove)(struct i2c_client *);

	/* driver model interfaces that don't relate to enumeration  */
	void (*shutdown)(struct i2c_client *);
	int (*suspend)(struct i2c_client *, pm_message_t mesg);
	int (*resume)(struct i2c_client *);

	/* Alert callback, for example for the SMBus alert protocol.
	 * The format and meaning of the data value depends on the protocol.
	 * For the SMBus alert protocol, there is a single bit of data passed
	 * as the alert response's low bit ("event flag").
	 */
	void (*alert)(struct i2c_client *, unsigned int data);

	/* a ioctl like command that can be used to perform specific functions
	 * with the device.
	 */
	int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);

	struct device_driver driver;
	const struct i2c_device_id *id_table;

	/* Device detection callback for automatic device creation */
	int (*detect)(struct i2c_client *, struct i2c_board_info *);
	const unsigned short *address_list;
	struct list_head clients;
};

成员非常多,但是目前我们需要的其实只有下面这几个

int (*probe)(struct i2c_client *, const struct i2c_device_id *);//匹配到设备后调用
int (*remove)(struct i2c_client *);//与probe成对使用,注销时调用
struct device_driver driver;//用于匹配设备
const struct i2c_device_id *id_table;//用于匹配设备

而其中的 driver 和 id_table 就与我们之前在设备树中MPU6050的信息匹配起来。

 

接着我们来看看注册和销毁i2c驱动的两个API。

int i2c_add_adapter(struct i2c_adapter * adapter);//注册
void i2c_del_adapter(struct i2c_adapter * adap);//销毁

有了这些内容,我们就能搭建出一个基本框架了

#include
#include
#include
#include
#include 
#include 	/* for struct device */
#include 	/* for completion */
#include 
#include 		/* for struct device_node */
#include 		/* for swab16 */
#include 

/*
	做一个i2c 的驱动
*/

struct dev_desc mpu6050_dev_desc={
	.name = "mpu6050_drv",
};


static const struct of_device_id mpu6050_of_match[] = {
	{ .compatible = "InvenSense,mpu6050" },
	{},
};

const struct i2c_device_id mpu6050_id_table[] = {
	{ "mpu6050", 0 },
	{},
};

static int mpu6050_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	printk("-----------%s-----------\n", __FUNCTION__);

	return 0;
}

int mpu6050_remove(struct i2c_client *client)
{
	printk("-----------%s-----------\n", __FUNCTION__);

	return 0;
}

struct i2c_driver mpu6050_drv = 
{
	.probe = mpu6050_probe,
	.remove = mpu6050_remove,
	.driver= {
		.name = "mpu6050_drv",//sys/bus/i2c/driver
		.of_match_table = of_match_ptr(mpu6050_of_match),
	},
	.id_table = mpu6050_id_table,
};

static int __init i2cdrv_init(void)
{
	printk("-----------%s-----------\n", __FUNCTION__);
	
	return i2c_register_driver(THIS_MODULE, &mpu6050_drv);
}


static void __exit i2cdrv_exit(void)
{
	printk("-----------%s-----------\n", __FUNCTION__);

	i2c_del_driver(&mpu6050_drv);	
}

module_init(i2cdrv_init);
module_exit(i2cdrv_exit);
MODULE_LICENSE("GPL");

先编译生成.ko文件放在板子上跑一下,检测能不能正常运行。

[root@farsight ]# insmod iic_drv.ko
[   10.210000] -----------i2cdrv_init-----------
[root@farsight ]# ls /sys/bus/i2c/drivers/mpu6050_drv/
bind    module  uevent  unbind
[root@farsight ]# ls /sys/bus/i2c/drivers/mpu6050_drv/module/drivers/
i2c:mpu6050_drv

这样就表示我们的框架已经成功在匹配到了设备上。

你可能感兴趣的:(嵌入式驱动开发)