Lines Matching +full:bat +full:- +full:present
5 * 2004-2007 Matt Reimer
111 struct power_supply *bat; member
127 mutex_lock(&sl->master->bus_mutex); in w1_ds2760_io()
134 count = DS2760_DATA_SIZE - addr; in w1_ds2760_io()
138 w1_write_8(sl->master, W1_DS2760_READ_DATA); in w1_ds2760_io()
139 w1_write_8(sl->master, addr); in w1_ds2760_io()
140 count = w1_read_block(sl->master, buf, count); in w1_ds2760_io()
142 w1_write_8(sl->master, W1_DS2760_WRITE_DATA); in w1_ds2760_io()
143 w1_write_8(sl->master, addr); in w1_ds2760_io()
144 w1_write_block(sl->master, buf, count); in w1_ds2760_io()
150 mutex_unlock(&sl->master->bus_mutex); in w1_ds2760_io()
174 return -EINVAL; in w1_ds2760_eeprom_cmd()
176 mutex_lock(&sl->master->bus_mutex); in w1_ds2760_eeprom_cmd()
179 w1_write_8(sl->master, cmd); in w1_ds2760_eeprom_cmd()
180 w1_write_8(sl->master, addr); in w1_ds2760_eeprom_cmd()
183 mutex_unlock(&sl->master->bus_mutex); in w1_ds2760_eeprom_cmd()
231 1800, /* HP iPAQ hx4700 3.7V 1800mAh (359113-001) */
242 3600, /* HP iPAQ hx4700 3.7V 3600mAh (359114-001) */
260 return array[index] + (((array[index + 1] - array[index]) * dt) / 10); in battery_interpolate()
267 if (di->update_time && time_before(jiffies, di->update_time + in ds2760_battery_read_status()
273 if (di->update_time == 0) { in ds2760_battery_read_status()
278 count = DS2760_TEMP_LSB - start + 1; in ds2760_battery_read_status()
281 ret = w1_ds2760_read(di->dev, di->raw + start, start, count); in ds2760_battery_read_status()
283 dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n", in ds2760_battery_read_status()
284 di->dev); in ds2760_battery_read_status()
288 di->update_time = jiffies; in ds2760_battery_read_status()
292 di->voltage_raw = (di->raw[DS2760_VOLTAGE_MSB] << 3) | in ds2760_battery_read_status()
293 (di->raw[DS2760_VOLTAGE_LSB] >> 5); in ds2760_battery_read_status()
294 di->voltage_uV = di->voltage_raw * 4880; in ds2760_battery_read_status()
298 di->current_raw = in ds2760_battery_read_status()
299 (((signed char)di->raw[DS2760_CURRENT_MSB]) << 5) | in ds2760_battery_read_status()
300 (di->raw[DS2760_CURRENT_LSB] >> 3); in ds2760_battery_read_status()
301 di->current_uA = di->current_raw * 625; in ds2760_battery_read_status()
304 di->accum_current_raw = in ds2760_battery_read_status()
305 (((signed char)di->raw[DS2760_CURRENT_ACCUM_MSB]) << 8) | in ds2760_battery_read_status()
306 di->raw[DS2760_CURRENT_ACCUM_LSB]; in ds2760_battery_read_status()
307 di->accum_current_uAh = di->accum_current_raw * 250; in ds2760_battery_read_status()
312 di->temp_raw = (((signed char)di->raw[DS2760_TEMP_MSB]) << 3) | in ds2760_battery_read_status()
313 (di->raw[DS2760_TEMP_LSB] >> 5); in ds2760_battery_read_status()
314 di->temp_C = di->temp_raw + (di->temp_raw / 4); in ds2760_battery_read_status()
318 if (di->raw[DS2760_RATED_CAPACITY] < ARRAY_SIZE(rated_capacities)) in ds2760_battery_read_status()
319 di->rated_capacity = rated_capacities[ in ds2760_battery_read_status()
320 (unsigned int)di->raw[DS2760_RATED_CAPACITY]]; in ds2760_battery_read_status()
322 di->rated_capacity = di->raw[DS2760_RATED_CAPACITY] * 10; in ds2760_battery_read_status()
324 di->rated_capacity *= 1000; /* convert to µAh */ in ds2760_battery_read_status()
326 /* Calculate the full level at the present temperature. */ in ds2760_battery_read_status()
327 di->full_active_uAh = di->raw[DS2760_ACTIVE_FULL] << 8 | in ds2760_battery_read_status()
328 di->raw[DS2760_ACTIVE_FULL + 1]; in ds2760_battery_read_status()
333 if (di->full_active_uAh == 0) in ds2760_battery_read_status()
334 di->full_active_uAh = di->rated_capacity / 1000L; in ds2760_battery_read_status()
336 scale[0] = di->full_active_uAh; in ds2760_battery_read_status()
338 scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 1 + i]; in ds2760_battery_read_status()
340 di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10); in ds2760_battery_read_status()
341 di->full_active_uAh *= 1000; /* convert to µAh */ in ds2760_battery_read_status()
343 /* Calculate the empty level at the present temperature. */ in ds2760_battery_read_status()
344 scale[4] = di->raw[DS2760_ACTIVE_EMPTY + 4]; in ds2760_battery_read_status()
345 for (i = 3; i >= 0; i--) in ds2760_battery_read_status()
346 scale[i] = scale[i + 1] + di->raw[DS2760_ACTIVE_EMPTY + i]; in ds2760_battery_read_status()
348 di->empty_uAh = battery_interpolate(scale, di->temp_C / 10); in ds2760_battery_read_status()
349 di->empty_uAh *= 1000; /* convert to µAh */ in ds2760_battery_read_status()
351 if (di->full_active_uAh == di->empty_uAh) in ds2760_battery_read_status()
352 di->rem_capacity = 0; in ds2760_battery_read_status()
355 * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */ in ds2760_battery_read_status()
356 di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) / in ds2760_battery_read_status()
357 (di->full_active_uAh - di->empty_uAh); in ds2760_battery_read_status()
359 if (di->rem_capacity < 0) in ds2760_battery_read_status()
360 di->rem_capacity = 0; in ds2760_battery_read_status()
361 if (di->rem_capacity > 100) in ds2760_battery_read_status()
362 di->rem_capacity = 100; in ds2760_battery_read_status()
364 if (di->current_uA < -100L) in ds2760_battery_read_status()
365 di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * 36L) in ds2760_battery_read_status()
366 / (di->current_uA / 100L); in ds2760_battery_read_status()
368 di->life_sec = 0; in ds2760_battery_read_status()
385 if (w1_ds2760_write(di->dev, acr, DS2760_CURRENT_ACCUM_MSB, 2) < 2) in ds2760_battery_set_current_accum()
386 dev_warn(di->dev, "ACR write failed\n"); in ds2760_battery_set_current_accum()
391 int old_charge_status = di->charge_status; in ds2760_battery_update_status()
395 if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN) in ds2760_battery_update_status()
396 di->full_counter = 0; in ds2760_battery_update_status()
398 if (power_supply_am_i_supplied(di->bat)) { in ds2760_battery_update_status()
399 if (di->current_uA > 10000) { in ds2760_battery_update_status()
400 di->charge_status = POWER_SUPPLY_STATUS_CHARGING; in ds2760_battery_update_status()
401 di->full_counter = 0; in ds2760_battery_update_status()
402 } else if (di->current_uA < -5000) { in ds2760_battery_update_status()
403 if (di->charge_status != POWER_SUPPLY_STATUS_NOT_CHARGING) in ds2760_battery_update_status()
404 dev_notice(di->dev, "not enough power to " in ds2760_battery_update_status()
406 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; in ds2760_battery_update_status()
407 di->full_counter = 0; in ds2760_battery_update_status()
408 } else if (di->current_uA < 10000 && in ds2760_battery_update_status()
409 di->charge_status != POWER_SUPPLY_STATUS_FULL) { in ds2760_battery_update_status()
415 di->full_counter++; in ds2760_battery_update_status()
417 if (di->full_counter < 2) { in ds2760_battery_update_status()
418 di->charge_status = POWER_SUPPLY_STATUS_CHARGING; in ds2760_battery_update_status()
420 di->charge_status = POWER_SUPPLY_STATUS_FULL; in ds2760_battery_update_status()
422 di->full_active_uAh); in ds2760_battery_update_status()
426 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; in ds2760_battery_update_status()
427 di->full_counter = 0; in ds2760_battery_update_status()
430 if (di->charge_status != old_charge_status) in ds2760_battery_update_status()
431 power_supply_changed(di->bat); in ds2760_battery_update_status()
437 if (status == di->raw[DS2760_STATUS_REG]) in ds2760_battery_write_status()
440 w1_ds2760_write(di->dev, &status, DS2760_STATUS_WRITE_REG, 1); in ds2760_battery_write_status()
441 w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1); in ds2760_battery_write_status()
442 w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1); in ds2760_battery_write_status()
448 if (rated_capacity == di->raw[DS2760_RATED_CAPACITY]) in ds2760_battery_write_rated_capacity()
451 w1_ds2760_write(di->dev, &rated_capacity, DS2760_RATED_CAPACITY, 1); in ds2760_battery_write_rated_capacity()
452 w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1); in ds2760_battery_write_rated_capacity()
453 w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1); in ds2760_battery_write_rated_capacity()
464 if (tmp[0] == di->raw[DS2760_ACTIVE_FULL] && in ds2760_battery_write_active_full()
465 tmp[1] == di->raw[DS2760_ACTIVE_FULL + 1]) in ds2760_battery_write_active_full()
468 w1_ds2760_write(di->dev, tmp, DS2760_ACTIVE_FULL, sizeof(tmp)); in ds2760_battery_write_active_full()
469 w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK0); in ds2760_battery_write_active_full()
470 w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK0); in ds2760_battery_write_active_full()
472 /* Write to the di->raw[] buffer directly - the DS2760_ACTIVE_FULL in ds2760_battery_write_active_full()
474 di->raw[DS2760_ACTIVE_FULL] = tmp[0]; in ds2760_battery_write_active_full()
475 di->raw[DS2760_ACTIVE_FULL + 1] = tmp[1]; in ds2760_battery_write_active_full()
484 dev_dbg(di->dev, "%s\n", __func__); in ds2760_battery_work()
487 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval); in ds2760_battery_work()
494 dev_dbg(di->dev, "%s\n", __func__); in ds2760_battery_external_power_changed()
496 mod_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ/10); in ds2760_battery_external_power_changed()
506 dev_dbg(di->dev, "%s\n", __func__); in ds2760_battery_set_charged_work()
513 * too inaccurate to rely on - spec say something ~15% failure. in ds2760_battery_set_charged_work()
518 if (!power_supply_am_i_supplied(di->bat)) in ds2760_battery_set_charged_work()
521 bias = (signed char) di->current_raw + in ds2760_battery_set_charged_work()
522 (signed char) di->raw[DS2760_CURRENT_OFFSET_BIAS]; in ds2760_battery_set_charged_work()
524 dev_dbg(di->dev, "%s: bias = %d\n", __func__, bias); in ds2760_battery_set_charged_work()
526 w1_ds2760_write(di->dev, &bias, DS2760_CURRENT_OFFSET_BIAS, 1); in ds2760_battery_set_charged_work()
527 w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1); in ds2760_battery_set_charged_work()
528 w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1); in ds2760_battery_set_charged_work()
530 /* Write to the di->raw[] buffer directly - the CURRENT_OFFSET_BIAS in ds2760_battery_set_charged_work()
532 di->raw[DS2760_CURRENT_OFFSET_BIAS] = bias; in ds2760_battery_set_charged_work()
541 mod_delayed_work(di->monitor_wqueue, &di->set_charged_work, HZ * 20); in ds2760_battery_set_charged()
552 val->intval = di->charge_status; in ds2760_battery_get_property()
562 val->intval = di->voltage_uV; in ds2760_battery_get_property()
565 val->intval = di->current_uA; in ds2760_battery_get_property()
568 val->intval = di->rated_capacity; in ds2760_battery_get_property()
571 val->intval = di->full_active_uAh; in ds2760_battery_get_property()
574 val->intval = di->empty_uAh; in ds2760_battery_get_property()
577 val->intval = di->accum_current_uAh; in ds2760_battery_get_property()
580 val->intval = di->temp_C; in ds2760_battery_get_property()
583 val->intval = di->life_sec; in ds2760_battery_get_property()
586 val->intval = di->rem_capacity; in ds2760_battery_get_property()
589 return -EINVAL; in ds2760_battery_get_property()
604 ds2760_battery_write_active_full(di, val->intval / 1000L); in ds2760_battery_set_property()
609 ds2760_battery_set_current_accum(di, val->intval); in ds2760_battery_set_property()
613 return -EPERM; in ds2760_battery_set_property()
657 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; in ds2760_pm_notifier()
663 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; in ds2760_pm_notifier()
664 power_supply_changed(di->bat); in ds2760_pm_notifier()
665 mod_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ); in ds2760_pm_notifier()
681 struct device *dev = &sl->dev; in w1_ds2760_add_slave()
688 retval = -ENOMEM; in w1_ds2760_add_slave()
692 snprintf(name, sizeof(name), "ds2760-battery.%d", dev->id); in w1_ds2760_add_slave()
694 di->dev = dev; in w1_ds2760_add_slave()
695 di->bat_desc.name = name; in w1_ds2760_add_slave()
696 di->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; in w1_ds2760_add_slave()
697 di->bat_desc.properties = ds2760_battery_props; in w1_ds2760_add_slave()
698 di->bat_desc.num_properties = ARRAY_SIZE(ds2760_battery_props); in w1_ds2760_add_slave()
699 di->bat_desc.get_property = ds2760_battery_get_property; in w1_ds2760_add_slave()
700 di->bat_desc.set_property = ds2760_battery_set_property; in w1_ds2760_add_slave()
701 di->bat_desc.property_is_writeable = in w1_ds2760_add_slave()
703 di->bat_desc.set_charged = ds2760_battery_set_charged; in w1_ds2760_add_slave()
704 di->bat_desc.external_power_changed = in w1_ds2760_add_slave()
709 if (dev->of_node) { in w1_ds2760_add_slave()
712 psy_cfg.of_node = dev->of_node; in w1_ds2760_add_slave()
714 if (!of_property_read_bool(dev->of_node, "maxim,pmod-enabled")) in w1_ds2760_add_slave()
717 if (!of_property_read_u32(dev->of_node, in w1_ds2760_add_slave()
718 "maxim,cache-time-ms", &tmp)) in w1_ds2760_add_slave()
721 if (!of_property_read_u32(dev->of_node, in w1_ds2760_add_slave()
722 "rated-capacity-microamp-hours", in w1_ds2760_add_slave()
727 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; in w1_ds2760_add_slave()
729 sl->family_data = di; in w1_ds2760_add_slave()
733 status = di->raw[DS2760_STATUS_REG]; in w1_ds2760_add_slave()
750 di->bat = power_supply_register(dev, &di->bat_desc, &psy_cfg); in w1_ds2760_add_slave()
751 if (IS_ERR(di->bat)) { in w1_ds2760_add_slave()
752 dev_err(di->dev, "failed to register battery\n"); in w1_ds2760_add_slave()
753 retval = PTR_ERR(di->bat); in w1_ds2760_add_slave()
757 INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); in w1_ds2760_add_slave()
758 INIT_DELAYED_WORK(&di->set_charged_work, in w1_ds2760_add_slave()
760 di->monitor_wqueue = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); in w1_ds2760_add_slave()
761 if (!di->monitor_wqueue) { in w1_ds2760_add_slave()
762 retval = -ESRCH; in w1_ds2760_add_slave()
765 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1); in w1_ds2760_add_slave()
767 di->pm_notifier.notifier_call = ds2760_pm_notifier; in w1_ds2760_add_slave()
768 register_pm_notifier(&di->pm_notifier); in w1_ds2760_add_slave()
773 power_supply_unregister(di->bat); in w1_ds2760_add_slave()
782 struct ds2760_device_info *di = sl->family_data; in w1_ds2760_remove_slave()
784 unregister_pm_notifier(&di->pm_notifier); in w1_ds2760_remove_slave()
785 cancel_delayed_work_sync(&di->monitor_work); in w1_ds2760_remove_slave()
786 cancel_delayed_work_sync(&di->set_charged_work); in w1_ds2760_remove_slave()
787 destroy_workqueue(di->monitor_wqueue); in w1_ds2760_remove_slave()
788 power_supply_unregister(di->bat); in w1_ds2760_remove_slave()
814 MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip");
816 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2760));