Lines Matching +full:chip +full:- +full:to +full:- +full:chip

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2011-2015, 2017, 2020, The Linux Foundation. All rights reserved.
66 /* Over-temperature trip point values in mC */
89 * For TEMP_GEN2 v2.0, TEMP_DAC_STG1/2/3 registers are used to set the threshold
91 * TEMP_DAC_STG* = 0 --> 80 C
92 * Each 8 step increase in TEMP_DAC_STG* value corresponds to 5 C (5000 mC).
99 (((temp) - TEMP_DAC_MIN) * TEMP_DAC_SCALE_NUM / TEMP_DAC_SCALE_DEN)
128 int (*sync_thresholds)(struct qpnp_tm_chip *chip);
129 int (*get_temp_stage)(struct qpnp_tm_chip *chip);
130 int (*configure_trip_temps)(struct qpnp_tm_chip *chip);
143 /* protects .thresh, .stage and chip registers */
152 /* This array maps from GEN2 alarm state to GEN1 alarm stage */
155 static int qpnp_tm_read(struct qpnp_tm_chip *chip, u16 addr, u8 *data) in qpnp_tm_read() argument
160 ret = regmap_read(chip->map, chip->base + addr, &val); in qpnp_tm_read()
168 static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data) in qpnp_tm_write() argument
170 return regmap_write(chip->map, chip->base + addr, data); in qpnp_tm_write()
174 * qpnp_tm_decode_temp() - return temperature in mC corresponding to the
175 * specified over-temperature stage
176 * @chip: Pointer to the qpnp_tm chip
177 * @stage: Over-temperature stage
181 static long qpnp_tm_decode_temp(struct qpnp_tm_chip *chip, unsigned int stage) in qpnp_tm_decode_temp() argument
186 return chip->temp_thresh_map[stage - 1]; in qpnp_tm_decode_temp()
190 * qpnp_tm_gen1_get_temp_stage() - return over-temperature stage
191 * @chip: Pointer to the qpnp_tm chip
195 static int qpnp_tm_gen1_get_temp_stage(struct qpnp_tm_chip *chip) in qpnp_tm_gen1_get_temp_stage() argument
200 ret = qpnp_tm_read(chip, QPNP_TM_REG_STATUS, &reg); in qpnp_tm_gen1_get_temp_stage()
208 * qpnp_tm_gen2_get_temp_stage() - return over-temperature stage
209 * @chip: Pointer to the qpnp_tm chip
213 static int qpnp_tm_gen2_get_temp_stage(struct qpnp_tm_chip *chip) in qpnp_tm_gen2_get_temp_stage() argument
218 ret = qpnp_tm_read(chip, QPNP_TM_REG_STATUS, &reg); in qpnp_tm_gen2_get_temp_stage()
228 * qpnp_tm_lite_get_temp_stage() - return over-temperature stage
229 * @chip: Pointer to the qpnp_tm chip
233 static int qpnp_tm_lite_get_temp_stage(struct qpnp_tm_chip *chip) in qpnp_tm_lite_get_temp_stage() argument
238 ret = qpnp_tm_read(chip, QPNP_TM_REG_IRQ_STATUS, &reg); in qpnp_tm_lite_get_temp_stage()
249 static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip) in qpnp_tm_update_temp_no_adc() argument
254 WARN_ON(!mutex_is_locked(&chip->lock)); in qpnp_tm_update_temp_no_adc()
256 ret = chip->data->get_temp_stage(chip); in qpnp_tm_update_temp_no_adc()
260 stage_old = chip->stage; in qpnp_tm_update_temp_no_adc()
264 chip->temp = qpnp_tm_decode_temp(chip, stage_new) in qpnp_tm_update_temp_no_adc()
268 chip->temp = qpnp_tm_decode_temp(chip, stage_new + 1) in qpnp_tm_update_temp_no_adc()
269 - TEMP_STAGE_HYSTERESIS; in qpnp_tm_update_temp_no_adc()
272 chip->stage = stage_new; in qpnp_tm_update_temp_no_adc()
279 struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz); in qpnp_tm_get_temp() local
283 return -EINVAL; in qpnp_tm_get_temp()
285 if (!chip->initialized) { in qpnp_tm_get_temp()
290 if (!chip->adc) { in qpnp_tm_get_temp()
291 mutex_lock(&chip->lock); in qpnp_tm_get_temp()
292 ret = qpnp_tm_update_temp_no_adc(chip); in qpnp_tm_get_temp()
293 mutex_unlock(&chip->lock); in qpnp_tm_get_temp()
297 ret = iio_read_channel_processed(chip->adc, &mili_celsius); in qpnp_tm_get_temp()
301 chip->temp = mili_celsius; in qpnp_tm_get_temp()
304 *temp = chip->temp; in qpnp_tm_get_temp()
309 static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip, in qpnp_tm_update_critical_trip_temp() argument
312 long stage2_threshold_min = (*chip->data->temp_map)[THRESH_MIN][STAGE2]; in qpnp_tm_update_critical_trip_temp()
313 long stage2_threshold_max = (*chip->data->temp_map)[THRESH_MAX][STAGE2]; in qpnp_tm_update_critical_trip_temp()
317 WARN_ON(!mutex_is_locked(&chip->lock)); in qpnp_tm_update_critical_trip_temp()
332 threshold = THRESH_MAX - in qpnp_tm_update_critical_trip_temp()
333 ((stage2_threshold_max - temp) / in qpnp_tm_update_critical_trip_temp()
339 if (chip->adc) in qpnp_tm_update_critical_trip_temp()
342 dev_warn(chip->dev, in qpnp_tm_update_critical_trip_temp()
348 memcpy(chip->temp_thresh_map, chip->data->temp_map[threshold], in qpnp_tm_update_critical_trip_temp()
349 sizeof(chip->temp_thresh_map)); in qpnp_tm_update_critical_trip_temp()
351 if (disable_stage2_shutdown && !chip->require_stage2_shutdown) in qpnp_tm_update_critical_trip_temp()
354 return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg); in qpnp_tm_update_critical_trip_temp()
360 struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz); in qpnp_tm_set_trip_temp() local
363 if (trip->type != THERMAL_TRIP_CRITICAL) in qpnp_tm_set_trip_temp()
366 mutex_lock(&chip->lock); in qpnp_tm_set_trip_temp()
367 ret = qpnp_tm_update_critical_trip_temp(chip, temp); in qpnp_tm_set_trip_temp()
368 mutex_unlock(&chip->lock); in qpnp_tm_set_trip_temp()
378 static int qpnp_tm_gen2_rev2_set_temp_thresh(struct qpnp_tm_chip *chip, unsigned int trip, int temp) in qpnp_tm_gen2_rev2_set_temp_thresh() argument
383 WARN_ON(!mutex_is_locked(&chip->lock)); in qpnp_tm_gen2_rev2_set_temp_thresh()
386 dev_err(chip->dev, "invalid TEMP_DAC trip = %d\n", trip); in qpnp_tm_gen2_rev2_set_temp_thresh()
387 return -EINVAL; in qpnp_tm_gen2_rev2_set_temp_thresh()
389 dev_err(chip->dev, "invalid TEMP_DAC temp = %d\n", temp); in qpnp_tm_gen2_rev2_set_temp_thresh()
390 return -EINVAL; in qpnp_tm_gen2_rev2_set_temp_thresh()
396 ret = qpnp_tm_write(chip, QPNP_TM_REG_TEMP_DAC_STG1 + trip, reg); in qpnp_tm_gen2_rev2_set_temp_thresh()
398 dev_err(chip->dev, "TEMP_DAC_STG write failed, ret=%d\n", ret); in qpnp_tm_gen2_rev2_set_temp_thresh()
402 chip->temp_thresh_map[trip] = temp_cfg; in qpnp_tm_gen2_rev2_set_temp_thresh()
410 unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT(trip->priv); in qpnp_tm_gen2_rev2_set_trip_temp()
411 struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz); in qpnp_tm_gen2_rev2_set_trip_temp() local
414 mutex_lock(&chip->lock); in qpnp_tm_gen2_rev2_set_trip_temp()
415 ret = qpnp_tm_gen2_rev2_set_temp_thresh(chip, trip_index, temp); in qpnp_tm_gen2_rev2_set_trip_temp()
416 mutex_unlock(&chip->lock); in qpnp_tm_gen2_rev2_set_trip_temp()
426 static int qpnp_tm_lite_set_temp_thresh(struct qpnp_tm_chip *chip, unsigned int trip, int temp) in qpnp_tm_lite_set_temp_thresh() argument
433 WARN_ON(!mutex_is_locked(&chip->lock)); in qpnp_tm_lite_set_temp_thresh()
436 dev_err(chip->dev, "invalid TEMP_LITE trip = %d\n", trip); in qpnp_tm_lite_set_temp_thresh()
437 return -EINVAL; in qpnp_tm_lite_set_temp_thresh()
447 * The second trip point is purely in software to facilitate in qpnp_tm_lite_set_temp_thresh()
462 dev_err(chip->dev, "invalid TEMP_LITE temp = %d\n", temp); in qpnp_tm_lite_set_temp_thresh()
463 return -EINVAL; in qpnp_tm_lite_set_temp_thresh()
468 for (i = THRESH_MAX; i >= THRESH_MIN; i--) { in qpnp_tm_lite_set_temp_thresh()
476 if (temp_cfg == chip->temp_thresh_map[trip]) in qpnp_tm_lite_set_temp_thresh()
479 ret = qpnp_tm_read(chip, addr, &reg); in qpnp_tm_lite_set_temp_thresh()
481 dev_err(chip->dev, "LITE_TEMP_CFG read failed, ret=%d\n", ret); in qpnp_tm_lite_set_temp_thresh()
488 ret = qpnp_tm_write(chip, addr, reg); in qpnp_tm_lite_set_temp_thresh()
490 dev_err(chip->dev, "LITE_TEMP_CFG write failed, ret=%d\n", ret); in qpnp_tm_lite_set_temp_thresh()
494 chip->temp_thresh_map[trip] = temp_cfg; in qpnp_tm_lite_set_temp_thresh()
502 unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT(trip->priv); in qpnp_tm_lite_set_trip_temp()
503 struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz); in qpnp_tm_lite_set_trip_temp() local
506 mutex_lock(&chip->lock); in qpnp_tm_lite_set_trip_temp()
507 ret = qpnp_tm_lite_set_temp_thresh(chip, trip_index, temp); in qpnp_tm_lite_set_trip_temp()
508 mutex_unlock(&chip->lock); in qpnp_tm_lite_set_trip_temp()
520 struct qpnp_tm_chip *chip = data; in qpnp_tm_isr() local
522 thermal_zone_device_update(chip->tz_dev, THERMAL_EVENT_UNSPECIFIED); in qpnp_tm_isr()
528 static int qpnp_tm_sync_thresholds(struct qpnp_tm_chip *chip) in qpnp_tm_sync_thresholds() argument
533 ret = qpnp_tm_read(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, &reg); in qpnp_tm_sync_thresholds()
538 memcpy(chip->temp_thresh_map, chip->data->temp_map[threshold], in qpnp_tm_sync_thresholds()
539 sizeof(chip->temp_thresh_map)); in qpnp_tm_sync_thresholds()
544 static int qpnp_tm_configure_trip_temp(struct qpnp_tm_chip *chip) in qpnp_tm_configure_trip_temp() argument
548 ret = thermal_zone_get_crit_temp(chip->tz_dev, &crit_temp); in qpnp_tm_configure_trip_temp()
552 mutex_lock(&chip->lock); in qpnp_tm_configure_trip_temp()
553 ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); in qpnp_tm_configure_trip_temp()
554 mutex_unlock(&chip->lock); in qpnp_tm_configure_trip_temp()
562 struct qpnp_tm_chip *chip = data; in qpnp_tm_gen2_rev2_configure_trip_temps_cb() local
565 mutex_lock(&chip->lock); in qpnp_tm_gen2_rev2_configure_trip_temps_cb()
566 trip->priv = THERMAL_INT_TO_TRIP_PRIV(chip->ntrips); in qpnp_tm_gen2_rev2_configure_trip_temps_cb()
567 ret = qpnp_tm_gen2_rev2_set_temp_thresh(chip, chip->ntrips, trip->temperature); in qpnp_tm_gen2_rev2_configure_trip_temps_cb()
568 chip->ntrips++; in qpnp_tm_gen2_rev2_configure_trip_temps_cb()
569 mutex_unlock(&chip->lock); in qpnp_tm_gen2_rev2_configure_trip_temps_cb()
574 static int qpnp_tm_gen2_rev2_configure_trip_temps(struct qpnp_tm_chip *chip) in qpnp_tm_gen2_rev2_configure_trip_temps() argument
578 ret = thermal_zone_for_each_trip(chip->tz_dev, in qpnp_tm_gen2_rev2_configure_trip_temps()
579 qpnp_tm_gen2_rev2_configure_trip_temps_cb, chip); in qpnp_tm_gen2_rev2_configure_trip_temps()
585 if (chip->temp_thresh_map[i] <= chip->temp_thresh_map[i - 1]) { in qpnp_tm_gen2_rev2_configure_trip_temps()
586 dev_err(chip->dev, "Threshold %d=%ld <= threshold %d=%ld\n", in qpnp_tm_gen2_rev2_configure_trip_temps()
587 i, chip->temp_thresh_map[i], i - 1, in qpnp_tm_gen2_rev2_configure_trip_temps()
588 chip->temp_thresh_map[i - 1]); in qpnp_tm_gen2_rev2_configure_trip_temps()
589 return -EINVAL; in qpnp_tm_gen2_rev2_configure_trip_temps()
597 static int qpnp_tm_gen2_rev2_sync_thresholds(struct qpnp_tm_chip *chip) in qpnp_tm_gen2_rev2_sync_thresholds() argument
603 ret = qpnp_tm_read(chip, QPNP_TM_REG_TEMP_DAC_STG1 + i, &reg); in qpnp_tm_gen2_rev2_sync_thresholds()
607 chip->temp_thresh_map[i] = TEMP_DAC_REG_TO_TEMP(reg); in qpnp_tm_gen2_rev2_sync_thresholds()
616 struct qpnp_tm_chip *chip = data; in qpnp_tm_lite_configure_trip_temps_cb() local
619 mutex_lock(&chip->lock); in qpnp_tm_lite_configure_trip_temps_cb()
620 trip->priv = THERMAL_INT_TO_TRIP_PRIV(chip->ntrips); in qpnp_tm_lite_configure_trip_temps_cb()
621 ret = qpnp_tm_lite_set_temp_thresh(chip, chip->ntrips, trip->temperature); in qpnp_tm_lite_configure_trip_temps_cb()
622 chip->ntrips++; in qpnp_tm_lite_configure_trip_temps_cb()
623 mutex_unlock(&chip->lock); in qpnp_tm_lite_configure_trip_temps_cb()
628 static int qpnp_tm_lite_configure_trip_temps(struct qpnp_tm_chip *chip) in qpnp_tm_lite_configure_trip_temps() argument
632 ret = thermal_zone_for_each_trip(chip->tz_dev, qpnp_tm_lite_configure_trip_temps_cb, chip); in qpnp_tm_lite_configure_trip_temps()
637 if (chip->temp_thresh_map[2] <= chip->temp_thresh_map[0]) { in qpnp_tm_lite_configure_trip_temps()
638 dev_err(chip->dev, "Threshold 2=%ld <= threshold 0=%ld\n", in qpnp_tm_lite_configure_trip_temps()
639 chip->temp_thresh_map[2], chip->temp_thresh_map[0]); in qpnp_tm_lite_configure_trip_temps()
640 return -EINVAL; in qpnp_tm_lite_configure_trip_temps()
647 static int qpnp_tm_lite_sync_thresholds(struct qpnp_tm_chip *chip) in qpnp_tm_lite_sync_thresholds() argument
655 * to facilitate a controlled shutdown after the warning threshold is in qpnp_tm_lite_sync_thresholds()
657 * crossed. Thus, there is no register to read for the second trip in qpnp_tm_lite_sync_thresholds()
660 ret = qpnp_tm_read(chip, QPNP_TM_REG_LITE_TEMP_CFG1, &reg); in qpnp_tm_lite_sync_thresholds()
665 chip->temp_thresh_map[0] = temp_lite_warning_map[thresh]; in qpnp_tm_lite_sync_thresholds()
667 ret = qpnp_tm_read(chip, QPNP_TM_REG_LITE_TEMP_CFG2, &reg); in qpnp_tm_lite_sync_thresholds()
672 chip->temp_thresh_map[2] = temp_lite_shutdown_map[thresh]; in qpnp_tm_lite_sync_thresholds()
719 static int qpnp_tm_threshold_init(struct qpnp_tm_chip *chip) in qpnp_tm_threshold_init() argument
723 ret = chip->data->sync_thresholds(chip); in qpnp_tm_threshold_init()
727 ret = chip->data->get_temp_stage(chip); in qpnp_tm_threshold_init()
730 chip->stage = ret; in qpnp_tm_threshold_init()
731 chip->temp = DEFAULT_TEMP; in qpnp_tm_threshold_init()
733 if (chip->stage) in qpnp_tm_threshold_init()
734 chip->temp = qpnp_tm_decode_temp(chip, chip->stage); in qpnp_tm_threshold_init()
740 static int qpnp_tm_init(struct qpnp_tm_chip *chip) in qpnp_tm_init() argument
745 ret = chip->data->configure_trip_temps(chip); in qpnp_tm_init()
749 /* Enable the thermal alarm PMIC module in always-on mode. */ in qpnp_tm_init()
751 ret = qpnp_tm_write(chip, QPNP_TM_REG_ALARM_CTRL, reg); in qpnp_tm_init()
753 chip->initialized = true; in qpnp_tm_init()
760 struct qpnp_tm_chip *chip; in qpnp_tm_probe() local
766 node = pdev->dev.of_node; in qpnp_tm_probe()
768 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); in qpnp_tm_probe()
769 if (!chip) in qpnp_tm_probe()
770 return -ENOMEM; in qpnp_tm_probe()
772 chip->dev = &pdev->dev; in qpnp_tm_probe()
774 mutex_init(&chip->lock); in qpnp_tm_probe()
776 chip->map = dev_get_regmap(pdev->dev.parent, NULL); in qpnp_tm_probe()
777 if (!chip->map) in qpnp_tm_probe()
778 return -ENXIO; in qpnp_tm_probe()
789 chip->adc = devm_iio_channel_get(&pdev->dev, "thermal"); in qpnp_tm_probe()
790 if (IS_ERR(chip->adc)) { in qpnp_tm_probe()
791 ret = PTR_ERR(chip->adc); in qpnp_tm_probe()
792 chip->adc = NULL; in qpnp_tm_probe()
793 if (ret == -EPROBE_DEFER) in qpnp_tm_probe()
797 chip->base = res; in qpnp_tm_probe()
799 ret = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, &type); in qpnp_tm_probe()
801 return dev_err_probe(&pdev->dev, ret, in qpnp_tm_probe()
804 ret = qpnp_tm_read(chip, QPNP_TM_REG_SUBTYPE, &subtype); in qpnp_tm_probe()
806 return dev_err_probe(&pdev->dev, ret, in qpnp_tm_probe()
809 ret = qpnp_tm_read(chip, QPNP_TM_REG_DIG_MAJOR, &dig_major); in qpnp_tm_probe()
811 return dev_err_probe(&pdev->dev, ret, in qpnp_tm_probe()
814 ret = qpnp_tm_read(chip, QPNP_TM_REG_DIG_MINOR, &dig_minor); in qpnp_tm_probe()
816 return dev_err_probe(&pdev->dev, ret, in qpnp_tm_probe()
822 dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", in qpnp_tm_probe()
824 return -ENODEV; in qpnp_tm_probe()
827 chip->subtype = subtype; in qpnp_tm_probe()
829 chip->data = &spmi_temp_alarm_data; in qpnp_tm_probe()
831 chip->data = &spmi_temp_alarm_gen2_data; in qpnp_tm_probe()
833 chip->data = &spmi_temp_alarm_gen2_rev1_data; in qpnp_tm_probe()
835 chip->data = &spmi_temp_alarm_gen2_rev2_data; in qpnp_tm_probe()
837 chip->data = &spmi_temp_alarm_lite_data; in qpnp_tm_probe()
839 return -ENODEV; in qpnp_tm_probe()
841 if (chip->subtype == QPNP_TM_SUBTYPE_GEN2) { in qpnp_tm_probe()
845 * enabled to avoid potential repeated faults upon reaching in qpnp_tm_probe()
846 * over-temperature stage 3. in qpnp_tm_probe()
853 chip->require_stage2_shutdown = true; in qpnp_tm_probe()
858 ret = qpnp_tm_threshold_init(chip); in qpnp_tm_probe()
860 return dev_err_probe(&pdev->dev, ret, "threshold init failed\n"); in qpnp_tm_probe()
863 * Register the sensor before initializing the hardware to be able to in qpnp_tm_probe()
867 chip->tz_dev = devm_thermal_of_zone_register( in qpnp_tm_probe()
868 &pdev->dev, 0, chip, chip->data->ops); in qpnp_tm_probe()
869 if (IS_ERR(chip->tz_dev)) in qpnp_tm_probe()
870 return dev_err_probe(&pdev->dev, PTR_ERR(chip->tz_dev), in qpnp_tm_probe()
871 "failed to register sensor\n"); in qpnp_tm_probe()
873 ret = qpnp_tm_init(chip); in qpnp_tm_probe()
875 return dev_err_probe(&pdev->dev, ret, "init failed\n"); in qpnp_tm_probe()
877 devm_thermal_add_hwmon_sysfs(&pdev->dev, chip->tz_dev); in qpnp_tm_probe()
879 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, qpnp_tm_isr, in qpnp_tm_probe()
880 IRQF_ONESHOT, node->name, chip); in qpnp_tm_probe()
884 thermal_zone_device_update(chip->tz_dev, THERMAL_EVENT_UNSPECIFIED); in qpnp_tm_probe()
890 { .compatible = "qcom,spmi-temp-alarm" },
897 .name = "spmi-temp-alarm",
904 MODULE_ALIAS("platform:spmi-temp-alarm");