linux I2C驱动框架之设备驱动(四)

目录

  1. i2c设备驱动结构体
  2. 模块的加载和卸载
  3. I2C通信模板

i2c设备驱动结构体

I2C 设备驱动要使用i2c_driver和i2c_client数据结构并填充其中的成员函数。i2c_client 一般被包含在设备的私有信息结构体yyy_data 中,而i2c_driver 则适合被定义为全局变量并初始化,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 *);

	/* 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").
	 * For the SMBus Host Notify protocol, the data corresponds to the
	 * 16-bit payload data reported by the slave device acting as master.
	 */
	void (*alert)(struct i2c_client *, enum i2c_alert_protocol protocol,
		      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;
};

结构体重一共有四个变量比较重要:

struct device_driver driver:驱动实例

int (*probe)(struct i2c_client *, const struct i2c_device_id *):当驱动和设备匹配之后会调用此函数进行初始化

int (*remove)(struct i2c_client *):probe的对立函数,完成驱动的去初始化工作

const struct i2c_device_id *id_table:支持的驱动列表

以drivers\media\dvb-frontends\af9033.c为例

i2c_driver结构体初始化如下所示:

static struct i2c_driver af9033_driver = {
	.driver = {
		.name	= "af9033",
		.suppress_bind_attrs	= true,
	},
	.probe		= af9033_probe,
	.remove		= af9033_remove,
	.id_table	= af9033_id_table,
};

模块的加载和卸载

定义的i2c_driver需要通过函数i2c_add_driver将i2c_driver注册到linux系统中,需要通过函数i2c_del_driver从linux中卸载i2c_driver驱动。函数由i2c核心提供。

添加驱动方法如下所示:

static int __init af9033_i2c_init(void)
{
	return i2c_add_driver(&af9033_driver);
}
module_init(af9033_i2c_init);

static void __exit af9033_i2c_exit(void)
{
	i2c_del_driver(&af9033_driver);
}
module_exit(af9033_i2c_exit);

或者直接使用宏添加驱动

module_i2c_driver(af9033_driver);

I2C通信模板

添加完设备驱动之后就可以直接使用i2c进行通信了,通信模板如下所示:

static int af9033_rd_regs(struct af9033_dev *dev, u32 reg, u8 *val, int len)
{
	int ret;
	u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff,
			(reg >> 0) & 0xff };
	struct i2c_msg msg[2] = {
		{
			.addr = dev->client->addr,
			.flags = 0,
			.len = sizeof(buf),
			.buf = buf
		}, {
			.addr = dev->client->addr,
			.flags = I2C_M_RD,
			.len = len,
			.buf = val
		}
	};

	ret = i2c_transfer(dev->client->adapter, msg, 2);
	if (ret == 2) {
		ret = 0;
	} else {
		dev_warn(&dev->client->dev, "i2c rd failed=%d reg=%06x len=%d\n",
				ret, reg, len);
		ret = -EREMOTEIO;
	}

	return ret;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值