2323#define QPNP_TM_REG_TYPE 0x04
2424#define QPNP_TM_REG_SUBTYPE 0x05
2525#define QPNP_TM_REG_STATUS 0x08
26+ #define QPNP_TM_REG_IRQ_STATUS 0x10
2627#define QPNP_TM_REG_SHUTDOWN_CTRL1 0x40
2728#define QPNP_TM_REG_ALARM_CTRL 0x46
2829
2930/* TEMP_DAC_STGx registers are only present for TEMP_GEN2 v2.0 */
3031#define QPNP_TM_REG_TEMP_DAC_STG1 0x47
3132#define QPNP_TM_REG_TEMP_DAC_STG2 0x48
3233#define QPNP_TM_REG_TEMP_DAC_STG3 0x49
34+ #define QPNP_TM_REG_LITE_TEMP_CFG1 0x50
35+ #define QPNP_TM_REG_LITE_TEMP_CFG2 0x51
3336
3437#define QPNP_TM_TYPE 0x09
3538#define QPNP_TM_SUBTYPE_GEN1 0x08
3639#define QPNP_TM_SUBTYPE_GEN2 0x09
40+ #define QPNP_TM_SUBTYPE_LITE 0xC0
3741
3842#define STATUS_GEN1_STAGE_MASK GENMASK(1, 0)
3943#define STATUS_GEN2_STATE_MASK GENMASK(6, 4)
4044
45+ /* IRQ status only needed for TEMP_ALARM_LITE */
46+ #define IRQ_STATUS_MASK BIT(0)
47+
4148#define SHUTDOWN_CTRL1_OVERRIDE_STAGE2 BIT(6)
4249#define SHUTDOWN_CTRL1_THRESHOLD_MASK GENMASK(1, 0)
4350
4451#define SHUTDOWN_CTRL1_RATE_25HZ BIT(3)
4552
4653#define ALARM_CTRL_FORCE_ENABLE BIT(7)
4754
55+ #define LITE_TEMP_CFG_THRESHOLD_MASK GENMASK(3, 2)
56+
4857#define THRESH_COUNT 4
4958#define STAGE_COUNT 3
5059
@@ -95,6 +104,19 @@ static const long temp_dac_max[STAGE_COUNT] = {
95104 119375 , 159375 , 159375
96105};
97106
107+ /*
108+ * TEMP_ALARM_LITE has two stages: warning and shutdown with independently
109+ * configured threshold temperatures.
110+ */
111+
112+ static const long temp_lite_warning_map [THRESH_COUNT ] = {
113+ 115000 , 125000 , 135000 , 145000
114+ };
115+
116+ static const long temp_lite_shutdown_map [THRESH_COUNT ] = {
117+ 135000 , 145000 , 160000 , 175000
118+ };
119+
98120/* Temperature in Milli Celsius reported during stage 0 if no ADC is present */
99121#define DEFAULT_TEMP 37000
100122
@@ -202,6 +224,24 @@ static int qpnp_tm_gen2_get_temp_stage(struct qpnp_tm_chip *chip)
202224 return alarm_state_map [ret ];
203225}
204226
227+ /**
228+ * qpnp_tm_lite_get_temp_stage() - return over-temperature stage
229+ * @chip: Pointer to the qpnp_tm chip
230+ *
231+ * Return: alarm interrupt state on success, or errno on failure.
232+ */
233+ static int qpnp_tm_lite_get_temp_stage (struct qpnp_tm_chip * chip )
234+ {
235+ u8 reg = 0 ;
236+ int ret ;
237+
238+ ret = qpnp_tm_read (chip , QPNP_TM_REG_IRQ_STATUS , & reg );
239+ if (ret < 0 )
240+ return ret ;
241+
242+ return FIELD_GET (IRQ_STATUS_MASK , reg );
243+ }
244+
205245/*
206246 * This function updates the internal temp value based on the
207247 * current thermal stage and threshold as well as the previous stage
@@ -383,6 +423,98 @@ static const struct thermal_zone_device_ops qpnp_tm_gen2_rev2_sensor_ops = {
383423 .set_trip_temp = qpnp_tm_gen2_rev2_set_trip_temp ,
384424};
385425
426+ static int qpnp_tm_lite_set_temp_thresh (struct qpnp_tm_chip * chip , unsigned int trip , int temp )
427+ {
428+ int ret , temp_cfg , i ;
429+ const long * temp_map ;
430+ u8 reg , thresh ;
431+ u16 addr ;
432+
433+ WARN_ON (!mutex_is_locked (& chip -> lock ));
434+
435+ if (trip >= STAGE_COUNT ) {
436+ dev_err (chip -> dev , "invalid TEMP_LITE trip = %d\n" , trip );
437+ return - EINVAL ;
438+ }
439+
440+ switch (trip ) {
441+ case 0 :
442+ temp_map = temp_lite_warning_map ;
443+ addr = QPNP_TM_REG_LITE_TEMP_CFG1 ;
444+ break ;
445+ case 1 :
446+ /*
447+ * The second trip point is purely in software to facilitate
448+ * a controlled shutdown after the warning threshold is crossed
449+ * but before the automatic hardware shutdown threshold is
450+ * crossed.
451+ */
452+ return 0 ;
453+ case 2 :
454+ temp_map = temp_lite_shutdown_map ;
455+ addr = QPNP_TM_REG_LITE_TEMP_CFG2 ;
456+ break ;
457+ default :
458+ return 0 ;
459+ }
460+
461+ if (temp < temp_map [THRESH_MIN ] || temp > temp_map [THRESH_MAX ]) {
462+ dev_err (chip -> dev , "invalid TEMP_LITE temp = %d\n" , temp );
463+ return - EINVAL ;
464+ }
465+
466+ thresh = 0 ;
467+ temp_cfg = temp_map [thresh ];
468+ for (i = THRESH_MAX ; i >= THRESH_MIN ; i -- ) {
469+ if (temp >= temp_map [i ]) {
470+ thresh = i ;
471+ temp_cfg = temp_map [i ];
472+ break ;
473+ }
474+ }
475+
476+ if (temp_cfg == chip -> temp_thresh_map [trip ])
477+ return 0 ;
478+
479+ ret = qpnp_tm_read (chip , addr , & reg );
480+ if (ret < 0 ) {
481+ dev_err (chip -> dev , "LITE_TEMP_CFG read failed, ret=%d\n" , ret );
482+ return ret ;
483+ }
484+
485+ reg &= ~LITE_TEMP_CFG_THRESHOLD_MASK ;
486+ reg |= FIELD_PREP (LITE_TEMP_CFG_THRESHOLD_MASK , thresh );
487+
488+ ret = qpnp_tm_write (chip , addr , reg );
489+ if (ret < 0 ) {
490+ dev_err (chip -> dev , "LITE_TEMP_CFG write failed, ret=%d\n" , ret );
491+ return ret ;
492+ }
493+
494+ chip -> temp_thresh_map [trip ] = temp_cfg ;
495+
496+ return 0 ;
497+ }
498+
499+ static int qpnp_tm_lite_set_trip_temp (struct thermal_zone_device * tz ,
500+ const struct thermal_trip * trip , int temp )
501+ {
502+ unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT (trip -> priv );
503+ struct qpnp_tm_chip * chip = thermal_zone_device_priv (tz );
504+ int ret ;
505+
506+ mutex_lock (& chip -> lock );
507+ ret = qpnp_tm_lite_set_temp_thresh (chip , trip_index , temp );
508+ mutex_unlock (& chip -> lock );
509+
510+ return ret ;
511+ }
512+
513+ static const struct thermal_zone_device_ops qpnp_tm_lite_sensor_ops = {
514+ .get_temp = qpnp_tm_get_temp ,
515+ .set_trip_temp = qpnp_tm_lite_set_trip_temp ,
516+ };
517+
386518static irqreturn_t qpnp_tm_isr (int irq , void * data )
387519{
388520 struct qpnp_tm_chip * chip = data ;
@@ -478,6 +610,70 @@ static int qpnp_tm_gen2_rev2_sync_thresholds(struct qpnp_tm_chip *chip)
478610 return 0 ;
479611}
480612
613+ /* Configure TEMP_LITE registers based on DT thermal_zone trips */
614+ static int qpnp_tm_lite_configure_trip_temps_cb (struct thermal_trip * trip , void * data )
615+ {
616+ struct qpnp_tm_chip * chip = data ;
617+ int ret ;
618+
619+ mutex_lock (& chip -> lock );
620+ trip -> priv = THERMAL_INT_TO_TRIP_PRIV (chip -> ntrips );
621+ ret = qpnp_tm_lite_set_temp_thresh (chip , chip -> ntrips , trip -> temperature );
622+ chip -> ntrips ++ ;
623+ mutex_unlock (& chip -> lock );
624+
625+ return ret ;
626+ }
627+
628+ static int qpnp_tm_lite_configure_trip_temps (struct qpnp_tm_chip * chip )
629+ {
630+ int ret ;
631+
632+ ret = thermal_zone_for_each_trip (chip -> tz_dev , qpnp_tm_lite_configure_trip_temps_cb , chip );
633+ if (ret < 0 )
634+ return ret ;
635+
636+ /* Verify that trips are strictly increasing. */
637+ if (chip -> temp_thresh_map [2 ] <= chip -> temp_thresh_map [0 ]) {
638+ dev_err (chip -> dev , "Threshold 2=%ld <= threshold 0=%ld\n" ,
639+ chip -> temp_thresh_map [2 ], chip -> temp_thresh_map [0 ]);
640+ return - EINVAL ;
641+ }
642+
643+ return 0 ;
644+ }
645+
646+ /* Read the hardware default TEMP_LITE stage threshold temperatures */
647+ static int qpnp_tm_lite_sync_thresholds (struct qpnp_tm_chip * chip )
648+ {
649+ int ret , thresh ;
650+ u8 reg = 0 ;
651+
652+ /*
653+ * Store the warning trip temp in temp_thresh_map[0] and the shutdown trip
654+ * temp in temp_thresh_map[2]. The second trip point is purely in software
655+ * to facilitate a controlled shutdown after the warning threshold is
656+ * crossed but before the automatic hardware shutdown threshold is
657+ * crossed. Thus, there is no register to read for the second trip
658+ * point.
659+ */
660+ ret = qpnp_tm_read (chip , QPNP_TM_REG_LITE_TEMP_CFG1 , & reg );
661+ if (ret < 0 )
662+ return ret ;
663+
664+ thresh = FIELD_GET (LITE_TEMP_CFG_THRESHOLD_MASK , reg );
665+ chip -> temp_thresh_map [0 ] = temp_lite_warning_map [thresh ];
666+
667+ ret = qpnp_tm_read (chip , QPNP_TM_REG_LITE_TEMP_CFG2 , & reg );
668+ if (ret < 0 )
669+ return ret ;
670+
671+ thresh = FIELD_GET (LITE_TEMP_CFG_THRESHOLD_MASK , reg );
672+ chip -> temp_thresh_map [2 ] = temp_lite_shutdown_map [thresh ];
673+
674+ return 0 ;
675+ }
676+
481677static const struct spmi_temp_alarm_data spmi_temp_alarm_data = {
482678 .ops = & qpnp_tm_sensor_ops ,
483679 .temp_map = & temp_map_gen1 ,
@@ -509,6 +705,13 @@ static const struct spmi_temp_alarm_data spmi_temp_alarm_gen2_rev2_data = {
509705 .get_temp_stage = qpnp_tm_gen2_get_temp_stage ,
510706};
511707
708+ static const struct spmi_temp_alarm_data spmi_temp_alarm_lite_data = {
709+ .ops = & qpnp_tm_lite_sensor_ops ,
710+ .sync_thresholds = qpnp_tm_lite_sync_thresholds ,
711+ .configure_trip_temps = qpnp_tm_lite_configure_trip_temps ,
712+ .get_temp_stage = qpnp_tm_lite_get_temp_stage ,
713+ };
714+
512715/*
513716 * This function initializes the internal temp value based on only the
514717 * current thermal stage and threshold.
@@ -614,7 +817,8 @@ static int qpnp_tm_probe(struct platform_device *pdev)
614817 "could not read dig_minor\n" );
615818
616819 if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1
617- && subtype != QPNP_TM_SUBTYPE_GEN2 )) {
820+ && subtype != QPNP_TM_SUBTYPE_GEN2
821+ && subtype != QPNP_TM_SUBTYPE_LITE )) {
618822 dev_err (& pdev -> dev , "invalid type 0x%02x or subtype 0x%02x\n" ,
619823 type , subtype );
620824 return - ENODEV ;
@@ -629,6 +833,8 @@ static int qpnp_tm_probe(struct platform_device *pdev)
629833 chip -> data = & spmi_temp_alarm_gen2_rev1_data ;
630834 else if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major >= 2 )
631835 chip -> data = & spmi_temp_alarm_gen2_rev2_data ;
836+ else if (subtype == QPNP_TM_SUBTYPE_LITE )
837+ chip -> data = & spmi_temp_alarm_lite_data ;
632838 else
633839 return - ENODEV ;
634840
0 commit comments