i2c学习2

i2c学习2
i2c学习2

2.*struct i2c_driver-represent an I2C device driver

3.*@class:What kind of i2c device we instantiate(for detect)

4.*@attach_adapter:Callback for bus addition(for legacy drivers)

5.*@detach_adapter:Callback for bus removal(for legacy drivers)

6.*@probe:Callback for device binding

7.*@remove:Callback for device unbinding

8.*@shutdown:Callback for device shutdown

9.*@suspend:Callback for device suspend

10.*@resume:Callback for device resume

11.*@command:Callback for bus-wide signaling(optional)

12.*@driver:Device driver model driver

13.*@id_table:List of I2C devices supported by this driver

14.*@detect:Callback for device detection

15.*@address_list:The I2C addresses to probe(for detect)

16.*@clients:List of detected clients we created(for i2c-core use only)

17.*

18.*The driver.owner field should be set to the module owner of this driver.

19.*The https://www.360docs.net/doc/bc19076908.html, field should be set to the name of this driver.

20.*

21.*For automatic device detection,both@detect and

@address_data must

22.*be defined.@class should also be set,otherwise only devices forced

23.*with module parameters will be created.The detect function must

24.*fill at least the name field of the i2c_board_info structure it is

25.*handed upon successful detection,and possibly also the flags field.

26.*

27.*If@detect is missing,the driver will still work fine for

图2.1OMAP3630I2C控制器模块图

控制器1,2,3具有以下特征:

?兼容飞利浦I2C2.1版本

?支持标准I2C标准模式(100Kbps)和快速模式(400Kpbs)

?支持高达3.4Mbps的高速发送模式

?支持I2C2和I2C3模块的3线/2线的SCCB主从模式,I2C1模块的2线的SCCB主从模式,高达100kbit/s

?7-bit和10bit的设备地址模式

?多主控发送/从接收模式

?多主控接收/从发送模式

?联合的主机发送/接收和接收/发送模式

?内置FIFO(8,16,32,64字节大小)用于缓存读取和接收

?模块使能/关闭

?可编程的时钟

?8-bit的数据存取

?低功耗的设计

?两个DMA通道

?支持中断机制

?自动空闲机制

?空闲请求和应答握手机制

主从的发送机I2C4控制器有以下特征:

?支持高速和快速模式

?只能支持7-bit地址模式

?只支持主发送模式

关于I2C控制器的详细介绍请参考

OMAP36XX_ES1.1_NDA_TRM_V_G.pdf的第17章。

3OMAP3630I2C adapter驱动

在Linux内核中,I2C adapter驱动位于drivers/i2c/busses目录下,

14.{\

15..start=(irq),\

16..flags=IORESOURCE_IRQ,\

17.},

18.

19.static struct resource i2c_resources[][2]={

20.{I2C_RESOURCE_BUILDER(0,0)},

21.#if defined(CONFIG_ARCH_OMAP24XX)||

defined(CONFIG_ARCH_OMAP34XX)

22.{I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ)},

23.#endif

24.#if defined(CONFIG_ARCH_OMAP34XX)

25.{I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ)},

26.#endif

27.};

28.

29.#define I2C_DEV_BUILDER(bus_id,res,data)\

30.{\

31..id=(bus_id),\

https://www.360docs.net/doc/bc19076908.html,=name,\

33..num_resources=ARRAY_SIZE(res),\

34..resource=(res),\

35..dev={\

36..platform_data=(data),\

37.},\

38.}

39.

40.static u32i2c_rate[ARRAY_SIZE(i2c_resources)];

41.static struct platform_device omap_i2c_devices[]={

42.I2C_DEV_BUILDER(1,i2c_resources[0],&i2c_rate[0]),

43.#if defined(CONFIG_ARCH_OMAP24XX)||

defined(CONFIG_ARCH_OMAP34XX)

44.I2C_DEV_BUILDER(2,i2c_resources[1],&i2c_rate[1]),

45.#endif

46.#if defined(CONFIG_ARCH_OMAP34XX)

47.I2C_DEV_BUILDER(3,i2c_resources[2],&i2c_rate[2]),

48.#endif

49.};

