xref: /linux/drivers/thermal/airoha_thermal.c (revision b81e34131907d2c243c51117a4aff8dbe22ccc9c)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #include <linux/module.h>
4 #include <linux/bitfield.h>
5 #include <linux/delay.h>
6 #include <linux/interrupt.h>
7 #include <linux/mfd/syscon.h>
8 #include <linux/of.h>
9 #include <linux/of_address.h>
10 #include <linux/platform_device.h>
11 #include <linux/regmap.h>
12 #include <linux/thermal.h>
13 
14 /* SCU regs */
15 #define EN7581_PLLRG_PROTECT			0x268
16 #define EN7581_PWD_TADC				0x2ec
17 #define   EN7581_MUX_TADC			GENMASK(3, 1)
18 #define EN7581_DOUT_TADC			0x2f8
19 #define   EN7581_DOUT_TADC_MASK			GENMASK(15, 0)
20 
21 #define AN7583_MUX_SENSOR			0x2a0
22 #define   AN7583_LOAD_ADJ			GENMASK(3, 2)
23 #define AN7583_MUX_TADC				0x2e4
24 #define   AN7583_MUX_TADC_MASK			GENMASK(3, 1)
25 #define AN7583_DOUT_TADC			0x2f0
26 
27 /* PTP_THERMAL regs */
28 #define EN7581_TEMPMONCTL0			0x800
29 #define   EN7581_SENSE3_EN			BIT(3)
30 #define   EN7581_SENSE2_EN			BIT(2)
31 #define   EN7581_SENSE1_EN			BIT(1)
32 #define   EN7581_SENSE0_EN			BIT(0)
33 #define EN7581_TEMPMONCTL1			0x804
34 /* period unit calculated in BUS clock * 256 scaling-up */
35 #define   EN7581_PERIOD_UNIT			GENMASK(9, 0)
36 #define EN7581_TEMPMONCTL2			0x808
37 #define   EN7581_FILT_INTERVAL			GENMASK(25, 16)
38 #define   EN7581_SEN_INTERVAL			GENMASK(9, 0)
39 #define EN7581_TEMPMONINT			0x80C
40 #define   EN7581_STAGE3_INT_EN			BIT(31)
41 #define   EN7581_STAGE2_INT_EN			BIT(30)
42 #define   EN7581_STAGE1_INT_EN			BIT(29)
43 #define   EN7581_FILTER_INT_EN_3		BIT(28)
44 #define   EN7581_IMMD_INT_EN3			BIT(27)
45 #define   EN7581_NOHOTINTEN3			BIT(26)
46 #define   EN7581_HOFSINTEN3			BIT(25)
47 #define   EN7581_LOFSINTEN3			BIT(24)
48 #define   EN7581_HINTEN3			BIT(23)
49 #define   EN7581_CINTEN3			BIT(22)
50 #define   EN7581_FILTER_INT_EN_2		BIT(21)
51 #define   EN7581_FILTER_INT_EN_1		BIT(20)
52 #define   EN7581_FILTER_INT_EN_0		BIT(19)
53 #define   EN7581_IMMD_INT_EN2			BIT(18)
54 #define   EN7581_IMMD_INT_EN1			BIT(17)
55 #define   EN7581_IMMD_INT_EN0			BIT(16)
56 #define   EN7581_TIME_OUT_INT_EN		BIT(15)
57 #define   EN7581_NOHOTINTEN2			BIT(14)
58 #define   EN7581_HOFSINTEN2			BIT(13)
59 #define   EN7581_LOFSINTEN2			BIT(12)
60 #define   EN7581_HINTEN2			BIT(11)
61 #define   EN7581_CINTEN2			BIT(10)
62 #define   EN7581_NOHOTINTEN1			BIT(9)
63 #define   EN7581_HOFSINTEN1			BIT(8)
64 #define   EN7581_LOFSINTEN1			BIT(7)
65 #define   EN7581_HINTEN1			BIT(6)
66 #define   EN7581_CINTEN1			BIT(5)
67 #define   EN7581_NOHOTINTEN0			BIT(4)
68 /* Similar to COLD and HOT also these seems to be swapped in documentation */
69 #define   EN7581_LOFSINTEN0			BIT(3) /* In documentation: BIT(2) */
70 #define   EN7581_HOFSINTEN0			BIT(2) /* In documentation: BIT(3) */
71 /* It seems documentation have these swapped as the HW
72  * - Fire BIT(1) when lower than EN7581_COLD_THRE
73  * - Fire BIT(0) and BIT(5) when higher than EN7581_HOT2NORMAL_THRE or
74  *     EN7581_HOT_THRE
75  */
76 #define   EN7581_CINTEN0			BIT(1) /* In documentation: BIT(0) */
77 #define   EN7581_HINTEN0			BIT(0) /* In documentation: BIT(1) */
78 #define EN7581_TEMPMONINTSTS			0x810
79 #define   EN7581_STAGE3_INT_STAT		BIT(31)
80 #define   EN7581_STAGE2_INT_STAT		BIT(30)
81 #define   EN7581_STAGE1_INT_STAT		BIT(29)
82 #define   EN7581_FILTER_INT_STAT_3		BIT(28)
83 #define   EN7581_IMMD_INT_STS3			BIT(27)
84 #define   EN7581_NOHOTINTSTS3			BIT(26)
85 #define   EN7581_HOFSINTSTS3			BIT(25)
86 #define   EN7581_LOFSINTSTS3			BIT(24)
87 #define   EN7581_HINTSTS3			BIT(23)
88 #define   EN7581_CINTSTS3			BIT(22)
89 #define   EN7581_FILTER_INT_STAT_2		BIT(21)
90 #define   EN7581_FILTER_INT_STAT_1		BIT(20)
91 #define   EN7581_FILTER_INT_STAT_0		BIT(19)
92 #define   EN7581_IMMD_INT_STS2			BIT(18)
93 #define   EN7581_IMMD_INT_STS1			BIT(17)
94 #define   EN7581_IMMD_INT_STS0			BIT(16)
95 #define   EN7581_TIME_OUT_INT_STAT		BIT(15)
96 #define   EN7581_NOHOTINTSTS2			BIT(14)
97 #define   EN7581_HOFSINTSTS2			BIT(13)
98 #define   EN7581_LOFSINTSTS2			BIT(12)
99 #define   EN7581_HINTSTS2			BIT(11)
100 #define   EN7581_CINTSTS2			BIT(10)
101 #define   EN7581_NOHOTINTSTS1			BIT(9)
102 #define   EN7581_HOFSINTSTS1			BIT(8)
103 #define   EN7581_LOFSINTSTS1			BIT(7)
104 #define   EN7581_HINTSTS1			BIT(6)
105 #define   EN7581_CINTSTS1			BIT(5)
106 #define   EN7581_NOHOTINTSTS0			BIT(4)
107 /* Similar to COLD and HOT also these seems to be swapped in documentation */
108 #define   EN7581_LOFSINTSTS0			BIT(3) /* In documentation: BIT(2) */
109 #define   EN7581_HOFSINTSTS0			BIT(2) /* In documentation: BIT(3) */
110 /* It seems documentation have these swapped as the HW
111  * - Fire BIT(1) when lower than EN7581_COLD_THRE
112  * - Fire BIT(0) and BIT(5) when higher than EN7581_HOT2NORMAL_THRE or
113  *     EN7581_HOT_THRE
114  *
115  * To clear things, we swap the define but we keep them documented here.
116  */
117 #define   EN7581_CINTSTS0			BIT(1) /* In documentation: BIT(0) */
118 #define   EN7581_HINTSTS0			BIT(0) /* In documentation: BIT(1)*/
119 /* Monitor will take the bigger threshold between HOT2NORMAL and HOT
120  * and will fire both HOT2NORMAL and HOT interrupt when higher than the 2
121  *
122  * It has also been observed that not setting HOT2NORMAL makes the monitor
123  * treat COLD threshold as HOT2NORMAL.
124  */
125 #define EN7581_TEMPH2NTHRE			0x824
126 /* It seems HOT2NORMAL is actually NORMAL2HOT */
127 #define   EN7581_HOT2NORMAL_THRE		GENMASK(11, 0)
128 #define EN7581_TEMPHTHRE			0x828
129 #define   EN7581_HOT_THRE			GENMASK(11, 0)
130 /* Monitor will use this as HOT2NORMAL (fire interrupt when lower than...)*/
131 #define EN7581_TEMPCTHRE			0x82c
132 #define   EN7581_COLD_THRE			GENMASK(11, 0)
133 /* Also LOW and HIGH offset register are swapped */
134 #define EN7581_TEMPOFFSETL			0x830 /* In documentation: 0x834 */
135 #define   EN7581_LOW_OFFSET			GENMASK(11, 0)
136 #define EN7581_TEMPOFFSETH			0x834 /* In documentation: 0x830 */
137 #define   EN7581_HIGH_OFFSET			GENMASK(11, 0)
138 #define EN7581_TEMPMSRCTL0			0x838
139 #define   EN7581_MSRCTL3			GENMASK(11, 9)
140 #define   EN7581_MSRCTL2			GENMASK(8, 6)
141 #define   EN7581_MSRCTL1			GENMASK(5, 3)
142 #define   EN7581_MSRCTL0			GENMASK(2, 0)
143 #define EN7581_TEMPADCVALIDADDR			0x878
144 #define   EN7581_ADC_VALID_ADDR			GENMASK(31, 0)
145 #define EN7581_TEMPADCVOLTADDR			0x87c
146 #define   EN7581_ADC_VOLT_ADDR			GENMASK(31, 0)
147 #define EN7581_TEMPRDCTRL			0x880
148 /*
149  * NOTICE: AHB have this set to 0 by default. Means that
150  * the same addr is used for ADC volt and valid reading.
151  * In such case, VALID ADDR is used and volt addr is ignored.
152  */
153 #define   EN7581_RD_CTRL_DIFF			BIT(0)
154 #define EN7581_TEMPADCVALIDMASK			0x884
155 #define   EN7581_ADV_RD_VALID_POLARITY		BIT(5)
156 #define   EN7581_ADV_RD_VALID_POS		GENMASK(4, 0)
157 #define EN7581_TEMPADCVOLTAGESHIFT		0x888
158 #define   EN7581_ADC_VOLTAGE_SHIFT		GENMASK(4, 0)
159 /*
160  * Same values for each CTL.
161  * Can operate in:
162  * - 1 sample
163  * - 2 sample and make average of them
164  * - 4,6,10,16 sample, drop max and min and make average of them
165  */
166 #define   EN7581_MSRCTL_1SAMPLE			0x0
167 #define   EN7581_MSRCTL_AVG2SAMPLE		0x1
168 #define   EN7581_MSRCTL_4SAMPLE_MAX_MIX_AVG2	0x2
169 #define   EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4	0x3
170 #define   EN7581_MSRCTL_10SAMPLE_MAX_MIX_AVG8	0x4
171 #define   EN7581_MSRCTL_18SAMPLE_MAX_MIX_AVG16	0x5
172 #define EN7581_TEMPAHBPOLL			0x840
173 #define   EN7581_ADC_POLL_INTVL			GENMASK(31, 0)
174 /* PTPSPARE0,2 reg are used to store efuse info for calibrated temp offset */
175 #define EN7581_EFUSE_TEMP_OFFSET_REG		0xf20 /* PTPSPARE0 */
176 #define   EN7581_EFUSE_TEMP_OFFSET		GENMASK(31, 16)
177 #define EN7581_PTPSPARE1			0xf24 /* PTPSPARE1 */
178 #define EN7581_EFUSE_TEMP_CPU_SENSOR_REG	0xf28 /* PTPSPARE2 */
179 
180 #define EN7581_SLOPE_X100_DIO_DEFAULT		5645
181 #define EN7581_SLOPE_X100_DIO_AVS		5645
182 
183 #define EN7581_INIT_TEMP_CPK_X10		300
184 #define EN7581_INIT_TEMP_FTK_X10		620
185 #define EN7581_INIT_TEMP_NONK_X10		550
186 
187 #define EN7581_SCU_THERMAL_PROTECT_KEY		0x12
188 #define EN7581_SCU_THERMAL_MUX_DIODE1		0x7
189 
190 #define AN7583_SCU_THERMAL_PROTECT_KEY		0x80
191 #define AN7583_NUM_SENSOR			3
192 
193 #define AIROHA_THERMAL_NO_MUX_SENSOR		-1
194 
195 /* Convert temp to raw value as read from ADC	((((temp / 100) - init) * slope) / 1000) + offset */
196 #define TEMP_TO_RAW(priv, temp)			((((((temp) / 100) - (priv)->init_temp) * \
197 						  (priv)->default_slope) / 1000) + \
198 						 (priv)->default_offset)
199 
200 /* Convert raw to temp				((((temp - offset) * 1000) / slope + init) * 100) */
201 #define RAW_TO_TEMP(priv, raw)			(((((raw) - (priv)->default_offset) * 1000) / \
202 						  (priv)->default_slope + \
203 						  (priv)->init_temp) * 100)
204 
205 #define AIROHA_MAX_SAMPLES			6
206 
207 /*
208  * AN7583 supports all these ADC mux but the original driver
209  * always checked temp with the AN7583_BGP_TEMP_SENSOR.
210  * Assume using the other sensor temperature is invalid and
211  * always read from AN7583_BGP_TEMP_SENSOR.
212  *
213  * On top of this it's defined that AN7583 supports 3
214  * sensor: AN7583_BGP_TEMP_SENSOR, AN7583_GBE_TEMP_SENSOR,
215  * AN7583_CPU_TEMP_SENSOR.
216  *
217  * Provide the ADC mux for reference.
218  */
219 enum an7583_thermal_adc_mux {
220 	AN7583_BGP_TEMP_SENSOR,
221 	AN7583_PAD_AVS,
222 	AN7583_CORE_POWER,
223 	AN7583_AVSDAC_OUT,
224 	AN7583_VCM,
225 	AN7583_GBE_TEMP_SENSOR,
226 	AN7583_CPU_TEMP_SENSOR,
227 
228 	AN7583_ADC_MUX_MAX,
229 };
230 
231 enum an7583_thermal_diode_mux {
232 	AN7583_D0_TADC,
233 	AN7583_ZERO_TADC,
234 	AN7583_D1_TADC,
235 };
236 
237 enum airoha_thermal_chip_scu_field {
238 	AIROHA_THERMAL_DOUT_TADC,
239 	AIROHA_THERMAL_MUX_SENSOR,
240 	AIROHA_THERMAL_MUX_TADC,
241 
242 	/* keep last */
243 	AIROHA_THERMAL_FIELD_MAX,
244 };
245 
246 struct airoha_thermal_priv {
247 	struct regmap *map;
248 	struct regmap *chip_scu;
249 	struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX];
250 	struct resource scu_adc_res;
251 
252 	u32 pllrg_protect;
253 	int current_adc;
254 
255 	struct thermal_zone_device *tz;
256 	int init_temp;
257 	int default_slope;
258 	int default_offset;
259 };
260 
261 struct airoha_thermal_soc_data {
262 	u32 pllrg_protect;
263 
264 	const struct thermal_zone_device_ops *thdev_ops;
265 	int (*probe)(struct platform_device *pdev,
266 		     struct airoha_thermal_priv *priv);
267 	int (*post_probe)(struct platform_device *pdev);
268 };
269 
270 static const unsigned int an7583_thermal_coeff[AN7583_ADC_MUX_MAX] = {
271 	[AN7583_BGP_TEMP_SENSOR] = 973,
272 	[AN7583_GBE_TEMP_SENSOR] = 995,
273 	[AN7583_CPU_TEMP_SENSOR] = 1035,
274 };
275 
276 static const unsigned int an7583_thermal_slope[AN7583_ADC_MUX_MAX] = {
277 	[AN7583_BGP_TEMP_SENSOR] = 7440,
278 	[AN7583_GBE_TEMP_SENSOR] = 7620,
279 	[AN7583_CPU_TEMP_SENSOR] = 8390,
280 };
281 
282 static const unsigned int an7583_thermal_offset[AN7583_ADC_MUX_MAX] = {
283 	[AN7583_BGP_TEMP_SENSOR] = 294,
284 	[AN7583_GBE_TEMP_SENSOR] = 298,
285 	[AN7583_CPU_TEMP_SENSOR] = 344,
286 };
287 
airoha_get_thermal_ADC(struct airoha_thermal_priv * priv)288 static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
289 {
290 	u32 val;
291 
292 	regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC],
293 			  &val);
294 	return val;
295 }
296 
airoha_set_thermal_mux(struct airoha_thermal_priv * priv,int tdac_idx,int sensor_idx)297 static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
298 				   int tdac_idx, int sensor_idx)
299 {
300 	u32 pllrg;
301 
302 	/* Save PLLRG current value */
303 	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
304 
305 	/* Give access to Thermal regs */
306 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
307 		     priv->pllrg_protect);
308 
309 	/*
310 	 * Configure Thermal Sensor mux to sensor_idx.
311 	 * (if not supported, sensor_idx is AIROHA_THERMAL_NO_MUX_SENSOR)
312 	 */
313 	if (sensor_idx != AIROHA_THERMAL_NO_MUX_SENSOR)
314 		regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_SENSOR],
315 				   sensor_idx);
316 
317 	/* Configure Thermal ADC mux to tdac_idx */
318 	if (priv->current_adc != tdac_idx) {
319 		regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
320 				   tdac_idx);
321 		priv->current_adc = tdac_idx;
322 	}
323 
324 	/* Restore PLLRG value on exit */
325 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
326 
327 	/* Sleep 10 ms for Thermal ADC to enable */
328 	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
329 }
330 
en7581_thermal_get_temp(struct thermal_zone_device * tz,int * temp)331 static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
332 {
333 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
334 	int min_value, max_value, avg_value, value;
335 	int i;
336 
337 	avg_value = 0;
338 	min_value = INT_MAX;
339 	max_value = INT_MIN;
340 
341 	for (i = 0; i < AIROHA_MAX_SAMPLES; i++) {
342 		value = airoha_get_thermal_ADC(priv);
343 		min_value = min(value, min_value);
344 		max_value = max(value, max_value);
345 		avg_value += value;
346 	}
347 
348 	/* Drop min and max and average for the remaining sample */
349 	avg_value -= (min_value + max_value);
350 	avg_value /= AIROHA_MAX_SAMPLES - 2;
351 
352 	*temp = RAW_TO_TEMP(priv, avg_value);
353 	return 0;
354 }
355 
en7581_thermal_set_trips(struct thermal_zone_device * tz,int low,int high)356 static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low,
357 				    int high)
358 {
359 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
360 	bool enable_monitor = false;
361 
362 	if (high != INT_MAX) {
363 		/* Validate high and clamp it a supported value */
364 		high = clamp_t(int, high, RAW_TO_TEMP(priv, 0),
365 			       RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
366 
367 		/* We offset the high temp of 1°C to trigger correct event */
368 		regmap_write(priv->map, EN7581_TEMPOFFSETH,
369 			     TEMP_TO_RAW(priv, high) >> 4);
370 
371 		enable_monitor = true;
372 	}
373 
374 	if (low != -INT_MAX) {
375 		/* Validate low and clamp it to a supported value */
376 		low = clamp_t(int, low, RAW_TO_TEMP(priv, 0),
377 			      RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
378 
379 		/* We offset the low temp of 1°C to trigger correct event */
380 		regmap_write(priv->map, EN7581_TEMPOFFSETL,
381 			     TEMP_TO_RAW(priv, low) >> 4);
382 
383 		enable_monitor = true;
384 	}
385 
386 	/* Enable sensor 0 monitor after trip are set */
387 	if (enable_monitor)
388 		regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN);
389 
390 	return 0;
391 }
392 
393 static const struct thermal_zone_device_ops en7581_thdev_ops = {
394 	.get_temp = en7581_thermal_get_temp,
395 	.set_trips = en7581_thermal_set_trips,
396 };
397 
en7581_thermal_irq(int irq,void * data)398 static irqreturn_t en7581_thermal_irq(int irq, void *data)
399 {
400 	struct airoha_thermal_priv *priv = data;
401 	enum thermal_notify_event event;
402 	bool update = false;
403 	u32 status = 0;
404 
405 	regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status);
406 	switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
407 	case EN7581_HOFSINTSTS0:
408 		event = THERMAL_TRIP_VIOLATED;
409 		update = true;
410 		break;
411 	case EN7581_LOFSINTSTS0:
412 		event = THERMAL_EVENT_UNSPECIFIED;
413 		update = true;
414 		break;
415 	default:
416 		/* Should be impossible as we enable only these Interrupt */
417 		break;
418 	}
419 
420 	/* Reset Interrupt */
421 	regmap_write(priv->map, EN7581_TEMPMONINTSTS, status);
422 
423 	if (update)
424 		thermal_zone_device_update(priv->tz, event);
425 
426 	return IRQ_HANDLED;
427 }
428 
en7581_thermal_setup_adc_val(struct device * dev,struct airoha_thermal_priv * priv)429 static void en7581_thermal_setup_adc_val(struct device *dev,
430 					 struct airoha_thermal_priv *priv)
431 {
432 	u32 efuse_calib_info = 0;
433 	u32 cpu_sensor = 0;
434 
435 	/* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
436 	airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1,
437 			       AIROHA_THERMAL_NO_MUX_SENSOR);
438 
439 	regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
440 	if (efuse_calib_info) {
441 		priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info);
442 		/* Different slope are applied if the sensor is used for CPU or for package */
443 		regmap_read(priv->map, EN7581_EFUSE_TEMP_CPU_SENSOR_REG, &cpu_sensor);
444 		if (cpu_sensor) {
445 			priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;
446 			priv->init_temp = EN7581_INIT_TEMP_FTK_X10;
447 		} else {
448 			priv->default_slope = EN7581_SLOPE_X100_DIO_AVS;
449 			priv->init_temp = EN7581_INIT_TEMP_CPK_X10;
450 		}
451 	} else {
452 		priv->default_offset = airoha_get_thermal_ADC(priv);
453 		priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;
454 		priv->init_temp = EN7581_INIT_TEMP_NONK_X10;
455 		dev_info(dev, "missing thermal calibration EFUSE, using non calibrated value\n");
456 	}
457 }
458 
en7581_thermal_setup_monitor(struct airoha_thermal_priv * priv)459 static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv)
460 {
461 	/* Set measure mode */
462 	regmap_write(priv->map, EN7581_TEMPMSRCTL0,
463 		     FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4));
464 
465 	/*
466 	 * Configure ADC valid reading addr
467 	 * The AHB temp monitor system doesn't have direct access to the
468 	 * thermal sensor. It does instead work by providing various
469 	 * addresses to configure how to access and setup an ADC for the
470 	 * sensor. EN7581 supports only one sensor hence the
471 	 * implementation is greatly simplified but the AHB supports
472 	 * up to 4 different sensors from the same ADC that can be
473 	 * switched by tuning the ADC mux or writing address.
474 	 *
475 	 * We set valid instead of volt as we don't enable valid/volt
476 	 * split reading and AHB read valid addr in such case.
477 	 */
478 	regmap_write(priv->map, EN7581_TEMPADCVALIDADDR,
479 		     priv->scu_adc_res.start + EN7581_DOUT_TADC);
480 
481 	/*
482 	 * Configure valid bit on a fake value of bit 16. The ADC outputs
483 	 * max of 2 bytes for voltage.
484 	 */
485 	regmap_write(priv->map, EN7581_TEMPADCVALIDMASK,
486 		     FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16));
487 
488 	/*
489 	 * AHB supports max 12 bytes for ADC voltage. Shift the read
490 	 * value 4 bit to the right. Precision lost by this is minimal
491 	 * in the order of half a °C and is acceptable in the context
492 	 * of triggering interrupt in critical condition.
493 	 */
494 	regmap_write(priv->map, EN7581_TEMPADCVOLTAGESHIFT,
495 		     FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4));
496 
497 	/* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */
498 	regmap_write(priv->map, EN7581_TEMPMONCTL1,
499 		     FIELD_PREP(EN7581_PERIOD_UNIT, 3));
500 
501 	/*
502 	 * filt interval is 1 * 52.715us = 52.715us,
503 	 * sen interval is 379 * 52.715us = 19.97ms
504 	 */
505 	regmap_write(priv->map, EN7581_TEMPMONCTL2,
506 		     FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
507 		     FIELD_PREP(EN7581_SEN_INTERVAL, 379));
508 
509 	/* AHB poll is set to 146 * 68.64 = 10.02us */
510 	regmap_write(priv->map, EN7581_TEMPAHBPOLL,
511 		     FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
512 }
513 
514 static const struct regmap_config en7581_thermal_regmap_config = {
515 	.reg_bits		= 32,
516 	.reg_stride		= 4,
517 	.val_bits		= 32,
518 };
519 
520 static const struct reg_field en7581_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
521 	[AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(EN7581_DOUT_TADC, 0, 15),
522 	[AIROHA_THERMAL_MUX_TADC] = REG_FIELD(EN7581_PWD_TADC, 1, 3),
523 };
524 
en7581_thermal_probe(struct platform_device * pdev,struct airoha_thermal_priv * priv)525 static int en7581_thermal_probe(struct platform_device *pdev,
526 				struct airoha_thermal_priv *priv)
527 {
528 	struct device_node *chip_scu_np;
529 	struct device *dev = &pdev->dev;
530 	void __iomem *base;
531 	int i, irq, ret;
532 
533 	base = devm_platform_ioremap_resource(pdev, 0);
534 	if (IS_ERR(base))
535 		return PTR_ERR(base);
536 
537 	priv->map = devm_regmap_init_mmio(dev, base,
538 					  &en7581_thermal_regmap_config);
539 	if (IS_ERR(priv->map))
540 		return PTR_ERR(priv->map);
541 
542 	chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0);
543 	if (!chip_scu_np)
544 		return -EINVAL;
545 
546 	priv->chip_scu = syscon_node_to_regmap(chip_scu_np);
547 	if (IS_ERR(priv->chip_scu))
548 		return PTR_ERR(priv->chip_scu);
549 
550 	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
551 		struct regmap_field *field;
552 
553 		/* Skip registering MUX_SENSOR field as not supported */
554 		if (i == AIROHA_THERMAL_MUX_SENSOR)
555 			continue;
556 
557 		field = devm_regmap_field_alloc(dev, priv->chip_scu,
558 						en7581_chip_scu_fields[i]);
559 		if (IS_ERR(field)) {
560 			of_node_put(chip_scu_np);
561 			return PTR_ERR(field);
562 		}
563 
564 		priv->chip_scu_fields[i] = field;
565 	}
566 
567 	of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);
568 	of_node_put(chip_scu_np);
569 
570 	irq = platform_get_irq(pdev, 0);
571 	if (irq < 0)
572 		return irq;
573 
574 	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
575 					en7581_thermal_irq, IRQF_ONESHOT,
576 					pdev->name, priv);
577 	if (ret)
578 		return ret;
579 
580 	en7581_thermal_setup_monitor(priv);
581 	en7581_thermal_setup_adc_val(dev, priv);
582 
583 	return 0;
584 }
585 
en7581_thermal_post_probe(struct platform_device * pdev)586 static int en7581_thermal_post_probe(struct platform_device *pdev)
587 {
588 	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
589 
590 	/* Enable LOW and HIGH interrupt (if supported) */
591 	regmap_write(priv->map, EN7581_TEMPMONINT,
592 		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
593 
594 	return 0;
595 }
596 
an7583_thermal_get_temp(struct thermal_zone_device * tz,int * temp)597 static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
598 {
599 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
600 	int sensor_idx;
601 	int delta_diode, delta_gain;
602 	int coeff, slope, offset;
603 
604 	int diode_zero, diode_d0, diode_d1;
605 
606 	/* Always read sensor AN7583_BGP_TEMP_SENSOR */
607 	sensor_idx = AN7583_BGP_TEMP_SENSOR;
608 
609 	coeff = an7583_thermal_coeff[sensor_idx];
610 	slope = an7583_thermal_slope[sensor_idx];
611 	offset = an7583_thermal_offset[sensor_idx];
612 
613 	airoha_set_thermal_mux(priv, AN7583_ZERO_TADC, sensor_idx);
614 	diode_zero = airoha_get_thermal_ADC(priv);
615 	airoha_set_thermal_mux(priv, AN7583_D0_TADC, sensor_idx);
616 	diode_d0 = airoha_get_thermal_ADC(priv);
617 	airoha_set_thermal_mux(priv, AN7583_D1_TADC, sensor_idx);
618 	diode_d1 = airoha_get_thermal_ADC(priv);
619 
620 	delta_diode = diode_d1 - diode_d0;
621 	delta_gain = (delta_diode * coeff) / 100 + (diode_zero - diode_d1);
622 	if (!delta_gain)
623 		return -EINVAL;
624 
625 	*temp = (slope * delta_diode * 10) / delta_gain - offset * 10;
626 	*temp *= 100;
627 
628 	return 0;
629 }
630 
631 static const struct thermal_zone_device_ops an7583_tz_ops = {
632 	.get_temp = an7583_thermal_get_temp,
633 };
634 
635 static const struct reg_field an7583_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
636 	[AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(AN7583_DOUT_TADC, 0, 31),
637 	[AIROHA_THERMAL_MUX_TADC] = REG_FIELD(AN7583_MUX_TADC, 1, 3),
638 	[AIROHA_THERMAL_MUX_SENSOR] = REG_FIELD(AN7583_MUX_SENSOR, 2, 3),
639 };
640 
an7583_thermal_probe(struct platform_device * pdev,struct airoha_thermal_priv * priv)641 static int an7583_thermal_probe(struct platform_device *pdev,
642 				struct airoha_thermal_priv *priv)
643 {
644 	struct device *dev = &pdev->dev;
645 	int i;
646 
647 	priv->chip_scu = device_node_to_regmap(dev->of_node);
648 	if (IS_ERR(priv->chip_scu))
649 		return PTR_ERR(priv->chip_scu);
650 
651 	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
652 		struct regmap_field *field;
653 
654 		field = devm_regmap_field_alloc(dev, priv->chip_scu,
655 						an7583_chip_scu_fields[i]);
656 		if (IS_ERR(field))
657 			return PTR_ERR(field);
658 
659 		priv->chip_scu_fields[i] = field;
660 	}
661 
662 	return 0;
663 }
664 
airoha_thermal_probe(struct platform_device * pdev)665 static int airoha_thermal_probe(struct platform_device *pdev)
666 {
667 	const struct airoha_thermal_soc_data *soc_data;
668 	struct airoha_thermal_priv *priv;
669 	struct device *dev = &pdev->dev;
670 	int ret;
671 
672 	soc_data = device_get_match_data(dev);
673 
674 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
675 	if (!priv)
676 		return -ENOMEM;
677 
678 	priv->pllrg_protect = soc_data->pllrg_protect;
679 	priv->current_adc = -1;
680 
681 	if (!soc_data->probe)
682 		return -EINVAL;
683 
684 	ret = soc_data->probe(pdev, priv);
685 	if (ret)
686 		return ret;
687 
688 	/* register of thermal sensor and get info from DT */
689 	priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
690 						 soc_data->thdev_ops);
691 	if (IS_ERR(priv->tz)) {
692 		dev_err(dev, "register thermal zone sensor failed\n");
693 		return PTR_ERR(priv->tz);
694 	}
695 
696 	platform_set_drvdata(pdev, priv);
697 
698 	return soc_data->post_probe ? soc_data->post_probe(pdev) : 0;
699 }
700 
701 static const struct airoha_thermal_soc_data en7581_data = {
702 	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
703 	.thdev_ops = &en7581_thdev_ops,
704 	.probe = &en7581_thermal_probe,
705 	.post_probe = &en7581_thermal_post_probe,
706 };
707 
708 static const struct airoha_thermal_soc_data an7583_data = {
709 	.pllrg_protect = AN7583_SCU_THERMAL_PROTECT_KEY,
710 	.thdev_ops = &an7583_tz_ops,
711 	.probe = &an7583_thermal_probe,
712 };
713 
714 static const struct of_device_id airoha_thermal_match[] = {
715 	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
716 	{ .compatible = "airoha,an7583-chip-scu", .data = &an7583_data },
717 	{},
718 };
719 MODULE_DEVICE_TABLE(of, airoha_thermal_match);
720 
721 static struct platform_driver airoha_thermal_driver = {
722 	.driver = {
723 		.name = "airoha-thermal",
724 		.of_match_table = airoha_thermal_match,
725 	},
726 	.probe = airoha_thermal_probe,
727 };
728 
729 module_platform_driver(airoha_thermal_driver);
730 
731 MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
732 MODULE_DESCRIPTION("Airoha thermal driver");
733 MODULE_LICENSE("GPL");
734