Lines Matching +full:thermal +full:- +full:calibration

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
9 #include <linux/clk-provider.h>
20 #include <linux/thermal.h>
106 dev_dbg(sensor->dev, "low:%d high:%d\n", sensor->low_temp_enabled, in stm_enable_irq()
107 sensor->high_temp_enabled); in stm_enable_irq()
110 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET); in stm_enable_irq()
113 if (sensor->low_temp_enabled) in stm_enable_irq()
116 if (sensor->high_temp_enabled) in stm_enable_irq()
120 writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET); in stm_enable_irq()
129 dev_dbg(sensor->dev, "sr:%d\n", in stm_thermal_irq_handler()
130 readl_relaxed(sensor->base + DTS_SR_OFFSET)); in stm_thermal_irq_handler()
132 thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED); in stm_thermal_irq_handler()
137 writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET); in stm_thermal_irq_handler()
148 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_on()
150 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_on()
157 ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET, in stm_sensor_power_on()
164 value = readl_relaxed(sensor->base + in stm_sensor_power_on()
167 writel_relaxed(value, sensor->base + in stm_sensor_power_on()
170 sensor->mode = THERMAL_DEVICE_ENABLED; in stm_sensor_power_on()
179 sensor->mode = THERMAL_DEVICE_DISABLED; in stm_sensor_power_off()
182 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_off()
184 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_off()
190 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_off()
192 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_off()
195 return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value, in stm_sensor_power_off()
205 /* Figure out prescaler value for PCLK during calibration */ in stm_thermal_calibration()
206 clk_freq = clk_get_rate(sensor->clk); in stm_thermal_calibration()
208 return -EINVAL; in stm_thermal_calibration()
217 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); in stm_thermal_calibration()
231 /* Measure with calibration */ in stm_thermal_calibration()
238 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); in stm_thermal_calibration()
246 /* Retrieve engineering calibration temperature */ in stm_thermal_read_factory_settings()
247 sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) & in stm_thermal_read_factory_settings()
249 if (!sensor->t0) in stm_thermal_read_factory_settings()
250 sensor->t0 = TS1_T0_VAL0; in stm_thermal_read_factory_settings()
252 sensor->t0 = TS1_T0_VAL1; in stm_thermal_read_factory_settings()
255 sensor->fmt0 = ADJUST * (readl_relaxed(sensor->base + in stm_thermal_read_factory_settings()
259 sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) & in stm_thermal_read_factory_settings()
262 if (!sensor->fmt0 || !sensor->ramp_coeff) { in stm_thermal_read_factory_settings()
263 dev_err(sensor->dev, "%s: wrong setting\n", __func__); in stm_thermal_read_factory_settings()
264 return -EINVAL; in stm_thermal_read_factory_settings()
267 dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC", in stm_thermal_read_factory_settings()
268 __func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff); in stm_thermal_read_factory_settings()
279 freqM = ((temp - sensor->t0) * sensor->ramp_coeff) / 1000 + in stm_thermal_calculate_threshold()
280 sensor->fmt0; in stm_thermal_calculate_threshold()
283 *th = clk_get_rate(sensor->clk) * SAMPLING_TIME / freqM; in stm_thermal_calculate_threshold()
285 return -EINVAL; in stm_thermal_calculate_threshold()
287 dev_dbg(sensor->dev, "freqM=%d Hz, threshold=0x%x", freqM, *th); in stm_thermal_calculate_threshold()
298 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET); in stm_disable_irq()
300 writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET); in stm_disable_irq()
307 struct stm_thermal_sensor *sensor = tz->devdata; in stm_thermal_set_trips()
311 dev_dbg(sensor->dev, "set trips %d <--> %d\n", low, high); in stm_thermal_set_trips()
314 itr1 = readl_relaxed(sensor->base + DTS_ITR1_OFFSET); in stm_thermal_set_trips()
318 * Disable low-temp if "low" is too small. As per thermal framework in stm_thermal_set_trips()
319 * API, we use -INT_MAX rather than INT_MIN. in stm_thermal_set_trips()
322 if (low > -INT_MAX) { in stm_thermal_set_trips()
323 sensor->low_temp_enabled = 1; in stm_thermal_set_trips()
325 ret = stm_thermal_calculate_threshold(sensor, low - 500, &th); in stm_thermal_set_trips()
331 sensor->low_temp_enabled = 0; in stm_thermal_set_trips()
334 /* Disable high-temp if "high" is too big. */ in stm_thermal_set_trips()
336 sensor->high_temp_enabled = 1; in stm_thermal_set_trips()
343 sensor->high_temp_enabled = 0; in stm_thermal_set_trips()
347 writel_relaxed(itr1, sensor->base + DTS_ITR1_OFFSET); in stm_thermal_set_trips()
355 struct stm_thermal_sensor *sensor = tz->devdata; in stm_thermal_get_temp()
359 if (sensor->mode != THERMAL_DEVICE_ENABLED) in stm_thermal_get_temp()
360 return -EAGAIN; in stm_thermal_get_temp()
363 ret = readl_relaxed_poll_timeout(sensor->base + DTS_DR_OFFSET, periods, in stm_thermal_get_temp()
370 freqM = (clk_get_rate(sensor->clk) * SAMPLING_TIME) / periods; in stm_thermal_get_temp()
372 return -EINVAL; in stm_thermal_get_temp()
375 *temp = (freqM - sensor->fmt0) * 1000 / sensor->ramp_coeff + sensor->t0; in stm_thermal_get_temp()
383 struct device *dev = sensor->dev; in stm_register_irq()
387 sensor->irq = platform_get_irq(pdev, 0); in stm_register_irq()
388 if (sensor->irq < 0) in stm_register_irq()
389 return sensor->irq; in stm_register_irq()
391 ret = devm_request_threaded_irq(dev, sensor->irq, in stm_register_irq()
395 dev->driver->name, sensor); in stm_register_irq()
398 sensor->irq); in stm_register_irq()
402 dev_dbg(dev, "%s: thermal IRQ registered", __func__); in stm_register_irq()
417 clk_disable_unprepare(sensor->clk); in stm_thermal_sensor_off()
426 ret = clk_prepare_enable(sensor->clk); in stm_thermal_prepare()
441 clk_disable_unprepare(sensor->clk); in stm_thermal_prepare()
467 thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED); in stm_thermal_resume()
483 { .compatible = "st,stm32-thermal"},
495 if (!pdev->dev.of_node) { in stm_thermal_probe()
496 dev_err(&pdev->dev, "%s: device tree node not found\n", in stm_thermal_probe()
498 return -EINVAL; in stm_thermal_probe()
501 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL); in stm_thermal_probe()
503 return -ENOMEM; in stm_thermal_probe()
507 sensor->dev = &pdev->dev; in stm_thermal_probe()
510 base = devm_ioremap_resource(&pdev->dev, res); in stm_thermal_probe()
515 sensor->base = base; in stm_thermal_probe()
517 sensor->clk = devm_clk_get(&pdev->dev, "pclk"); in stm_thermal_probe()
518 if (IS_ERR(sensor->clk)) { in stm_thermal_probe()
519 dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n", in stm_thermal_probe()
521 return PTR_ERR(sensor->clk); in stm_thermal_probe()
527 writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET); in stm_thermal_probe()
532 dev_err(&pdev->dev, "Error prepare sensor: %d\n", ret); in stm_thermal_probe()
538 dev_err(&pdev->dev, "Error power on sensor: %d\n", ret); in stm_thermal_probe()
542 sensor->th_dev = devm_thermal_of_zone_register(&pdev->dev, 0, in stm_thermal_probe()
546 if (IS_ERR(sensor->th_dev)) { in stm_thermal_probe()
547 dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n", in stm_thermal_probe()
549 ret = PTR_ERR(sensor->th_dev); in stm_thermal_probe()
564 sensor->th_dev->tzp->no_hwmon = false; in stm_thermal_probe()
565 ret = thermal_add_hwmon_sysfs(sensor->th_dev); in stm_thermal_probe()
569 dev_info(&pdev->dev, "%s: Driver initialized successfully\n", in stm_thermal_probe()
583 thermal_remove_hwmon_sysfs(sensor->th_dev); in stm_thermal_remove()
599 MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");