Lines Matching refs:di
143 static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di, in ab8500_btemp_batctrl_volt_to_res() argument
148 if (is_ab8500_1p1_or_earlier(di->parent)) { in ab8500_btemp_batctrl_volt_to_res()
156 if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL) { in ab8500_btemp_batctrl_volt_to_res()
162 - di->bm->gnd_lift_resistance * inst_curr) in ab8500_btemp_batctrl_volt_to_res()
163 / di->curr_source; in ab8500_btemp_batctrl_volt_to_res()
181 static int ab8500_btemp_read_batctrl_voltage(struct ab8500_btemp *di) in ab8500_btemp_read_batctrl_voltage() argument
186 vbtemp = ab8500_gpadc_convert(di->gpadc, BAT_CTRL); in ab8500_btemp_read_batctrl_voltage()
188 dev_err(di->dev, in ab8500_btemp_read_batctrl_voltage()
204 static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, in ab8500_btemp_curr_source_enable() argument
214 if (is_ab8500_1p1_or_earlier(di->parent)) in ab8500_btemp_curr_source_enable()
218 if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { in ab8500_btemp_curr_source_enable()
220 if (is_ab8540(di->parent)) { in ab8500_btemp_curr_source_enable()
221 if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_60UA) in ab8500_btemp_curr_source_enable()
225 } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { in ab8500_btemp_curr_source_enable()
226 if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_16UA) in ab8500_btemp_curr_source_enable()
231 if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA) in ab8500_btemp_curr_source_enable()
237 dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source); in ab8500_btemp_curr_source_enable()
239 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
243 dev_err(di->dev, "%s failed setting cmp_force\n", in ab8500_btemp_curr_source_enable()
255 ret = abx500_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
259 dev_err(di->dev, "%s failed enabling current source\n", in ab8500_btemp_curr_source_enable()
263 } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { in ab8500_btemp_curr_source_enable()
264 dev_dbg(di->dev, "Disable BATCTRL curr source\n"); in ab8500_btemp_curr_source_enable()
266 if (is_ab8540(di->parent)) { in ab8500_btemp_curr_source_enable()
269 di->dev, in ab8500_btemp_curr_source_enable()
273 } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { in ab8500_btemp_curr_source_enable()
276 di->dev, in ab8500_btemp_curr_source_enable()
283 di->dev, in ab8500_btemp_curr_source_enable()
290 dev_err(di->dev, "%s failed disabling current source\n", in ab8500_btemp_curr_source_enable()
296 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
301 dev_err(di->dev, "%s failed enabling PU and comp\n", in ab8500_btemp_curr_source_enable()
314 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
318 dev_err(di->dev, "%s failed disabling force comp\n", in ab8500_btemp_curr_source_enable()
330 if (is_ab8540(di->parent)) { in ab8500_btemp_curr_source_enable()
332 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
336 } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { in ab8500_btemp_curr_source_enable()
338 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
344 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
351 dev_err(di->dev, "%s failed disabling current source\n", in ab8500_btemp_curr_source_enable()
357 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
362 dev_err(di->dev, "%s failed enabling PU and comp\n", in ab8500_btemp_curr_source_enable()
376 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
380 dev_err(di->dev, "%s failed disabling force comp\n", in ab8500_btemp_curr_source_enable()
395 static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di) in ab8500_btemp_get_batctrl_res() argument
407 ret = ab8500_btemp_curr_source_enable(di, true); in ab8500_btemp_get_batctrl_res()
409 dev_err(di->dev, "%s curr source enabled failed\n", __func__); in ab8500_btemp_get_batctrl_res()
413 if (!di->fg) in ab8500_btemp_get_batctrl_res()
414 di->fg = ab8500_fg_get(); in ab8500_btemp_get_batctrl_res()
415 if (!di->fg) { in ab8500_btemp_get_batctrl_res()
416 dev_err(di->dev, "No fg found\n"); in ab8500_btemp_get_batctrl_res()
420 ret = ab8500_fg_inst_curr_start(di->fg); in ab8500_btemp_get_batctrl_res()
423 dev_err(di->dev, "Failed to start current measurement\n"); in ab8500_btemp_get_batctrl_res()
429 } while (!ab8500_fg_inst_curr_started(di->fg)); in ab8500_btemp_get_batctrl_res()
434 batctrl += ab8500_btemp_read_batctrl_voltage(di); in ab8500_btemp_get_batctrl_res()
437 } while (!ab8500_fg_inst_curr_done(di->fg)); in ab8500_btemp_get_batctrl_res()
440 ret = ab8500_fg_inst_curr_finalize(di->fg, &inst_curr); in ab8500_btemp_get_batctrl_res()
442 dev_err(di->dev, "Failed to finalize current measurement\n"); in ab8500_btemp_get_batctrl_res()
446 res = ab8500_btemp_batctrl_volt_to_res(di, batctrl, inst_curr); in ab8500_btemp_get_batctrl_res()
448 ret = ab8500_btemp_curr_source_enable(di, false); in ab8500_btemp_get_batctrl_res()
450 dev_err(di->dev, "%s curr source disable failed\n", __func__); in ab8500_btemp_get_batctrl_res()
454 dev_dbg(di->dev, "%s batctrl: %d res: %d inst_curr: %d samples: %d\n", in ab8500_btemp_get_batctrl_res()
470 static int ab8500_btemp_res_to_temp(struct ab8500_btemp *di, in ab8500_btemp_res_to_temp() argument
502 static int ab8500_btemp_measure_temp(struct ab8500_btemp *di) in ab8500_btemp_measure_temp() argument
509 id = di->bm->batt_id; in ab8500_btemp_measure_temp()
511 if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && in ab8500_btemp_measure_temp()
514 rbat = ab8500_btemp_get_batctrl_res(di); in ab8500_btemp_measure_temp()
516 dev_err(di->dev, "%s get batctrl res failed\n", in ab8500_btemp_measure_temp()
525 temp = ab8500_btemp_res_to_temp(di, in ab8500_btemp_measure_temp()
526 di->bm->bat_type[id].r_to_t_tbl, in ab8500_btemp_measure_temp()
527 di->bm->bat_type[id].n_temp_tbl_elements, rbat); in ab8500_btemp_measure_temp()
529 vntc = ab8500_gpadc_convert(di->gpadc, BTEMP_BALL); in ab8500_btemp_measure_temp()
531 dev_err(di->dev, in ab8500_btemp_measure_temp()
542 temp = ab8500_btemp_res_to_temp(di, in ab8500_btemp_measure_temp()
543 di->bm->bat_type[id].r_to_t_tbl, in ab8500_btemp_measure_temp()
544 di->bm->bat_type[id].n_temp_tbl_elements, rntc); in ab8500_btemp_measure_temp()
547 dev_dbg(di->dev, "Battery temperature is %d\n", temp); in ab8500_btemp_measure_temp()
559 static int ab8500_btemp_id(struct ab8500_btemp *di) in ab8500_btemp_id() argument
563 if (is_ab8540(di->parent)) in ab8500_btemp_id()
564 di->curr_source = BTEMP_BATCTRL_CURR_SRC_60UA; in ab8500_btemp_id()
565 else if (is_ab9540(di->parent) || is_ab8505(di->parent)) in ab8500_btemp_id()
566 di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; in ab8500_btemp_id()
568 di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; in ab8500_btemp_id()
570 di->bm->batt_id = BATTERY_UNKNOWN; in ab8500_btemp_id()
572 res = ab8500_btemp_get_batctrl_res(di); in ab8500_btemp_id()
574 dev_err(di->dev, "%s get batctrl res failed\n", __func__); in ab8500_btemp_id()
579 for (i = BATTERY_UNKNOWN + 1; i < di->bm->n_btypes; i++) { in ab8500_btemp_id()
580 if ((res <= di->bm->bat_type[i].resis_high) && in ab8500_btemp_id()
581 (res >= di->bm->bat_type[i].resis_low)) { in ab8500_btemp_id()
582 dev_dbg(di->dev, "Battery detected on %s" in ab8500_btemp_id()
585 di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL ? in ab8500_btemp_id()
587 di->bm->bat_type[i].resis_low, res, in ab8500_btemp_id()
588 di->bm->bat_type[i].resis_high, i); in ab8500_btemp_id()
590 di->bm->batt_id = i; in ab8500_btemp_id()
595 if (di->bm->batt_id == BATTERY_UNKNOWN) { in ab8500_btemp_id()
596 dev_warn(di->dev, "Battery identified as unknown" in ab8500_btemp_id()
605 if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && in ab8500_btemp_id()
606 di->bm->batt_id == 1) { in ab8500_btemp_id()
607 if (is_ab8540(di->parent)) { in ab8500_btemp_id()
608 dev_dbg(di->dev, in ab8500_btemp_id()
610 di->curr_source = BTEMP_BATCTRL_CURR_SRC_60UA; in ab8500_btemp_id()
611 } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { in ab8500_btemp_id()
612 dev_dbg(di->dev, in ab8500_btemp_id()
614 di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; in ab8500_btemp_id()
616 dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); in ab8500_btemp_id()
617 di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; in ab8500_btemp_id()
621 return di->bm->batt_id; in ab8500_btemp_id()
634 struct ab8500_btemp *di = container_of(work, in ab8500_btemp_periodic_work() local
637 if (!di->initialized) { in ab8500_btemp_periodic_work()
639 if (ab8500_btemp_id(di) < 0) in ab8500_btemp_periodic_work()
640 dev_warn(di->dev, "failed to identify the battery\n"); in ab8500_btemp_periodic_work()
643 bat_temp = ab8500_btemp_measure_temp(di); in ab8500_btemp_periodic_work()
650 if ((bat_temp == di->prev_bat_temp) || !di->initialized) { in ab8500_btemp_periodic_work()
651 if ((di->bat_temp != di->prev_bat_temp) || !di->initialized) { in ab8500_btemp_periodic_work()
652 di->initialized = true; in ab8500_btemp_periodic_work()
653 di->bat_temp = bat_temp; in ab8500_btemp_periodic_work()
654 power_supply_changed(di->btemp_psy); in ab8500_btemp_periodic_work()
656 } else if (bat_temp < di->prev_bat_temp) { in ab8500_btemp_periodic_work()
657 di->bat_temp--; in ab8500_btemp_periodic_work()
658 power_supply_changed(di->btemp_psy); in ab8500_btemp_periodic_work()
659 } else if (bat_temp > di->prev_bat_temp) { in ab8500_btemp_periodic_work()
660 di->bat_temp++; in ab8500_btemp_periodic_work()
661 power_supply_changed(di->btemp_psy); in ab8500_btemp_periodic_work()
663 di->prev_bat_temp = bat_temp; in ab8500_btemp_periodic_work()
665 if (di->events.ac_conn || di->events.usb_conn) in ab8500_btemp_periodic_work()
666 interval = di->bm->temp_interval_chg; in ab8500_btemp_periodic_work()
668 interval = di->bm->temp_interval_nochg; in ab8500_btemp_periodic_work()
671 queue_delayed_work(di->btemp_wq, in ab8500_btemp_periodic_work()
672 &di->btemp_periodic_work, in ab8500_btemp_periodic_work()
685 struct ab8500_btemp *di = _di; in ab8500_btemp_batctrlindb_handler() local
686 dev_err(di->dev, "Battery removal detected!\n"); in ab8500_btemp_batctrlindb_handler()
688 di->events.batt_rem = true; in ab8500_btemp_batctrlindb_handler()
689 power_supply_changed(di->btemp_psy); in ab8500_btemp_batctrlindb_handler()
703 struct ab8500_btemp *di = _di; in ab8500_btemp_templow_handler() local
705 if (is_ab8500_3p3_or_earlier(di->parent)) { in ab8500_btemp_templow_handler()
706 dev_dbg(di->dev, "Ignore false btemp low irq" in ab8500_btemp_templow_handler()
709 dev_crit(di->dev, "Battery temperature lower than -10deg c\n"); in ab8500_btemp_templow_handler()
711 di->events.btemp_low = true; in ab8500_btemp_templow_handler()
712 di->events.btemp_high = false; in ab8500_btemp_templow_handler()
713 di->events.btemp_medhigh = false; in ab8500_btemp_templow_handler()
714 di->events.btemp_lowmed = false; in ab8500_btemp_templow_handler()
715 power_supply_changed(di->btemp_psy); in ab8500_btemp_templow_handler()
730 struct ab8500_btemp *di = _di; in ab8500_btemp_temphigh_handler() local
732 dev_crit(di->dev, "Battery temperature is higher than MAX temp\n"); in ab8500_btemp_temphigh_handler()
734 di->events.btemp_high = true; in ab8500_btemp_temphigh_handler()
735 di->events.btemp_medhigh = false; in ab8500_btemp_temphigh_handler()
736 di->events.btemp_lowmed = false; in ab8500_btemp_temphigh_handler()
737 di->events.btemp_low = false; in ab8500_btemp_temphigh_handler()
738 power_supply_changed(di->btemp_psy); in ab8500_btemp_temphigh_handler()
752 struct ab8500_btemp *di = _di; in ab8500_btemp_lowmed_handler() local
754 dev_dbg(di->dev, "Battery temperature is between low and medium\n"); in ab8500_btemp_lowmed_handler()
756 di->events.btemp_lowmed = true; in ab8500_btemp_lowmed_handler()
757 di->events.btemp_medhigh = false; in ab8500_btemp_lowmed_handler()
758 di->events.btemp_high = false; in ab8500_btemp_lowmed_handler()
759 di->events.btemp_low = false; in ab8500_btemp_lowmed_handler()
760 power_supply_changed(di->btemp_psy); in ab8500_btemp_lowmed_handler()
774 struct ab8500_btemp *di = _di; in ab8500_btemp_medhigh_handler() local
776 dev_dbg(di->dev, "Battery temperature is between medium and high\n"); in ab8500_btemp_medhigh_handler()
778 di->events.btemp_medhigh = true; in ab8500_btemp_medhigh_handler()
779 di->events.btemp_lowmed = false; in ab8500_btemp_medhigh_handler()
780 di->events.btemp_high = false; in ab8500_btemp_medhigh_handler()
781 di->events.btemp_low = false; in ab8500_btemp_medhigh_handler()
782 power_supply_changed(di->btemp_psy); in ab8500_btemp_medhigh_handler()
795 static void ab8500_btemp_periodic(struct ab8500_btemp *di, in ab8500_btemp_periodic() argument
798 dev_dbg(di->dev, "Enable periodic temperature measurements: %d\n", in ab8500_btemp_periodic()
804 cancel_delayed_work_sync(&di->btemp_periodic_work); in ab8500_btemp_periodic()
807 queue_delayed_work(di->btemp_wq, &di->btemp_periodic_work, 0); in ab8500_btemp_periodic()
816 int ab8500_btemp_get_temp(struct ab8500_btemp *di) in ab8500_btemp_get_temp() argument
824 if (is_ab8500_3p3_or_earlier(di->parent)) { in ab8500_btemp_get_temp()
825 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
827 if (di->events.btemp_low) { in ab8500_btemp_get_temp()
828 if (temp > di->btemp_ranges.btemp_low_limit) in ab8500_btemp_get_temp()
829 temp = di->btemp_ranges.btemp_low_limit * 10; in ab8500_btemp_get_temp()
831 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
832 } else if (di->events.btemp_high) { in ab8500_btemp_get_temp()
833 if (temp < di->btemp_ranges.btemp_high_limit) in ab8500_btemp_get_temp()
834 temp = di->btemp_ranges.btemp_high_limit * 10; in ab8500_btemp_get_temp()
836 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
837 } else if (di->events.btemp_lowmed) { in ab8500_btemp_get_temp()
838 if (temp > di->btemp_ranges.btemp_med_limit) in ab8500_btemp_get_temp()
839 temp = di->btemp_ranges.btemp_med_limit * 10; in ab8500_btemp_get_temp()
841 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
842 } else if (di->events.btemp_medhigh) { in ab8500_btemp_get_temp()
843 if (temp < di->btemp_ranges.btemp_med_limit) in ab8500_btemp_get_temp()
844 temp = di->btemp_ranges.btemp_med_limit * 10; in ab8500_btemp_get_temp()
846 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
848 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
884 struct ab8500_btemp *di = power_supply_get_drvdata(psy); in ab8500_btemp_get_property() local
889 if (di->events.batt_rem) in ab8500_btemp_get_property()
895 val->intval = di->bm->bat_type[di->bm->batt_id].name; in ab8500_btemp_get_property()
898 val->intval = ab8500_btemp_get_temp(di); in ab8500_btemp_get_property()
910 struct ab8500_btemp *di; in ab8500_btemp_get_ext_psy_data() local
917 di = power_supply_get_drvdata(psy); in ab8500_btemp_get_ext_psy_data()
944 if (!ret.intval && di->events.ac_conn) { in ab8500_btemp_get_ext_psy_data()
945 di->events.ac_conn = false; in ab8500_btemp_get_ext_psy_data()
948 else if (ret.intval && !di->events.ac_conn) { in ab8500_btemp_get_ext_psy_data()
949 di->events.ac_conn = true; in ab8500_btemp_get_ext_psy_data()
950 if (!di->events.usb_conn) in ab8500_btemp_get_ext_psy_data()
951 ab8500_btemp_periodic(di, true); in ab8500_btemp_get_ext_psy_data()
956 if (!ret.intval && di->events.usb_conn) { in ab8500_btemp_get_ext_psy_data()
957 di->events.usb_conn = false; in ab8500_btemp_get_ext_psy_data()
960 else if (ret.intval && !di->events.usb_conn) { in ab8500_btemp_get_ext_psy_data()
961 di->events.usb_conn = true; in ab8500_btemp_get_ext_psy_data()
962 if (!di->events.ac_conn) in ab8500_btemp_get_ext_psy_data()
963 ab8500_btemp_periodic(di, true); in ab8500_btemp_get_ext_psy_data()
988 struct ab8500_btemp *di = power_supply_get_drvdata(psy); in ab8500_btemp_external_power_changed() local
991 di->btemp_psy, ab8500_btemp_get_ext_psy_data); in ab8500_btemp_external_power_changed()
1006 struct ab8500_btemp *di = platform_get_drvdata(pdev); in ab8500_btemp_resume() local
1008 ab8500_btemp_periodic(di, true); in ab8500_btemp_resume()
1016 struct ab8500_btemp *di = platform_get_drvdata(pdev); in ab8500_btemp_suspend() local
1018 ab8500_btemp_periodic(di, false); in ab8500_btemp_suspend()
1029 struct ab8500_btemp *di = platform_get_drvdata(pdev); in ab8500_btemp_remove() local
1035 free_irq(irq, di); in ab8500_btemp_remove()
1039 destroy_workqueue(di->btemp_wq); in ab8500_btemp_remove()
1042 power_supply_unregister(di->btemp_psy); in ab8500_btemp_remove()
1066 struct ab8500_btemp *di; in ab8500_btemp_probe() local
1070 di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); in ab8500_btemp_probe()
1071 if (!di) { in ab8500_btemp_probe()
1080 di->bm = plat; in ab8500_btemp_probe()
1083 ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm); in ab8500_btemp_probe()
1091 di->dev = &pdev->dev; in ab8500_btemp_probe()
1092 di->parent = dev_get_drvdata(pdev->dev.parent); in ab8500_btemp_probe()
1093 di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); in ab8500_btemp_probe()
1095 di->initialized = false; in ab8500_btemp_probe()
1099 psy_cfg.drv_data = di; in ab8500_btemp_probe()
1102 di->btemp_wq = in ab8500_btemp_probe()
1104 if (di->btemp_wq == NULL) { in ab8500_btemp_probe()
1105 dev_err(di->dev, "failed to create work queue\n"); in ab8500_btemp_probe()
1110 INIT_DEFERRABLE_WORK(&di->btemp_periodic_work, in ab8500_btemp_probe()
1114 di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT; in ab8500_btemp_probe()
1115 di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT; in ab8500_btemp_probe()
1117 ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, in ab8500_btemp_probe()
1120 dev_err(di->dev, "%s ab8500 read failed\n", __func__); in ab8500_btemp_probe()
1126 di->btemp_ranges.btemp_high_limit = in ab8500_btemp_probe()
1130 di->btemp_ranges.btemp_high_limit = in ab8500_btemp_probe()
1134 di->btemp_ranges.btemp_high_limit = in ab8500_btemp_probe()
1140 di->btemp_psy = power_supply_register(di->dev, &ab8500_btemp_desc, in ab8500_btemp_probe()
1142 if (IS_ERR(di->btemp_psy)) { in ab8500_btemp_probe()
1143 dev_err(di->dev, "failed to register BTEMP psy\n"); in ab8500_btemp_probe()
1144 ret = PTR_ERR(di->btemp_psy); in ab8500_btemp_probe()
1153 ab8500_btemp_irq[i].name, di); in ab8500_btemp_probe()
1156 dev_err(di->dev, "failed to request %s IRQ %d: %d\n" in ab8500_btemp_probe()
1160 dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", in ab8500_btemp_probe()
1164 platform_set_drvdata(pdev, di); in ab8500_btemp_probe()
1167 ab8500_btemp_periodic(di, true); in ab8500_btemp_probe()
1168 list_add_tail(&di->node, &ab8500_btemp_list); in ab8500_btemp_probe()
1173 power_supply_unregister(di->btemp_psy); in ab8500_btemp_probe()
1178 free_irq(irq, di); in ab8500_btemp_probe()
1181 destroy_workqueue(di->btemp_wq); in ab8500_btemp_probe()