Linux驱动开发 (IIC子系统)

1.IIC协议简介 

在之前的ARM裸机里面有介绍:ARM裸机 - I2C通信协议是最常用的协议_一对多i2c-CSDN博客

2.Linux的IIC子系统框架

在这里插入图片描述

I2C主机驱动:I2C主机控制器的驱动,一般由SoC芯片厂商负责设计实现,用于控制II2C主机控制器发出时序信号。

I2C Core:为上层提供统一的API接口和对其他模块进行注册和注销等管理等。

I2C 驱动和我们之前接触到的平台总线设备驱动非常类似,都有总线、设备和驱这三者。

I2C驱动框架的主要目标是:让驱动开发者可以在内核中方便的添加自己的I2C设备的驱动程序,从而可以更容易的在linux下驱动自己的I2C接口硬件。

源码中I2C相关的驱动均位于:drivers/i2c目录下。

3.linux内核的I2C子系统源代码分析

I2C子系统的4个关键结构体:

struct i2c_adapter : I2C适配器

struct i2c_adapter {
	struct module *owner;
	unsigned int id;
	unsigned int class;		          /* classes to allow probing for */
	const struct i2c_algorithm *algo; /* the algorithm to access the bus */
	void *algo_data;

	/* data fields that are valid for all devices	*/
	struct rt_mutex bus_lock;
	int timeout;		         	 /* in jiffies */
	int retries;
	struct device dev;		         /* the adapter device */

	int nr;
	char name[48];
	struct completion dev_released;
	struct list_head userspace_clients;
};

struct i2c_algorithm : I2C算法

struct i2c_algorithm {
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,  int num);
int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data);

/* To determine what the adapter supports */
u32 (*functionality) (struct i2c_adapter *);
};

struct i2c_client :I2C(从机)设备信息

struct i2c_client {
	unsigned short flags;		/* div., see below		*/
	unsigned short addr;		/* chip address - NOTE: 7bit	*/
					            /* addresses are stored in the	*/
				             	/* _LOWER_ 7 bits		*/
	char name[I2C_NAME_SIZE];
	struct i2c_adapter *adapter;/* the adapter we sit on	*/
	struct i2c_driver *driver;	/* and our access routines	*/
	struct device dev;		    /* the device structure		*/
	int irq;			        /* irq issued by device		*/
	struct list_head detected;
};

struct i2c_driver : I2C(从机)设备驱动

struct i2c_driver {
	unsigned int class;
	int (*attach_adapter)(struct i2c_adapter *);
	int (*detach_adapter)(struct i2c_adapter *);

	/* 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 *);
	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;
};

4.i2c-core.c分析

在这里插入图片描述

match函数:

在这里插入图片描述

probe函数:

在这里插入图片描述

I2C总线上有2条分支:i2c_client链和i2c_driver链,当任何一个driver或者client去注册时,I2C总线都会调用match函数去对client.name和driver.id_table.name进行循环匹配。如果driver.id_table中所有的id都匹配不上则说明client并没有找到一个对应的driver。
 

5.i2c_s3c2410.c分析

driver和device配对过程:

在这里插入图片描述

probe函数:

填充一个i2c_adapter结构体,并且调用接口去注册之。

从platform_device接收硬件信息,做必要的处理(request_mem_region & ioremap、request_irq等)。

对硬件做初始化(直接操作210内部I2C控制器的寄存器)。

在这里插入图片描述

6.gslX680的驱动为例-----i2c_driver 和 i2c_client 

i2c_driver:

在这里插入图片描述

i2c_client实现原理 :

内核维护一个链表 __i2c_board_list,这个链表上链接的是I2C总线上挂接的所有硬件设备的信息结构体。也就是说这个链表维护的是一个struct i2c_board_info结构体链表。

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式_笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值