linux I2C 驱动之----i2c_client 的注册

我们知道,linux的设备模型将设备分成了driver,device两大部分,driver即是设备的驱动,device即是硬件设备的具体描述,比如说:设备所拥有的中断,地址等,这里分析一下I2C驱动中device,也即i2c_client的注册。

       (注:这里所说明的是linux 系统i2c设备新采用的方法。)

        在注册i2c驱动的时候,会去linux系统中的全局变量_i2c_board_list链表中去匹配i2c_client,匹配的条件是:名字和i2c的地址。所以,在注册i2c设备驱动的时候要先注册好i2c设备。注册的方法如下:

        首先,定义一个 i2c_board_info 的变量,i2c_board_info 是i2c系统定义的一个结构体,其定义如下:(include\linux\i2c.h)

                       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;
                       };

其中最重要是type和addr,前者是名字,后者是地址,至于其他的不需要的话可以不用管他,给一个例子:struct i2c_board_info __initdata xxx_ls_cm3212 =
                              {
                                      I2C_BOARD_INFO("cm3212",0x90),

                             // I2C_BOARD_INFO是个简单的宏:.type="cm3212",.addr=0x90.
                              };

        然后,在板级系统初始化的时候注册:

   i2c_register_board_info(int busnum,struct i2c_board_info const *info, unsigned len)

其中busnum表示你对应系统的那个 i2c 控制(adapter),len表示你注册的info的个数。

        这样,系统中就存在了一个名字为type,地址为addr的i2c_client,当注册对应的驱动时,就会匹配成功,从而调用驱动的probe函数。

        嗯,今天就到这,下次再说一下i2c_driver的注册。

 

I2c设备初始化方法1--通过总线编号初始化i2c设备

 

(本文的部分内容来源自Documentation/i2c/instantiating-devices)

I2c不像PCI或是USB设备,它不能在硬件层被枚举,软件部分必须明确了解哪些i2c设备连接到总线上了,以及哪些地址可用。因此,内核代码必须明确初始化i2c设备。I2c初始化方式有4种:

a)       通过总线编号初始化i2c设备;

b)       直接初始化设备;

c)       侦测一个指定的i2c设备;

d)       从用户空间初始化i2c设备;

下面就对上述四种初始化方法进行详细解释:

方式1:通过总线编号初始化i2c设备

-----------------------------------------------

这种方式使用于大多数嵌入式系统中使用I2C总线作为一种系统总线的情况。在这种系统中,每一个I2C设备都有一个预先分配好的地址,因此才可能预定义总线上的I2C设备。预定义工作是通过调用一个被注册的结构数组i2c_board_info实现的。

以smdk6410开发板的I2C设备初始化为例:

staticstruct i2c_board_info i2c_devs0[] __initdata = {

    { I2C_BOARD_INFO("24c08", 0x50),},

    { I2C_BOARD_INFO("wm8580", 0x1b),},

#ifdefCONFIG_SMDK6410_WM1192_EV1

    { I2C_BOARD_INFO("wm8312", 0x34),

     .platform_data = &smdk6410_wm1192_pdata,

      .irq= S3C_EINT(12),

    },

#endif

#ifdefCONFIG_SMDK6410_WM1190_EV1

    { I2C_BOARD_INFO("wm8350", 0x1a),

     .platform_data = &smdk6410_wm8350_pdata,

      .irq= S3C_EINT(12),

    },

#endif

};

staticvoid __init smdk6410_machine_init(void)

{

    s3c_i2c0_set_platdata(NULL);

    s3c_i2c1_set_platdata(NULL);{

    (...)

    i2c_register_board_info(0, i2c_devs0,ARRAY_SIZE(i2c_devs0));

    (...)

}

上面的代码在I2C bus 0上声明了4个设备(其中"24c08"、"wm8580"为固定声明的设备"wm8312"、"wm8350"需要通过编译CONFIG_SMDK6410_WM1192_EV1和CONFIG_SMDK6410_WM1190_EV1实现),声明包括地址和驱动程序所需的数据。当I2C总线按要求注册后,I2C设备会被i2c-core自动初始化创建。

当I2C设备移除时会被自动取消绑定和销毁。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值