Lines Matching refs:di

142 static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di,  in ab8500_btemp_batctrl_volt_to_res()  argument
147 if (is_ab8500_1p1_or_earlier(di->parent)) { in ab8500_btemp_batctrl_volt_to_res()
155 if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL) { in ab8500_btemp_batctrl_volt_to_res()
161 - di->bm->gnd_lift_resistance * inst_curr) in ab8500_btemp_batctrl_volt_to_res()
162 / di->curr_source; in ab8500_btemp_batctrl_volt_to_res()
180 static int ab8500_btemp_read_batctrl_voltage(struct ab8500_btemp *di) in ab8500_btemp_read_batctrl_voltage() argument
185 ret = iio_read_channel_processed(di->bat_ctrl, &vbtemp); in ab8500_btemp_read_batctrl_voltage()
187 dev_err(di->dev, in ab8500_btemp_read_batctrl_voltage()
203 static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, in ab8500_btemp_curr_source_enable() argument
213 if (is_ab8500_1p1_or_earlier(di->parent)) in ab8500_btemp_curr_source_enable()
217 if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { in ab8500_btemp_curr_source_enable()
219 if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA) in ab8500_btemp_curr_source_enable()
224 dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source); in ab8500_btemp_curr_source_enable()
226 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
230 dev_err(di->dev, "%s failed setting cmp_force\n", in ab8500_btemp_curr_source_enable()
242 ret = abx500_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
246 dev_err(di->dev, "%s failed enabling current source\n", in ab8500_btemp_curr_source_enable()
250 } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { in ab8500_btemp_curr_source_enable()
251 dev_dbg(di->dev, "Disable BATCTRL curr source\n"); in ab8500_btemp_curr_source_enable()
255 di->dev, in ab8500_btemp_curr_source_enable()
261 dev_err(di->dev, "%s failed disabling current source\n", in ab8500_btemp_curr_source_enable()
267 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
272 dev_err(di->dev, "%s failed enabling PU and comp\n", in ab8500_btemp_curr_source_enable()
285 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
289 dev_err(di->dev, "%s failed disabling force comp\n", in ab8500_btemp_curr_source_enable()
302 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
308 dev_err(di->dev, "%s failed disabling current source\n", in ab8500_btemp_curr_source_enable()
314 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
319 dev_err(di->dev, "%s failed enabling PU and comp\n", in ab8500_btemp_curr_source_enable()
333 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_btemp_curr_source_enable()
337 dev_err(di->dev, "%s failed disabling force comp\n", in ab8500_btemp_curr_source_enable()
352 static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di) in ab8500_btemp_get_batctrl_res() argument
364 ret = ab8500_btemp_curr_source_enable(di, true); in ab8500_btemp_get_batctrl_res()
366 dev_err(di->dev, "%s curr source enabled failed\n", __func__); in ab8500_btemp_get_batctrl_res()
370 if (!di->fg) in ab8500_btemp_get_batctrl_res()
371 di->fg = ab8500_fg_get(); in ab8500_btemp_get_batctrl_res()
372 if (!di->fg) { in ab8500_btemp_get_batctrl_res()
373 dev_err(di->dev, "No fg found\n"); in ab8500_btemp_get_batctrl_res()
377 ret = ab8500_fg_inst_curr_start(di->fg); in ab8500_btemp_get_batctrl_res()
380 dev_err(di->dev, "Failed to start current measurement\n"); in ab8500_btemp_get_batctrl_res()
386 } while (!ab8500_fg_inst_curr_started(di->fg)); in ab8500_btemp_get_batctrl_res()
391 batctrl += ab8500_btemp_read_batctrl_voltage(di); in ab8500_btemp_get_batctrl_res()
394 } while (!ab8500_fg_inst_curr_done(di->fg)); in ab8500_btemp_get_batctrl_res()
397 ret = ab8500_fg_inst_curr_finalize(di->fg, &inst_curr); in ab8500_btemp_get_batctrl_res()
399 dev_err(di->dev, "Failed to finalize current measurement\n"); in ab8500_btemp_get_batctrl_res()
403 res = ab8500_btemp_batctrl_volt_to_res(di, batctrl, inst_curr); in ab8500_btemp_get_batctrl_res()
405 ret = ab8500_btemp_curr_source_enable(di, false); in ab8500_btemp_get_batctrl_res()
407 dev_err(di->dev, "%s curr source disable failed\n", __func__); in ab8500_btemp_get_batctrl_res()
411 dev_dbg(di->dev, "%s batctrl: %d res: %d inst_curr: %d samples: %d\n", in ab8500_btemp_get_batctrl_res()
427 static int ab8500_btemp_res_to_temp(struct ab8500_btemp *di, in ab8500_btemp_res_to_temp() argument
458 static int ab8500_btemp_measure_temp(struct ab8500_btemp *di) in ab8500_btemp_measure_temp() argument
465 id = di->bm->batt_id; in ab8500_btemp_measure_temp()
467 if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && in ab8500_btemp_measure_temp()
470 rbat = ab8500_btemp_get_batctrl_res(di); in ab8500_btemp_measure_temp()
472 dev_err(di->dev, "%s get batctrl res failed\n", in ab8500_btemp_measure_temp()
481 temp = ab8500_btemp_res_to_temp(di, in ab8500_btemp_measure_temp()
482 di->bm->bat_type[id].r_to_t_tbl, in ab8500_btemp_measure_temp()
483 di->bm->bat_type[id].n_temp_tbl_elements, rbat); in ab8500_btemp_measure_temp()
485 ret = iio_read_channel_processed(di->btemp_ball, &vntc); in ab8500_btemp_measure_temp()
487 dev_err(di->dev, in ab8500_btemp_measure_temp()
498 temp = ab8500_btemp_res_to_temp(di, in ab8500_btemp_measure_temp()
499 di->bm->bat_type[id].r_to_t_tbl, in ab8500_btemp_measure_temp()
500 di->bm->bat_type[id].n_temp_tbl_elements, rntc); in ab8500_btemp_measure_temp()
503 dev_dbg(di->dev, "Battery temperature is %d\n", temp); in ab8500_btemp_measure_temp()
515 static int ab8500_btemp_id(struct ab8500_btemp *di) in ab8500_btemp_id() argument
520 di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; in ab8500_btemp_id()
521 di->bm->batt_id = BATTERY_UNKNOWN; in ab8500_btemp_id()
523 res = ab8500_btemp_get_batctrl_res(di); in ab8500_btemp_id()
525 dev_err(di->dev, "%s get batctrl res failed\n", __func__); in ab8500_btemp_id()
530 for (i = BATTERY_UNKNOWN + 1; i < di->bm->n_btypes; i++) { in ab8500_btemp_id()
531 if ((res <= di->bm->bat_type[i].resis_high) && in ab8500_btemp_id()
532 (res >= di->bm->bat_type[i].resis_low)) { in ab8500_btemp_id()
533 dev_dbg(di->dev, "Battery detected on %s" in ab8500_btemp_id()
536 di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL ? in ab8500_btemp_id()
538 di->bm->bat_type[i].resis_low, res, in ab8500_btemp_id()
539 di->bm->bat_type[i].resis_high, i); in ab8500_btemp_id()
541 di->bm->batt_id = i; in ab8500_btemp_id()
546 if (di->bm->batt_id == BATTERY_UNKNOWN) { in ab8500_btemp_id()
547 dev_warn(di->dev, "Battery identified as unknown" in ab8500_btemp_id()
556 if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && in ab8500_btemp_id()
557 di->bm->batt_id == 1) { in ab8500_btemp_id()
558 dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); in ab8500_btemp_id()
559 di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; in ab8500_btemp_id()
562 return di->bm->batt_id; in ab8500_btemp_id()
575 struct ab8500_btemp *di = container_of(work, in ab8500_btemp_periodic_work() local
578 if (!di->initialized) { in ab8500_btemp_periodic_work()
580 if (ab8500_btemp_id(di) < 0) in ab8500_btemp_periodic_work()
581 dev_warn(di->dev, "failed to identify the battery\n"); in ab8500_btemp_periodic_work()
584 bat_temp = ab8500_btemp_measure_temp(di); in ab8500_btemp_periodic_work()
591 if ((bat_temp == di->prev_bat_temp) || !di->initialized) { in ab8500_btemp_periodic_work()
592 if ((di->bat_temp != di->prev_bat_temp) || !di->initialized) { in ab8500_btemp_periodic_work()
593 di->initialized = true; in ab8500_btemp_periodic_work()
594 di->bat_temp = bat_temp; in ab8500_btemp_periodic_work()
595 power_supply_changed(di->btemp_psy); in ab8500_btemp_periodic_work()
597 } else if (bat_temp < di->prev_bat_temp) { in ab8500_btemp_periodic_work()
598 di->bat_temp--; in ab8500_btemp_periodic_work()
599 power_supply_changed(di->btemp_psy); in ab8500_btemp_periodic_work()
600 } else if (bat_temp > di->prev_bat_temp) { in ab8500_btemp_periodic_work()
601 di->bat_temp++; in ab8500_btemp_periodic_work()
602 power_supply_changed(di->btemp_psy); in ab8500_btemp_periodic_work()
604 di->prev_bat_temp = bat_temp; in ab8500_btemp_periodic_work()
606 if (di->events.ac_conn || di->events.usb_conn) in ab8500_btemp_periodic_work()
607 interval = di->bm->temp_interval_chg; in ab8500_btemp_periodic_work()
609 interval = di->bm->temp_interval_nochg; in ab8500_btemp_periodic_work()
612 queue_delayed_work(di->btemp_wq, in ab8500_btemp_periodic_work()
613 &di->btemp_periodic_work, in ab8500_btemp_periodic_work()
626 struct ab8500_btemp *di = _di; in ab8500_btemp_batctrlindb_handler() local
627 dev_err(di->dev, "Battery removal detected!\n"); in ab8500_btemp_batctrlindb_handler()
629 di->events.batt_rem = true; in ab8500_btemp_batctrlindb_handler()
630 power_supply_changed(di->btemp_psy); in ab8500_btemp_batctrlindb_handler()
644 struct ab8500_btemp *di = _di; in ab8500_btemp_templow_handler() local
646 if (is_ab8500_3p3_or_earlier(di->parent)) { in ab8500_btemp_templow_handler()
647 dev_dbg(di->dev, "Ignore false btemp low irq" in ab8500_btemp_templow_handler()
650 dev_crit(di->dev, "Battery temperature lower than -10deg c\n"); in ab8500_btemp_templow_handler()
652 di->events.btemp_low = true; in ab8500_btemp_templow_handler()
653 di->events.btemp_high = false; in ab8500_btemp_templow_handler()
654 di->events.btemp_medhigh = false; in ab8500_btemp_templow_handler()
655 di->events.btemp_lowmed = false; in ab8500_btemp_templow_handler()
656 power_supply_changed(di->btemp_psy); in ab8500_btemp_templow_handler()
671 struct ab8500_btemp *di = _di; in ab8500_btemp_temphigh_handler() local
673 dev_crit(di->dev, "Battery temperature is higher than MAX temp\n"); in ab8500_btemp_temphigh_handler()
675 di->events.btemp_high = true; in ab8500_btemp_temphigh_handler()
676 di->events.btemp_medhigh = false; in ab8500_btemp_temphigh_handler()
677 di->events.btemp_lowmed = false; in ab8500_btemp_temphigh_handler()
678 di->events.btemp_low = false; in ab8500_btemp_temphigh_handler()
679 power_supply_changed(di->btemp_psy); in ab8500_btemp_temphigh_handler()
693 struct ab8500_btemp *di = _di; in ab8500_btemp_lowmed_handler() local
695 dev_dbg(di->dev, "Battery temperature is between low and medium\n"); in ab8500_btemp_lowmed_handler()
697 di->events.btemp_lowmed = true; in ab8500_btemp_lowmed_handler()
698 di->events.btemp_medhigh = false; in ab8500_btemp_lowmed_handler()
699 di->events.btemp_high = false; in ab8500_btemp_lowmed_handler()
700 di->events.btemp_low = false; in ab8500_btemp_lowmed_handler()
701 power_supply_changed(di->btemp_psy); in ab8500_btemp_lowmed_handler()
715 struct ab8500_btemp *di = _di; in ab8500_btemp_medhigh_handler() local
717 dev_dbg(di->dev, "Battery temperature is between medium and high\n"); in ab8500_btemp_medhigh_handler()
719 di->events.btemp_medhigh = true; in ab8500_btemp_medhigh_handler()
720 di->events.btemp_lowmed = false; in ab8500_btemp_medhigh_handler()
721 di->events.btemp_high = false; in ab8500_btemp_medhigh_handler()
722 di->events.btemp_low = false; in ab8500_btemp_medhigh_handler()
723 power_supply_changed(di->btemp_psy); in ab8500_btemp_medhigh_handler()
736 static void ab8500_btemp_periodic(struct ab8500_btemp *di, in ab8500_btemp_periodic() argument
739 dev_dbg(di->dev, "Enable periodic temperature measurements: %d\n", in ab8500_btemp_periodic()
745 cancel_delayed_work_sync(&di->btemp_periodic_work); in ab8500_btemp_periodic()
748 queue_delayed_work(di->btemp_wq, &di->btemp_periodic_work, 0); in ab8500_btemp_periodic()
757 int ab8500_btemp_get_temp(struct ab8500_btemp *di) in ab8500_btemp_get_temp() argument
765 if (is_ab8500_3p3_or_earlier(di->parent)) { in ab8500_btemp_get_temp()
766 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
768 if (di->events.btemp_low) { in ab8500_btemp_get_temp()
769 if (temp > di->btemp_ranges.btemp_low_limit) in ab8500_btemp_get_temp()
770 temp = di->btemp_ranges.btemp_low_limit * 10; in ab8500_btemp_get_temp()
772 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
773 } else if (di->events.btemp_high) { in ab8500_btemp_get_temp()
774 if (temp < di->btemp_ranges.btemp_high_limit) in ab8500_btemp_get_temp()
775 temp = di->btemp_ranges.btemp_high_limit * 10; in ab8500_btemp_get_temp()
777 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
778 } else if (di->events.btemp_lowmed) { in ab8500_btemp_get_temp()
779 if (temp > di->btemp_ranges.btemp_med_limit) in ab8500_btemp_get_temp()
780 temp = di->btemp_ranges.btemp_med_limit * 10; in ab8500_btemp_get_temp()
782 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
783 } else if (di->events.btemp_medhigh) { in ab8500_btemp_get_temp()
784 if (temp < di->btemp_ranges.btemp_med_limit) in ab8500_btemp_get_temp()
785 temp = di->btemp_ranges.btemp_med_limit * 10; in ab8500_btemp_get_temp()
787 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
789 temp = di->bat_temp * 10; in ab8500_btemp_get_temp()
825 struct ab8500_btemp *di = power_supply_get_drvdata(psy); in ab8500_btemp_get_property() local
830 if (di->events.batt_rem) in ab8500_btemp_get_property()
836 val->intval = di->bm->bat_type[di->bm->batt_id].name; in ab8500_btemp_get_property()
839 val->intval = ab8500_btemp_get_temp(di); in ab8500_btemp_get_property()
852 struct ab8500_btemp *di; in ab8500_btemp_get_ext_psy_data() local
857 di = power_supply_get_drvdata(psy); in ab8500_btemp_get_ext_psy_data()
880 if (!ret.intval && di->events.ac_conn) { in ab8500_btemp_get_ext_psy_data()
881 di->events.ac_conn = false; in ab8500_btemp_get_ext_psy_data()
884 else if (ret.intval && !di->events.ac_conn) { in ab8500_btemp_get_ext_psy_data()
885 di->events.ac_conn = true; in ab8500_btemp_get_ext_psy_data()
886 if (!di->events.usb_conn) in ab8500_btemp_get_ext_psy_data()
887 ab8500_btemp_periodic(di, true); in ab8500_btemp_get_ext_psy_data()
892 if (!ret.intval && di->events.usb_conn) { in ab8500_btemp_get_ext_psy_data()
893 di->events.usb_conn = false; in ab8500_btemp_get_ext_psy_data()
896 else if (ret.intval && !di->events.usb_conn) { in ab8500_btemp_get_ext_psy_data()
897 di->events.usb_conn = true; in ab8500_btemp_get_ext_psy_data()
898 if (!di->events.ac_conn) in ab8500_btemp_get_ext_psy_data()
899 ab8500_btemp_periodic(di, true); in ab8500_btemp_get_ext_psy_data()
924 struct ab8500_btemp *di = power_supply_get_drvdata(psy); in ab8500_btemp_external_power_changed() local
927 di->btemp_psy, ab8500_btemp_get_ext_psy_data); in ab8500_btemp_external_power_changed()
942 struct ab8500_btemp *di = platform_get_drvdata(pdev); in ab8500_btemp_resume() local
944 ab8500_btemp_periodic(di, true); in ab8500_btemp_resume()
952 struct ab8500_btemp *di = platform_get_drvdata(pdev); in ab8500_btemp_suspend() local
954 ab8500_btemp_periodic(di, false); in ab8500_btemp_suspend()
965 struct ab8500_btemp *di = platform_get_drvdata(pdev); in ab8500_btemp_remove() local
971 free_irq(irq, di); in ab8500_btemp_remove()
975 destroy_workqueue(di->btemp_wq); in ab8500_btemp_remove()
978 power_supply_unregister(di->btemp_psy); in ab8500_btemp_remove()
1002 struct ab8500_btemp *di; in ab8500_btemp_probe() local
1006 di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); in ab8500_btemp_probe()
1007 if (!di) { in ab8500_btemp_probe()
1016 di->bm = plat; in ab8500_btemp_probe()
1019 ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm); in ab8500_btemp_probe()
1027 di->dev = &pdev->dev; in ab8500_btemp_probe()
1028 di->parent = dev_get_drvdata(pdev->dev.parent); in ab8500_btemp_probe()
1031 di->btemp_ball = devm_iio_channel_get(&pdev->dev, "btemp_ball"); in ab8500_btemp_probe()
1032 if (IS_ERR(di->btemp_ball)) { in ab8500_btemp_probe()
1033 if (PTR_ERR(di->btemp_ball) == -ENODEV) in ab8500_btemp_probe()
1036 return PTR_ERR(di->btemp_ball); in ab8500_btemp_probe()
1038 di->bat_ctrl = devm_iio_channel_get(&pdev->dev, "bat_ctrl"); in ab8500_btemp_probe()
1039 if (IS_ERR(di->bat_ctrl)) { in ab8500_btemp_probe()
1040 if (PTR_ERR(di->bat_ctrl) == -ENODEV) in ab8500_btemp_probe()
1043 return PTR_ERR(di->bat_ctrl); in ab8500_btemp_probe()
1046 di->initialized = false; in ab8500_btemp_probe()
1050 psy_cfg.drv_data = di; in ab8500_btemp_probe()
1053 di->btemp_wq = in ab8500_btemp_probe()
1055 if (di->btemp_wq == NULL) { in ab8500_btemp_probe()
1056 dev_err(di->dev, "failed to create work queue\n"); in ab8500_btemp_probe()
1061 INIT_DEFERRABLE_WORK(&di->btemp_periodic_work, in ab8500_btemp_probe()
1065 di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT; in ab8500_btemp_probe()
1066 di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT; in ab8500_btemp_probe()
1068 ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, in ab8500_btemp_probe()
1071 dev_err(di->dev, "%s ab8500 read failed\n", __func__); in ab8500_btemp_probe()
1077 di->btemp_ranges.btemp_high_limit = in ab8500_btemp_probe()
1081 di->btemp_ranges.btemp_high_limit = in ab8500_btemp_probe()
1085 di->btemp_ranges.btemp_high_limit = in ab8500_btemp_probe()
1091 di->btemp_psy = power_supply_register(di->dev, &ab8500_btemp_desc, in ab8500_btemp_probe()
1093 if (IS_ERR(di->btemp_psy)) { in ab8500_btemp_probe()
1094 dev_err(di->dev, "failed to register BTEMP psy\n"); in ab8500_btemp_probe()
1095 ret = PTR_ERR(di->btemp_psy); in ab8500_btemp_probe()
1109 ab8500_btemp_irq[i].name, di); in ab8500_btemp_probe()
1112 dev_err(di->dev, "failed to request %s IRQ %d: %d\n" in ab8500_btemp_probe()
1116 dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", in ab8500_btemp_probe()
1120 platform_set_drvdata(pdev, di); in ab8500_btemp_probe()
1123 ab8500_btemp_periodic(di, true); in ab8500_btemp_probe()
1124 list_add_tail(&di->node, &ab8500_btemp_list); in ab8500_btemp_probe()
1132 free_irq(irq, di); in ab8500_btemp_probe()
1135 power_supply_unregister(di->btemp_psy); in ab8500_btemp_probe()
1137 destroy_workqueue(di->btemp_wq); in ab8500_btemp_probe()