Chinaunix首页 | 论坛 | 博客
  • 博客访问: 290729
  • 博文数量: 86
  • 博客积分: 694
  • 博客等级: 上士
  • 技术积分: 833
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-31 16:40
文章分类

全部博文(86)

文章存档

2012年(75)

2011年(6)

2010年(5)

分类: BSD

2010-12-31 17:59:05

对于i2c设备的注册过程,首先在/arch/arm/mach_msm的相关目录下面有这样的i2c_board_info结构

在static void __init es209ra_init(void)中有这样一个
函数初始化函数
i2c_register_board_info(0, msm_i2c_board_info,ARRAY_SIZE(msm_i2c_board_info));
这个函数相当于就会去注册i2c设备信息实现如下
int __init
i2c_register_board_info(int busnum,
    struct i2c_board_info const *info, unsigned len)
{
    int status;

    mutex_lock(&__i2c_board_lock);

    /* dynamic bus numbers will be assigned after the last static one */
    if (busnum >= __i2c_first_dynamic_bus_num)
        __i2c_first_dynamic_bus_num = busnum + 1;

    for (status = 0; len; len--, info++) {
        struct i2c_devinfo  *devinfo;

        devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
        if (!devinfo) {
            pr_debug("i2c-core: can't register boardinfo!\n");
            status = -ENOMEM;
            break;
        }

        devinfo->busnum = busnum;
        devinfo->board_info = *info;
        list_add_tail(&devinfo->list, &__i2c_board_list);
    }

    mutex_unlock(&__i2c_board_lock);

    return status;
}  
而参数 msm_i2c_board_info由如下过程组成:
=====================================================
/**
 * struct i2c_board_info - template for device creation                                                                                                                         
 * @type: chip type, to initialize i2c_client.name
 * @flags: to initialize i2c_client.flags
 * @addr: stored in i2c_client.addr
 * @platform_data: stored in i2c_client.dev.platform_data
 * @archdata: copied into i2c_client.dev.archdata
 * @irq: stored in i2c_client.irq
 *
 * I2C doesn't actually support hardware probing, although controllers and
 * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's
 * a device at a given address.  Drivers commonly need more information than
 * that, such as chip type, configuration, associated IRQ, and so on.
 *
 * i2c_board_info is used to build tables of information listing I2C devices
 * that are present.  This information is used to grow the driver model tree
 * for "new style" I2C drivers.  For mainboards this is done statically using
 * i2c_register_board_info(); bus numbers identify adapters that aren't
 * yet available.  For add-on boards, i2c_new_device() does this dynamically
 * with the adapter already known.
 */
struct i2c_board_info {
    char        type[I2C_NAME_SIZE];
    unsigned short  flags;
    unsigned short  addr;
    void        *platform_data;
    struct dev_archdata *archdata;
    int     irq;
};
=====================================================
static struct i2c_board_info msm_i2c_board_info[] __initdata = {
    {    
        I2C_BOARD_INFO("tps65023", 0x48),
    },   
#ifdef CONFIG_MAX17040_FUELGAUGE                                                                                                                                                
    {    
        I2C_BOARD_INFO("max17040_fuel_gauge", 0x36),
        .platform_data = &max17040_platform_data,
    },   
#endif
    {    
        I2C_BOARD_INFO("lv5219lg", 0x74),
    },   
#ifdef CONFIG_SENSORS_AK8973
    {    
        I2C_BOARD_INFO("akm8973", 0x1C),
        .platform_data = &akm8973_platform_data,
    },   
#endif
    {    
        I2C_BOARD_INFO("bma150", 0x38),
        .irq           =  INT_ES209RA_GPIO_ACCEL,
    },   
    {      

 
        I2C_BOARD_INFO("semc_imx046_camera", 0x1F),
        .irq           =  INT_ES209RA_GPIO_CAM_ISP,
    },  
};
上面申请这个数组表示i2c总线上面有这么些设备,包含驱动名称,从地址地址,中断号什么的,还有私有数据结构
上面有六个i2c设备,我们以akm8973分析:
针对I2C_BOARD_INFO("akm8973", 0x1C),
/**
 * I2C_BOARD_INFO - macro used to list an i2c device and its address
 * @dev_type: identifies the device type
 * @dev_addr: the device's address on the bus.
 *
 * This macro initializes essential fields of a struct i2c_board_info,
 * declaring what has been provided on a particular board.  Optional
 * fields (such as associated irq, or device-specific platform_data)
 * are provided using conventional syntax.
 */
#define I2C_BOARD_INFO(dev_type, dev_addr) \                                                                                                                                   
    .type = (dev_type), .addr = (dev_addr)

 .platform_data = &akm8973_platform_data,
static struct akm8973_i2c_platform_data akm8973_platform_data = {                                                                                                              
    .gpio_config = ak8973_gpio_config,
    .xres = ak8973_xres
};
========================================================================================

现在回到函数i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)中
list_add_tail(&devinfo->list, &__i2c_board_list);
这句话会将i2c设备添加到全局链表__i2c_board_list上面去

实际上到这里如果我们在arch这边的board——info里面定义了设备的话,那么这是i2c设别在这条链表上面了,

 static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
{
    struct i2c_devinfo  *devinfo;

    mutex_lock(&__i2c_board_lock);
    list_for_each_entry(devinfo, &__i2c_board_list, list) {                                                                                                                    
        if (devinfo->busnum == adapter->nr
                && !i2c_new_device(adapter,
                        &devinfo->board_info))
            printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n",
                i2c_adapter_id(adapter),
                devinfo->board_info.addr);
    }   
    mutex_unlock(&__i2c_board_lock);
}
阅读(3315) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~