Loading drivers/thermal/qcom/qcom-spmi-temp-alarm.c +61 −30 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "../thermal_core.h" #define QPNP_TM_REG_DIG_MAJOR 0x01 #define QPNP_TM_REG_TYPE 0x04 #define QPNP_TM_REG_SUBTYPE 0x05 #define QPNP_TM_REG_STATUS 0x08 Loading @@ -38,26 +39,30 @@ #define ALARM_CTRL_FORCE_ENABLE BIT(7) /* * Trip point values based on threshold control * 0 = {105 C, 125 C, 145 C} * 1 = {110 C, 130 C, 150 C} * 2 = {115 C, 135 C, 155 C} * 3 = {120 C, 140 C, 160 C} */ #define TEMP_STAGE_STEP 20000 /* Stage step: 20.000 C */ #define TEMP_STAGE_HYSTERESIS 2000 #define THRESH_COUNT 4 #define STAGE_COUNT 3 /* Over-temperature trip point values in mC */ static const long temp_map_gen1[THRESH_COUNT][STAGE_COUNT] = { {105000, 125000, 145000}, {110000, 130000, 150000}, {115000, 135000, 155000}, {120000, 140000, 160000}, }; static const long temp_map_gen2_v1[THRESH_COUNT][STAGE_COUNT] = { { 90000, 110000, 140000}, { 95000, 115000, 145000}, {100000, 120000, 150000}, {105000, 125000, 155000}, }; #define TEMP_THRESH_MIN 105000 /* Threshold Min: 105 C */ #define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */ #define THRESH_MIN 0 #define THRESH_MAX 3 /* Stage 2 Threshold Min: 125 C */ #define STAGE2_THRESHOLD_MIN 125000 /* Stage 2 Threshold Max: 140 C */ #define STAGE2_THRESHOLD_MAX 140000 #define TEMP_STAGE_HYSTERESIS 2000 /* Temperature in Milli Celsius reported during stage 0 if no ADC is present */ #define DEFAULT_TEMP 37000 Loading @@ -77,6 +82,7 @@ struct qpnp_tm_chip { bool initialized; struct iio_channel *adc; const long (*temp_map)[THRESH_COUNT][STAGE_COUNT]; }; /* This array maps from GEN2 alarm state to GEN1 alarm stage */ Loading @@ -100,6 +106,23 @@ static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data) return regmap_write(chip->map, chip->base + addr, data); } /** * qpnp_tm_decode_temp() - return temperature in mC corresponding to the * specified over-temperature stage * @chip: Pointer to the qpnp_tm chip * @stage: Over-temperature stage * * Return: temperature in mC */ static long qpnp_tm_decode_temp(struct qpnp_tm_chip *chip, unsigned int stage) { if (!chip->temp_map || chip->thresh >= THRESH_COUNT || stage == 0 || stage > STAGE_COUNT) return 0; return (*chip->temp_map)[chip->thresh][stage - 1]; } /** * qpnp_tm_get_temp_stage() - return over-temperature stage * @chip: Pointer to the qpnp_tm chip Loading Loading @@ -149,14 +172,12 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip) if (stage_new > stage_old) { /* increasing stage, use lower bound */ chip->temp = (stage_new - 1) * TEMP_STAGE_STEP + chip->thresh * TEMP_THRESH_STEP + TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; chip->temp = qpnp_tm_decode_temp(chip, stage_new) + TEMP_STAGE_HYSTERESIS; } else if (stage_new < stage_old) { /* decreasing stage, use upper bound */ chip->temp = stage_new * TEMP_STAGE_STEP + chip->thresh * TEMP_THRESH_STEP - TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; chip->temp = qpnp_tm_decode_temp(chip, stage_new + 1) - TEMP_STAGE_HYSTERESIS; } chip->stage = stage; Loading Loading @@ -199,26 +220,28 @@ static int qpnp_tm_get_temp(void *data, int *temp) static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip, int temp) { u8 reg; long stage2_threshold_min = (*chip->temp_map)[THRESH_MIN][1]; long stage2_threshold_max = (*chip->temp_map)[THRESH_MAX][1]; bool disable_s2_shutdown = false; u8 reg; WARN_ON(!mutex_is_locked(&chip->lock)); /* * Default: S2 and S3 shutdown enabled, thresholds at * 105C/125C/145C, monitoring at 25Hz * lowest threshold set, monitoring at 25Hz */ reg = SHUTDOWN_CTRL1_RATE_25HZ; if (temp == THERMAL_TEMP_INVALID || temp < STAGE2_THRESHOLD_MIN) { temp < stage2_threshold_min) { chip->thresh = THRESH_MIN; goto skip; } if (temp <= STAGE2_THRESHOLD_MAX) { if (temp <= stage2_threshold_max) { chip->thresh = THRESH_MAX - ((STAGE2_THRESHOLD_MAX - temp) / ((stage2_threshold_max - temp) / TEMP_THRESH_STEP); disable_s2_shutdown = true; } else { Loading Loading @@ -326,9 +349,7 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) ? chip->stage : alarm_state_map[chip->stage]; if (stage) chip->temp = chip->thresh * TEMP_THRESH_STEP + (stage - 1) * TEMP_STAGE_STEP + TEMP_THRESH_MIN; chip->temp = qpnp_tm_decode_temp(chip, stage); crit_temp = qpnp_tm_get_critical_trip_temp(chip); ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); Loading @@ -350,7 +371,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) { struct qpnp_tm_chip *chip; struct device_node *node; u8 type, subtype; u8 type, subtype, dig_major; u32 res; int ret, irq; Loading Loading @@ -400,6 +421,12 @@ static int qpnp_tm_probe(struct platform_device *pdev) return ret; } ret = qpnp_tm_read(chip, QPNP_TM_REG_DIG_MAJOR, &dig_major); if (ret < 0) { dev_err(&pdev->dev, "could not read dig_major\n"); return ret; } if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1 && subtype != QPNP_TM_SUBTYPE_GEN2)) { dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", Loading @@ -408,6 +435,10 @@ static int qpnp_tm_probe(struct platform_device *pdev) } chip->subtype = subtype; if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major >= 1) chip->temp_map = &temp_map_gen2_v1; else chip->temp_map = &temp_map_gen1; /* * Register the sensor before initializing the hardware to be able to Loading Loading
drivers/thermal/qcom/qcom-spmi-temp-alarm.c +61 −30 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "../thermal_core.h" #define QPNP_TM_REG_DIG_MAJOR 0x01 #define QPNP_TM_REG_TYPE 0x04 #define QPNP_TM_REG_SUBTYPE 0x05 #define QPNP_TM_REG_STATUS 0x08 Loading @@ -38,26 +39,30 @@ #define ALARM_CTRL_FORCE_ENABLE BIT(7) /* * Trip point values based on threshold control * 0 = {105 C, 125 C, 145 C} * 1 = {110 C, 130 C, 150 C} * 2 = {115 C, 135 C, 155 C} * 3 = {120 C, 140 C, 160 C} */ #define TEMP_STAGE_STEP 20000 /* Stage step: 20.000 C */ #define TEMP_STAGE_HYSTERESIS 2000 #define THRESH_COUNT 4 #define STAGE_COUNT 3 /* Over-temperature trip point values in mC */ static const long temp_map_gen1[THRESH_COUNT][STAGE_COUNT] = { {105000, 125000, 145000}, {110000, 130000, 150000}, {115000, 135000, 155000}, {120000, 140000, 160000}, }; static const long temp_map_gen2_v1[THRESH_COUNT][STAGE_COUNT] = { { 90000, 110000, 140000}, { 95000, 115000, 145000}, {100000, 120000, 150000}, {105000, 125000, 155000}, }; #define TEMP_THRESH_MIN 105000 /* Threshold Min: 105 C */ #define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */ #define THRESH_MIN 0 #define THRESH_MAX 3 /* Stage 2 Threshold Min: 125 C */ #define STAGE2_THRESHOLD_MIN 125000 /* Stage 2 Threshold Max: 140 C */ #define STAGE2_THRESHOLD_MAX 140000 #define TEMP_STAGE_HYSTERESIS 2000 /* Temperature in Milli Celsius reported during stage 0 if no ADC is present */ #define DEFAULT_TEMP 37000 Loading @@ -77,6 +82,7 @@ struct qpnp_tm_chip { bool initialized; struct iio_channel *adc; const long (*temp_map)[THRESH_COUNT][STAGE_COUNT]; }; /* This array maps from GEN2 alarm state to GEN1 alarm stage */ Loading @@ -100,6 +106,23 @@ static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data) return regmap_write(chip->map, chip->base + addr, data); } /** * qpnp_tm_decode_temp() - return temperature in mC corresponding to the * specified over-temperature stage * @chip: Pointer to the qpnp_tm chip * @stage: Over-temperature stage * * Return: temperature in mC */ static long qpnp_tm_decode_temp(struct qpnp_tm_chip *chip, unsigned int stage) { if (!chip->temp_map || chip->thresh >= THRESH_COUNT || stage == 0 || stage > STAGE_COUNT) return 0; return (*chip->temp_map)[chip->thresh][stage - 1]; } /** * qpnp_tm_get_temp_stage() - return over-temperature stage * @chip: Pointer to the qpnp_tm chip Loading Loading @@ -149,14 +172,12 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip) if (stage_new > stage_old) { /* increasing stage, use lower bound */ chip->temp = (stage_new - 1) * TEMP_STAGE_STEP + chip->thresh * TEMP_THRESH_STEP + TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; chip->temp = qpnp_tm_decode_temp(chip, stage_new) + TEMP_STAGE_HYSTERESIS; } else if (stage_new < stage_old) { /* decreasing stage, use upper bound */ chip->temp = stage_new * TEMP_STAGE_STEP + chip->thresh * TEMP_THRESH_STEP - TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; chip->temp = qpnp_tm_decode_temp(chip, stage_new + 1) - TEMP_STAGE_HYSTERESIS; } chip->stage = stage; Loading Loading @@ -199,26 +220,28 @@ static int qpnp_tm_get_temp(void *data, int *temp) static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip, int temp) { u8 reg; long stage2_threshold_min = (*chip->temp_map)[THRESH_MIN][1]; long stage2_threshold_max = (*chip->temp_map)[THRESH_MAX][1]; bool disable_s2_shutdown = false; u8 reg; WARN_ON(!mutex_is_locked(&chip->lock)); /* * Default: S2 and S3 shutdown enabled, thresholds at * 105C/125C/145C, monitoring at 25Hz * lowest threshold set, monitoring at 25Hz */ reg = SHUTDOWN_CTRL1_RATE_25HZ; if (temp == THERMAL_TEMP_INVALID || temp < STAGE2_THRESHOLD_MIN) { temp < stage2_threshold_min) { chip->thresh = THRESH_MIN; goto skip; } if (temp <= STAGE2_THRESHOLD_MAX) { if (temp <= stage2_threshold_max) { chip->thresh = THRESH_MAX - ((STAGE2_THRESHOLD_MAX - temp) / ((stage2_threshold_max - temp) / TEMP_THRESH_STEP); disable_s2_shutdown = true; } else { Loading Loading @@ -326,9 +349,7 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) ? chip->stage : alarm_state_map[chip->stage]; if (stage) chip->temp = chip->thresh * TEMP_THRESH_STEP + (stage - 1) * TEMP_STAGE_STEP + TEMP_THRESH_MIN; chip->temp = qpnp_tm_decode_temp(chip, stage); crit_temp = qpnp_tm_get_critical_trip_temp(chip); ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); Loading @@ -350,7 +371,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) { struct qpnp_tm_chip *chip; struct device_node *node; u8 type, subtype; u8 type, subtype, dig_major; u32 res; int ret, irq; Loading Loading @@ -400,6 +421,12 @@ static int qpnp_tm_probe(struct platform_device *pdev) return ret; } ret = qpnp_tm_read(chip, QPNP_TM_REG_DIG_MAJOR, &dig_major); if (ret < 0) { dev_err(&pdev->dev, "could not read dig_major\n"); return ret; } if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1 && subtype != QPNP_TM_SUBTYPE_GEN2)) { dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", Loading @@ -408,6 +435,10 @@ static int qpnp_tm_probe(struct platform_device *pdev) } chip->subtype = subtype; if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major >= 1) chip->temp_map = &temp_map_gen2_v1; else chip->temp_map = &temp_map_gen1; /* * Register the sensor before initializing the hardware to be able to Loading