Lines Matching +full:thermal +full:- +full:calibration
1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/nvmem-consumer.h>
12 #include <linux/thermal.h>
57 /* thermal sensor calibration parameters */
58 #define SPRD_THM_TEMP_LOW -40000
139 return -EINVAL; in sprd_thm_cal_read()
154 * According to thermal datasheet, the default calibration offset is 64, in sprd_thm_sensor_calibration()
163 ratio += thm->ratio_sign * thm->ratio_off; in sprd_thm_sensor_calibration()
167 * calibration value of thermal from efuse, then calibrate the real in sprd_thm_sensor_calibration()
170 * b_cal = b + (dt_offset - 64) * 500. in sprd_thm_sensor_calibration()
172 sen->cal_slope = (thm->var_data->ideal_k * ratio) / 1000; in sprd_thm_sensor_calibration()
173 sen->cal_offset = thm->var_data->ideal_b + (dt_offset - 128) * 250; in sprd_thm_sensor_calibration()
184 * According to the thermal datasheet, the formula of converting in sprd_thm_rawdata_to_temp()
186 * T_final = k_cal * x - b_cal. in sprd_thm_rawdata_to_temp()
188 return sen->cal_slope * rawdata - sen->cal_offset; in sprd_thm_rawdata_to_temp()
198 * According to the thermal datasheet, the formula of converting in sprd_thm_temp_to_rawdata()
200 * T_final = k_cal * x - b_cal. in sprd_thm_temp_to_rawdata()
202 val = (temp + sen->cal_offset) / sen->cal_slope; in sprd_thm_temp_to_rawdata()
204 return clamp(val, val, (u32)(SPRD_THM_RAW_DATA_HIGH - 1)); in sprd_thm_temp_to_rawdata()
209 struct sprd_thermal_sensor *sen = tz->devdata; in sprd_thm_read_temp()
212 data = readl(sen->data->base + SPRD_THM_TEMP(sen->id)) & in sprd_thm_read_temp()
230 * Wait for thermal ready status before configuring thermal parameters. in sprd_thm_poll_ready_status()
232 ret = readl_poll_timeout(thm->base + SPRD_THM_CTL, val, in sprd_thm_poll_ready_status()
239 sprd_thm_update_bits(thm->base + SPRD_THM_CTL, SPRD_THM_MON_EN, in sprd_thm_poll_ready_status()
241 sprd_thm_update_bits(thm->base + SPRD_THM_CTL, SPRD_THM_SET_RDY, in sprd_thm_poll_ready_status()
251 return readl_poll_timeout(thm->base + SPRD_THM_INTERNAL_STS1, val, in sprd_thm_wait_temp_ready()
266 * Clear interrupt status, enable thermal interrupt and enable thermal. in sprd_thm_set_ready()
268 * The SPRD thermal controller integrates a hardware interrupt signal, in sprd_thm_set_ready()
274 writel(SPRD_THM_INT_CLR_MASK, thm->base + SPRD_THM_INT_CLR); in sprd_thm_set_ready()
275 sprd_thm_update_bits(thm->base + SPRD_THM_INT_EN, in sprd_thm_set_ready()
277 sprd_thm_update_bits(thm->base + SPRD_THM_CTL, in sprd_thm_set_ready()
291 sprd_thm_update_bits(thm->base + SPRD_THM_INT_EN, in sprd_thm_sensor_init()
292 SPRD_THM_SEN_OVERHEAT_ALARM_EN(sen->id), in sprd_thm_sensor_init()
293 SPRD_THM_SEN_OVERHEAT_ALARM_EN(sen->id)); in sprd_thm_sensor_init()
296 sprd_thm_update_bits(thm->base + SPRD_THM_THRES(sen->id), in sprd_thm_sensor_init()
302 sprd_thm_update_bits(thm->base + SPRD_THM_CTL, SPRD_THM_SEN(sen->id), in sprd_thm_sensor_init()
303 SPRD_THM_SEN(sen->id)); in sprd_thm_sensor_init()
309 sprd_thm_update_bits(thm->base + SPRD_THM_DET_PERIOD, in sprd_thm_para_config()
313 sprd_thm_update_bits(thm->base + SPRD_THM_MON_CTL, in sprd_thm_para_config()
317 sprd_thm_update_bits(thm->base + SPRD_THM_MON_PERIOD, in sprd_thm_para_config()
323 struct thermal_zone_device *tzd = sen->tzd; in sprd_thm_toggle_sensor()
333 struct device_node *np = pdev->dev.of_node; in sprd_thm_probe()
341 pdata = of_device_get_match_data(&pdev->dev); in sprd_thm_probe()
343 dev_err(&pdev->dev, "No matching driver data found\n"); in sprd_thm_probe()
344 return -EINVAL; in sprd_thm_probe()
347 thm = devm_kzalloc(&pdev->dev, sizeof(*thm), GFP_KERNEL); in sprd_thm_probe()
349 return -ENOMEM; in sprd_thm_probe()
351 thm->var_data = pdata; in sprd_thm_probe()
352 thm->base = devm_platform_ioremap_resource(pdev, 0); in sprd_thm_probe()
353 if (IS_ERR(thm->base)) in sprd_thm_probe()
354 return PTR_ERR(thm->base); in sprd_thm_probe()
356 thm->nr_sensors = of_get_child_count(np); in sprd_thm_probe()
357 if (thm->nr_sensors == 0 || thm->nr_sensors > SPRD_THM_MAX_SENSOR) { in sprd_thm_probe()
358 dev_err(&pdev->dev, "incorrect sensor count\n"); in sprd_thm_probe()
359 return -EINVAL; in sprd_thm_probe()
362 thm->clk = devm_clk_get(&pdev->dev, "enable"); in sprd_thm_probe()
363 if (IS_ERR(thm->clk)) { in sprd_thm_probe()
364 dev_err(&pdev->dev, "failed to get enable clock\n"); in sprd_thm_probe()
365 return PTR_ERR(thm->clk); in sprd_thm_probe()
368 ret = clk_prepare_enable(thm->clk); in sprd_thm_probe()
379 thm->ratio_sign = -1; in sprd_thm_probe()
381 thm->ratio_sign = 1; in sprd_thm_probe()
383 ret = sprd_thm_cal_read(np, "thm_ratio_cal", &thm->ratio_off); in sprd_thm_probe()
388 sen = devm_kzalloc(&pdev->dev, sizeof(*sen), GFP_KERNEL); in sprd_thm_probe()
390 ret = -ENOMEM; in sprd_thm_probe()
394 sen->data = thm; in sprd_thm_probe()
395 sen->dev = &pdev->dev; in sprd_thm_probe()
397 ret = of_property_read_u32(sen_child, "reg", &sen->id); in sprd_thm_probe()
399 dev_err(&pdev->dev, "get sensor reg failed"); in sprd_thm_probe()
405 dev_err(&pdev->dev, "efuse cal analysis failed"); in sprd_thm_probe()
411 sen->tzd = devm_thermal_of_zone_register(sen->dev, in sprd_thm_probe()
412 sen->id, in sprd_thm_probe()
415 if (IS_ERR(sen->tzd)) { in sprd_thm_probe()
416 dev_err(&pdev->dev, "register thermal zone failed %d\n", in sprd_thm_probe()
417 sen->id); in sprd_thm_probe()
418 ret = PTR_ERR(sen->tzd); in sprd_thm_probe()
422 thm->sensor[sen->id] = sen; in sprd_thm_probe()
434 for (i = 0; i < thm->nr_sensors; i++) in sprd_thm_probe()
435 sprd_thm_toggle_sensor(thm->sensor[i], true); in sprd_thm_probe()
443 clk_disable_unprepare(thm->clk); in sprd_thm_probe()
452 for (i = 0; i < thm->nr_sensors; i++) { in sprd_thm_hw_suspend()
453 sprd_thm_update_bits(thm->base + SPRD_THM_CTL, in sprd_thm_hw_suspend()
454 SPRD_THM_SEN(thm->sensor[i]->id), 0); in sprd_thm_hw_suspend()
457 sprd_thm_update_bits(thm->base + SPRD_THM_CTL, in sprd_thm_hw_suspend()
466 for (i = 0; i < thm->nr_sensors; i++) in sprd_thm_suspend()
467 sprd_thm_toggle_sensor(thm->sensor[i], false); in sprd_thm_suspend()
470 clk_disable_unprepare(thm->clk); in sprd_thm_suspend()
479 for (i = 0; i < thm->nr_sensors; i++) { in sprd_thm_hw_resume()
480 sprd_thm_update_bits(thm->base + SPRD_THM_CTL, in sprd_thm_hw_resume()
481 SPRD_THM_SEN(thm->sensor[i]->id), in sprd_thm_hw_resume()
482 SPRD_THM_SEN(thm->sensor[i]->id)); in sprd_thm_hw_resume()
489 writel(SPRD_THM_INT_CLR_MASK, thm->base + SPRD_THM_INT_CLR); in sprd_thm_hw_resume()
490 sprd_thm_update_bits(thm->base + SPRD_THM_CTL, in sprd_thm_hw_resume()
500 ret = clk_prepare_enable(thm->clk); in sprd_thm_resume()
508 for (i = 0; i < thm->nr_sensors; i++) in sprd_thm_resume()
509 sprd_thm_toggle_sensor(thm->sensor[i], true); in sprd_thm_resume()
514 clk_disable_unprepare(thm->clk); in sprd_thm_resume()
524 for (i = 0; i < thm->nr_sensors; i++) { in sprd_thm_remove()
525 sprd_thm_toggle_sensor(thm->sensor[i], false); in sprd_thm_remove()
526 devm_thermal_of_zone_unregister(&pdev->dev, in sprd_thm_remove()
527 thm->sensor[i]->tzd); in sprd_thm_remove()
530 clk_disable_unprepare(thm->clk); in sprd_thm_remove()
535 { .compatible = "sprd,ums512-thermal", .data = &ums512_data },
548 .name = "sprd-thermal",
557 MODULE_DESCRIPTION("Spreadtrum thermal driver");