max77620_thermal.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Junction temperature thermal driver for Maxim Max77620.
  3. *
  4. * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
  5. *
  6. * Author: Laxman Dewangan <ldewangan@nvidia.com>
  7. * Mallikarjun Kasoju <mkasoju@nvidia.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms and conditions of the GNU General Public License,
  11. * version 2, as published by the Free Software Foundation.
  12. */
  13. #include <linux/irq.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/mfd/max77620.h>
  16. #include <linux/module.h>
  17. #include <linux/of.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/regmap.h>
  20. #include <linux/slab.h>
  21. #include <linux/thermal.h>
  22. #define MAX77620_NORMAL_OPERATING_TEMP 100000
  23. #define MAX77620_TJALARM1_TEMP 120000
  24. #define MAX77620_TJALARM2_TEMP 140000
  25. struct max77620_therm_info {
  26. struct device *dev;
  27. struct regmap *rmap;
  28. struct thermal_zone_device *tz_device;
  29. int irq_tjalarm1;
  30. int irq_tjalarm2;
  31. };
  32. /**
  33. * max77620_thermal_read_temp: Read PMIC die temperatue.
  34. * @data: Device specific data.
  35. * temp: Temperature in millidegrees Celsius
  36. *
  37. * The actual temperature of PMIC die is not available from PMIC.
  38. * PMIC only tells the status if it has crossed or not the threshold level
  39. * of 120degC or 140degC.
  40. * If threshold has not been crossed then assume die temperature as 100degC
  41. * else 120degC or 140deG based on the PMIC die temp threshold status.
  42. *
  43. * Return 0 on success otherwise error number to show reason of failure.
  44. */
  45. static int max77620_thermal_read_temp(void *data, int *temp)
  46. {
  47. struct max77620_therm_info *mtherm = data;
  48. unsigned int val;
  49. int ret;
  50. ret = regmap_read(mtherm->rmap, MAX77620_REG_STATLBT, &val);
  51. if (ret < 0) {
  52. dev_err(mtherm->dev, "Failed to read STATLBT: %d\n", ret);
  53. return ret;
  54. }
  55. if (val & MAX77620_IRQ_TJALRM2_MASK)
  56. *temp = MAX77620_TJALARM2_TEMP;
  57. else if (val & MAX77620_IRQ_TJALRM1_MASK)
  58. *temp = MAX77620_TJALARM1_TEMP;
  59. else
  60. *temp = MAX77620_NORMAL_OPERATING_TEMP;
  61. return 0;
  62. }
  63. static const struct thermal_zone_of_device_ops max77620_thermal_ops = {
  64. .get_temp = max77620_thermal_read_temp,
  65. };
  66. static irqreturn_t max77620_thermal_irq(int irq, void *data)
  67. {
  68. struct max77620_therm_info *mtherm = data;
  69. if (irq == mtherm->irq_tjalarm1)
  70. dev_warn(mtherm->dev, "Junction Temp Alarm1(120C) occurred\n");
  71. else if (irq == mtherm->irq_tjalarm2)
  72. dev_crit(mtherm->dev, "Junction Temp Alarm2(140C) occurred\n");
  73. thermal_zone_device_update(mtherm->tz_device,
  74. THERMAL_EVENT_UNSPECIFIED);
  75. return IRQ_HANDLED;
  76. }
  77. static int max77620_thermal_probe(struct platform_device *pdev)
  78. {
  79. struct max77620_therm_info *mtherm;
  80. int ret;
  81. mtherm = devm_kzalloc(&pdev->dev, sizeof(*mtherm), GFP_KERNEL);
  82. if (!mtherm)
  83. return -ENOMEM;
  84. mtherm->irq_tjalarm1 = platform_get_irq(pdev, 0);
  85. mtherm->irq_tjalarm2 = platform_get_irq(pdev, 1);
  86. if ((mtherm->irq_tjalarm1 < 0) || (mtherm->irq_tjalarm2 < 0)) {
  87. dev_err(&pdev->dev, "Alarm irq number not available\n");
  88. return -EINVAL;
  89. }
  90. mtherm->dev = &pdev->dev;
  91. mtherm->rmap = dev_get_regmap(pdev->dev.parent, NULL);
  92. if (!mtherm->rmap) {
  93. dev_err(&pdev->dev, "Failed to get parent regmap\n");
  94. return -ENODEV;
  95. }
  96. /*
  97. * The reference taken to the parent's node which will be balanced on
  98. * reprobe or on platform-device release.
  99. */
  100. device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
  101. mtherm->tz_device = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
  102. mtherm, &max77620_thermal_ops);
  103. if (IS_ERR(mtherm->tz_device)) {
  104. ret = PTR_ERR(mtherm->tz_device);
  105. dev_err(&pdev->dev, "Failed to register thermal zone: %d\n",
  106. ret);
  107. return ret;
  108. }
  109. ret = devm_request_threaded_irq(&pdev->dev, mtherm->irq_tjalarm1, NULL,
  110. max77620_thermal_irq,
  111. IRQF_ONESHOT | IRQF_SHARED,
  112. dev_name(&pdev->dev), mtherm);
  113. if (ret < 0) {
  114. dev_err(&pdev->dev, "Failed to request irq1: %d\n", ret);
  115. return ret;
  116. }
  117. ret = devm_request_threaded_irq(&pdev->dev, mtherm->irq_tjalarm2, NULL,
  118. max77620_thermal_irq,
  119. IRQF_ONESHOT | IRQF_SHARED,
  120. dev_name(&pdev->dev), mtherm);
  121. if (ret < 0) {
  122. dev_err(&pdev->dev, "Failed to request irq2: %d\n", ret);
  123. return ret;
  124. }
  125. platform_set_drvdata(pdev, mtherm);
  126. return 0;
  127. }
  128. static struct platform_device_id max77620_thermal_devtype[] = {
  129. { .name = "max77620-thermal", },
  130. {},
  131. };
  132. MODULE_DEVICE_TABLE(platform, max77620_thermal_devtype);
  133. static struct platform_driver max77620_thermal_driver = {
  134. .driver = {
  135. .name = "max77620-thermal",
  136. },
  137. .probe = max77620_thermal_probe,
  138. .id_table = max77620_thermal_devtype,
  139. };
  140. module_platform_driver(max77620_thermal_driver);
  141. MODULE_DESCRIPTION("Max77620 Junction temperature Thermal driver");
  142. MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
  143. MODULE_AUTHOR("Mallikarjun Kasoju <mkasoju@nvidia.com>");
  144. MODULE_LICENSE("GPL v2");