Lines Matching +full:calibration +full:- +full:data
1 // SPDX-License-Identifier: GPL-2.0
17 #include <linux/nvmem-consumer.h>
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)
103 return tmdev->chip->offset - (reg * tmdev->chip->scale / 10); in sun8i_ths_calc_temp()
110 return -1191 * reg / 10 + 223000; in sun50i_h5_calc_temp()
112 return -1452 * reg / 10 + 259000; in sun50i_h5_calc_temp()
114 return -1590 * reg / 10 + 276000; in sun50i_h5_calc_temp()
120 struct ths_device *tmdev = s->tmdev; in sun8i_ths_get_temp()
123 regmap_read(tmdev->regmap, tmdev->chip->temp_data_base + in sun8i_ths_get_temp()
124 0x4 * s->id, &val); in sun8i_ths_get_temp()
126 /* ths have no data yet */ in sun8i_ths_get_temp()
128 return -EAGAIN; in sun8i_ths_get_temp()
130 *temp = tmdev->chip->calc_temp(tmdev, s->id, val); in sun8i_ths_get_temp()
137 * do this, the correct calibration formula is hard to know. in sun8i_ths_get_temp()
139 *temp += tmdev->chip->ft_deviation; in sun8i_ths_get_temp()
161 regmap_read(tmdev->regmap, SUN8I_THS_IS, &state); in sun8i_h3_irq_ack()
163 for (i = 0; i < tmdev->chip->sensor_num; i++) { in sun8i_h3_irq_ack()
165 regmap_write(tmdev->regmap, SUN8I_THS_IS, in sun8i_h3_irq_ack()
179 regmap_read(tmdev->regmap, SUN50I_H6_THS_DIS, &state); in sun50i_h6_irq_ack()
181 for (i = 0; i < tmdev->chip->sensor_num; i++) { in sun50i_h6_irq_ack()
183 regmap_write(tmdev->regmap, SUN50I_H6_THS_DIS, in sun50i_h6_irq_ack()
192 static irqreturn_t sun8i_irq_thread(int irq, void *data) in sun8i_irq_thread() argument
194 struct ths_device *tmdev = data; in sun8i_irq_thread()
195 unsigned long irq_bitmap = tmdev->chip->irq_ack(tmdev); in sun8i_irq_thread()
198 for_each_set_bit(i, &irq_bitmap, tmdev->chip->sensor_num) { in sun8i_irq_thread()
200 if (IS_ERR(tmdev->sensor[i].tzd)) in sun8i_irq_thread()
202 thermal_zone_device_update(tmdev->sensor[i].tzd, in sun8i_irq_thread()
214 if (!caldata[0] || callen < 2 * tmdev->chip->sensor_num) in sun8i_h3_ths_calibrate()
215 return -EINVAL; in sun8i_h3_ths_calibrate()
217 for (i = 0; i < tmdev->chip->sensor_num; i++) { in sun8i_h3_ths_calibrate()
220 regmap_update_bits(tmdev->regmap, in sun8i_h3_ths_calibrate()
232 struct device *dev = tmdev->dev; in sun50i_h6_ths_calibrate()
236 return -EINVAL; in sun50i_h6_ths_calibrate()
242 * +----------+-----------+-----------+-----------+ in sun50i_h6_ths_calibrate()
244 * +----------+-----------+-----------+-----------+ in sun50i_h6_ths_calibrate()
251 * The calibration data on the H6 is the ambient temperature and in sun50i_h6_ths_calibrate()
257 * register values and this will become a calibration offset. in sun50i_h6_ths_calibrate()
261 for (i = 0; i < tmdev->chip->sensor_num; i++) { in sun50i_h6_ths_calibrate()
271 sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg); in sun50i_h6_ths_calibrate()
274 * Calibration data is CALIBRATE_DEFAULT - (calculated in sun50i_h6_ths_calibrate()
279 cdata = CALIBRATE_DEFAULT - in sun50i_h6_ths_calibrate()
280 ((sensor_temp - ft_temp) * 10 / tmdev->chip->scale); in sun50i_h6_ths_calibrate()
283 * Calibration value more than 12-bit, but calibration in sun50i_h6_ths_calibrate()
284 * register is 12-bit. In this case, ths hardware can in sun50i_h6_ths_calibrate()
285 * still work without calibration, although the data in sun50i_h6_ths_calibrate()
293 regmap_update_bits(tmdev->regmap, in sun50i_h6_ths_calibrate()
305 struct device *dev = tmdev->dev; in sun8i_ths_calibrate()
310 calcell = nvmem_cell_get(dev, "calibration"); in sun8i_ths_calibrate()
312 if (PTR_ERR(calcell) == -EPROBE_DEFER) in sun8i_ths_calibrate()
313 return -EPROBE_DEFER; in sun8i_ths_calibrate()
315 * Even if the external calibration data stored in sid is in sun8i_ths_calibrate()
317 * the data won't be so accurate. in sun8i_ths_calibrate()
319 * The default value of calibration register is 0x800 for in sun8i_ths_calibrate()
320 * every sensor, and the calibration value is usually 0x7xx in sun8i_ths_calibrate()
324 * So here we do not return error if the calibration data is in sun8i_ths_calibrate()
336 tmdev->chip->calibrate(tmdev, caldata, callen); in sun8i_ths_calibrate()
345 static void sun8i_ths_reset_control_assert(void *data) in sun8i_ths_reset_control_assert() argument
347 reset_control_assert(data); in sun8i_ths_reset_control_assert()
358 return ERR_PTR(-ENODEV); in sun8i_ths_get_sram_regmap()
363 return ERR_PTR(-EPROBE_DEFER); in sun8i_ths_get_sram_regmap()
367 regmap = dev_get_regmap(&sram_pdev->dev, NULL); in sun8i_ths_get_sram_regmap()
369 regmap = ERR_PTR(-EINVAL); in sun8i_ths_get_sram_regmap()
378 struct device *dev = tmdev->dev; in sun8i_ths_resource_init()
387 tmdev->regmap = devm_regmap_init_mmio(dev, base, &config); in sun8i_ths_resource_init()
388 if (IS_ERR(tmdev->regmap)) in sun8i_ths_resource_init()
389 return PTR_ERR(tmdev->regmap); in sun8i_ths_resource_init()
391 if (tmdev->chip->has_bus_clk_reset) { in sun8i_ths_resource_init()
392 tmdev->reset = devm_reset_control_get(dev, NULL); in sun8i_ths_resource_init()
393 if (IS_ERR(tmdev->reset)) in sun8i_ths_resource_init()
394 return PTR_ERR(tmdev->reset); in sun8i_ths_resource_init()
396 ret = reset_control_deassert(tmdev->reset); in sun8i_ths_resource_init()
401 tmdev->reset); in sun8i_ths_resource_init()
405 tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus"); in sun8i_ths_resource_init()
406 if (IS_ERR(tmdev->bus_clk)) in sun8i_ths_resource_init()
407 return PTR_ERR(tmdev->bus_clk); in sun8i_ths_resource_init()
410 if (tmdev->chip->has_mod_clk) { in sun8i_ths_resource_init()
411 tmdev->mod_clk = devm_clk_get_enabled(&pdev->dev, "mod"); in sun8i_ths_resource_init()
412 if (IS_ERR(tmdev->mod_clk)) in sun8i_ths_resource_init()
413 return PTR_ERR(tmdev->mod_clk); in sun8i_ths_resource_init()
416 ret = clk_set_rate(tmdev->mod_clk, 24000000); in sun8i_ths_resource_init()
420 if (tmdev->chip->needs_sram) { in sun8i_ths_resource_init()
423 regmap = sun8i_ths_get_sram_regmap(dev->of_node); in sun8i_ths_resource_init()
426 tmdev->sram_regmap_field = devm_regmap_field_alloc(dev, in sun8i_ths_resource_init()
429 if (IS_ERR(tmdev->sram_regmap_field)) in sun8i_ths_resource_init()
430 return PTR_ERR(tmdev->sram_regmap_field); in sun8i_ths_resource_init()
445 regmap_write(tmdev->regmap, SUN8I_THS_MFC, in sun8i_h3_thermal_init()
453 * x = period * clkin / 4096 / filter_samples - 1 in sun8i_h3_thermal_init()
456 val = GENMASK(7 + tmdev->chip->sensor_num, 8); in sun8i_h3_thermal_init()
457 regmap_write(tmdev->regmap, SUN8I_THS_IC, in sun8i_h3_thermal_init()
463 * x = T_acq * clkin - 1 in sun8i_h3_thermal_init()
466 regmap_write(tmdev->regmap, SUN8I_THS_CTRL0, in sun8i_h3_thermal_init()
468 val = GENMASK(tmdev->chip->sensor_num - 1, 0); in sun8i_h3_thermal_init()
469 regmap_write(tmdev->regmap, SUN8I_THS_CTRL2, in sun8i_h3_thermal_init()
480 if (tmdev->sram_regmap_field) in sun50i_h6_thermal_init()
481 regmap_field_write(tmdev->sram_regmap_field, 0); in sun50i_h6_thermal_init()
497 regmap_write(tmdev->regmap, SUN50I_THS_CTRL0, in sun50i_h6_thermal_init()
501 regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC, in sun50i_h6_thermal_init()
509 * x = period * clkin / 4096 / filter_samples - 1 in sun50i_h6_thermal_init()
512 regmap_write(tmdev->regmap, SUN50I_H6_THS_PC, in sun50i_h6_thermal_init()
515 val = GENMASK(tmdev->chip->sensor_num - 1, 0); in sun50i_h6_thermal_init()
516 regmap_write(tmdev->regmap, SUN50I_H6_THS_ENABLE, val); in sun50i_h6_thermal_init()
517 /* thermal data interrupt enable */ in sun50i_h6_thermal_init()
518 val = GENMASK(tmdev->chip->sensor_num - 1, 0); in sun50i_h6_thermal_init()
519 regmap_write(tmdev->regmap, SUN50I_H6_THS_DIC, val); in sun50i_h6_thermal_init()
528 for (i = 0; i < tmdev->chip->sensor_num; i++) { in sun8i_ths_register()
529 tmdev->sensor[i].tmdev = tmdev; in sun8i_ths_register()
530 tmdev->sensor[i].id = i; in sun8i_ths_register()
531 tmdev->sensor[i].tzd = in sun8i_ths_register()
532 devm_thermal_of_zone_register(tmdev->dev, in sun8i_ths_register()
534 &tmdev->sensor[i], in sun8i_ths_register()
542 if (IS_ERR(tmdev->sensor[i].tzd)) { in sun8i_ths_register()
543 if (PTR_ERR(tmdev->sensor[i].tzd) == -EPROBE_DEFER) in sun8i_ths_register()
544 return PTR_ERR(tmdev->sensor[i].tzd); in sun8i_ths_register()
548 devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd); in sun8i_ths_register()
557 struct device *dev = &pdev->dev; in sun8i_ths_probe()
562 return -ENOMEM; in sun8i_ths_probe()
564 tmdev->dev = dev; in sun8i_ths_probe()
565 tmdev->chip = of_device_get_match_data(&pdev->dev); in sun8i_ths_probe()
566 if (!tmdev->chip) in sun8i_ths_probe()
567 return -EINVAL; in sun8i_ths_probe()
577 ret = tmdev->chip->init(tmdev); in sun8i_ths_probe()
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 },
729 .name = "sun8i-thermal",