HardBirch

IIC总线驱动架构

时间:09-10-31 栏目:系统技术篇 作者:鲁智森也有文化 评论:0 点击: 1,630 次

 

1.    

Linux


I2C

驱动

架构

Linux


I2C


总线的驱动

分为两个部分,总线驱动

BUS
)和设备驱动

DEVICE
)。其中总线驱动

的职责,是为系统中每个I2C


总线增加相应的读写方法。但是总线驱动

本身并不会进行任何的通讯,它只是存在在那里,等待设备驱动

调用其函数。

 

设备驱动

则是与挂在I2C


总线上的具体的设备通讯的驱动

。通过I2C


总线驱动

提供的函数,设备驱动

可以忽略不同总线控制器的差异,不考虑其实现细节地与硬件设备通讯。

 

1.1

总线驱动

在系统开机时,首先装载的是I2C


总线驱动

。一个总线驱动

用于支持一条特定的I2C


总线的读写。一个总线驱动

通常需要两个模块,一个struct i2c

_adapter

和一个struct i2c

_algorithm



来描述:

static struct i2c

_adapter pb1550_board_adapter = {


  name:              "pb1550 adapter",


  id:                I2C

_HW_AU1550_PSC,


  algo:              NULL,


  algo_data:         &pb1550_i2c

_info,


  inc_use:           pb1550_inc_use,


  dec_use:           pb1550_dec_use,


  client_register:   pb1550_reg,


  client_unregister: pb1550_unreg,


  client_count:      0,


};


 

这个样例挂接了一个叫做“pb1550 adapter
”的驱动

。但这个模块并未提供读写函数,具体的读写方法由第二个模块,struct i2c

_algorithm

供。

 

static struct i2c

_algorithm au1550_algo = {


.name         = "Au1550 algorithm",

.id      = I2C

_ALGO_AU1550,


.master_xfer  = au1550_xfer,

.functionality     = au1550_func,

};

 

i2c

_adap->algo = &au1550_algo;


   

这个样例给上述总线驱动

增加了读写“算法”。通常情况下每个I2C


总线驱动

都定义一个自己的读写算法,但鉴于有些总线使用相同的算法,因而可以共用同一套读写函数。本例中的驱动

定义了自己的读写算法模块,起名叫“Au1550 algorithm
”。

 

全部填妥后,通过调用:

i2c

_add_adapter(i2c

_adap);

 

将这两个模块注册到操作系统里,总线驱动

就算装上了。对于AMD au1550
,这部分已经由AMD
提供了。

1.2

设备驱动

如前所述,总线驱动

只是提供了对一条总线的读写机制,本身并不会去做通信。通信是由I2C


设备驱动

来做的,设备驱动

透过I2C


总线同具体的设备进行通讯。一个设备驱动

有两个模块来描述,struct i2c

_driver

struct i2c

_client

 

当系统开机、I2C


总线驱动

装入完成后,就可以装入设备驱动

了。首先装入如下结构:

 

static struct i2c

_driver driver = {

        .name           = "i2c

TV tuner driver",

        .id             = I2C

_DRIVERID_TUNER,

        .flags          = I2C

_DF_NOTIFY,

        .attach_adapter = tuner_probe,

        .detach_client  = tuner_detach,

        .command        = tuner_command,

};

 

i2c

_add_driver(&driver);

 

这个i2c

_driver

一旦装入完成,其中的attach_adapter
函数就会被调用。在其中可以遍历系统中的每个i2c


总线驱动

,探测想要访问的设备:

 

static int tuner_probe(struct i2c

_adapter *adap)


{

return i2c

_probe(adap, &addr_data, tuner_attach);


}

 

注意探测可能会找到多个设备,因而不仅一个I2C


总线可以挂多个不同类型的设备,一个设备驱动

也可以同时为挂在多个不同I2C


总线上的设备服务。

 

每当设备驱动

探测到了一个它能支持的设备,它就创建一个struct i2c

_client

来标识这个设备:

new_client->addr = address;

new_client->adapter = adapter;

new_client->driver = &driver;

 

/* Tell the I2C

layer a new client has arrived */


err = i2c

_attach_client(new_client);


if (err)

    goto error;

 

可见,一个i2c

_client

代表着位于adapter
总线上,地址为address
,使用driver
驱动

的一个设备。它将总线驱动

与设备驱动

,以及设备地址绑定在了一起。一个i2c

_client

就代表着一个I2C


设备。

 

当得到I2C


设备后,就可以直接对此设备进行读写:

/*

 * The master routines are the ones normally used to transmit data to devices

 * on a bus (or read from them). Apart from two basic transfer functions to

 * transmit one message at a time, a more complex version can be used to

 * transmit an arbitrary number of messages without interruption.

 */

extern int i2c

_master_send(struct i2c

_client *,const char* ,int);


extern int i2c

_master_recv(struct i2c

_client *,char* ,int);


 

与通常意义上的读写函数一样,这两个函数对i2c

_client

指针指定的设备,读写int
char
。返回值为读写的字节数。对于我们现有的SLIC
驱动

,只要将最后要往总线上进行读写的数据引出传输到这两个函数中,移植工作就算完成了,我们将得到一个Linux


版的I2C


设备驱动

声明: 本文由( 鲁智森也有文化 )原创编译,转载请保留链接: IIC总线驱动架构

IIC总线驱动架构:等您坐沙发呢!

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