1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2011-2015, 2017, 2020, The Linux Foundation. All rights reserved.
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <linux/bitops.h>
7*4882a593Smuzhiyun #include <linux/delay.h>
8*4882a593Smuzhiyun #include <linux/err.h>
9*4882a593Smuzhiyun #include <linux/iio/consumer.h>
10*4882a593Smuzhiyun #include <linux/interrupt.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/of.h>
13*4882a593Smuzhiyun #include <linux/of_device.h>
14*4882a593Smuzhiyun #include <linux/platform_device.h>
15*4882a593Smuzhiyun #include <linux/regmap.h>
16*4882a593Smuzhiyun #include <linux/thermal.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include "../thermal_core.h"
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #define QPNP_TM_REG_TYPE 0x04
21*4882a593Smuzhiyun #define QPNP_TM_REG_SUBTYPE 0x05
22*4882a593Smuzhiyun #define QPNP_TM_REG_STATUS 0x08
23*4882a593Smuzhiyun #define QPNP_TM_REG_SHUTDOWN_CTRL1 0x40
24*4882a593Smuzhiyun #define QPNP_TM_REG_ALARM_CTRL 0x46
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #define QPNP_TM_TYPE 0x09
27*4882a593Smuzhiyun #define QPNP_TM_SUBTYPE_GEN1 0x08
28*4882a593Smuzhiyun #define QPNP_TM_SUBTYPE_GEN2 0x09
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define STATUS_GEN1_STAGE_MASK GENMASK(1, 0)
31*4882a593Smuzhiyun #define STATUS_GEN2_STATE_MASK GENMASK(6, 4)
32*4882a593Smuzhiyun #define STATUS_GEN2_STATE_SHIFT 4
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define SHUTDOWN_CTRL1_OVERRIDE_S2 BIT(6)
35*4882a593Smuzhiyun #define SHUTDOWN_CTRL1_THRESHOLD_MASK GENMASK(1, 0)
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define SHUTDOWN_CTRL1_RATE_25HZ BIT(3)
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #define ALARM_CTRL_FORCE_ENABLE BIT(7)
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun * Trip point values based on threshold control
43*4882a593Smuzhiyun * 0 = {105 C, 125 C, 145 C}
44*4882a593Smuzhiyun * 1 = {110 C, 130 C, 150 C}
45*4882a593Smuzhiyun * 2 = {115 C, 135 C, 155 C}
46*4882a593Smuzhiyun * 3 = {120 C, 140 C, 160 C}
47*4882a593Smuzhiyun */
48*4882a593Smuzhiyun #define TEMP_STAGE_STEP 20000 /* Stage step: 20.000 C */
49*4882a593Smuzhiyun #define TEMP_STAGE_HYSTERESIS 2000
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #define TEMP_THRESH_MIN 105000 /* Threshold Min: 105 C */
52*4882a593Smuzhiyun #define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define THRESH_MIN 0
55*4882a593Smuzhiyun #define THRESH_MAX 3
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* Stage 2 Threshold Min: 125 C */
58*4882a593Smuzhiyun #define STAGE2_THRESHOLD_MIN 125000
59*4882a593Smuzhiyun /* Stage 2 Threshold Max: 140 C */
60*4882a593Smuzhiyun #define STAGE2_THRESHOLD_MAX 140000
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /* Temperature in Milli Celsius reported during stage 0 if no ADC is present */
63*4882a593Smuzhiyun #define DEFAULT_TEMP 37000
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun struct qpnp_tm_chip {
66*4882a593Smuzhiyun struct regmap *map;
67*4882a593Smuzhiyun struct device *dev;
68*4882a593Smuzhiyun struct thermal_zone_device *tz_dev;
69*4882a593Smuzhiyun unsigned int subtype;
70*4882a593Smuzhiyun long temp;
71*4882a593Smuzhiyun unsigned int thresh;
72*4882a593Smuzhiyun unsigned int stage;
73*4882a593Smuzhiyun unsigned int prev_stage;
74*4882a593Smuzhiyun unsigned int base;
75*4882a593Smuzhiyun /* protects .thresh, .stage and chip registers */
76*4882a593Smuzhiyun struct mutex lock;
77*4882a593Smuzhiyun bool initialized;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun struct iio_channel *adc;
80*4882a593Smuzhiyun };
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /* This array maps from GEN2 alarm state to GEN1 alarm stage */
83*4882a593Smuzhiyun static const unsigned int alarm_state_map[8] = {0, 1, 1, 2, 2, 3, 3, 3};
84*4882a593Smuzhiyun
qpnp_tm_read(struct qpnp_tm_chip * chip,u16 addr,u8 * data)85*4882a593Smuzhiyun static int qpnp_tm_read(struct qpnp_tm_chip *chip, u16 addr, u8 *data)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun unsigned int val;
88*4882a593Smuzhiyun int ret;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun ret = regmap_read(chip->map, chip->base + addr, &val);
91*4882a593Smuzhiyun if (ret < 0)
92*4882a593Smuzhiyun return ret;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun *data = val;
95*4882a593Smuzhiyun return 0;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
qpnp_tm_write(struct qpnp_tm_chip * chip,u16 addr,u8 data)98*4882a593Smuzhiyun static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun return regmap_write(chip->map, chip->base + addr, data);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun /**
104*4882a593Smuzhiyun * qpnp_tm_get_temp_stage() - return over-temperature stage
105*4882a593Smuzhiyun * @chip: Pointer to the qpnp_tm chip
106*4882a593Smuzhiyun *
107*4882a593Smuzhiyun * Return: stage (GEN1) or state (GEN2) on success, or errno on failure.
108*4882a593Smuzhiyun */
qpnp_tm_get_temp_stage(struct qpnp_tm_chip * chip)109*4882a593Smuzhiyun static int qpnp_tm_get_temp_stage(struct qpnp_tm_chip *chip)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun int ret;
112*4882a593Smuzhiyun u8 reg = 0;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun ret = qpnp_tm_read(chip, QPNP_TM_REG_STATUS, ®);
115*4882a593Smuzhiyun if (ret < 0)
116*4882a593Smuzhiyun return ret;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun if (chip->subtype == QPNP_TM_SUBTYPE_GEN1)
119*4882a593Smuzhiyun ret = reg & STATUS_GEN1_STAGE_MASK;
120*4882a593Smuzhiyun else
121*4882a593Smuzhiyun ret = (reg & STATUS_GEN2_STATE_MASK) >> STATUS_GEN2_STATE_SHIFT;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun return ret;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun /*
127*4882a593Smuzhiyun * This function updates the internal temp value based on the
128*4882a593Smuzhiyun * current thermal stage and threshold as well as the previous stage
129*4882a593Smuzhiyun */
qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip * chip)130*4882a593Smuzhiyun static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun unsigned int stage, stage_new, stage_old;
133*4882a593Smuzhiyun int ret;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun WARN_ON(!mutex_is_locked(&chip->lock));
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun ret = qpnp_tm_get_temp_stage(chip);
138*4882a593Smuzhiyun if (ret < 0)
139*4882a593Smuzhiyun return ret;
140*4882a593Smuzhiyun stage = ret;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun if (chip->subtype == QPNP_TM_SUBTYPE_GEN1) {
143*4882a593Smuzhiyun stage_new = stage;
144*4882a593Smuzhiyun stage_old = chip->stage;
145*4882a593Smuzhiyun } else {
146*4882a593Smuzhiyun stage_new = alarm_state_map[stage];
147*4882a593Smuzhiyun stage_old = alarm_state_map[chip->stage];
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun if (stage_new > stage_old) {
151*4882a593Smuzhiyun /* increasing stage, use lower bound */
152*4882a593Smuzhiyun chip->temp = (stage_new - 1) * TEMP_STAGE_STEP +
153*4882a593Smuzhiyun chip->thresh * TEMP_THRESH_STEP +
154*4882a593Smuzhiyun TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
155*4882a593Smuzhiyun } else if (stage_new < stage_old) {
156*4882a593Smuzhiyun /* decreasing stage, use upper bound */
157*4882a593Smuzhiyun chip->temp = stage_new * TEMP_STAGE_STEP +
158*4882a593Smuzhiyun chip->thresh * TEMP_THRESH_STEP -
159*4882a593Smuzhiyun TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun chip->stage = stage;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun return 0;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
qpnp_tm_get_temp(void * data,int * temp)167*4882a593Smuzhiyun static int qpnp_tm_get_temp(void *data, int *temp)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun struct qpnp_tm_chip *chip = data;
170*4882a593Smuzhiyun int ret, mili_celsius;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (!temp)
173*4882a593Smuzhiyun return -EINVAL;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun if (!chip->initialized) {
176*4882a593Smuzhiyun *temp = DEFAULT_TEMP;
177*4882a593Smuzhiyun return 0;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun if (!chip->adc) {
181*4882a593Smuzhiyun mutex_lock(&chip->lock);
182*4882a593Smuzhiyun ret = qpnp_tm_update_temp_no_adc(chip);
183*4882a593Smuzhiyun mutex_unlock(&chip->lock);
184*4882a593Smuzhiyun if (ret < 0)
185*4882a593Smuzhiyun return ret;
186*4882a593Smuzhiyun } else {
187*4882a593Smuzhiyun ret = iio_read_channel_processed(chip->adc, &mili_celsius);
188*4882a593Smuzhiyun if (ret < 0)
189*4882a593Smuzhiyun return ret;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun chip->temp = mili_celsius;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun *temp = chip->temp;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun return 0;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip * chip,int temp)199*4882a593Smuzhiyun static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
200*4882a593Smuzhiyun int temp)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun u8 reg;
203*4882a593Smuzhiyun bool disable_s2_shutdown = false;
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun WARN_ON(!mutex_is_locked(&chip->lock));
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun /*
208*4882a593Smuzhiyun * Default: S2 and S3 shutdown enabled, thresholds at
209*4882a593Smuzhiyun * 105C/125C/145C, monitoring at 25Hz
210*4882a593Smuzhiyun */
211*4882a593Smuzhiyun reg = SHUTDOWN_CTRL1_RATE_25HZ;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun if (temp == THERMAL_TEMP_INVALID ||
214*4882a593Smuzhiyun temp < STAGE2_THRESHOLD_MIN) {
215*4882a593Smuzhiyun chip->thresh = THRESH_MIN;
216*4882a593Smuzhiyun goto skip;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun if (temp <= STAGE2_THRESHOLD_MAX) {
220*4882a593Smuzhiyun chip->thresh = THRESH_MAX -
221*4882a593Smuzhiyun ((STAGE2_THRESHOLD_MAX - temp) /
222*4882a593Smuzhiyun TEMP_THRESH_STEP);
223*4882a593Smuzhiyun disable_s2_shutdown = true;
224*4882a593Smuzhiyun } else {
225*4882a593Smuzhiyun chip->thresh = THRESH_MAX;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun if (chip->adc)
228*4882a593Smuzhiyun disable_s2_shutdown = true;
229*4882a593Smuzhiyun else
230*4882a593Smuzhiyun dev_warn(chip->dev,
231*4882a593Smuzhiyun "No ADC is configured and critical temperature is above the maximum stage 2 threshold of 140 C! Configuring stage 2 shutdown at 140 C.\n");
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun skip:
235*4882a593Smuzhiyun reg |= chip->thresh;
236*4882a593Smuzhiyun if (disable_s2_shutdown)
237*4882a593Smuzhiyun reg |= SHUTDOWN_CTRL1_OVERRIDE_S2;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg);
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
qpnp_tm_set_trip_temp(void * data,int trip,int temp)242*4882a593Smuzhiyun static int qpnp_tm_set_trip_temp(void *data, int trip, int temp)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun struct qpnp_tm_chip *chip = data;
245*4882a593Smuzhiyun const struct thermal_trip *trip_points;
246*4882a593Smuzhiyun int ret;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun trip_points = of_thermal_get_trip_points(chip->tz_dev);
249*4882a593Smuzhiyun if (!trip_points)
250*4882a593Smuzhiyun return -EINVAL;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun if (trip_points[trip].type != THERMAL_TRIP_CRITICAL)
253*4882a593Smuzhiyun return 0;
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun mutex_lock(&chip->lock);
256*4882a593Smuzhiyun ret = qpnp_tm_update_critical_trip_temp(chip, temp);
257*4882a593Smuzhiyun mutex_unlock(&chip->lock);
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun return ret;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun static const struct thermal_zone_of_device_ops qpnp_tm_sensor_ops = {
263*4882a593Smuzhiyun .get_temp = qpnp_tm_get_temp,
264*4882a593Smuzhiyun .set_trip_temp = qpnp_tm_set_trip_temp,
265*4882a593Smuzhiyun };
266*4882a593Smuzhiyun
qpnp_tm_isr(int irq,void * data)267*4882a593Smuzhiyun static irqreturn_t qpnp_tm_isr(int irq, void *data)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun struct qpnp_tm_chip *chip = data;
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun thermal_zone_device_update(chip->tz_dev, THERMAL_EVENT_UNSPECIFIED);
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun return IRQ_HANDLED;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip * chip)276*4882a593Smuzhiyun static int qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip *chip)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun int ntrips;
279*4882a593Smuzhiyun const struct thermal_trip *trips;
280*4882a593Smuzhiyun int i;
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun ntrips = of_thermal_get_ntrips(chip->tz_dev);
283*4882a593Smuzhiyun if (ntrips <= 0)
284*4882a593Smuzhiyun return THERMAL_TEMP_INVALID;
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun trips = of_thermal_get_trip_points(chip->tz_dev);
287*4882a593Smuzhiyun if (!trips)
288*4882a593Smuzhiyun return THERMAL_TEMP_INVALID;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun for (i = 0; i < ntrips; i++) {
291*4882a593Smuzhiyun if (of_thermal_is_trip_valid(chip->tz_dev, i) &&
292*4882a593Smuzhiyun trips[i].type == THERMAL_TRIP_CRITICAL)
293*4882a593Smuzhiyun return trips[i].temperature;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun return THERMAL_TEMP_INVALID;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun /*
300*4882a593Smuzhiyun * This function initializes the internal temp value based on only the
301*4882a593Smuzhiyun * current thermal stage and threshold. Setup threshold control and
302*4882a593Smuzhiyun * disable shutdown override.
303*4882a593Smuzhiyun */
qpnp_tm_init(struct qpnp_tm_chip * chip)304*4882a593Smuzhiyun static int qpnp_tm_init(struct qpnp_tm_chip *chip)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun unsigned int stage;
307*4882a593Smuzhiyun int ret;
308*4882a593Smuzhiyun u8 reg = 0;
309*4882a593Smuzhiyun int crit_temp;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun mutex_lock(&chip->lock);
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun ret = qpnp_tm_read(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, ®);
314*4882a593Smuzhiyun if (ret < 0)
315*4882a593Smuzhiyun goto out;
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun chip->thresh = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK;
318*4882a593Smuzhiyun chip->temp = DEFAULT_TEMP;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun ret = qpnp_tm_get_temp_stage(chip);
321*4882a593Smuzhiyun if (ret < 0)
322*4882a593Smuzhiyun goto out;
323*4882a593Smuzhiyun chip->stage = ret;
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun stage = chip->subtype == QPNP_TM_SUBTYPE_GEN1
326*4882a593Smuzhiyun ? chip->stage : alarm_state_map[chip->stage];
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun if (stage)
329*4882a593Smuzhiyun chip->temp = chip->thresh * TEMP_THRESH_STEP +
330*4882a593Smuzhiyun (stage - 1) * TEMP_STAGE_STEP +
331*4882a593Smuzhiyun TEMP_THRESH_MIN;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun crit_temp = qpnp_tm_get_critical_trip_temp(chip);
334*4882a593Smuzhiyun ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp);
335*4882a593Smuzhiyun if (ret < 0)
336*4882a593Smuzhiyun goto out;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun /* Enable the thermal alarm PMIC module in always-on mode. */
339*4882a593Smuzhiyun reg = ALARM_CTRL_FORCE_ENABLE;
340*4882a593Smuzhiyun ret = qpnp_tm_write(chip, QPNP_TM_REG_ALARM_CTRL, reg);
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun chip->initialized = true;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun out:
345*4882a593Smuzhiyun mutex_unlock(&chip->lock);
346*4882a593Smuzhiyun return ret;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
qpnp_tm_probe(struct platform_device * pdev)349*4882a593Smuzhiyun static int qpnp_tm_probe(struct platform_device *pdev)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun struct qpnp_tm_chip *chip;
352*4882a593Smuzhiyun struct device_node *node;
353*4882a593Smuzhiyun u8 type, subtype;
354*4882a593Smuzhiyun u32 res;
355*4882a593Smuzhiyun int ret, irq;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun node = pdev->dev.of_node;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
360*4882a593Smuzhiyun if (!chip)
361*4882a593Smuzhiyun return -ENOMEM;
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun dev_set_drvdata(&pdev->dev, chip);
364*4882a593Smuzhiyun chip->dev = &pdev->dev;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun mutex_init(&chip->lock);
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun chip->map = dev_get_regmap(pdev->dev.parent, NULL);
369*4882a593Smuzhiyun if (!chip->map)
370*4882a593Smuzhiyun return -ENXIO;
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun ret = of_property_read_u32(node, "reg", &res);
373*4882a593Smuzhiyun if (ret < 0)
374*4882a593Smuzhiyun return ret;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
377*4882a593Smuzhiyun if (irq < 0)
378*4882a593Smuzhiyun return irq;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun /* ADC based measurements are optional */
381*4882a593Smuzhiyun chip->adc = devm_iio_channel_get(&pdev->dev, "thermal");
382*4882a593Smuzhiyun if (IS_ERR(chip->adc)) {
383*4882a593Smuzhiyun ret = PTR_ERR(chip->adc);
384*4882a593Smuzhiyun chip->adc = NULL;
385*4882a593Smuzhiyun if (ret == -EPROBE_DEFER)
386*4882a593Smuzhiyun return ret;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun chip->base = res;
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun ret = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, &type);
392*4882a593Smuzhiyun if (ret < 0) {
393*4882a593Smuzhiyun dev_err(&pdev->dev, "could not read type\n");
394*4882a593Smuzhiyun return ret;
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun ret = qpnp_tm_read(chip, QPNP_TM_REG_SUBTYPE, &subtype);
398*4882a593Smuzhiyun if (ret < 0) {
399*4882a593Smuzhiyun dev_err(&pdev->dev, "could not read subtype\n");
400*4882a593Smuzhiyun return ret;
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1
404*4882a593Smuzhiyun && subtype != QPNP_TM_SUBTYPE_GEN2)) {
405*4882a593Smuzhiyun dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n",
406*4882a593Smuzhiyun type, subtype);
407*4882a593Smuzhiyun return -ENODEV;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun chip->subtype = subtype;
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun /*
413*4882a593Smuzhiyun * Register the sensor before initializing the hardware to be able to
414*4882a593Smuzhiyun * read the trip points. get_temp() returns the default temperature
415*4882a593Smuzhiyun * before the hardware initialization is completed.
416*4882a593Smuzhiyun */
417*4882a593Smuzhiyun chip->tz_dev = devm_thermal_zone_of_sensor_register(
418*4882a593Smuzhiyun &pdev->dev, 0, chip, &qpnp_tm_sensor_ops);
419*4882a593Smuzhiyun if (IS_ERR(chip->tz_dev)) {
420*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to register sensor\n");
421*4882a593Smuzhiyun return PTR_ERR(chip->tz_dev);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun ret = qpnp_tm_init(chip);
425*4882a593Smuzhiyun if (ret < 0) {
426*4882a593Smuzhiyun dev_err(&pdev->dev, "init failed\n");
427*4882a593Smuzhiyun return ret;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, qpnp_tm_isr,
431*4882a593Smuzhiyun IRQF_ONESHOT, node->name, chip);
432*4882a593Smuzhiyun if (ret < 0)
433*4882a593Smuzhiyun return ret;
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun thermal_zone_device_update(chip->tz_dev, THERMAL_EVENT_UNSPECIFIED);
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun return 0;
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun static const struct of_device_id qpnp_tm_match_table[] = {
441*4882a593Smuzhiyun { .compatible = "qcom,spmi-temp-alarm" },
442*4882a593Smuzhiyun { }
443*4882a593Smuzhiyun };
444*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, qpnp_tm_match_table);
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun static struct platform_driver qpnp_tm_driver = {
447*4882a593Smuzhiyun .driver = {
448*4882a593Smuzhiyun .name = "spmi-temp-alarm",
449*4882a593Smuzhiyun .of_match_table = qpnp_tm_match_table,
450*4882a593Smuzhiyun },
451*4882a593Smuzhiyun .probe = qpnp_tm_probe,
452*4882a593Smuzhiyun };
453*4882a593Smuzhiyun module_platform_driver(qpnp_tm_driver);
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun MODULE_ALIAS("platform:spmi-temp-alarm");
456*4882a593Smuzhiyun MODULE_DESCRIPTION("QPNP PMIC Temperature Alarm driver");
457*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
458