Commit aa92b331 authored by David Collins's avatar David Collins Committed by Daniel Lezcano

thermal/drivers/qcom-spmi-temp-alarm: Add support for GEN2 rev 1 PMIC peripherals

Add support for TEMP_ALARM GEN2 PMIC peripherals with digital
major revision 1.  This revision utilizes a different temperature
threshold mapping than earlier revisions.
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
Signed-off-by: default avatarGuru Das Srinagesh <gurus@codeaurora.org>
Reviewed-by: default avatarStephen Boyd <sboyd@kernel.org>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/69c90a004b3f5b7ae282f5ec5ca2920a48f23e02.1596040416.git.gurus@codeaurora.org
parent 34ab17cc
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "../thermal_core.h" #include "../thermal_core.h"
#define QPNP_TM_REG_DIG_MAJOR 0x01
#define QPNP_TM_REG_TYPE 0x04 #define QPNP_TM_REG_TYPE 0x04
#define QPNP_TM_REG_SUBTYPE 0x05 #define QPNP_TM_REG_SUBTYPE 0x05
#define QPNP_TM_REG_STATUS 0x08 #define QPNP_TM_REG_STATUS 0x08
...@@ -38,26 +39,30 @@ ...@@ -38,26 +39,30 @@
#define ALARM_CTRL_FORCE_ENABLE BIT(7) #define ALARM_CTRL_FORCE_ENABLE BIT(7)
/* #define THRESH_COUNT 4
* Trip point values based on threshold control #define STAGE_COUNT 3
* 0 = {105 C, 125 C, 145 C}
* 1 = {110 C, 130 C, 150 C} /* Over-temperature trip point values in mC */
* 2 = {115 C, 135 C, 155 C} static const long temp_map_gen1[THRESH_COUNT][STAGE_COUNT] = {
* 3 = {120 C, 140 C, 160 C} { 105000, 125000, 145000 },
*/ { 110000, 130000, 150000 },
#define TEMP_STAGE_STEP 20000 /* Stage step: 20.000 C */ { 115000, 135000, 155000 },
#define TEMP_STAGE_HYSTERESIS 2000 { 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 TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */
#define THRESH_MIN 0 #define THRESH_MIN 0
#define THRESH_MAX 3 #define THRESH_MAX 3
/* Stage 2 Threshold Min: 125 C */ #define TEMP_STAGE_HYSTERESIS 2000
#define STAGE2_THRESHOLD_MIN 125000
/* Stage 2 Threshold Max: 140 C */
#define STAGE2_THRESHOLD_MAX 140000
/* Temperature in Milli Celsius reported during stage 0 if no ADC is present */ /* Temperature in Milli Celsius reported during stage 0 if no ADC is present */
#define DEFAULT_TEMP 37000 #define DEFAULT_TEMP 37000
...@@ -77,6 +82,7 @@ struct qpnp_tm_chip { ...@@ -77,6 +82,7 @@ struct qpnp_tm_chip {
bool initialized; bool initialized;
struct iio_channel *adc; struct iio_channel *adc;
const long (*temp_map)[THRESH_COUNT][STAGE_COUNT];
}; };
/* This array maps from GEN2 alarm state to GEN1 alarm stage */ /* This array maps from GEN2 alarm state to GEN1 alarm stage */
...@@ -100,6 +106,23 @@ static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data) ...@@ -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); 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 * qpnp_tm_get_temp_stage() - return over-temperature stage
* @chip: Pointer to the qpnp_tm chip * @chip: Pointer to the qpnp_tm chip
...@@ -149,14 +172,12 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip) ...@@ -149,14 +172,12 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip)
if (stage_new > stage_old) { if (stage_new > stage_old) {
/* increasing stage, use lower bound */ /* increasing stage, use lower bound */
chip->temp = (stage_new - 1) * TEMP_STAGE_STEP + chip->temp = qpnp_tm_decode_temp(chip, stage_new)
chip->thresh * TEMP_THRESH_STEP + + TEMP_STAGE_HYSTERESIS;
TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
} else if (stage_new < stage_old) { } else if (stage_new < stage_old) {
/* decreasing stage, use upper bound */ /* decreasing stage, use upper bound */
chip->temp = stage_new * TEMP_STAGE_STEP + chip->temp = qpnp_tm_decode_temp(chip, stage_new + 1)
chip->thresh * TEMP_THRESH_STEP - - TEMP_STAGE_HYSTERESIS;
TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
} }
chip->stage = stage; chip->stage = stage;
...@@ -199,26 +220,28 @@ static int qpnp_tm_get_temp(void *data, int *temp) ...@@ -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, static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
int temp) 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; bool disable_s2_shutdown = false;
u8 reg;
WARN_ON(!mutex_is_locked(&chip->lock)); WARN_ON(!mutex_is_locked(&chip->lock));
/* /*
* Default: S2 and S3 shutdown enabled, thresholds at * 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; reg = SHUTDOWN_CTRL1_RATE_25HZ;
if (temp == THERMAL_TEMP_INVALID || if (temp == THERMAL_TEMP_INVALID ||
temp < STAGE2_THRESHOLD_MIN) { temp < stage2_threshold_min) {
chip->thresh = THRESH_MIN; chip->thresh = THRESH_MIN;
goto skip; goto skip;
} }
if (temp <= STAGE2_THRESHOLD_MAX) { if (temp <= stage2_threshold_max) {
chip->thresh = THRESH_MAX - chip->thresh = THRESH_MAX -
((STAGE2_THRESHOLD_MAX - temp) / ((stage2_threshold_max - temp) /
TEMP_THRESH_STEP); TEMP_THRESH_STEP);
disable_s2_shutdown = true; disable_s2_shutdown = true;
} else { } else {
...@@ -326,9 +349,7 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) ...@@ -326,9 +349,7 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip)
? chip->stage : alarm_state_map[chip->stage]; ? chip->stage : alarm_state_map[chip->stage];
if (stage) if (stage)
chip->temp = chip->thresh * TEMP_THRESH_STEP + chip->temp = qpnp_tm_decode_temp(chip, stage);
(stage - 1) * TEMP_STAGE_STEP +
TEMP_THRESH_MIN;
crit_temp = qpnp_tm_get_critical_trip_temp(chip); crit_temp = qpnp_tm_get_critical_trip_temp(chip);
ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp);
...@@ -350,7 +371,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) ...@@ -350,7 +371,7 @@ static int qpnp_tm_probe(struct platform_device *pdev)
{ {
struct qpnp_tm_chip *chip; struct qpnp_tm_chip *chip;
struct device_node *node; struct device_node *node;
u8 type, subtype; u8 type, subtype, dig_major;
u32 res; u32 res;
int ret, irq; int ret, irq;
...@@ -400,6 +421,12 @@ static int qpnp_tm_probe(struct platform_device *pdev) ...@@ -400,6 +421,12 @@ static int qpnp_tm_probe(struct platform_device *pdev)
return ret; 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 if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1
&& subtype != QPNP_TM_SUBTYPE_GEN2)) { && subtype != QPNP_TM_SUBTYPE_GEN2)) {
dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n",
...@@ -408,6 +435,10 @@ static int qpnp_tm_probe(struct platform_device *pdev) ...@@ -408,6 +435,10 @@ static int qpnp_tm_probe(struct platform_device *pdev)
} }
chip->subtype = subtype; 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 * Register the sensor before initializing the hardware to be able to
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment