44 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
55 */
66
7+ #include <linux/bitfield.h>
78#include <linux/bitops.h>
89#include <linux/delay.h>
910#include <linux/err.h>
3132
3233#define STATUS_GEN1_STAGE_MASK GENMASK(1, 0)
3334#define STATUS_GEN2_STATE_MASK GENMASK(6, 4)
34- #define STATUS_GEN2_STATE_SHIFT 4
3535
3636#define SHUTDOWN_CTRL1_OVERRIDE_STAGE2 BIT(6)
3737#define SHUTDOWN_CTRL1_THRESHOLD_MASK GENMASK(1, 0)
4343#define THRESH_COUNT 4
4444#define STAGE_COUNT 3
4545
46+ enum overtemp_stage {
47+ STAGE1 = 0 ,
48+ STAGE2 ,
49+ STAGE3 ,
50+ };
51+
4652/* Over-temperature trip point values in mC */
4753static const long temp_map_gen1 [THRESH_COUNT ][STAGE_COUNT ] = {
4854 { 105000 , 125000 , 145000 },
@@ -68,22 +74,29 @@ static const long temp_map_gen2_v1[THRESH_COUNT][STAGE_COUNT] = {
6874/* Temperature in Milli Celsius reported during stage 0 if no ADC is present */
6975#define DEFAULT_TEMP 37000
7076
77+ struct qpnp_tm_chip ;
78+
79+ struct spmi_temp_alarm_data {
80+ const long (* temp_map )[THRESH_COUNT ][STAGE_COUNT ];
81+ int (* get_temp_stage )(struct qpnp_tm_chip * chip );
82+ };
83+
7184struct qpnp_tm_chip {
7285 struct regmap * map ;
7386 struct device * dev ;
7487 struct thermal_zone_device * tz_dev ;
88+ const struct spmi_temp_alarm_data * data ;
7589 unsigned int subtype ;
7690 long temp ;
77- unsigned int thresh ;
7891 unsigned int stage ;
7992 unsigned int base ;
8093 /* protects .thresh, .stage and chip registers */
8194 struct mutex lock ;
8295 bool initialized ;
8396 bool require_stage2_shutdown ;
97+ long temp_thresh_map [STAGE_COUNT ];
8498
8599 struct iio_channel * adc ;
86- const long (* temp_map )[THRESH_COUNT ][STAGE_COUNT ];
87100};
88101
89102/* This array maps from GEN2 alarm state to GEN1 alarm stage */
@@ -117,34 +130,48 @@ static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data)
117130 */
118131static long qpnp_tm_decode_temp (struct qpnp_tm_chip * chip , unsigned int stage )
119132{
120- if (!chip -> temp_map || chip -> thresh >= THRESH_COUNT || stage == 0 ||
121- stage > STAGE_COUNT )
133+ if (stage == 0 || stage > STAGE_COUNT )
122134 return 0 ;
123135
124- return ( * chip -> temp_map )[ chip -> thresh ] [stage - 1 ];
136+ return chip -> temp_thresh_map [stage - 1 ];
125137}
126138
127139/**
128- * qpnp_tm_get_temp_stage () - return over-temperature stage
140+ * qpnp_tm_gen1_get_temp_stage () - return over-temperature stage
129141 * @chip: Pointer to the qpnp_tm chip
130142 *
131- * Return: stage (GEN1) or state (GEN2) on success, or errno on failure.
143+ * Return: stage on success, or errno on failure.
132144 */
133- static int qpnp_tm_get_temp_stage (struct qpnp_tm_chip * chip )
145+ static int qpnp_tm_gen1_get_temp_stage (struct qpnp_tm_chip * chip )
134146{
135147 int ret ;
136- u8 reg = 0 ;
148+ u8 reg ;
137149
138150 ret = qpnp_tm_read (chip , QPNP_TM_REG_STATUS , & reg );
139151 if (ret < 0 )
140152 return ret ;
141153
142- if (chip -> subtype == QPNP_TM_SUBTYPE_GEN1 )
143- ret = reg & STATUS_GEN1_STAGE_MASK ;
144- else
145- ret = (reg & STATUS_GEN2_STATE_MASK ) >> STATUS_GEN2_STATE_SHIFT ;
154+ return FIELD_GET (STATUS_GEN1_STAGE_MASK , reg );
155+ }
146156
147- return ret ;
157+ /**
158+ * qpnp_tm_gen2_get_temp_stage() - return over-temperature stage
159+ * @chip: Pointer to the qpnp_tm chip
160+ *
161+ * Return: stage on success, or errno on failure.
162+ */
163+ static int qpnp_tm_gen2_get_temp_stage (struct qpnp_tm_chip * chip )
164+ {
165+ int ret ;
166+ u8 reg ;
167+
168+ ret = qpnp_tm_read (chip , QPNP_TM_REG_STATUS , & reg );
169+ if (ret < 0 )
170+ return ret ;
171+
172+ ret = FIELD_GET (STATUS_GEN2_STATE_MASK , reg );
173+
174+ return alarm_state_map [ret ];
148175}
149176
150177/*
@@ -153,23 +180,16 @@ static int qpnp_tm_get_temp_stage(struct qpnp_tm_chip *chip)
153180 */
154181static int qpnp_tm_update_temp_no_adc (struct qpnp_tm_chip * chip )
155182{
156- unsigned int stage , stage_new , stage_old ;
183+ unsigned int stage_new , stage_old ;
157184 int ret ;
158185
159186 WARN_ON (!mutex_is_locked (& chip -> lock ));
160187
161- ret = qpnp_tm_get_temp_stage (chip );
188+ ret = chip -> data -> get_temp_stage (chip );
162189 if (ret < 0 )
163190 return ret ;
164- stage = ret ;
165-
166- if (chip -> subtype == QPNP_TM_SUBTYPE_GEN1 ) {
167- stage_new = stage ;
168- stage_old = chip -> stage ;
169- } else {
170- stage_new = alarm_state_map [stage ];
171- stage_old = alarm_state_map [chip -> stage ];
172- }
191+ stage_new = ret ;
192+ stage_old = chip -> stage ;
173193
174194 if (stage_new > stage_old ) {
175195 /* increasing stage, use lower bound */
@@ -181,7 +201,7 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip)
181201 - TEMP_STAGE_HYSTERESIS ;
182202 }
183203
184- chip -> stage = stage ;
204+ chip -> stage = stage_new ;
185205
186206 return 0 ;
187207}
@@ -221,10 +241,10 @@ static int qpnp_tm_get_temp(struct thermal_zone_device *tz, int *temp)
221241static int qpnp_tm_update_critical_trip_temp (struct qpnp_tm_chip * chip ,
222242 int temp )
223243{
224- long stage2_threshold_min = (* chip -> temp_map )[THRESH_MIN ][1 ];
225- long stage2_threshold_max = (* chip -> temp_map )[THRESH_MAX ][1 ];
244+ long stage2_threshold_min = (* chip -> data -> temp_map )[THRESH_MIN ][STAGE2 ];
245+ long stage2_threshold_max = (* chip -> data -> temp_map )[THRESH_MAX ][STAGE2 ];
226246 bool disable_stage2_shutdown = false;
227- u8 reg ;
247+ u8 reg , threshold ;
228248
229249 WARN_ON (!mutex_is_locked (& chip -> lock ));
230250
@@ -236,17 +256,17 @@ static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
236256
237257 if (temp == THERMAL_TEMP_INVALID ||
238258 temp < stage2_threshold_min ) {
239- chip -> thresh = THRESH_MIN ;
259+ threshold = THRESH_MIN ;
240260 goto skip ;
241261 }
242262
243263 if (temp <= stage2_threshold_max ) {
244- chip -> thresh = THRESH_MAX -
264+ threshold = THRESH_MAX -
245265 ((stage2_threshold_max - temp ) /
246266 TEMP_THRESH_STEP );
247267 disable_stage2_shutdown = true;
248268 } else {
249- chip -> thresh = THRESH_MAX ;
269+ threshold = THRESH_MAX ;
250270
251271 if (chip -> adc )
252272 disable_stage2_shutdown = true;
@@ -257,7 +277,9 @@ static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
257277 }
258278
259279skip :
260- reg |= chip -> thresh ;
280+ memcpy (chip -> temp_thresh_map , chip -> data -> temp_map [threshold ],
281+ sizeof (chip -> temp_thresh_map ));
282+ reg |= threshold ;
261283 if (disable_stage2_shutdown && !chip -> require_stage2_shutdown )
262284 reg |= SHUTDOWN_CTRL1_OVERRIDE_STAGE2 ;
263285
@@ -294,37 +316,52 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data)
294316 return IRQ_HANDLED ;
295317}
296318
319+ static const struct spmi_temp_alarm_data spmi_temp_alarm_data = {
320+ .temp_map = & temp_map_gen1 ,
321+ .get_temp_stage = qpnp_tm_gen1_get_temp_stage ,
322+ };
323+
324+ static const struct spmi_temp_alarm_data spmi_temp_alarm_gen2_data = {
325+ .temp_map = & temp_map_gen1 ,
326+ .get_temp_stage = qpnp_tm_gen2_get_temp_stage ,
327+ };
328+
329+ static const struct spmi_temp_alarm_data spmi_temp_alarm_gen2_rev1_data = {
330+ .temp_map = & temp_map_gen2_v1 ,
331+ .get_temp_stage = qpnp_tm_gen2_get_temp_stage ,
332+ };
333+
297334/*
298335 * This function initializes the internal temp value based on only the
299336 * current thermal stage and threshold. Setup threshold control and
300337 * disable shutdown override.
301338 */
302339static int qpnp_tm_init (struct qpnp_tm_chip * chip )
303340{
304- unsigned int stage ;
305- int ret ;
306- u8 reg = 0 ;
307341 int crit_temp ;
342+ u8 threshold ;
343+ int ret ;
344+ u8 reg ;
308345
309346 mutex_lock (& chip -> lock );
310347
311348 ret = qpnp_tm_read (chip , QPNP_TM_REG_SHUTDOWN_CTRL1 , & reg );
312349 if (ret < 0 )
313350 goto out ;
314351
315- chip -> thresh = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK ;
352+ threshold = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK ;
353+ memcpy (chip -> temp_thresh_map , chip -> data -> temp_map [threshold ],
354+ sizeof (chip -> temp_thresh_map ));
355+
316356 chip -> temp = DEFAULT_TEMP ;
317357
318- ret = qpnp_tm_get_temp_stage (chip );
358+ ret = chip -> data -> get_temp_stage (chip );
319359 if (ret < 0 )
320360 goto out ;
321361 chip -> stage = ret ;
322362
323- stage = chip -> subtype == QPNP_TM_SUBTYPE_GEN1
324- ? chip -> stage : alarm_state_map [chip -> stage ];
325-
326- if (stage )
327- chip -> temp = qpnp_tm_decode_temp (chip , stage );
363+ if (chip -> stage )
364+ chip -> temp = qpnp_tm_decode_temp (chip , chip -> stage );
328365
329366 mutex_unlock (& chip -> lock );
330367
@@ -418,10 +455,14 @@ static int qpnp_tm_probe(struct platform_device *pdev)
418455 }
419456
420457 chip -> subtype = subtype ;
421- if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major >= 1 )
422- chip -> temp_map = & temp_map_gen2_v1 ;
458+ if (subtype == QPNP_TM_SUBTYPE_GEN1 )
459+ chip -> data = & spmi_temp_alarm_data ;
460+ else if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major == 0 )
461+ chip -> data = & spmi_temp_alarm_gen2_data ;
462+ else if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major >= 1 )
463+ chip -> data = & spmi_temp_alarm_gen2_rev1_data ;
423464 else
424- chip -> temp_map = & temp_map_gen1 ;
465+ return - ENODEV ;
425466
426467 if (chip -> subtype == QPNP_TM_SUBTYPE_GEN2 ) {
427468 dig_revision = (dig_major << 8 ) | dig_minor ;
0 commit comments