接着上一节讲,板级i2c设备的初始化,板级中的代码如下:就以马达驱动isa1200为例:
先把用到的数据贴出来。
/*该马达的平台数据*/
#define PMIC_GPIO_HAP_ENABLE 18 /* PMIC GPIO Number 19 */
static struct isa1200_platform_data
isa1200_1_pdata = {
.name = "vibrator",
.power_on = isa1200_power,
.dev_setup = isa1200_dev_setup,
/*gpio to enable haptic*/
.hap_en_gpio = PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE),
.max_timeout = 15000,
.mode_ctrl = PWM_GEN_MODE,
.pwm_fd = {
.pwm_div = 256,
},
.is_erm = false,
.smart_en = true,
.ext_clk_en = true,
.chip_en = 1,
};
/*该马达的板级结构*/
static struct i2c_board_info msm_isa1200_board_info[] = {
{
I2C_BOARD_INFO("isa1200_1", 0x90>>1),
.platform_data = &isa1200_1_pdata,
},
};
struct i2c_registry {
u8 machs;
int bus;
struct i2c_board_info *info;
int len;
};
#define I2C_FLUID (1 << 4)
#define MSM_GSBI8_QUP_I2C_BUS_ID 3
/*初始化该注册结构*/
static struct i2c_registry msm8x60_i2c_devices[] __initdata = {
I2C_FLUID,
MSM_GSBI8_QUP_I2C_BUS_ID,
msm_isa1200_board_info,
ARRAY_SIZE(msm_isa1200_board_info),
}
注册该结构的流程如下:
static void __init msm8x60_init(struct msm_board_data *board_data)
{
......
register_i2c_devices();
.......
}
static void register_i2c_devices(void)
{
...........
/*循环注册每一个设备*/
for (i = 0; i < ARRAY_SIZE(msm8x60_i2c_devices); ++i) {
if (msm8x60_i2c_devices[i].machs & mach_mask)
i2c_register_board_info(msm8x60_i2c_devices[i].bus,msm8x60_i2c_devices[i].info,
msm8x60_i2c_devices[i].len);
}
}
继续看注册函数:
int i2c_register_board_info(int busnum,struct i2c_board_info const *info, unsigned len)
{
/*更新__i2c_first_dynamic_bus_num*/
if (busnum >= __i2c_first_dynamic_bus_num)
__i2c_first_dynamic_bus_num = busnum + 1;
/*为每一个要注册的设备分配一个devinfo,为其赋值,并把它挂到全局链表&__i2c_board_list中*/
for (status = 0; len; len--, info++) {
struct i2c_devinfo *devinfo;
devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
devinfo->busnum = busnum;
devinfo->board_info = *info;
list_add_tail(&devinfo->list, &__i2c_board_list);
}
up_write(&__i2c_board_lock);
return status;
}
上一节最后那个函数会扫描该链表上的结构,前提是该链表上的busnum要和adapter的nr号匹配。
这些资源注册后,继续跟踪上一节没有分析完的部分:
static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
{
struct i2c_devinfo *devinfo;
/*取出每一个结构,并且用该结构的busnum和adapter的nr进行比较,相等的话,继续处理*/
list_for_each_entry(devinfo, &__i2c_board_list, list) {
if (devinfo->busnum == adapter->nr && !i2c_new_device(adapter,&devinfo->board_info))
}
}
接着看处理的函数:
在分析前,看下一个结构体
struct i2c_client {
unsigned short flags;
unsigned short addr;/*chip address NOTE: 7bit addresses are stored in the _LOWER_ 7 bits*/
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */
struct device dev; /* the device structure */
int irq; /* irq issued by device */
struct list_head detected;
};
下面的函数所做的主要事情是:为每一个在BSP文件注册的i2c_board_info生成一个client设备。
struct i2c_client *
i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
{
struct i2c_client *client;
/* 分配一个client客户端结构体*/
client = kzalloc(sizeof *client, GFP_KERNEL);
/*为该结构体各项分别赋值*/
client->adapter = adap;
client->dev.platform_data = info->platform_data;
if (info->archdata)
client->dev.archdata = *info->archdata;
client->flags = info->flags;
client->addr = info->addr;
client->irq = info->irq;
strlcpy(client->name, info->type, sizeof(client->name));
/* 检查客户端的地址是否有效*/
status = i2c_check_client_addr_validity(client);
/*检查客户端的地址是否被占用*/
status = i2c_check_addr_busy(adap, client->addr);
/*为client的dev成员赋值*/
client->dev.parent = &client->adapter->dev;
client->dev.bus = &i2c_bus_type;
client->dev.type = &i2c_client_type;
client->dev.of_node = info->of_node;
dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),client->addr);
/*注册该dev*/
status = device_register(&client->dev);
}