从Tiny4412--mma7660 gsensor驱动探索Linux内核I2C总线驱动框架

源码位于: driver/hwmon/mma7660.c
参考博客:http://www.cnblogs.com/pengdonglin137/p/5240416.html

参考mma7660的芯片数据手册:https://wenku.baidu.com/view/3ef59c28ed630b1c59eeb521.html

从Tiny4412--mma7660 gsensor驱动探索Linux内核I2C总线驱动框架

从Tiny4412--mma7660 gsensor驱动探索Linux内核I2C总线驱动框架

从Tiny4412--mma7660 gsensor驱动探索Linux内核I2C总线驱动框架

从Tiny4412--mma7660 gsensor驱动探索Linux内核I2C总线驱动框架

那么驱动分析完了,设备板级配置文件配置在哪里呢?
代码位置:/arch/arm/mach-exynos/mach-tiny4412.c
在大约2856行的地方,可以看到:
这里通过CONFIG_SENSORS_MMA7660来识别是否有在内核中配置这个sensor,这个配置在源码根目录下的tiny4412_android_defconfig中:
可以搜索到:CONFIG_SENSORS_MMA7660=y

//判断是否有配置CONFIG_SENSORS_MMA7660
#ifdef CONFIG_SENSORS_MMA7660
//如果配置了,就包含7660驱动相关的头文件,并配置板级信息
#include <linux/mma7660.h>
static struct mma7660_platform_data mma7660_pdata = {
	.irq			= IRQ_EINT(25),  //设置外部中断号
	.poll_interval	= 100,			
	.input_fuzz		= 4,
	.input_flat		= 4,
};
#endif

static struct s3c2410_platform_i2c tiny4412_i2c3_data __initdata = {
	.flags			= 0,
	.bus_num		= 3,
	.slave_addr		= 0x10,
	.frequency		= 200*1000,
	.sda_delay		= 100,
};

static struct i2c_board_info i2c_devs3[] __initdata = {
#ifdef CONFIG_SENSORS_MMA7660
	{
		//这就是所谓的i2c_client的信息,在驱动中可以获取
		I2C_BOARD_INFO("mma7660", 0x4c),  //I2C板级注册信息
		.platform_data = &mma7660_pdata,  //将信息存储在platform_data中:
	},
#endif
};
以下为I2C_BOARD_INFO的原型:

/**
 * I2C_BOARD_INFO - macro used to list an i2c device and its address
 * @dev_type: identifies the device type
 * @dev_addr: the device's address on the bus.
 *
 * This macro initializes essential fields of a struct i2c_board_info,
 * declaring what has been provided on a particular board.  Optional
 * fields (such as associated irq, or device-specific platform_data)
 * are provided using conventional syntax.
 */
#define I2C_BOARD_INFO(dev_type, dev_addr) \
	.type = dev_type, .addr = (dev_addr)


大约4084行,找到初始化函数:
static void __init smdk4x12_machine_init(void)
大约4147行可以看到,在初始化硬件信息的时候向i2c注册了板级信息:
s3c_i2c3_set_platdata(&tiny4412_i2c3_data);
i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));


该函数原型:
int __init
i2c_register_board_info(int busnum,
	struct i2c_board_info const *info, unsigned len)
	
i2c_board_info结构体的实现:
struct i2c_board_info {
	char		type[I2C_NAME_SIZE];
	unsigned short	flags;
	unsigned short	addr;
	void		*platform_data;
	struct dev_archdata	*archdata;
	struct device_node *of_node;
	int		irq;
};


而i2c_client的数据存放在以下结构体中;
//#define I2C_NAME_SIZE	20
struct i2c_client {
	unsigned short flags;			//标明i2c设备的地址占多少位, 0为7bit, I2C_CLIENT_TEN为10位
	unsigned short addr;			//设备地址 								
	char name[I2C_NAME_SIZE];		//设备名称
	struct i2c_adapter *adapter;	//指向使用的i2c控制器
	struct i2c_driver *driver;		//指向匹配上的i2c设备驱动
	struct device dev;				//描述设备的结构体
	int irq;						//设备的中断号
	struct list_head detected;		//可以将这些信息加入到链表中去
};

适配器相关的结构体:
//描述一个i2c控制器
struct i2c_adapter { 
	struct module *owner;
	unsigned int id;
	unsigned int class;		  /* classes to allow probing for */
	const struct i2c_algorithm *algo; //使用哪种协议去传输数据
	void *algo_data;

	char name[48];
	struct completion dev_released;
	...
};
参考博客:http://blog.csdn.net/rockrockwu/article/details/7434752 i2c子系统之内核中I2C子系统的结构
参考博客:http://blog.csdn.net/rockrockwu/article/details/7434953 i2c子系统之i2c bus初始化——i2c_init()
在Linux内核启动的时候最先执行的和I2C子系统相关的函数应该是driver/i2c/i2c-core.c文件中的i2c_init()函数。

从Tiny4412--mma7660 gsensor驱动探索Linux内核I2C总线驱动框架

最后再说说,驱动和设备是怎么联系起来的:

从Tiny4412--mma7660 gsensor驱动探索Linux内核I2C总线驱动框架

上一篇:三星将于今年晚些时候生产第二代10nm芯片


下一篇:视频和音频