@@ -240,9 +240,32 @@ static int rk817_record_battery_nvram_values(struct rk817_charger *charger)
240240static int rk817_bat_calib_cap (struct rk817_charger * charger )
241241{
242242 struct rk808 * rk808 = charger -> rk808 ;
243- int tmp , charge_now , charge_now_adc , volt_avg ;
243+ int charge_now , charge_now_adc ;
244244 u8 bulk_reg [4 ];
245245
246+ /* Don't do anything if there's no battery. */
247+ if (!charger -> battery_present )
248+ return 0 ;
249+
250+ /*
251+ * When resuming from suspend, sometimes the voltage value would be
252+ * incorrect. BSP would simply wait two seconds and try reading the
253+ * values again. Do not do any sort of calibration activity when the
254+ * reported value is incorrect. The next scheduled update of battery
255+ * vaules should then return valid data and the driver can continue.
256+ * Use 2.7v as the sanity value because per the datasheet the PMIC
257+ * can in no way support a battery voltage lower than this. BSP only
258+ * checked for values too low, but I'm adding in a check for values
259+ * too high just in case; again the PMIC can in no way support
260+ * voltages above 4.45v, so this seems like a good value.
261+ */
262+ if ((charger -> volt_avg_uv < 2700000 ) || (charger -> volt_avg_uv > 4450000 )) {
263+ dev_dbg (charger -> dev ,
264+ "Battery voltage of %d is invalid, ignoring.\n" ,
265+ charger -> volt_avg_uv );
266+ return - EINVAL ;
267+ }
268+
246269 /* Calibrate the soc and fcc on a fully charged battery */
247270
248271 if (charger -> charge_status == CHARGE_FINISH && (!charger -> soc_cal )) {
@@ -304,51 +327,6 @@ static int rk817_bat_calib_cap(struct rk817_charger *charger)
304327 }
305328 }
306329
307- /*
308- * Calibrate the fully charged capacity when we previously had a full
309- * battery (soc_cal = 1) and are now empty (at or below minimum design
310- * voltage). If our columb counter is still positive, subtract that
311- * from our fcc value to get a calibrated fcc, and if our columb
312- * counter is negative add that to our fcc (but not to exceed our
313- * design capacity).
314- */
315- regmap_bulk_read (charger -> rk808 -> regmap , RK817_GAS_GAUGE_BAT_VOL_H ,
316- bulk_reg , 2 );
317- tmp = get_unaligned_be16 (bulk_reg );
318- volt_avg = (charger -> voltage_k * tmp ) + 1000 * charger -> voltage_b ;
319- if (volt_avg <= charger -> bat_voltage_min_design_uv &&
320- charger -> soc_cal ) {
321- regmap_bulk_read (rk808 -> regmap , RK817_GAS_GAUGE_Q_PRES_H3 ,
322- bulk_reg , 4 );
323- charge_now_adc = get_unaligned_be32 (bulk_reg );
324- charge_now = ADC_TO_CHARGE_UAH (charge_now_adc ,
325- charger -> res_div );
326- /*
327- * Note, if charge_now is negative this will add it (what we
328- * want) and if it's positive this will subtract (also what
329- * we want).
330- */
331- charger -> fcc_mah = charger -> fcc_mah - (charge_now / 1000 );
332-
333- dev_dbg (charger -> dev ,
334- "Recalibrating full charge capacity to %d uah\n" ,
335- charger -> fcc_mah * 1000 );
336- }
337-
338- /*
339- * Set the SOC to 0 if we are below the minimum system voltage.
340- */
341- if (volt_avg <= charger -> bat_voltage_min_design_uv ) {
342- charger -> soc = 0 ;
343- charge_now_adc = CHARGE_TO_ADC (0 , charger -> res_div );
344- put_unaligned_be32 (charge_now_adc , bulk_reg );
345- regmap_bulk_write (rk808 -> regmap ,
346- RK817_GAS_GAUGE_Q_INIT_H3 , bulk_reg , 4 );
347- dev_warn (charger -> dev ,
348- "Battery voltage %d below minimum voltage %d\n" ,
349- volt_avg , charger -> bat_voltage_min_design_uv );
350- }
351-
352330 rk817_record_battery_nvram_values (charger );
353331
354332 return 0 ;
@@ -648,6 +626,24 @@ static irqreturn_t rk817_plug_out_isr(int irq, void *cg)
648626 return IRQ_HANDLED ;
649627}
650628
629+ static int rk817_bat_set_prop (struct power_supply * ps ,
630+ enum power_supply_property prop ,
631+ const union power_supply_propval * val )
632+ {
633+ struct rk817_charger * charger = power_supply_get_drvdata (ps );
634+
635+ switch (prop ) {
636+ case POWER_SUPPLY_PROP_CHARGE_FULL :
637+ if ((val -> intval < 500000 ) ||
638+ (val -> intval > charger -> bat_charge_full_design_uah ))
639+ return - EINVAL ;
640+ charger -> fcc_mah = val -> intval / 1000 ;
641+ return rk817_bat_calib_cap (charger );
642+ default :
643+ return - EINVAL ;
644+ }
645+ }
646+
651647static enum power_supply_property rk817_bat_props [] = {
652648 POWER_SUPPLY_PROP_PRESENT ,
653649 POWER_SUPPLY_PROP_STATUS ,
@@ -673,12 +669,25 @@ static enum power_supply_property rk817_chg_props[] = {
673669 POWER_SUPPLY_PROP_VOLTAGE_AVG ,
674670};
675671
672+ static int rk817_bat_prop_writeable (struct power_supply * psy ,
673+ enum power_supply_property psp )
674+ {
675+ switch (psp ) {
676+ case POWER_SUPPLY_PROP_CHARGE_FULL :
677+ return 1 ;
678+ default :
679+ return 0 ;
680+ }
681+ }
682+
676683static const struct power_supply_desc rk817_bat_desc = {
677684 .name = "rk817-battery" ,
678685 .type = POWER_SUPPLY_TYPE_BATTERY ,
679686 .properties = rk817_bat_props ,
687+ .property_is_writeable = rk817_bat_prop_writeable ,
680688 .num_properties = ARRAY_SIZE (rk817_bat_props ),
681689 .get_property = rk817_bat_get_prop ,
690+ .set_property = rk817_bat_set_prop ,
682691};
683692
684693static const struct power_supply_desc rk817_chg_desc = {
0 commit comments