系统启动后调用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;
}
阅读(2296) | 评论(0) | 转发(0) |