Lines Matching +full:temp +full:- +full:sensor
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2014-2016, Fuzhou Rockchip Electronics Co., Ltd
4 * Caesar Wang <wxt@rock-chips.com>
55 * struct chip_tsadc_table - hold information about chip-specific differences
69 * struct rockchip_tsadc_chip - hold the private data of tsadc chip
72 * @tshut_temp: the hardware-controlled shutdown temperature value
73 * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)
74 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
80 * @set_tshut_temp: set the hardware-controlled shutdown temperature
81 * @set_tshut_mode: set the hardware-controlled shutdown mode
82 * @table: the chip-specific conversion table
85 /* The sensor id of chip correspond to the ADC channel */
89 /* The hardware-controlled tshut property */
94 /* Chip-wide methods */
100 /* Per-sensor methods */
102 int chn, void __iomem *reg, int *temp);
104 int chn, void __iomem *reg, int temp);
106 int chn, void __iomem *reg, int temp);
109 /* Per-table methods */
114 * struct rockchip_thermal_sensor - hold the information of thermal sensor
117 * @id: identifier of the thermal sensor
126 * struct rockchip_thermal_data - hold the private data of thermal driver
135 * @tshut_temp: the hardware-controlled shutdown temperature value
136 * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)
137 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
158 * TSADC Sensor Register description:
253 * struct tsadc_table - code to temperature conversion table
255 * @temp: the temperature
257 * code to temperature mapping of the temperature sensor is a piece wise linear
264 int temp; member
268 {0, -40000},
269 {374, -40000},
270 {382, -35000},
271 {389, -30000},
272 {397, -25000},
273 {405, -20000},
274 {413, -15000},
275 {421, -10000},
276 {429, -5000},
307 {0, -40000},
308 {588, -40000},
309 {593, -35000},
310 {598, -30000},
311 {603, -25000},
312 {608, -20000},
313 {613, -15000},
314 {618, -10000},
315 {623, -5000},
346 {TSADCV2_DATA_MASK, -40000},
347 {3800, -40000},
348 {3792, -35000},
349 {3783, -30000},
350 {3774, -25000},
351 {3765, -20000},
352 {3756, -15000},
353 {3747, -10000},
354 {3737, -5000},
385 {0, -40000},
386 {296, -40000},
387 {304, -35000},
388 {313, -30000},
389 {331, -20000},
390 {340, -15000},
391 {349, -10000},
392 {359, -5000},
423 {0, -40000},
424 {106, -40000},
425 {108, -35000},
426 {110, -30000},
427 {112, -25000},
428 {114, -20000},
429 {116, -15000},
430 {118, -10000},
431 {120, -5000},
462 {0, -40000},
463 {402, -40000},
464 {410, -35000},
465 {419, -30000},
466 {427, -25000},
467 {436, -20000},
468 {444, -15000},
469 {453, -10000},
470 {461, -5000},
501 {0, -40000},
502 {1584, -40000},
503 {1620, -35000},
504 {1652, -30000},
505 {1688, -25000},
506 {1720, -20000},
507 {1756, -15000},
508 {1788, -10000},
509 {1824, -5000},
540 {0, -40000},
541 {215, -40000},
549 int temp) in rk_tsadcv2_temp_to_code() argument
554 u32 error = table->data_mask; in rk_tsadcv2_temp_to_code()
557 high = (table->length - 1) - 1; /* ignore the last check for table */ in rk_tsadcv2_temp_to_code()
560 /* Return mask code data when the temp is over table range */ in rk_tsadcv2_temp_to_code()
561 if (temp < table->id[low].temp || temp > table->id[high].temp) in rk_tsadcv2_temp_to_code()
565 if (temp == table->id[mid].temp) in rk_tsadcv2_temp_to_code()
566 return table->id[mid].code; in rk_tsadcv2_temp_to_code()
567 else if (temp < table->id[mid].temp) in rk_tsadcv2_temp_to_code()
568 high = mid - 1; in rk_tsadcv2_temp_to_code()
580 num = abs(table->id[mid + 1].code - table->id[mid].code); in rk_tsadcv2_temp_to_code()
581 num *= temp - table->id[mid].temp; in rk_tsadcv2_temp_to_code()
582 denom = table->id[mid + 1].temp - table->id[mid].temp; in rk_tsadcv2_temp_to_code()
584 switch (table->mode) { in rk_tsadcv2_temp_to_code()
586 return table->id[mid].code - (num / denom); in rk_tsadcv2_temp_to_code()
588 return table->id[mid].code + (num / denom); in rk_tsadcv2_temp_to_code()
590 pr_err("%s: unknown table mode: %d\n", __func__, table->mode); in rk_tsadcv2_temp_to_code()
595 pr_err("%s: invalid temperature, temp=%d error=%d\n", in rk_tsadcv2_temp_to_code()
596 __func__, temp, error); in rk_tsadcv2_temp_to_code()
601 u32 code, int *temp) in rk_tsadcv2_code_to_temp() argument
604 unsigned int high = table->length - 1; in rk_tsadcv2_code_to_temp()
609 WARN_ON(table->length < 2); in rk_tsadcv2_code_to_temp()
611 switch (table->mode) { in rk_tsadcv2_code_to_temp()
613 code &= table->data_mask; in rk_tsadcv2_code_to_temp()
614 if (code <= table->id[high].code) in rk_tsadcv2_code_to_temp()
615 return -EAGAIN; /* Incorrect reading */ in rk_tsadcv2_code_to_temp()
618 if (code >= table->id[mid].code && in rk_tsadcv2_code_to_temp()
619 code < table->id[mid - 1].code) in rk_tsadcv2_code_to_temp()
621 else if (code < table->id[mid].code) in rk_tsadcv2_code_to_temp()
624 high = mid - 1; in rk_tsadcv2_code_to_temp()
630 code &= table->data_mask; in rk_tsadcv2_code_to_temp()
631 if (code < table->id[low].code) in rk_tsadcv2_code_to_temp()
632 return -EAGAIN; /* Incorrect reading */ in rk_tsadcv2_code_to_temp()
635 if (code <= table->id[mid].code && in rk_tsadcv2_code_to_temp()
636 code > table->id[mid - 1].code) in rk_tsadcv2_code_to_temp()
638 else if (code > table->id[mid].code) in rk_tsadcv2_code_to_temp()
641 high = mid - 1; in rk_tsadcv2_code_to_temp()
647 pr_err("%s: unknown table mode: %d\n", __func__, table->mode); in rk_tsadcv2_code_to_temp()
648 return -EINVAL; in rk_tsadcv2_code_to_temp()
653 * assume that the relationship between sensor readings and in rk_tsadcv2_code_to_temp()
657 num = table->id[mid].temp - table->id[mid - 1].temp; in rk_tsadcv2_code_to_temp()
658 num *= abs(table->id[mid - 1].code - code); in rk_tsadcv2_code_to_temp()
659 denom = abs(table->id[mid - 1].code - table->id[mid].code); in rk_tsadcv2_code_to_temp()
660 *temp = table->id[mid - 1].temp + (num / denom); in rk_tsadcv2_code_to_temp()
666 * rk_tsadcv2_initialize - initialize TASDC Controller.
669 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
703 * rk_tsadcv3_initialize - initialize TASDC Controller.
706 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
878 * rk_tsadcv3_control - the tsadc controller is enabled or disabled.
883 * tsadc_q_sel bit on TSADCV2_AUTO_CON[1]. The (1024 - tsadc_q) as output
912 int chn, void __iomem *regs, int *temp) in rk_tsadcv2_get_temp() argument
918 return rk_tsadcv2_code_to_temp(table, val, temp); in rk_tsadcv2_get_temp()
922 int chn, void __iomem *regs, int *temp) in rk_tsadcv4_get_temp() argument
928 return rk_tsadcv2_code_to_temp(table, val, temp); in rk_tsadcv4_get_temp()
932 int chn, void __iomem *regs, int temp) in rk_tsadcv2_alarm_temp() argument
939 * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm in rk_tsadcv2_alarm_temp()
943 if (temp == INT_MAX) { in rk_tsadcv2_alarm_temp()
951 alarm_value = rk_tsadcv2_temp_to_code(table, temp); in rk_tsadcv2_alarm_temp()
952 if (alarm_value == table->data_mask) in rk_tsadcv2_alarm_temp()
953 return -ERANGE; in rk_tsadcv2_alarm_temp()
955 writel_relaxed(alarm_value & table->data_mask, in rk_tsadcv2_alarm_temp()
966 int chn, void __iomem *regs, int temp) in rk_tsadcv3_alarm_temp() argument
972 * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm in rk_tsadcv3_alarm_temp()
976 if (temp == INT_MAX) { in rk_tsadcv3_alarm_temp()
982 alarm_value = rk_tsadcv2_temp_to_code(table, temp); in rk_tsadcv3_alarm_temp()
983 if (alarm_value == table->data_mask) in rk_tsadcv3_alarm_temp()
984 return -ERANGE; in rk_tsadcv3_alarm_temp()
985 writel_relaxed(alarm_value & table->data_mask, in rk_tsadcv3_alarm_temp()
993 int chn, void __iomem *regs, int temp) in rk_tsadcv2_tshut_temp() argument
998 tshut_value = rk_tsadcv2_temp_to_code(table, temp); in rk_tsadcv2_tshut_temp()
999 if (tshut_value == table->data_mask) in rk_tsadcv2_tshut_temp()
1000 return -ERANGE; in rk_tsadcv2_tshut_temp()
1012 int chn, void __iomem *regs, int temp) in rk_tsadcv3_tshut_temp() argument
1017 tshut_value = rk_tsadcv2_temp_to_code(table, temp); in rk_tsadcv3_tshut_temp()
1018 if (tshut_value == table->data_mask) in rk_tsadcv3_tshut_temp()
1019 return -ERANGE; in rk_tsadcv3_tshut_temp()
1309 { .compatible = "rockchip,px30-tsadc",
1313 .compatible = "rockchip,rv1108-tsadc",
1317 .compatible = "rockchip,rk3228-tsadc",
1321 .compatible = "rockchip,rk3288-tsadc",
1325 .compatible = "rockchip,rk3328-tsadc",
1329 .compatible = "rockchip,rk3366-tsadc",
1333 .compatible = "rockchip,rk3368-tsadc",
1337 .compatible = "rockchip,rk3399-tsadc",
1341 .compatible = "rockchip,rk3568-tsadc",
1345 .compatible = "rockchip,rk3588-tsadc",
1353 rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on) in rockchip_thermal_toggle_sensor() argument
1355 struct thermal_zone_device *tzd = sensor->tzd; in rockchip_thermal_toggle_sensor()
1368 dev_dbg(&thermal->pdev->dev, "thermal alarm\n"); in rockchip_thermal_alarm_irq_thread()
1370 thermal->chip->irq_ack(thermal->regs); in rockchip_thermal_alarm_irq_thread()
1372 for (i = 0; i < thermal->chip->chn_num; i++) in rockchip_thermal_alarm_irq_thread()
1373 thermal_zone_device_update(thermal->sensors[i].tzd, in rockchip_thermal_alarm_irq_thread()
1381 struct rockchip_thermal_sensor *sensor = thermal_zone_device_priv(tz); in rockchip_thermal_set_trips() local
1382 struct rockchip_thermal_data *thermal = sensor->thermal; in rockchip_thermal_set_trips()
1383 const struct rockchip_tsadc_chip *tsadc = thermal->chip; in rockchip_thermal_set_trips()
1385 dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n", in rockchip_thermal_set_trips()
1386 __func__, sensor->id, low, high); in rockchip_thermal_set_trips()
1388 return tsadc->set_alarm_temp(&tsadc->table, in rockchip_thermal_set_trips()
1389 sensor->id, thermal->regs, high); in rockchip_thermal_set_trips()
1394 struct rockchip_thermal_sensor *sensor = thermal_zone_device_priv(tz); in rockchip_thermal_get_temp() local
1395 struct rockchip_thermal_data *thermal = sensor->thermal; in rockchip_thermal_get_temp()
1396 const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip; in rockchip_thermal_get_temp()
1399 retval = tsadc->get_temp(&tsadc->table, in rockchip_thermal_get_temp()
1400 sensor->id, thermal->regs, out_temp); in rockchip_thermal_get_temp()
1415 if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) { in rockchip_configure_from_dt()
1417 "Missing tshut temp property, using default %d\n", in rockchip_configure_from_dt()
1418 thermal->chip->tshut_temp); in rockchip_configure_from_dt()
1419 thermal->tshut_temp = thermal->chip->tshut_temp; in rockchip_configure_from_dt()
1424 return -ERANGE; in rockchip_configure_from_dt()
1426 thermal->tshut_temp = shut_temp; in rockchip_configure_from_dt()
1429 if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) { in rockchip_configure_from_dt()
1432 thermal->chip->tshut_mode == TSHUT_MODE_GPIO ? in rockchip_configure_from_dt()
1434 thermal->tshut_mode = thermal->chip->tshut_mode; in rockchip_configure_from_dt()
1436 thermal->tshut_mode = tshut_mode; in rockchip_configure_from_dt()
1439 if (thermal->tshut_mode > 1) { in rockchip_configure_from_dt()
1441 thermal->tshut_mode); in rockchip_configure_from_dt()
1442 return -EINVAL; in rockchip_configure_from_dt()
1445 if (of_property_read_u32(np, "rockchip,hw-tshut-polarity", in rockchip_configure_from_dt()
1448 "Missing tshut-polarity property, using default (%s)\n", in rockchip_configure_from_dt()
1449 thermal->chip->tshut_polarity == TSHUT_LOW_ACTIVE ? in rockchip_configure_from_dt()
1451 thermal->tshut_polarity = thermal->chip->tshut_polarity; in rockchip_configure_from_dt()
1453 thermal->tshut_polarity = tshut_polarity; in rockchip_configure_from_dt()
1456 if (thermal->tshut_polarity > 1) { in rockchip_configure_from_dt()
1457 dev_err(dev, "Invalid tshut-polarity specified: %d\n", in rockchip_configure_from_dt()
1458 thermal->tshut_polarity); in rockchip_configure_from_dt()
1459 return -EINVAL; in rockchip_configure_from_dt()
1465 thermal->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); in rockchip_configure_from_dt()
1466 if (IS_ERR(thermal->grf)) in rockchip_configure_from_dt()
1475 struct rockchip_thermal_sensor *sensor, in rockchip_thermal_register_sensor() argument
1478 const struct rockchip_tsadc_chip *tsadc = thermal->chip; in rockchip_thermal_register_sensor()
1481 tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode); in rockchip_thermal_register_sensor()
1483 error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs, in rockchip_thermal_register_sensor()
1484 thermal->tshut_temp); in rockchip_thermal_register_sensor()
1486 dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n", in rockchip_thermal_register_sensor()
1487 __func__, thermal->tshut_temp, error); in rockchip_thermal_register_sensor()
1489 sensor->thermal = thermal; in rockchip_thermal_register_sensor()
1490 sensor->id = id; in rockchip_thermal_register_sensor()
1491 sensor->tzd = devm_thermal_of_zone_register(&pdev->dev, id, sensor, in rockchip_thermal_register_sensor()
1493 if (IS_ERR(sensor->tzd)) { in rockchip_thermal_register_sensor()
1494 error = PTR_ERR(sensor->tzd); in rockchip_thermal_register_sensor()
1495 dev_err(&pdev->dev, "failed to register sensor %d: %d\n", in rockchip_thermal_register_sensor()
1504 * rockchip_thermal_reset_controller - Reset TSADC Controller, reset all tsadc registers.
1516 struct device_node *np = pdev->dev.of_node; in rockchip_thermal_probe()
1524 return -EINVAL; in rockchip_thermal_probe()
1526 thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data), in rockchip_thermal_probe()
1529 return -ENOMEM; in rockchip_thermal_probe()
1531 thermal->pdev = pdev; in rockchip_thermal_probe()
1533 thermal->chip = device_get_match_data(&pdev->dev); in rockchip_thermal_probe()
1534 if (!thermal->chip) in rockchip_thermal_probe()
1535 return -EINVAL; in rockchip_thermal_probe()
1537 thermal->sensors = devm_kcalloc(&pdev->dev, thermal->chip->chn_num, in rockchip_thermal_probe()
1538 sizeof(*thermal->sensors), GFP_KERNEL); in rockchip_thermal_probe()
1539 if (!thermal->sensors) in rockchip_thermal_probe()
1540 return -ENOMEM; in rockchip_thermal_probe()
1542 thermal->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in rockchip_thermal_probe()
1543 if (IS_ERR(thermal->regs)) in rockchip_thermal_probe()
1544 return PTR_ERR(thermal->regs); in rockchip_thermal_probe()
1546 thermal->reset = devm_reset_control_array_get_exclusive(&pdev->dev); in rockchip_thermal_probe()
1547 if (IS_ERR(thermal->reset)) in rockchip_thermal_probe()
1548 return dev_err_probe(&pdev->dev, PTR_ERR(thermal->reset), in rockchip_thermal_probe()
1551 thermal->clk = devm_clk_get_enabled(&pdev->dev, "tsadc"); in rockchip_thermal_probe()
1552 if (IS_ERR(thermal->clk)) in rockchip_thermal_probe()
1553 return dev_err_probe(&pdev->dev, PTR_ERR(thermal->clk), in rockchip_thermal_probe()
1556 thermal->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk"); in rockchip_thermal_probe()
1557 if (IS_ERR(thermal->pclk)) in rockchip_thermal_probe()
1558 return dev_err_probe(&pdev->dev, PTR_ERR(thermal->pclk), in rockchip_thermal_probe()
1561 rockchip_thermal_reset_controller(thermal->reset); in rockchip_thermal_probe()
1563 error = rockchip_configure_from_dt(&pdev->dev, np, thermal); in rockchip_thermal_probe()
1565 return dev_err_probe(&pdev->dev, error, in rockchip_thermal_probe()
1568 thermal->chip->initialize(thermal->grf, thermal->regs, in rockchip_thermal_probe()
1569 thermal->tshut_polarity); in rockchip_thermal_probe()
1571 for (i = 0; i < thermal->chip->chn_num; i++) { in rockchip_thermal_probe()
1573 &thermal->sensors[i], in rockchip_thermal_probe()
1574 thermal->chip->chn_offset + i); in rockchip_thermal_probe()
1576 return dev_err_probe(&pdev->dev, error, in rockchip_thermal_probe()
1577 "failed to register sensor[%d].\n", i); in rockchip_thermal_probe()
1580 error = devm_request_threaded_irq(&pdev->dev, irq, NULL, in rockchip_thermal_probe()
1585 return dev_err_probe(&pdev->dev, error, in rockchip_thermal_probe()
1588 thermal->chip->control(thermal->regs, true); in rockchip_thermal_probe()
1590 for (i = 0; i < thermal->chip->chn_num; i++) { in rockchip_thermal_probe()
1591 rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); in rockchip_thermal_probe()
1592 error = thermal_add_hwmon_sysfs(thermal->sensors[i].tzd); in rockchip_thermal_probe()
1594 dev_warn(&pdev->dev, in rockchip_thermal_probe()
1595 "failed to register sensor %d with hwmon: %d\n", in rockchip_thermal_probe()
1609 for (i = 0; i < thermal->chip->chn_num; i++) { in rockchip_thermal_remove()
1610 struct rockchip_thermal_sensor *sensor = &thermal->sensors[i]; in rockchip_thermal_remove() local
1612 thermal_remove_hwmon_sysfs(sensor->tzd); in rockchip_thermal_remove()
1613 rockchip_thermal_toggle_sensor(sensor, false); in rockchip_thermal_remove()
1616 thermal->chip->control(thermal->regs, false); in rockchip_thermal_remove()
1624 for (i = 0; i < thermal->chip->chn_num; i++) in rockchip_thermal_suspend()
1625 rockchip_thermal_toggle_sensor(&thermal->sensors[i], false); in rockchip_thermal_suspend()
1627 thermal->chip->control(thermal->regs, false); in rockchip_thermal_suspend()
1629 clk_disable(thermal->pclk); in rockchip_thermal_suspend()
1630 clk_disable(thermal->clk); in rockchip_thermal_suspend()
1643 error = clk_enable(thermal->clk); in rockchip_thermal_resume()
1647 error = clk_enable(thermal->pclk); in rockchip_thermal_resume()
1649 clk_disable(thermal->clk); in rockchip_thermal_resume()
1653 rockchip_thermal_reset_controller(thermal->reset); in rockchip_thermal_resume()
1655 thermal->chip->initialize(thermal->grf, thermal->regs, in rockchip_thermal_resume()
1656 thermal->tshut_polarity); in rockchip_thermal_resume()
1658 for (i = 0; i < thermal->chip->chn_num; i++) { in rockchip_thermal_resume()
1659 int id = thermal->sensors[i].id; in rockchip_thermal_resume()
1661 thermal->chip->set_tshut_mode(id, thermal->regs, in rockchip_thermal_resume()
1662 thermal->tshut_mode); in rockchip_thermal_resume()
1664 error = thermal->chip->set_tshut_temp(&thermal->chip->table, in rockchip_thermal_resume()
1665 id, thermal->regs, in rockchip_thermal_resume()
1666 thermal->tshut_temp); in rockchip_thermal_resume()
1669 __func__, thermal->tshut_temp, error); in rockchip_thermal_resume()
1672 thermal->chip->control(thermal->regs, true); in rockchip_thermal_resume()
1674 for (i = 0; i < thermal->chip->chn_num; i++) in rockchip_thermal_resume()
1675 rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); in rockchip_thermal_resume()
1687 .name = "rockchip-thermal",
1700 MODULE_ALIAS("platform:rockchip-thermal");