可以看到,这边定义了三个I2C适配器的Platform device,id分别为“1,2,3”,name都为“i2c_omap”,变量resource中定义了适配器的寄存器基地址,irq中断号等。

3.1.2Platform device的注册

Platform device的注册是由内核启动后,具体产品的板级初始化完成的。xxxx项目的I2C adapter的Platform device注册过程如下图:

图3.1Platform device注册过程

函数omap_i2c_add_bus()中,通过函数platform_device_register()注册Platform device到platform bus上,代码如下:

1.static int__init omap_i2c_add_bus(int bus_id)

2.{

3.struct platform_device*pdev;

2.struct resource*res;

3.resource_size_t base,irq;

4.……

5.……

6.return platform_device_register(pdev);

7.}

注册完成后,中断号及寄存器的基地址等信息会在设备树中描述了,此后只需利用platform_get_resource等标准接口自动获取即可,实现了驱动和资源的分离。

3.2I2C adapter的Platform driver

Andrord2.1中Platform driver的注册的代码位于内核的

drivers/i2c/busses/i2c-omap.c中,该驱动的注册目的是初始化OMAP3630的I2C adapter,提供I2C总线传输的具体实现,并且向I2C core注册I2C adapter。

3.2.1Platform driver的定义

在文件drivers/i2c/busses/i2c-omap.c中,platform driver定义如下:

1.static struct platform_driver omap_i2c_driver={

2..probe=omap_i2c_probe,

3..remove=omap_i2c_remove,

4..driver={

https://www.360docs.net/doc/bc19076908.html,="i2c_omap",

2..owner=THIS_MODULE,

3.},

4.};

3.2.2Platform driver的注册

在文件drivers/i2c/busses/i2c-omap.c中,platform driver注册如下:

1./*I2C may be needed to bring up other drivers*/

2.static int__init.omap_i2c_init_driver(void)

3.{

4.return platform_driver_register(&omap_i2c_driver);

5.}

6.subsys_initcall(omap_i2c_init_driver);

通过platform_driver_register()函数注册Platform driver

omap_i2c_driver时,会扫描platform bus上的所有设备,由于匹配因子是name即"i2c_omap",而之前已经将name为"i2c_omap"的Platform device注册到platform bus上,因此匹配成功,调用函数omap_i2c_probe将设备和驱动绑定起来。

在drivers/i2c/busses/i2c-omap.c中会涉及到一个数据结构

omap_i2c_dev,这个结构定义了omap3630的I2C控制器,结构如下:

1.struct omap_i2c_dev{

2.struct device*dev;

2.void__iomem*base;/*virtual*/

3.int irq;

4.struct clk*iclk;/*Interface clock*/

5.struct clk*fclk;/*Functional clock*/

6.struct completion cmd_complete;

7.struct resource*ioarea;

8.u32speed;/*Speed of bus in Khz*/

9.u16cmd_err;

10.u8*buf;

11.size_t buf_len;

12.struct i2c_adapter adapter;

13.u8fifo_size;/*use as flag and value

14.*fifo_size==0implies no fifo

15.*if set,should be trsh+1

16.*/

17.u8rev;

18.unsigned b_hw:1;/*bad h/w fixes*/

19.unsigned idle:1;

20.u16iestate;/*Saved interrupt register*/

21.u16pscstate;

22.u16scllstate;

23.u16sclhstate;

24.u16bufstate;

25.u16syscstate;

26.u16westate;

27.};

Base对应I2C控制器寄存器的虚拟地址。

Irq对应I2C控制器的中断号。

Buf对应上层传下来的需要发送数据或者I2C控制接收到数据的缓存空间,buf_len是其大小。

Adapter对应I2C控制器的适配器结构。

U16类型的各个state变量是用于对应I2C控制器的寄存器的值。

函数omap_i2c_probe的执行流程如下图:

相关主题
相关文档
最新文档