Lines Matching +full:thermal +full:- +full:sensors
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>
18 #include <linux/thermal.h>
33 * The system Temperature Sensors tshut(tshut) polarity
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
89 /* The hardware-controlled tshut property */
94 /* Chip-wide methods */
100 /* Per-sensor methods */
109 /* Per-table methods */
114 * struct rockchip_thermal_sensor - hold the information of thermal sensor
115 * @thermal: pointer to the platform/configuration data
116 * @tzd: pointer to a thermal zone
117 * @id: identifier of the thermal sensor
120 struct rockchip_thermal_data *thermal; member
126 * struct rockchip_thermal_data - hold the private data of thermal driver
128 * @pdev: platform device of thermal
130 * @sensors: array of thermal sensors
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)
144 struct rockchip_thermal_sensor *sensors; member
253 * struct tsadc_table - code to temperature conversion table
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 {322, -25000},
390 {331, -20000},
391 {340, -15000},
392 {349, -10000},
393 {359, -5000},
424 {0, -40000},
425 {106, -40000},
426 {108, -35000},
427 {110, -30000},
428 {112, -25000},
429 {114, -20000},
430 {116, -15000},
431 {118, -10000},
432 {120, -5000},
463 {0, -40000},
464 {402, -40000},
465 {410, -35000},
466 {419, -30000},
467 {427, -25000},
468 {436, -20000},
469 {444, -15000},
470 {453, -10000},
471 {461, -5000},
502 {0, -40000},
503 {1584, -40000},
504 {1620, -35000},
505 {1652, -30000},
506 {1688, -25000},
507 {1720, -20000},
508 {1756, -15000},
509 {1788, -10000},
510 {1824, -5000},
541 {0, -40000},
542 {215, -40000},
555 u32 error = table->data_mask; in rk_tsadcv2_temp_to_code()
558 high = (table->length - 1) - 1; /* ignore the last check for table */ in rk_tsadcv2_temp_to_code()
562 if (temp < table->id[low].temp || temp > table->id[high].temp) in rk_tsadcv2_temp_to_code()
566 if (temp == table->id[mid].temp) in rk_tsadcv2_temp_to_code()
567 return table->id[mid].code; in rk_tsadcv2_temp_to_code()
568 else if (temp < table->id[mid].temp) in rk_tsadcv2_temp_to_code()
569 high = mid - 1; in rk_tsadcv2_temp_to_code()
581 num = abs(table->id[mid + 1].code - table->id[mid].code); in rk_tsadcv2_temp_to_code()
582 num *= temp - table->id[mid].temp; in rk_tsadcv2_temp_to_code()
583 denom = table->id[mid + 1].temp - table->id[mid].temp; in rk_tsadcv2_temp_to_code()
585 switch (table->mode) { in rk_tsadcv2_temp_to_code()
587 return table->id[mid].code - (num / denom); in rk_tsadcv2_temp_to_code()
589 return table->id[mid].code + (num / denom); in rk_tsadcv2_temp_to_code()
591 pr_err("%s: unknown table mode: %d\n", __func__, table->mode); in rk_tsadcv2_temp_to_code()
605 unsigned int high = table->length - 1; in rk_tsadcv2_code_to_temp()
610 WARN_ON(table->length < 2); in rk_tsadcv2_code_to_temp()
612 switch (table->mode) { in rk_tsadcv2_code_to_temp()
614 code &= table->data_mask; in rk_tsadcv2_code_to_temp()
615 if (code <= table->id[high].code) in rk_tsadcv2_code_to_temp()
616 return -EAGAIN; /* Incorrect reading */ in rk_tsadcv2_code_to_temp()
619 if (code >= table->id[mid].code && in rk_tsadcv2_code_to_temp()
620 code < table->id[mid - 1].code) in rk_tsadcv2_code_to_temp()
622 else if (code < table->id[mid].code) in rk_tsadcv2_code_to_temp()
625 high = mid - 1; in rk_tsadcv2_code_to_temp()
631 code &= table->data_mask; in rk_tsadcv2_code_to_temp()
632 if (code < table->id[low].code) in rk_tsadcv2_code_to_temp()
633 return -EAGAIN; /* Incorrect reading */ in rk_tsadcv2_code_to_temp()
636 if (code <= table->id[mid].code && in rk_tsadcv2_code_to_temp()
637 code > table->id[mid - 1].code) in rk_tsadcv2_code_to_temp()
639 else if (code > table->id[mid].code) in rk_tsadcv2_code_to_temp()
642 high = mid - 1; in rk_tsadcv2_code_to_temp()
648 pr_err("%s: unknown table mode: %d\n", __func__, table->mode); in rk_tsadcv2_code_to_temp()
649 return -EINVAL; in rk_tsadcv2_code_to_temp()
658 num = table->id[mid].temp - table->id[mid - 1].temp; in rk_tsadcv2_code_to_temp()
659 num *= abs(table->id[mid - 1].code - code); in rk_tsadcv2_code_to_temp()
660 denom = abs(table->id[mid - 1].code - table->id[mid].code); in rk_tsadcv2_code_to_temp()
661 *temp = table->id[mid - 1].temp + (num / denom); in rk_tsadcv2_code_to_temp()
667 * rk_tsadcv2_initialize - initialize TASDC Controller.
670 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
704 * rk_tsadcv3_initialize - initialize TASDC Controller.
707 * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
879 * rk_tsadcv3_control - the tsadc controller is enabled or disabled.
884 * tsadc_q_sel bit on TSADCV2_AUTO_CON[1]. The (1024 - tsadc_q) as output
939 * In some cases, some sensors didn't need the trip points, the in rk_tsadcv2_alarm_temp()
940 * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm in rk_tsadcv2_alarm_temp()
953 if (alarm_value == table->data_mask) in rk_tsadcv2_alarm_temp()
954 return -ERANGE; in rk_tsadcv2_alarm_temp()
956 writel_relaxed(alarm_value & table->data_mask, in rk_tsadcv2_alarm_temp()
972 * In some cases, some sensors didn't need the trip points, the in rk_tsadcv3_alarm_temp()
973 * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm in rk_tsadcv3_alarm_temp()
984 if (alarm_value == table->data_mask) in rk_tsadcv3_alarm_temp()
985 return -ERANGE; in rk_tsadcv3_alarm_temp()
986 writel_relaxed(alarm_value & table->data_mask, in rk_tsadcv3_alarm_temp()
1000 if (tshut_value == table->data_mask) in rk_tsadcv2_tshut_temp()
1001 return -ERANGE; in rk_tsadcv2_tshut_temp()
1019 if (tshut_value == table->data_mask) in rk_tsadcv3_tshut_temp()
1020 return -ERANGE; in rk_tsadcv3_tshut_temp()
1310 { .compatible = "rockchip,px30-tsadc",
1314 .compatible = "rockchip,rv1108-tsadc",
1318 .compatible = "rockchip,rk3228-tsadc",
1322 .compatible = "rockchip,rk3288-tsadc",
1326 .compatible = "rockchip,rk3328-tsadc",
1330 .compatible = "rockchip,rk3366-tsadc",
1334 .compatible = "rockchip,rk3368-tsadc",
1338 .compatible = "rockchip,rk3399-tsadc",
1342 .compatible = "rockchip,rk3568-tsadc",
1346 .compatible = "rockchip,rk3588-tsadc",
1356 struct thermal_zone_device *tzd = sensor->tzd; in rockchip_thermal_toggle_sensor()
1366 struct rockchip_thermal_data *thermal = dev; in rockchip_thermal_alarm_irq_thread() local
1369 dev_dbg(&thermal->pdev->dev, "thermal alarm\n"); in rockchip_thermal_alarm_irq_thread()
1371 thermal->chip->irq_ack(thermal->regs); in rockchip_thermal_alarm_irq_thread()
1373 for (i = 0; i < thermal->chip->chn_num; i++) in rockchip_thermal_alarm_irq_thread()
1374 thermal_zone_device_update(thermal->sensors[i].tzd, in rockchip_thermal_alarm_irq_thread()
1383 struct rockchip_thermal_data *thermal = sensor->thermal; in rockchip_thermal_set_trips() local
1384 const struct rockchip_tsadc_chip *tsadc = thermal->chip; in rockchip_thermal_set_trips()
1386 dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n", in rockchip_thermal_set_trips()
1387 __func__, sensor->id, low, high); in rockchip_thermal_set_trips()
1389 return tsadc->set_alarm_temp(&tsadc->table, in rockchip_thermal_set_trips()
1390 sensor->id, thermal->regs, high); in rockchip_thermal_set_trips()
1396 struct rockchip_thermal_data *thermal = sensor->thermal; in rockchip_thermal_get_temp() local
1397 const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip; in rockchip_thermal_get_temp()
1400 retval = tsadc->get_temp(&tsadc->table, in rockchip_thermal_get_temp()
1401 sensor->id, thermal->regs, out_temp); in rockchip_thermal_get_temp()
1412 struct rockchip_thermal_data *thermal) in rockchip_configure_from_dt() argument
1416 if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) { in rockchip_configure_from_dt()
1419 thermal->chip->tshut_temp); in rockchip_configure_from_dt()
1420 thermal->tshut_temp = thermal->chip->tshut_temp; in rockchip_configure_from_dt()
1425 return -ERANGE; in rockchip_configure_from_dt()
1427 thermal->tshut_temp = shut_temp; in rockchip_configure_from_dt()
1430 if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) { in rockchip_configure_from_dt()
1433 thermal->chip->tshut_mode == TSHUT_MODE_GPIO ? in rockchip_configure_from_dt()
1435 thermal->tshut_mode = thermal->chip->tshut_mode; in rockchip_configure_from_dt()
1437 thermal->tshut_mode = tshut_mode; in rockchip_configure_from_dt()
1440 if (thermal->tshut_mode > 1) { in rockchip_configure_from_dt()
1442 thermal->tshut_mode); in rockchip_configure_from_dt()
1443 return -EINVAL; in rockchip_configure_from_dt()
1446 if (of_property_read_u32(np, "rockchip,hw-tshut-polarity", in rockchip_configure_from_dt()
1449 "Missing tshut-polarity property, using default (%s)\n", in rockchip_configure_from_dt()
1450 thermal->chip->tshut_polarity == TSHUT_LOW_ACTIVE ? in rockchip_configure_from_dt()
1452 thermal->tshut_polarity = thermal->chip->tshut_polarity; in rockchip_configure_from_dt()
1454 thermal->tshut_polarity = tshut_polarity; in rockchip_configure_from_dt()
1457 if (thermal->tshut_polarity > 1) { in rockchip_configure_from_dt()
1458 dev_err(dev, "Invalid tshut-polarity specified: %d\n", in rockchip_configure_from_dt()
1459 thermal->tshut_polarity); in rockchip_configure_from_dt()
1460 return -EINVAL; in rockchip_configure_from_dt()
1466 thermal->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); in rockchip_configure_from_dt()
1467 if (IS_ERR(thermal->grf)) in rockchip_configure_from_dt()
1475 struct rockchip_thermal_data *thermal, in rockchip_thermal_register_sensor() argument
1479 const struct rockchip_tsadc_chip *tsadc = thermal->chip; in rockchip_thermal_register_sensor()
1482 tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode); in rockchip_thermal_register_sensor()
1484 error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs, in rockchip_thermal_register_sensor()
1485 thermal->tshut_temp); in rockchip_thermal_register_sensor()
1487 dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n", in rockchip_thermal_register_sensor()
1488 __func__, thermal->tshut_temp, error); in rockchip_thermal_register_sensor()
1490 sensor->thermal = thermal; in rockchip_thermal_register_sensor()
1491 sensor->id = id; in rockchip_thermal_register_sensor()
1492 sensor->tzd = devm_thermal_of_zone_register(&pdev->dev, id, sensor, in rockchip_thermal_register_sensor()
1494 if (IS_ERR(sensor->tzd)) { in rockchip_thermal_register_sensor()
1495 error = PTR_ERR(sensor->tzd); in rockchip_thermal_register_sensor()
1496 dev_err(&pdev->dev, "failed to register sensor %d: %d\n", in rockchip_thermal_register_sensor()
1505 * rockchip_thermal_reset_controller - Reset TSADC Controller, reset all tsadc registers.
1517 struct device_node *np = pdev->dev.of_node; in rockchip_thermal_probe()
1518 struct rockchip_thermal_data *thermal; in rockchip_thermal_probe() local
1525 return -EINVAL; in rockchip_thermal_probe()
1527 thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data), in rockchip_thermal_probe()
1529 if (!thermal) in rockchip_thermal_probe()
1530 return -ENOMEM; in rockchip_thermal_probe()
1532 thermal->pdev = pdev; in rockchip_thermal_probe()
1534 thermal->chip = device_get_match_data(&pdev->dev); in rockchip_thermal_probe()
1535 if (!thermal->chip) in rockchip_thermal_probe()
1536 return -EINVAL; in rockchip_thermal_probe()
1538 thermal->sensors = devm_kcalloc(&pdev->dev, thermal->chip->chn_num, in rockchip_thermal_probe()
1539 sizeof(*thermal->sensors), GFP_KERNEL); in rockchip_thermal_probe()
1540 if (!thermal->sensors) in rockchip_thermal_probe()
1541 return -ENOMEM; in rockchip_thermal_probe()
1543 thermal->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in rockchip_thermal_probe()
1544 if (IS_ERR(thermal->regs)) in rockchip_thermal_probe()
1545 return PTR_ERR(thermal->regs); in rockchip_thermal_probe()
1547 thermal->reset = devm_reset_control_array_get_exclusive(&pdev->dev); in rockchip_thermal_probe()
1548 if (IS_ERR(thermal->reset)) in rockchip_thermal_probe()
1549 return dev_err_probe(&pdev->dev, PTR_ERR(thermal->reset), in rockchip_thermal_probe()
1552 thermal->clk = devm_clk_get_enabled(&pdev->dev, "tsadc"); in rockchip_thermal_probe()
1553 if (IS_ERR(thermal->clk)) in rockchip_thermal_probe()
1554 return dev_err_probe(&pdev->dev, PTR_ERR(thermal->clk), in rockchip_thermal_probe()
1557 thermal->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk"); in rockchip_thermal_probe()
1558 if (IS_ERR(thermal->pclk)) in rockchip_thermal_probe()
1559 return dev_err_probe(&pdev->dev, PTR_ERR(thermal->pclk), in rockchip_thermal_probe()
1562 rockchip_thermal_reset_controller(thermal->reset); in rockchip_thermal_probe()
1564 error = rockchip_configure_from_dt(&pdev->dev, np, thermal); in rockchip_thermal_probe()
1566 return dev_err_probe(&pdev->dev, error, in rockchip_thermal_probe()
1569 thermal->chip->initialize(thermal->grf, thermal->regs, in rockchip_thermal_probe()
1570 thermal->tshut_polarity); in rockchip_thermal_probe()
1572 for (i = 0; i < thermal->chip->chn_num; i++) { in rockchip_thermal_probe()
1573 error = rockchip_thermal_register_sensor(pdev, thermal, in rockchip_thermal_probe()
1574 &thermal->sensors[i], in rockchip_thermal_probe()
1575 thermal->chip->chn_offset + i); in rockchip_thermal_probe()
1577 return dev_err_probe(&pdev->dev, error, in rockchip_thermal_probe()
1581 error = devm_request_threaded_irq(&pdev->dev, irq, NULL, in rockchip_thermal_probe()
1584 "rockchip_thermal", thermal); in rockchip_thermal_probe()
1586 return dev_err_probe(&pdev->dev, error, in rockchip_thermal_probe()
1589 thermal->chip->control(thermal->regs, true); in rockchip_thermal_probe()
1591 for (i = 0; i < thermal->chip->chn_num; i++) { in rockchip_thermal_probe()
1592 rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); in rockchip_thermal_probe()
1593 error = thermal_add_hwmon_sysfs(thermal->sensors[i].tzd); in rockchip_thermal_probe()
1595 dev_warn(&pdev->dev, in rockchip_thermal_probe()
1600 platform_set_drvdata(pdev, thermal); in rockchip_thermal_probe()
1607 struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); in rockchip_thermal_remove() local
1610 for (i = 0; i < thermal->chip->chn_num; i++) { in rockchip_thermal_remove()
1611 struct rockchip_thermal_sensor *sensor = &thermal->sensors[i]; in rockchip_thermal_remove()
1613 thermal_remove_hwmon_sysfs(sensor->tzd); in rockchip_thermal_remove()
1617 thermal->chip->control(thermal->regs, false); in rockchip_thermal_remove()
1622 struct rockchip_thermal_data *thermal = dev_get_drvdata(dev); in rockchip_thermal_suspend() local
1625 for (i = 0; i < thermal->chip->chn_num; i++) in rockchip_thermal_suspend()
1626 rockchip_thermal_toggle_sensor(&thermal->sensors[i], false); in rockchip_thermal_suspend()
1628 thermal->chip->control(thermal->regs, false); in rockchip_thermal_suspend()
1630 clk_disable(thermal->pclk); in rockchip_thermal_suspend()
1631 clk_disable(thermal->clk); in rockchip_thermal_suspend()
1640 struct rockchip_thermal_data *thermal = dev_get_drvdata(dev); in rockchip_thermal_resume() local
1644 error = clk_enable(thermal->clk); in rockchip_thermal_resume()
1648 error = clk_enable(thermal->pclk); in rockchip_thermal_resume()
1650 clk_disable(thermal->clk); in rockchip_thermal_resume()
1654 rockchip_thermal_reset_controller(thermal->reset); in rockchip_thermal_resume()
1656 thermal->chip->initialize(thermal->grf, thermal->regs, in rockchip_thermal_resume()
1657 thermal->tshut_polarity); in rockchip_thermal_resume()
1659 for (i = 0; i < thermal->chip->chn_num; i++) { in rockchip_thermal_resume()
1660 int id = thermal->sensors[i].id; in rockchip_thermal_resume()
1662 thermal->chip->set_tshut_mode(id, thermal->regs, in rockchip_thermal_resume()
1663 thermal->tshut_mode); in rockchip_thermal_resume()
1665 error = thermal->chip->set_tshut_temp(&thermal->chip->table, in rockchip_thermal_resume()
1666 id, thermal->regs, in rockchip_thermal_resume()
1667 thermal->tshut_temp); in rockchip_thermal_resume()
1670 __func__, thermal->tshut_temp, error); in rockchip_thermal_resume()
1673 thermal->chip->control(thermal->regs, true); in rockchip_thermal_resume()
1675 for (i = 0; i < thermal->chip->chn_num; i++) in rockchip_thermal_resume()
1676 rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); in rockchip_thermal_resume()
1688 .name = "rockchip-thermal",
1698 MODULE_DESCRIPTION("ROCKCHIP THERMAL Driver");
1701 MODULE_ALIAS("platform:rockchip-thermal");