Chinaunix首页 | 论坛 | 博客
  • 博客访问: 620368
  • 博文数量: 121
  • 博客积分: 8469
  • 博客等级: 中将
  • 技术积分: 1065
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-03 10:32
文章分类

全部博文(121)

文章存档

2013年(1)

2012年(15)

2010年(2)

2009年(8)

2008年(95)

我的朋友

分类: 嵌入式

2012-10-17 13:24:41

系统启动后调用ds278x_init
static struct i2c_driver ds278x_battery_driver = {
    .driver     = {
        .name    = "ds2786-battery",
    },
    .probe        = ds278x_battery_probe, //设备注册后执行
    .remove        = ds278x_battery_remove,
    .id_table    = ds278x_id,
};
static int __init ds278x_init(void)
{
    int ret = i2c_add_driver(&ds278x_battery_driver);
   
    ds2786_i2c_register(); //注册I2C设备
   
    return ret;
}
module_init(ds278x_init);

注册I2C设备,函数定义如下:
static int ds2786_i2c_register(void)
{
    struct i2c_board_info info;
    struct i2c_adapter *adapter;
    struct i2c_client *client;

    memset(&info, 0, sizeof(struct i2c_board_info));
    info.addr = DS2786_I2C_ADDRESS;  //I2C总线client地址
    strlcpy(info.type, "ds2786", sizeof("ds2786")); //设备名称

    ds2786_dbg("++%s\n", __FUNCTION__);

    adapter = i2c_get_adapter(I2C_BUS); //I2C_BUS为总线号
    if (!adapter)
    {
        ds2786_dbg(KERN_ERR "can't get i2c adapter 0 for s3c-Gsensor-kxtf9\n");
        return -ENODEV;
    }

    client = i2c_new_device(adapter, &info);
    i2c_put_adapter(adapter);
    if (!client)
    {
        ds2786_dbg(KERN_ERR "can't add i2c device at 0x%x\n", (unsigned int)info.addr);
        return -ENODEV;
    }   

    ds2786_i2c_client = client;
   
    ds2786_dbg("--%s \n", __FUNCTION__);   

    return 0;
}

之后执行ds278x_battery_probe,主要包括I2C设备信息初始化和power supply类注册。
I2C设备信息初始化
    i2c_set_clientdata(client, info);
    info->client = client;
    info->id = num;
    info->ops  = &ds278x_ops[id->driver_data];
其中的ds278x_ops是获取电池信息的接口函数结构,定义如下:
static struct ds278x_battery_ops ds278x_ops[] = {
    [DS2782] = {
        .get_battery_current  = ds2782_get_current,
        .get_battery_voltage  = ds2782_get_voltage,
        .get_battery_capacity = ds2782_get_capacity,
    },
    [DS2786] = {
        .get_battery_current  = ds2786_get_current,
        .get_battery_voltage  = ds2786_get_voltage,
        .get_battery_capacity = ds2786_get_capacity,
    }
};

power supply类注册
ds278x_power_supply_init(&info->battery);

    ret = power_supply_register(&client->dev, &info->battery);
    if (ret) {
        dev_err(&client->dev, "failed to register battery\n");
        goto fail_register;
    }
其中ds278x_power_supply_init完成power supply初始化
static void ds278x_power_supply_init(struct power_supply *battery)
{
    battery->type            = POWER_SUPPLY_TYPE_BATTERY;
    battery->properties        = ds278x_battery_props;
    battery->num_properties        = ARRAY_SIZE(ds278x_battery_props);
    battery->get_property        = ds278x_battery_get_property;
    battery->external_power_changed    = NULL;
}
电池属性结构ds278x_battery_props定义如下:
static enum power_supply_property ds278x_battery_props[] = {
    POWER_SUPPLY_PROP_STATUS,   //状态
    POWER_SUPPLY_PROP_CAPACITY,   //电量
    POWER_SUPPLY_PROP_VOLTAGE_NOW,   //电压
    POWER_SUPPLY_PROP_CURRENT_NOW,   //电流
    POWER_SUPPLY_PROP_TEMP,   //温度
};
在/sys/class/power_supply/ds2786-0目录下就有对应的status,capacity,voltage_now,current_now,temp
这几个文件。

而电量信息是通过ds278x_battery_get_property函数获取:
static int ds278x_battery_get_property(struct power_supply *psy,
                       enum power_supply_property prop,
                       union power_supply_propval *val)
{
    struct ds278x_info *info = to_ds278x_info(psy);
    int ret;

    ds2786_dbg("++%s prop %x\r\n", __FUNCTION__, prop);

    switch (prop) {
    case POWER_SUPPLY_PROP_STATUS: //状态
        ret = ds278x_get_status(info, &val->intval);
        break;

    case POWER_SUPPLY_PROP_CAPACITY: //读取电量,info->ops就是前面提到的ds278x_ops
        ret = info->ops->get_battery_capacity(info, &val->intval);
        break;

    case POWER_SUPPLY_PROP_VOLTAGE_NOW: //读取电压
        ret = info->ops->get_battery_voltage(info, &val->intval);
        break;

    case POWER_SUPPLY_PROP_CURRENT_NOW: //读取电流
        ret = info->ops->get_battery_current(info, &val->intval);
        break;

    case POWER_SUPPLY_PROP_TEMP:   //读取温度
        ret = ds278x_get_temp(info, &val->intval);
        break;

    default:
        ret = -EINVAL;
    }

    return ret;
}

通过读取DS2786的寄存器数值并计算,就可获取电池信息,比如获取电量函数:
static int ds2786_get_capacity(struct ds278x_info *info, int *capacity)
{
    int err;
    u8 raw;

    err = ds278x_read_reg(info, DS2786_REG_RARC, &raw);
    if (err)
        return err;
    /* Relative capacity is displayed with resolution 0.5 % */
    *capacity = raw/2 ;
    return 0;
}
阅读(2106) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~