方法一:静态声明 I2C 设备
I2C总线事先已知设备的编号,用于预先声明总线上的I2C器件。此信息在不同的体系结构上以不同的方式提供给内核:设备树、ACPI 或主板文件。当有问题的I2C总线被注册时,I2C器件将由i2c内核自动实例化。当设备所在的 I2C 总线消失(如果有)时,设备将自动解除绑定并销毁。
-
设备树声明I2C设备
i2c1: i2c@400a0000 {
/* ... master properties skipped ... */
clock-frequency = <100000>;
flash@50 {
compatible = "atmel,24c256";
reg = <0x50>;
};
pca9532: gpio@60 {
compatible = "nxp,pca9532";
gpio-controller;
#gpio-cells = <2>;
reg = <0x60>;
};
};
-
板级声明I2C设备
通过电路板文件实例化 I2C 器件是通过调用 i2c_register_board_info()来注册的结构i2c_board_info阵列完成的。
eg:
static struct i2c_board_info h4_i2c_board_info[] __initdata = {
{
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(125),
},
{ /* EEPROM on mainboard */
I2C_BOARD_INFO("24c01", 0x52),
.platform_data = &m24c01,
},
{ /* EEPROM on cpu card */
I2C_BOARD_INFO("24c01", 0x57),
.platform_data = &m24c01,
},
};
static void __init omap_h4_init(void)
{
(...)
i2c_register_board_info(1, h4_i2c_board_info,
ARRAY_SIZE(h4_i2c_board_info));
(...)
}
方法二:显式实例化设备
一个典型的例子是电视适配器。这些可以视频解码器,音频解码器等,通常通过I2C总线连接到主芯片。您事先不知道 I2C 总线的编号,因此无法使用上述方法 一。相反,您可以显式实例化 I2C 设备。这是通过填充结构i2c_board_info并调用 i2c_new_client_device() 来完成的。
eg:
static struct i2c_board_info sfe4001_hwmon_info = {
I2C_BOARD_INFO("max6647", 0x4e),
};
int sfe4001_init(struct efx_nic *efx)
{
(...)
efx->board_info.hwmon_client =
i2c_new_client_device(&efx->i2c_adap, &sfe4001_hwmon_info);
(...)
}
这种情况的变体是当您不确定是否存在I2C设备时,或者它可能由于厂商配置具有不同的地址。在这种情况下,您可以调用 i2c_new_scanned_device() 而不是 i2c_new_client_device()。
eg:
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
static int usb_hcd_nxp_probe(struct platform_device *pdev)
{
(...)
struct i2c_adapter *i2c_adap;
struct i2c_board_info i2c_info;
(...)
i2c_adap = i2c_get_adapter(2);
memset(&i2c_info, 0, sizeof(struct i2c_board_info));
strscpy(i2c_info.type, "isp1301_nxp", sizeof(i2c_info.type));
isp1301_i2c_client = i2c_new_scanned_device(i2c_adap, &i2c_info,
normal_i2c, NULL);
i2c_put_adapter(i2c_adap);
(...)
}
备注:
1. i2c_new_client_device() 或 i2c_new_scanned_device()获取client
2. i2c_unregister_device()注销client设备
方法三:探测某些设备的I2C总线
方法四:从用户空间实例化
在开发的过程中,对于不开源的操作系统,不能通过设备树去添加管理设备,我们就可以通过用户层去手动添加注册和移除设备(new_device和delete_device)
eg:
# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device
虽然此接口应仅在无法执行内核内设备声明时使用,但在很多情况下,它都会有所帮助:
-
I2C 驱动程序通常检测设备(上面的方法 3),但设备所在的总线段没有设置正确的类位,因此不会触发检测。
-
I2C 驱动程序通常会检测设备,但设备位于意外的地址。
-
I2C 驱动程序通常会检测设备,但未检测到您的设备,因为检测例程过于严格,或者因为您的设备尚未正式受支持,但您知道它是兼容的。
-
您正在测试板上开发驱动程序,您自己焊接了I2C器件。