u8 soc_tab[16]; int cc_cnf; int vm_cnf; int cc_adj; int vm_adj; int avg_current; int avg_voltage; int batt_current; int voltage; int temp; int soc; int ocv; int hrsoc; int presence;
};
staticint stc3117_convert(int value, int factor)
{
value = (value * factor) / 4096; return value * 1000;
}
/* current in uA*/
value = (reg_list[7] << 8) + reg_list[6];
data->batt_current = stc3117_convert(value,
CURRENT_LSB_VALUE / data->battery_info.sense_resistor);
/* voltage in uV */
value = (reg_list[9] << 8) + reg_list[8];
data->voltage = stc3117_convert(value, VOLTAGE_LSB_VALUE);
/* temp in 1/10 °C */
data->temp = reg_list[10] * 10;
/* Avg current in uA */
value = (reg_list[12] << 8) + reg_list[11];
regmap_read(data->regmap, STC3117_ADDR_MODE, &mode); if (!(mode & STC3117_VMODE)) {
value = stc3117_convert(value,
CURRENT_LSB_VALUE / data->battery_info.sense_resistor);
value = value / 4;
} else {
value = stc3117_convert(value, 36 * STC3117_NOMINAL_CAPACITY);
}
data->avg_current = value;
/* ocv in uV */
value = (reg_list[14] << 8) + reg_list[13];
value = stc3117_convert(value, VOLTAGE_LSB_VALUE);
value = (value + 2) / 4;
data->ocv = value;
/* CC & VM adjustment counters */
regmap_bulk_read(data->regmap, STC3117_ADDR_CC_ADJ_L,
data_adjust, sizeof(data_adjust));
value = (data_adjust[1] << 8) + data_adjust[0];
data->cc_adj = value;
value = (data_adjust[3] << 8) + data_adjust[2];
data->vm_adj = value;
return 0;
}
staticint ram_write(struct stc3117_data *data)
{ int ret;
ret = regmap_bulk_write(data->regmap, STC3117_ADDR_RAM,
data->ram_data.ram_bytes, STC3117_RAM_SIZE); if (ret) return ret;
return 0;
};
staticint ram_read(struct stc3117_data *data)
{ int ret;
ret = regmap_bulk_read(data->regmap, STC3117_ADDR_RAM,
data->ram_data.ram_bytes, STC3117_RAM_SIZE); if (ret) return ret;
return 0;
};
staticint stc3117_set_para(struct stc3117_data *data)
{ int ret;
ret = regmap_write(data->regmap, STC3117_ADDR_MODE, STC3117_VMODE);
for (int i = 0; i < STC3117_OCV_TABLE_SIZE; i++)
ret |= regmap_write(data->regmap, STC3117_ADDR_OCV_TABLE + i,
ocv_value[i] * 100 / 55); if (data->soc_tab[1] != 0)
ret |= regmap_bulk_write(data->regmap, STC3117_ADDR_SOC_TABLE,
data->soc_tab, STC3117_OCV_TABLE_SIZE);
ret |= regmap_write(data->regmap, STC3117_ADDR_CC_CNF_H,
(data->ram_data.reg.cc_cnf >> 8) & 0xFF);
ret |= regmap_write(data->regmap, STC3117_ADDR_CC_CNF_L,
data->ram_data.reg.cc_cnf & 0xFF);
ret |= regmap_write(data->regmap, STC3117_ADDR_VM_CNF_H,
(data->ram_data.reg.vm_cnf >> 8) & 0xFF);
ret |= regmap_write(data->regmap, STC3117_ADDR_VM_CNF_L,
data->ram_data.reg.vm_cnf & 0xFF);
ret |= regmap_write(data->regmap, STC3117_ADDR_CTRL, 0x03);
ret |= regmap_write(data->regmap, STC3117_ADDR_MODE,
STC3117_MIXED_MODE | STC3117_GG_RUN);
return ret;
};
staticint stc3117_init(struct stc3117_data *data)
{ int id, ret; int ctrl; int ocv_m, ocv_l;
regmap_read(data->regmap, STC3117_ADDR_ID, &id); if (id != STC3117_ID) return -EINVAL;
/* check battery presence status */
ret = regmap_read(data->regmap, STC3117_ADDR_CTRL, &mode); if ((mode & STC3117_BATFAIL) != 0) {
data->presence = 0;
data->ram_data.reg.testword = 0;
data->ram_data.reg.state = STC3117_INIT;
ret = ram_write(data);
ret |= regmap_write(data->regmap, STC3117_ADDR_CTRL, STC3117_PORDET); if (ret) return ret;
}
data->presence = 1;
ret = regmap_read(data->regmap, STC3117_ADDR_MODE, &mode); if (ret) return ret; if ((mode & STC3117_GG_RUN) == 0) { if (data->ram_data.reg.state > STC3117_INIT) {
ret = stc3117_set_para(data);
ret |= regmap_write(data->regmap, STC3117_ADDR_SOC_H,
(data->ram_data.reg.hrsoc >> 8 & 0xFF));
ret |= regmap_write(data->regmap, STC3117_ADDR_SOC_L,
(data->ram_data.reg.hrsoc & 0xFF)); if (ret) return ret;
} else {
ret = regmap_read(data->regmap, STC3117_ADDR_OCV_H, &ocv_m);
ret |= regmap_read(data->regmap, STC3117_ADDR_OCV_L, &ocv_l);
ret |= stc3117_set_para(data);
ret |= regmap_write(data->regmap, STC3117_ADDR_OCV_H, ocv_m);
ret |= regmap_write(data->regmap, STC3117_ADDR_OCV_L, ocv_l); if (ret) return ret;
}
data->ram_data.reg.state = STC3117_INIT;
}
data->battery = devm_power_supply_register(&client->dev,
&stc3117_battery_desc, &psy_cfg); if (IS_ERR(data->battery)) return dev_err_probe(&client->dev, PTR_ERR(data->battery), "failed to register battery\n");
ret = device_property_read_u32(&client->dev, "shunt-resistor-micro-ohms",
&data->battery_info.sense_resistor); if (ret) return dev_err_probe(&client->dev, ret, "failed to get shunt-resistor-micro-ohms\n");
data->battery_info.sense_resistor = data->battery_info.sense_resistor / 1000;
ret = power_supply_get_battery_info(data->battery, &info); if (ret) return dev_err_probe(&client->dev, ret, "failed to get battery information\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.