总线驱动的职责,是为系统中每个I2C总线增加相应的读写方法。但是总线驱动本身并不会进行任何的通讯,它只是存在在那里,等待设备驱动调用其函数。( T0 ]( w; v% t" S
( h, n' e# E5 u6 G
在系统开机时,首先装载的是I2C总线驱动。一个总线驱动用于支持一条特定的I2C总线的读写。一个总线驱动通常需要两个模块,一个struct i2c_adapter和一个struct i2c_algorithm来描述:9 _; o& m- \6 B
: |9 v" @! j1 ]# J. |- S7 n4 w1 W
在 buses目录下的i2c-pxa.c中实现了PXA的I2C总线适配器,I2C adapter 构造一个对I2C core层接口的数据结构,并通过接口函数向I2C core注册一个控制器。I2C adapter主要实现对I2C总线访问的算法,iic_xfer() 函数就是I2C adapter底层对I2C总线读写方法的实现。同时I2C adpter 中还实现了对I2C控制器中断的处理函数。
4 Q. ^: ?" ]# q- y' O0 V2 c
8 s# X9 t) I& T# q" w 1) i2c-pxa.c定义了i2c_algorithm,并且实现了master的发送函数i2c_pxa_xfer(),以及设备查询总线的模式的函数i2c_pxa_functionality()
+ U2 ^5 e( q# c7 x / a b+ P) d2 p; c
static const struct i2c_algorithm i2c_pxa_algorithm = {
" a. x, t/ X8 z- R' \- ^4 i5 p / m! Y5 ?2 f( _- ~ L3 y6 _
.master_xfer = i2c_pxa_xfer,
7 ?" q& a# y7 R( d' f5 i ( L) g9 y8 r/ b6 Q* d
.functionality = i2c_pxa_functionality,
& n1 d6 H" d+ F$ E7 J " U3 _# }2 D, G# e/ u' Y2 s8 N, T; H" s
};0 l, \) T4 r9 Q6 b+ o6 d$ [* y
; ^ [& v1 \# l, b8 P
2) i2c-pxa.c中,实现了i2c_adapter,主要是在定义pxa-i2c时进行初始化,并且i2c_pxa_probe()中进行填充parent指针,并且调用6 q: |2 w: j' U h; u
& S% K0 R5 R( |5 {9 X& g) R ret = i2c_add_adapter(&i2c->adap);3 _, u# p! K: [) e
1 m8 F# ~$ N4 _
进行添加。
4 ~5 j3 g) L) o3 j, n6 ?/ G U- G7 Z/ W( ]( i. [2 n
static struct pxa_i2c i2c_pxa = {: U! B, v& i2 B* B5 E9 x) T
# M; h* F2 \! V ~ .lock = SPIN_LOCK_UNLOCKED,
+ j' I1 G8 m* k0 Z' c" A / T" ]. ^* a; r
.adap = {: b. _: y6 E2 E. n5 s0 H2 D
! f; c% Q5 k' l3 M* C$ {8 |! ]
.owner = THIS_MODULE,
: s4 |+ f0 F1 a: w0 |- b1 Z " Q2 R$ X/ b' o0 {3 U
.algo = &i2c_pxa_algorithm,
+ e0 m1 |: }" Y- Y! X, j! u, `7 g ; c$ ]' |# f; o; v5 H$ K- \! q
.name = "pxa2xx-i2c.0",
" J7 K$ O+ }! l. f* h& K8 ]
3 G: A l6 a+ h .retries = 5,: n( p- T8 ~* ^; u4 _
* ^5 c, N4 t: o7 n' ?$ w },; T, [! a) t2 t. h
+ ~% e/ G2 a) k+ \0 E2 e4 _' H+ S };
. O; }# B% x; J% b; ` O! b( Y $ L' I p- E' v& _7 Q! x
总的来说,在i2c-pxa中,使用platform驱动模型,完成了i2c的总线两种模块struct i2c_adapter和struct i2c_algorithm
/ ]( ?: ~; l* J' H+ u& P 0 _" h4 o R2 y. n$ `
3. I2C device driver
4 @% G# ]$ h7 W1 [
8 p S+ q0 Q5 D I2C只有总线驱动是不够的,必须有设备才能工作。这就是I2C device driver的必要性。I2C的device是有两个模块来描述的,struct i2c_driver和struct i2c_client.$ q/ K7 n' |$ n. f
. \) h( c$ B1 e+ ^+ w, @- w
在介绍chips目录下的device driver前有必要介绍一下i2c-dev.c文件。
& K9 G. x; z' @8 \2 @
5 b2 I- R/ p4 g/ D! `- |( Q1 W0 u6 j i2c-dev.c中提供了一个通用的I2C设备的驱动程序,实现了字符类型设备的访问接口,对设备的具体访问是通过I2C adapter来实现的。构造一个对I2C core层接口的数据结构,通过接口函数向 I2C Core注册一个I2C设备驱动。同时构造一个对用户层接口的数据结构,并通过接口函数向内核注册为一个主设备号为89的字符类型设备。
1 a, ?$ O* Y. C" g J ' t2 k! _* q8 W9 ?
static struct i2c_driver i2cdev_driver = {7 F: ~0 j. j" u" S
/ N: ^! ^2 c+ X6 i .driver = {, I, @% D: E' }. A. F$ U4 [
$ f6 O4 P* L" q
.name = "dev_driver",) y3 m( R0 h( ^' y: Q) s
. } b9 T# o5 Q4 X' r* U },
2 Y% l, U3 {% Q/ C; c9 v
3 U G/ b+ Q/ Q! i- {- O .id = I2C_DRIVERID_I2CDEV,, Q8 S6 X* \, Y( @+ F
3 b3 M2 B$ p3 c9 a
.attach_adapter = i2cdev_attach_adapter,
/ @! O$ r" J9 ]* [1 y3 M
& }; N: V. J: v9 F4 V2 J .detach_adapter = i2cdev_detach_adapter,
. S; @' ~0 Q9 p9 _% b
* F9 D! Q9 y. K# x( [ .detach_client = i2cdev_detach_client,/ c6 T& ]1 N3 d) Z; k$ P6 x- L
8 c. Y3 ~8 X; Z& r% A+ Z& `
};
( K( R& c2 `9 ?
) `% X! r% w8 W5 G/ j struct i2c_dev {
$ i* r. Z* ]) H! d6 F) k8 z2 e
/ `) |# ^1 n8 ?+ \) W9 l' P struct list_head list;( F+ `) k; g8 v3 s" `1 n
2 j0 l6 [0 v+ G struct i2c_adapter *adap;5 c6 X3 {) N: q
5 t* t+ ~0 [3 @: Q struct device *dev;1 J- j* J$ L- M- Y
5 i o( ]1 m. }. J' | }; |