Lines Matching +full:clk +full:- +full:out +full:- +full:frequency +full:- +full:hz
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
8 #include <linux/clk.h>
9 #include <linux/clk-provider.h>
91 struct clk *clk; member
103 dev_dbg(sensor->dev, "low:%d high:%d\n", sensor->low_temp_enabled, in stm_enable_irq()
104 sensor->high_temp_enabled); in stm_enable_irq()
107 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET); in stm_enable_irq()
110 if (sensor->low_temp_enabled) in stm_enable_irq()
113 if (sensor->high_temp_enabled) in stm_enable_irq()
117 writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET); in stm_enable_irq()
126 dev_dbg(sensor->dev, "sr:%d\n", in stm_thermal_irq_handler()
127 readl_relaxed(sensor->base + DTS_SR_OFFSET)); in stm_thermal_irq_handler()
129 thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED); in stm_thermal_irq_handler()
134 writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET); in stm_thermal_irq_handler()
145 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_on()
147 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_on()
154 ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET, in stm_sensor_power_on()
161 value = readl_relaxed(sensor->base + in stm_sensor_power_on()
164 writel_relaxed(value, sensor->base + in stm_sensor_power_on()
167 sensor->mode = THERMAL_DEVICE_ENABLED; in stm_sensor_power_on()
176 sensor->mode = THERMAL_DEVICE_DISABLED; in stm_sensor_power_off()
179 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_off()
181 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_off()
187 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_off()
189 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); in stm_sensor_power_off()
192 return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value, in stm_sensor_power_off()
202 /* Figure out prescaler value for PCLK during calibration */ in stm_thermal_calibration()
203 clk_freq = clk_get_rate(sensor->clk); in stm_thermal_calibration()
205 return -EINVAL; in stm_thermal_calibration()
214 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET); in stm_thermal_calibration()
235 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET); in stm_thermal_calibration()
244 sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) & in stm_thermal_read_factory_settings()
246 if (!sensor->t0) in stm_thermal_read_factory_settings()
247 sensor->t0 = TS1_T0_VAL0; in stm_thermal_read_factory_settings()
249 sensor->t0 = TS1_T0_VAL1; in stm_thermal_read_factory_settings()
251 /* Retrieve fmt0 and put it on Hz */ in stm_thermal_read_factory_settings()
252 sensor->fmt0 = ADJUST * (readl_relaxed(sensor->base + in stm_thermal_read_factory_settings()
256 sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) & in stm_thermal_read_factory_settings()
259 if (!sensor->fmt0 || !sensor->ramp_coeff) { in stm_thermal_read_factory_settings()
260 dev_err(sensor->dev, "%s: wrong setting\n", __func__); in stm_thermal_read_factory_settings()
261 return -EINVAL; in stm_thermal_read_factory_settings()
264 dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC", in stm_thermal_read_factory_settings()
265 __func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff); in stm_thermal_read_factory_settings()
275 /* Figure out the CLK_PTAT frequency for a given temperature */ in stm_thermal_calculate_threshold()
276 freqM = ((temp - sensor->t0) * sensor->ramp_coeff) / 1000 + in stm_thermal_calculate_threshold()
277 sensor->fmt0; in stm_thermal_calculate_threshold()
279 /* Figure out the threshold sample number */ in stm_thermal_calculate_threshold()
280 *th = clk_get_rate(sensor->clk) * SAMPLING_TIME / freqM; in stm_thermal_calculate_threshold()
282 return -EINVAL; in stm_thermal_calculate_threshold()
284 dev_dbg(sensor->dev, "freqM=%d Hz, threshold=0x%x", freqM, *th); in stm_thermal_calculate_threshold()
295 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET); in stm_disable_irq()
297 writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET); in stm_disable_irq()
308 dev_dbg(sensor->dev, "set trips %d <--> %d\n", low, high); in stm_thermal_set_trips()
311 itr1 = readl_relaxed(sensor->base + DTS_ITR1_OFFSET); in stm_thermal_set_trips()
315 * Disable low-temp if "low" is too small. As per thermal framework in stm_thermal_set_trips()
316 * API, we use -INT_MAX rather than INT_MIN. in stm_thermal_set_trips()
319 if (low > -INT_MAX) { in stm_thermal_set_trips()
320 sensor->low_temp_enabled = 1; in stm_thermal_set_trips()
322 ret = stm_thermal_calculate_threshold(sensor, low - 500, &th); in stm_thermal_set_trips()
328 sensor->low_temp_enabled = 0; in stm_thermal_set_trips()
331 /* Disable high-temp if "high" is too big. */ in stm_thermal_set_trips()
333 sensor->high_temp_enabled = 1; in stm_thermal_set_trips()
340 sensor->high_temp_enabled = 0; in stm_thermal_set_trips()
344 writel_relaxed(itr1, sensor->base + DTS_ITR1_OFFSET); in stm_thermal_set_trips()
356 if (sensor->mode != THERMAL_DEVICE_ENABLED) in stm_thermal_get_temp()
357 return -EAGAIN; in stm_thermal_get_temp()
360 ret = readl_relaxed_poll_timeout(sensor->base + DTS_DR_OFFSET, periods, in stm_thermal_get_temp()
366 /* Figure out the CLK_PTAT frequency */ in stm_thermal_get_temp()
367 freqM = (clk_get_rate(sensor->clk) * SAMPLING_TIME) / periods; in stm_thermal_get_temp()
369 return -EINVAL; in stm_thermal_get_temp()
371 /* Figure out the temperature in mili celsius */ in stm_thermal_get_temp()
372 *temp = (freqM - sensor->fmt0) * 1000 / sensor->ramp_coeff + sensor->t0; in stm_thermal_get_temp()
380 struct device *dev = sensor->dev; in stm_register_irq()
384 sensor->irq = platform_get_irq(pdev, 0); in stm_register_irq()
385 if (sensor->irq < 0) in stm_register_irq()
386 return sensor->irq; in stm_register_irq()
388 ret = devm_request_threaded_irq(dev, sensor->irq, in stm_register_irq()
392 dev->driver->name, sensor); in stm_register_irq()
395 sensor->irq); in stm_register_irq()
414 clk_disable_unprepare(sensor->clk); in stm_thermal_sensor_off()
423 ret = clk_prepare_enable(sensor->clk); in stm_thermal_prepare()
438 clk_disable_unprepare(sensor->clk); in stm_thermal_prepare()
463 thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED); in stm_thermal_resume()
478 { .compatible = "st,stm32-thermal"},
489 if (!pdev->dev.of_node) { in stm_thermal_probe()
490 dev_err(&pdev->dev, "%s: device tree node not found\n", in stm_thermal_probe()
492 return -EINVAL; in stm_thermal_probe()
495 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL); in stm_thermal_probe()
497 return -ENOMEM; in stm_thermal_probe()
501 sensor->dev = &pdev->dev; in stm_thermal_probe()
508 sensor->base = base; in stm_thermal_probe()
510 sensor->clk = devm_clk_get(&pdev->dev, "pclk"); in stm_thermal_probe()
511 if (IS_ERR(sensor->clk)) { in stm_thermal_probe()
512 dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n", in stm_thermal_probe()
514 return PTR_ERR(sensor->clk); in stm_thermal_probe()
520 writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET); in stm_thermal_probe()
525 dev_err(&pdev->dev, "Error prepare sensor: %d\n", ret); in stm_thermal_probe()
531 dev_err(&pdev->dev, "Error power on sensor: %d\n", ret); in stm_thermal_probe()
535 sensor->th_dev = devm_thermal_of_zone_register(&pdev->dev, 0, in stm_thermal_probe()
539 if (IS_ERR(sensor->th_dev)) { in stm_thermal_probe()
540 dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n", in stm_thermal_probe()
542 ret = PTR_ERR(sensor->th_dev); in stm_thermal_probe()
557 ret = thermal_add_hwmon_sysfs(sensor->th_dev); in stm_thermal_probe()
561 dev_info(&pdev->dev, "%s: Driver initialized successfully\n", in stm_thermal_probe()
575 thermal_remove_hwmon_sysfs(sensor->th_dev); in stm_thermal_remove()