1 // SPDX-License-Identifier: GPL-2.0
3 * Thermal sensor driver for Allwinner SOC
4 * Copyright (C) 2019 Yangtao Li
6 * Based on the work of Icenowy Zheng <icenowy@aosc.io>
7 * Based on the work of Ondrej Jirman <megous@megous.com>
8 * Based on the work of Josef Gajdusek <atx@atx.name>
11 #include <linux/bitmap.h>
12 #include <linux/cleanup.h>
13 #include <linux/clk.h>
14 #include <linux/device.h>
15 #include <linux/interrupt.h>
16 #include <linux/module.h>
17 #include <linux/nvmem-consumer.h>
19 #include <linux/of_platform.h>
20 #include <linux/platform_device.h>
21 #include <linux/regmap.h>
22 #include <linux/reset.h>
23 #include <linux/slab.h>
24 #include <linux/thermal.h>
26 #include "thermal_hwmon.h"
28 #define MAX_SENSOR_NUM 4
30 #define FT_TEMP_MASK GENMASK(11, 0)
31 #define TEMP_CALIB_MASK GENMASK(11, 0)
32 #define CALIBRATE_DEFAULT 0x800
34 #define SUN8I_THS_CTRL0 0x00
35 #define SUN8I_THS_CTRL2 0x40
36 #define SUN8I_THS_IC 0x44
37 #define SUN8I_THS_IS 0x48
38 #define SUN8I_THS_MFC 0x70
39 #define SUN8I_THS_TEMP_CALIB 0x74
40 #define SUN8I_THS_TEMP_DATA 0x80
42 #define SUN50I_THS_CTRL0 0x00
43 #define SUN50I_H6_THS_ENABLE 0x04
44 #define SUN50I_H6_THS_PC 0x08
45 #define SUN50I_H6_THS_DIC 0x10
46 #define SUN50I_H6_THS_DIS 0x20
47 #define SUN50I_H6_THS_MFC 0x30
48 #define SUN50I_H6_THS_TEMP_CALIB 0xa0
49 #define SUN50I_H6_THS_TEMP_DATA 0xc0
51 #define SUN8I_THS_CTRL0_T_ACQ0(x) (GENMASK(15, 0) & (x))
52 #define SUN8I_THS_CTRL2_T_ACQ1(x) ((GENMASK(15, 0) & (x)) << 16)
53 #define SUN8I_THS_DATA_IRQ_STS(x) BIT(x + 8)
55 #define SUN50I_THS_CTRL0_T_ACQ(x) (GENMASK(15, 0) & ((x) - 1))
56 #define SUN50I_THS_CTRL0_T_SAMPLE_PER(x) ((GENMASK(15, 0) & ((x) - 1)) << 16)
57 #define SUN50I_THS_FILTER_EN BIT(2)
58 #define SUN50I_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
59 #define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12)
60 #define SUN50I_H6_THS_DATA_IRQ_STS(x) BIT(x)
63 struct ths_device
*tmdev
;
64 struct thermal_zone_device
*tzd
;
68 struct ths_thermal_chip
{
70 bool has_bus_clk_reset
;
77 int (*calibrate
)(struct ths_device
*tmdev
,
78 u16
*caldata
, int callen
);
79 int (*init
)(struct ths_device
*tmdev
);
80 unsigned long (*irq_ack
)(struct ths_device
*tmdev
);
81 int (*calc_temp
)(struct ths_device
*tmdev
,
86 const struct ths_thermal_chip
*chip
;
88 struct regmap
*regmap
;
89 struct regmap_field
*sram_regmap_field
;
90 struct reset_control
*reset
;
93 struct tsensor sensor
[MAX_SENSOR_NUM
];
96 /* The H616 needs to have a bit 16 in the SRAM control register cleared. */
97 static const struct reg_field sun8i_ths_sram_reg_field
= REG_FIELD(0x0, 16, 16);
99 /* Temp Unit: millidegree Celsius */
100 static int sun8i_ths_calc_temp(struct ths_device
*tmdev
,
103 return tmdev
->chip
->offset
- (reg
* tmdev
->chip
->scale
/ 10);
106 static int sun50i_h5_calc_temp(struct ths_device
*tmdev
,
110 return -1191 * reg
/ 10 + 223000;
112 return -1452 * reg
/ 10 + 259000;
114 return -1590 * reg
/ 10 + 276000;
117 static int sun8i_ths_get_temp(struct thermal_zone_device
*tz
, int *temp
)
119 struct tsensor
*s
= thermal_zone_device_priv(tz
);
120 struct ths_device
*tmdev
= s
->tmdev
;
123 regmap_read(tmdev
->regmap
, tmdev
->chip
->temp_data_base
+
126 /* ths have no data yet */
130 *temp
= tmdev
->chip
->calc_temp(tmdev
, s
->id
, val
);
132 * According to the original sdk, there are some platforms(rarely)
133 * that add a fixed offset value after calculating the temperature
134 * value. We can't simply put it on the formula for calculating the
135 * temperature above, because the formula for calculating the
136 * temperature above is also used when the sensor is calibrated. If
137 * do this, the correct calibration formula is hard to know.
139 *temp
+= tmdev
->chip
->ft_deviation
;
144 static const struct thermal_zone_device_ops ths_ops
= {
145 .get_temp
= sun8i_ths_get_temp
,
148 static const struct regmap_config config
= {
153 .max_register
= 0xfc,
156 static unsigned long sun8i_h3_irq_ack(struct ths_device
*tmdev
)
158 unsigned long irq_bitmap
= 0;
161 regmap_read(tmdev
->regmap
, SUN8I_THS_IS
, &state
);
163 for (i
= 0; i
< tmdev
->chip
->sensor_num
; i
++) {
164 if (state
& SUN8I_THS_DATA_IRQ_STS(i
)) {
165 regmap_write(tmdev
->regmap
, SUN8I_THS_IS
,
166 SUN8I_THS_DATA_IRQ_STS(i
));
167 bitmap_set(&irq_bitmap
, i
, 1);
174 static unsigned long sun50i_h6_irq_ack(struct ths_device
*tmdev
)
176 unsigned long irq_bitmap
= 0;
179 regmap_read(tmdev
->regmap
, SUN50I_H6_THS_DIS
, &state
);
181 for (i
= 0; i
< tmdev
->chip
->sensor_num
; i
++) {
182 if (state
& SUN50I_H6_THS_DATA_IRQ_STS(i
)) {
183 regmap_write(tmdev
->regmap
, SUN50I_H6_THS_DIS
,
184 SUN50I_H6_THS_DATA_IRQ_STS(i
));
185 bitmap_set(&irq_bitmap
, i
, 1);
192 static irqreturn_t
sun8i_irq_thread(int irq
, void *data
)
194 struct ths_device
*tmdev
= data
;
195 unsigned long irq_bitmap
= tmdev
->chip
->irq_ack(tmdev
);
198 for_each_set_bit(i
, &irq_bitmap
, tmdev
->chip
->sensor_num
) {
199 /* We allow some zones to not register. */
200 if (IS_ERR(tmdev
->sensor
[i
].tzd
))
202 thermal_zone_device_update(tmdev
->sensor
[i
].tzd
,
203 THERMAL_EVENT_UNSPECIFIED
);
209 static int sun8i_h3_ths_calibrate(struct ths_device
*tmdev
,
210 u16
*caldata
, int callen
)
214 if (!caldata
[0] || callen
< 2 * tmdev
->chip
->sensor_num
)
217 for (i
= 0; i
< tmdev
->chip
->sensor_num
; i
++) {
218 int offset
= (i
% 2) << 4;
220 regmap_update_bits(tmdev
->regmap
,
221 SUN8I_THS_TEMP_CALIB
+ (4 * (i
>> 1)),
222 TEMP_CALIB_MASK
<< offset
,
223 caldata
[i
] << offset
);
229 static int sun50i_h6_ths_calibrate(struct ths_device
*tmdev
,
230 u16
*caldata
, int callen
)
232 struct device
*dev
= tmdev
->dev
;
241 * 0 11 16 27 32 43 48 57
242 * +----------+-----------+-----------+-----------+
243 * | temp | |sensor0| |sensor1| |sensor2| |
244 * +----------+-----------+-----------+-----------+
251 * The calibration data on the H6 is the ambient temperature and
252 * sensor values that are filled during the factory test stage.
254 * The unit of stored FT temperature is 0.1 degree celsius.
256 * We need to calculate a delta between measured and caluclated
257 * register values and this will become a calibration offset.
259 ft_temp
= (caldata
[0] & FT_TEMP_MASK
) * 100;
261 for (i
= 0; i
< tmdev
->chip
->sensor_num
; i
++) {
262 int sensor_reg
, sensor_temp
, cdata
, offset
;
265 sensor_reg
= (caldata
[1] >> 12)
266 | ((caldata
[2] >> 12) << 4)
267 | ((caldata
[3] >> 12) << 8);
269 sensor_reg
= caldata
[i
+ 1] & TEMP_CALIB_MASK
;
271 sensor_temp
= tmdev
->chip
->calc_temp(tmdev
, i
, sensor_reg
);
274 * Calibration data is CALIBRATE_DEFAULT - (calculated
275 * temperature from sensor reading at factory temperature
276 * minus actual factory temperature) * 14.88 (scale from
277 * temperature to register values)
279 cdata
= CALIBRATE_DEFAULT
-
280 ((sensor_temp
- ft_temp
) * 10 / tmdev
->chip
->scale
);
281 if (cdata
& ~TEMP_CALIB_MASK
) {
283 * Calibration value more than 12-bit, but calibration
284 * register is 12-bit. In this case, ths hardware can
285 * still work without calibration, although the data
286 * won't be so accurate.
288 dev_warn(dev
, "sensor%d is not calibrated.\n", i
);
292 offset
= (i
% 2) * 16;
293 regmap_update_bits(tmdev
->regmap
,
294 SUN50I_H6_THS_TEMP_CALIB
+ (i
/ 2 * 4),
295 TEMP_CALIB_MASK
<< offset
,
302 static int sun8i_ths_calibrate(struct ths_device
*tmdev
)
304 struct nvmem_cell
*calcell
;
305 struct device
*dev
= tmdev
->dev
;
310 calcell
= nvmem_cell_get(dev
, "calibration");
311 if (IS_ERR(calcell
)) {
312 if (PTR_ERR(calcell
) == -EPROBE_DEFER
)
313 return -EPROBE_DEFER
;
315 * Even if the external calibration data stored in sid is
316 * not accessible, the THS hardware can still work, although
317 * the data won't be so accurate.
319 * The default value of calibration register is 0x800 for
320 * every sensor, and the calibration value is usually 0x7xx
321 * or 0x8xx, so they won't be away from the default value
324 * So here we do not return error if the calibration data is
325 * not available, except the probe needs deferring.
330 caldata
= nvmem_cell_read(calcell
, &callen
);
331 if (IS_ERR(caldata
)) {
332 ret
= PTR_ERR(caldata
);
336 tmdev
->chip
->calibrate(tmdev
, caldata
, callen
);
340 if (!IS_ERR(calcell
))
341 nvmem_cell_put(calcell
);
345 static void sun8i_ths_reset_control_assert(void *data
)
347 reset_control_assert(data
);
350 static struct regmap
*sun8i_ths_get_sram_regmap(struct device_node
*node
)
352 struct platform_device
*sram_pdev
;
353 struct regmap
*regmap
= NULL
;
355 struct device_node
*sram_node
__free(device_node
) =
356 of_parse_phandle(node
, "allwinner,sram", 0);
358 return ERR_PTR(-ENODEV
);
360 sram_pdev
= of_find_device_by_node(sram_node
);
362 /* platform device might not be probed yet */
363 return ERR_PTR(-EPROBE_DEFER
);
366 /* If no regmap is found then the other device driver is at fault */
367 regmap
= dev_get_regmap(&sram_pdev
->dev
, NULL
);
369 regmap
= ERR_PTR(-EINVAL
);
371 platform_device_put(sram_pdev
);
376 static int sun8i_ths_resource_init(struct ths_device
*tmdev
)
378 struct device
*dev
= tmdev
->dev
;
379 struct platform_device
*pdev
= to_platform_device(dev
);
383 base
= devm_platform_ioremap_resource(pdev
, 0);
385 return PTR_ERR(base
);
387 tmdev
->regmap
= devm_regmap_init_mmio(dev
, base
, &config
);
388 if (IS_ERR(tmdev
->regmap
))
389 return PTR_ERR(tmdev
->regmap
);
391 if (tmdev
->chip
->has_bus_clk_reset
) {
392 tmdev
->reset
= devm_reset_control_get(dev
, NULL
);
393 if (IS_ERR(tmdev
->reset
))
394 return PTR_ERR(tmdev
->reset
);
396 ret
= reset_control_deassert(tmdev
->reset
);
400 ret
= devm_add_action_or_reset(dev
, sun8i_ths_reset_control_assert
,
405 tmdev
->bus_clk
= devm_clk_get_enabled(&pdev
->dev
, "bus");
406 if (IS_ERR(tmdev
->bus_clk
))
407 return PTR_ERR(tmdev
->bus_clk
);
410 if (tmdev
->chip
->has_mod_clk
) {
411 tmdev
->mod_clk
= devm_clk_get_enabled(&pdev
->dev
, "mod");
412 if (IS_ERR(tmdev
->mod_clk
))
413 return PTR_ERR(tmdev
->mod_clk
);
416 ret
= clk_set_rate(tmdev
->mod_clk
, 24000000);
420 if (tmdev
->chip
->needs_sram
) {
421 struct regmap
*regmap
;
423 regmap
= sun8i_ths_get_sram_regmap(dev
->of_node
);
425 return PTR_ERR(regmap
);
426 tmdev
->sram_regmap_field
= devm_regmap_field_alloc(dev
,
428 sun8i_ths_sram_reg_field
);
429 if (IS_ERR(tmdev
->sram_regmap_field
))
430 return PTR_ERR(tmdev
->sram_regmap_field
);
433 ret
= sun8i_ths_calibrate(tmdev
);
440 static int sun8i_h3_thermal_init(struct ths_device
*tmdev
)
444 /* average over 4 samples */
445 regmap_write(tmdev
->regmap
, SUN8I_THS_MFC
,
446 SUN50I_THS_FILTER_EN
|
447 SUN50I_THS_FILTER_TYPE(1));
453 * x = period * clkin / 4096 / filter_samples - 1
456 val
= GENMASK(7 + tmdev
->chip
->sensor_num
, 8);
457 regmap_write(tmdev
->regmap
, SUN8I_THS_IC
,
458 SUN50I_H6_THS_PC_TEMP_PERIOD(365) | val
);
463 * x = T_acq * clkin - 1
466 regmap_write(tmdev
->regmap
, SUN8I_THS_CTRL0
,
467 SUN8I_THS_CTRL0_T_ACQ0(479));
468 val
= GENMASK(tmdev
->chip
->sensor_num
- 1, 0);
469 regmap_write(tmdev
->regmap
, SUN8I_THS_CTRL2
,
470 SUN8I_THS_CTRL2_T_ACQ1(479) | val
);
475 static int sun50i_h6_thermal_init(struct ths_device
*tmdev
)
479 /* The H616 needs to have a bit in the SRAM control register cleared. */
480 if (tmdev
->sram_regmap_field
)
481 regmap_field_write(tmdev
->sram_regmap_field
, 0);
484 * The manual recommends an overall sample frequency of 50 KHz (20us,
485 * 480 cycles at 24 MHz), which provides plenty of time for both the
486 * acquisition time (>24 cycles) and the actual conversion time
488 * The lower half of the CTRL register holds the "acquire time", in
489 * clock cycles, which the manual recommends to be 2us:
490 * 24MHz * 2us = 48 cycles.
491 * The high half of THS_CTRL encodes the sample frequency, in clock
492 * cycles: 24MHz * 20us = 480 cycles.
493 * This is explained in the H616 manual, but apparently wrongly
494 * described in the H6 manual, although the BSP code does the same
497 regmap_write(tmdev
->regmap
, SUN50I_THS_CTRL0
,
498 SUN50I_THS_CTRL0_T_ACQ(48) |
499 SUN50I_THS_CTRL0_T_SAMPLE_PER(480));
500 /* average over 4 samples */
501 regmap_write(tmdev
->regmap
, SUN50I_H6_THS_MFC
,
502 SUN50I_THS_FILTER_EN
|
503 SUN50I_THS_FILTER_TYPE(1));
509 * x = period * clkin / 4096 / filter_samples - 1
512 regmap_write(tmdev
->regmap
, SUN50I_H6_THS_PC
,
513 SUN50I_H6_THS_PC_TEMP_PERIOD(365));
515 val
= GENMASK(tmdev
->chip
->sensor_num
- 1, 0);
516 regmap_write(tmdev
->regmap
, SUN50I_H6_THS_ENABLE
, val
);
517 /* thermal data interrupt enable */
518 val
= GENMASK(tmdev
->chip
->sensor_num
- 1, 0);
519 regmap_write(tmdev
->regmap
, SUN50I_H6_THS_DIC
, val
);
524 static int sun8i_ths_register(struct ths_device
*tmdev
)
528 for (i
= 0; i
< tmdev
->chip
->sensor_num
; i
++) {
529 tmdev
->sensor
[i
].tmdev
= tmdev
;
530 tmdev
->sensor
[i
].id
= i
;
531 tmdev
->sensor
[i
].tzd
=
532 devm_thermal_of_zone_register(tmdev
->dev
,
538 * If an individual zone fails to register for reasons
539 * other than probe deferral (eg, a bad DT) then carry
540 * on, other zones might register successfully.
542 if (IS_ERR(tmdev
->sensor
[i
].tzd
)) {
543 if (PTR_ERR(tmdev
->sensor
[i
].tzd
) == -EPROBE_DEFER
)
544 return PTR_ERR(tmdev
->sensor
[i
].tzd
);
548 devm_thermal_add_hwmon_sysfs(tmdev
->dev
, tmdev
->sensor
[i
].tzd
);
554 static int sun8i_ths_probe(struct platform_device
*pdev
)
556 struct ths_device
*tmdev
;
557 struct device
*dev
= &pdev
->dev
;
560 tmdev
= devm_kzalloc(dev
, sizeof(*tmdev
), GFP_KERNEL
);
565 tmdev
->chip
= of_device_get_match_data(&pdev
->dev
);
569 ret
= sun8i_ths_resource_init(tmdev
);
573 irq
= platform_get_irq(pdev
, 0);
577 ret
= tmdev
->chip
->init(tmdev
);
581 ret
= sun8i_ths_register(tmdev
);
586 * Avoid entering the interrupt handler, the thermal device is not
587 * registered yet, we deffer the registration of the interrupt to
590 ret
= devm_request_threaded_irq(dev
, irq
, NULL
,
592 IRQF_ONESHOT
, "ths", tmdev
);
599 static const struct ths_thermal_chip sun8i_a83t_ths
= {
603 .temp_data_base
= SUN8I_THS_TEMP_DATA
,
604 .calibrate
= sun8i_h3_ths_calibrate
,
605 .init
= sun8i_h3_thermal_init
,
606 .irq_ack
= sun8i_h3_irq_ack
,
607 .calc_temp
= sun8i_ths_calc_temp
,
610 static const struct ths_thermal_chip sun8i_h3_ths
= {
615 .has_bus_clk_reset
= true,
616 .temp_data_base
= SUN8I_THS_TEMP_DATA
,
617 .calibrate
= sun8i_h3_ths_calibrate
,
618 .init
= sun8i_h3_thermal_init
,
619 .irq_ack
= sun8i_h3_irq_ack
,
620 .calc_temp
= sun8i_ths_calc_temp
,
623 static const struct ths_thermal_chip sun8i_r40_ths
= {
628 .has_bus_clk_reset
= true,
629 .temp_data_base
= SUN8I_THS_TEMP_DATA
,
630 .calibrate
= sun8i_h3_ths_calibrate
,
631 .init
= sun8i_h3_thermal_init
,
632 .irq_ack
= sun8i_h3_irq_ack
,
633 .calc_temp
= sun8i_ths_calc_temp
,
636 static const struct ths_thermal_chip sun50i_a64_ths
= {
641 .has_bus_clk_reset
= true,
642 .temp_data_base
= SUN8I_THS_TEMP_DATA
,
643 .calibrate
= sun8i_h3_ths_calibrate
,
644 .init
= sun8i_h3_thermal_init
,
645 .irq_ack
= sun8i_h3_irq_ack
,
646 .calc_temp
= sun8i_ths_calc_temp
,
649 static const struct ths_thermal_chip sun50i_a100_ths
= {
651 .has_bus_clk_reset
= true,
652 .ft_deviation
= 8000,
655 .temp_data_base
= SUN50I_H6_THS_TEMP_DATA
,
656 .calibrate
= sun50i_h6_ths_calibrate
,
657 .init
= sun50i_h6_thermal_init
,
658 .irq_ack
= sun50i_h6_irq_ack
,
659 .calc_temp
= sun8i_ths_calc_temp
,
662 static const struct ths_thermal_chip sun50i_h5_ths
= {
665 .has_bus_clk_reset
= true,
666 .temp_data_base
= SUN8I_THS_TEMP_DATA
,
667 .calibrate
= sun8i_h3_ths_calibrate
,
668 .init
= sun8i_h3_thermal_init
,
669 .irq_ack
= sun8i_h3_irq_ack
,
670 .calc_temp
= sun50i_h5_calc_temp
,
673 static const struct ths_thermal_chip sun50i_h6_ths
= {
675 .has_bus_clk_reset
= true,
676 .ft_deviation
= 7000,
679 .temp_data_base
= SUN50I_H6_THS_TEMP_DATA
,
680 .calibrate
= sun50i_h6_ths_calibrate
,
681 .init
= sun50i_h6_thermal_init
,
682 .irq_ack
= sun50i_h6_irq_ack
,
683 .calc_temp
= sun8i_ths_calc_temp
,
686 static const struct ths_thermal_chip sun20i_d1_ths
= {
688 .has_bus_clk_reset
= true,
691 .temp_data_base
= SUN50I_H6_THS_TEMP_DATA
,
692 .calibrate
= sun50i_h6_ths_calibrate
,
693 .init
= sun50i_h6_thermal_init
,
694 .irq_ack
= sun50i_h6_irq_ack
,
695 .calc_temp
= sun8i_ths_calc_temp
,
698 static const struct ths_thermal_chip sun50i_h616_ths
= {
700 .has_bus_clk_reset
= true,
702 .ft_deviation
= 8000,
705 .temp_data_base
= SUN50I_H6_THS_TEMP_DATA
,
706 .calibrate
= sun50i_h6_ths_calibrate
,
707 .init
= sun50i_h6_thermal_init
,
708 .irq_ack
= sun50i_h6_irq_ack
,
709 .calc_temp
= sun8i_ths_calc_temp
,
712 static const struct of_device_id of_ths_match
[] = {
713 { .compatible
= "allwinner,sun8i-a83t-ths", .data
= &sun8i_a83t_ths
},
714 { .compatible
= "allwinner,sun8i-h3-ths", .data
= &sun8i_h3_ths
},
715 { .compatible
= "allwinner,sun8i-r40-ths", .data
= &sun8i_r40_ths
},
716 { .compatible
= "allwinner,sun50i-a64-ths", .data
= &sun50i_a64_ths
},
717 { .compatible
= "allwinner,sun50i-a100-ths", .data
= &sun50i_a100_ths
},
718 { .compatible
= "allwinner,sun50i-h5-ths", .data
= &sun50i_h5_ths
},
719 { .compatible
= "allwinner,sun50i-h6-ths", .data
= &sun50i_h6_ths
},
720 { .compatible
= "allwinner,sun20i-d1-ths", .data
= &sun20i_d1_ths
},
721 { .compatible
= "allwinner,sun50i-h616-ths", .data
= &sun50i_h616_ths
},
724 MODULE_DEVICE_TABLE(of
, of_ths_match
);
726 static struct platform_driver ths_driver
= {
727 .probe
= sun8i_ths_probe
,
729 .name
= "sun8i-thermal",
730 .of_match_table
= of_ths_match
,
733 module_platform_driver(ths_driver
);
735 MODULE_DESCRIPTION("Thermal sensor driver for Allwinner SOC");
736 MODULE_LICENSE("GPL v2");