linux驱动笔记-I2C驱动

i2c_adapter

struct i2c_adapter代表一个i2c控制器,本质上也是一个设备,所以包含struct device,其中包含重要成员struct i2c_algorithm,i2c_algorithm 中的master_xfer()用来实现i2c数据通信方法。

i2c_driver

代表i2c设备的驱动,包含struct device_driver,device_driver中包含of_device_id,match()函数用于匹配驱动和设备。还包含两个函数指针,int (*probe)(struct i2c_client *),int (*remove)(struct i2c_client *)。

i2c_client

代表i2c从设备,其中包含struct device,用于和i2c_driver进行匹配,还包含i2c_adapter,用于指定此设备挂载在哪个i2c控制器上,i2c从设备地址由其中的addr保存。

i2c_msg

struct i2c_msg {
	__u16 addr; /* slave address */
	 __u16 flags;
	#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
	#define I2C_M_RD 0x0001 /* read data, from slave to master */
	#define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
	#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
	#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
	#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
	#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
	#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
	 __u16 len; /* msg length */
	 __u8 *buf; /* pointer to msg data */
};

linux中i2c信号的传输以i2c_msg为单位,i2c_msg包含addr,flag,buf,len。
从机驱动中使用i2c_transfer()来实现寄存器的读写,一般写函数中定义一个i2c_msg,读函数定义两个i2c_msg,调用i2c_transfer()本质上是调用i2c_algorithm中的master_xfer(),适配器中调用i2c_master_recv()和i2c_master_send()来实现数据传输。

i2c_driver实现要点

  1. probe(struct *client)中一般实现字符设备驱动的基本框架并需要将参数client的值赋给驱动文件中定义的xxx_client。xxx_client赋值成功后需要将xxx_client传递给i2c_msg。
  2. __init 中需要i2c_add_driver(),__exit函数中需要i2c_del_driver()。

i2c_adapter驱动

RK3399 i2c适配器驱动采用platform框架,驱动中定义rk3x_i2c,其中包含i2c_adapter,regs,驱动头部定义寄存器。probe函数中初始化i2c_adapter,包括algorithm、device.of_node、platform_get_resource(),并将返回值赋给rk3x_i2c->regs(regs保存i2c控制器的首地址,其他寄存器的地址为该地址加头部定义的偏移量)。

i2c->adap.owner = THIS_MODULE;
i2c->adap.algo = &rk3x_i2c_algorithm;
i2c->adap.retries = 3;
i2c->adap.dev.of_node = np;
i2c->adap.algo_data = i2c;
i2c->adap.dev.parent = &pdev->dev;

执行i2c_add_adapter。
remove函数中i2c_del_adapter。

rk3x_i2c_xfer

i2c_adapter和i2c_client通信的底层都是调用i2c_transfer(),i2c_transfer()调用i2c_adapter驱动中的rk3x_i2c_xfer。再底层就是调用readl(),writel()来实现。readl(),writerl()为内存映射的 I/O 空间读取或写入数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值