qcom-spmi-mbg-tm.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #include <linux/interrupt.h>
  6. #include <linux/irq.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/of_device.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/regmap.h>
  12. #include <linux/thermal.h>
  13. #include <linux/iio/consumer.h>
  14. #include "../thermal_core.h"
  15. #define MBG_TEMP_MON_MM_MON2_FAULT_STATUS 0x50
  16. #define MON_FAULT_STATUS_MASK GENMASK(7, 6)
  17. #define MON_FAULT_STATUS_SHIFT 6
  18. #define MON2_LVL1_ERR 0x1
  19. #define MON2_LVL1_UP_THRESH 0x59
  20. #define MBG_TEMP_MON_MM_MON2_MISC_CFG 0x5f
  21. #define UP_THRESH_EN BIT(1)
  22. #define STEP_MV 8
  23. #define MBG_DEFAULT_TEMP_MV 600
  24. #define MBG_TEMP_CONSTANT 1000
  25. struct mbg_tm_chip {
  26. struct regmap *map;
  27. struct device *dev;
  28. struct thermal_zone_device *tz_dev;
  29. struct mutex lock;
  30. unsigned int base;
  31. int irq;
  32. int last_temp;
  33. bool last_temp_set;
  34. struct iio_channel *adc;
  35. };
  36. struct mbg_map_table {
  37. int min_temp;
  38. int max_temp;
  39. int vtemp0;
  40. int tc;
  41. int t0;
  42. };
  43. static const struct mbg_map_table map_table[] = {
  44. /* minT maxT vtemp0 tc t0 */
  45. { -60000, -40000, 4337, 1967, -60000 },
  46. { -40000, -20000, 4731, 1964, -40000 },
  47. { -20000, 0, 5124, 1957, -20000 },
  48. { 0, 20000, 5515, 1949, 0 },
  49. { 20000, 40000, 5905, 1940, 20000 },
  50. { 40000, 60000, 6293, 1930, 40000 },
  51. { 60000, 80000, 6679, 1921, 60000 },
  52. { 80000, 100000, 7064, 1910, 80000 },
  53. { 100000, 120000, 7446, 1896, 100000 },
  54. { 120000, 140000, 7825, 1878, 120000 },
  55. { 140000, 160000, 8201, 1859, 140000 },
  56. };
  57. static int mbg_tm_read(struct mbg_tm_chip *chip, u16 addr, int *data)
  58. {
  59. return regmap_read(chip->map, chip->base + addr, data);
  60. }
  61. static int mbg_tm_write(struct mbg_tm_chip *chip, u16 addr, int data)
  62. {
  63. return regmap_write(chip->map, chip->base + addr, data);
  64. }
  65. static int mbg_tm_reg_update(struct mbg_tm_chip *chip, u16 addr, u8 mask, u8 val)
  66. {
  67. return regmap_write_bits(chip->map, chip->base + addr, mask, val);
  68. }
  69. static int mbg_tm_get_temp(struct thermal_zone_device *tz, int *temp)
  70. {
  71. struct mbg_tm_chip *chip = tz->devdata;
  72. int ret, milli_celsius;
  73. if (!temp)
  74. return -EINVAL;
  75. if (chip->last_temp_set) {
  76. pr_debug("last_temp: %d\n", chip->last_temp);
  77. chip->last_temp_set = false;
  78. *temp = chip->last_temp;
  79. return 0;
  80. }
  81. ret = iio_read_channel_processed(chip->adc, &milli_celsius);
  82. if (ret < 0) {
  83. dev_err(chip->dev, "failed to read iio channel %d\n", ret);
  84. return ret;
  85. }
  86. *temp = milli_celsius;
  87. return 0;
  88. }
  89. static int temp_to_vtemp(int temp)
  90. {
  91. int idx, vtemp, tc = 0, t0 = 0, vtemp0 = 0;
  92. for (idx = 0; idx < ARRAY_SIZE(map_table); idx++)
  93. if (temp >= map_table[idx].min_temp &&
  94. temp < map_table[idx].max_temp) {
  95. tc = map_table[idx].tc;
  96. t0 = map_table[idx].t0;
  97. vtemp0 = map_table[idx].vtemp0;
  98. break;
  99. }
  100. /*
  101. * Formula to calculate vtemp from a given temp
  102. * vtemp = (t-t0) * tc + vtemp0
  103. * tc, t0 and vtemp0 values are mentioned in the map_table array.
  104. */
  105. vtemp = (temp - t0)/1000 * tc/1000 + vtemp0/10;
  106. return abs(vtemp - MBG_DEFAULT_TEMP_MV)/STEP_MV;
  107. }
  108. static int mbg_tm_set_trip_temp(struct thermal_zone_device *tz, int low_thresh, int temp)
  109. {
  110. struct mbg_tm_chip *chip = tz->devdata;
  111. int ret = 0, vtemp = 0;
  112. mutex_lock(&chip->lock);
  113. if (temp != INT_MAX) {
  114. mbg_tm_reg_update(chip, MBG_TEMP_MON_MM_MON2_MISC_CFG,
  115. UP_THRESH_EN, UP_THRESH_EN);
  116. vtemp = temp_to_vtemp(temp);
  117. ret = mbg_tm_write(chip, MON2_LVL1_UP_THRESH, vtemp);
  118. if (ret < 0) {
  119. mutex_unlock(&chip->lock);
  120. return ret;
  121. }
  122. } else {
  123. mbg_tm_reg_update(chip, MBG_TEMP_MON_MM_MON2_MISC_CFG,
  124. UP_THRESH_EN, 0);
  125. }
  126. mutex_unlock(&chip->lock);
  127. /*
  128. * Configure the last_temp one degree higher, to ensure the
  129. * violated temp is returned to thermal framework after the
  130. * violation happens. This is needed to account for the
  131. * inaccuracy in the conversion formula used which leads
  132. * to the thermal framework setting back the same thresholds
  133. * in case the temperature it reads does not show violation.
  134. */
  135. chip->last_temp = temp + MBG_TEMP_CONSTANT;
  136. return ret;
  137. }
  138. static const struct thermal_zone_device_ops mbg_tm_ops = {
  139. .get_temp = mbg_tm_get_temp,
  140. .set_trips = mbg_tm_set_trip_temp,
  141. };
  142. static irqreturn_t mbg_tm_isr(int irq, void *data)
  143. {
  144. struct mbg_tm_chip *chip = data;
  145. int ret;
  146. int val = 0;
  147. mutex_lock(&chip->lock);
  148. ret = mbg_tm_read(chip, MBG_TEMP_MON_MM_MON2_FAULT_STATUS, &val);
  149. mutex_unlock(&chip->lock);
  150. if (ret < 0)
  151. return IRQ_HANDLED;
  152. val &= MON_FAULT_STATUS_MASK;
  153. if ((val >> MON_FAULT_STATUS_SHIFT) & MON2_LVL1_ERR) {
  154. chip->last_temp_set = true;
  155. thermal_zone_device_update(chip->tz_dev,
  156. THERMAL_TRIP_VIOLATED);
  157. pr_debug("Notifying Thermal, val=%d\n", val);
  158. } else {
  159. pr_debug("High trip not violated, ignoring IRQ\n");
  160. }
  161. return IRQ_HANDLED;
  162. }
  163. static int mbg_tm_probe(struct platform_device *pdev)
  164. {
  165. struct mbg_tm_chip *chip;
  166. struct device_node *node;
  167. u32 res;
  168. int ret = 0;
  169. node = pdev->dev.of_node;
  170. chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
  171. if (!chip)
  172. return -ENOMEM;
  173. chip->dev = &pdev->dev;
  174. mutex_init(&chip->lock);
  175. chip->map = dev_get_regmap(pdev->dev.parent, NULL);
  176. if (!chip->map)
  177. return -ENXIO;
  178. ret = of_property_read_u32(node, "reg", &res);
  179. if (ret < 0)
  180. return ret;
  181. chip->base = res;
  182. chip->irq = platform_get_irq(pdev, 0);
  183. if (chip->irq < 0)
  184. return chip->irq;
  185. chip->adc = devm_iio_channel_get(&pdev->dev, "thermal");
  186. if (IS_ERR(chip->adc))
  187. return PTR_ERR(chip->adc);
  188. chip->tz_dev = devm_thermal_of_zone_register(&pdev->dev,
  189. 0, chip, &mbg_tm_ops);
  190. if (IS_ERR(chip->tz_dev)) {
  191. dev_err(&pdev->dev, "failed to register sensor\n");
  192. return PTR_ERR(chip->tz_dev);
  193. }
  194. ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL,
  195. mbg_tm_isr, IRQF_ONESHOT, node->name, chip);
  196. return ret;
  197. }
  198. static const struct of_device_id mbg_tm_match_table[] = {
  199. { .compatible = "qcom,spmi-mgb-tm" },
  200. { }
  201. };
  202. MODULE_DEVICE_TABLE(of, mbg_tm_match_table);
  203. static struct platform_driver mbg_tm_driver = {
  204. .driver = {
  205. .name = "qcom-spmi-mbg-tm",
  206. .of_match_table = mbg_tm_match_table,
  207. },
  208. .probe = mbg_tm_probe,
  209. };
  210. module_platform_driver(mbg_tm_driver);
  211. MODULE_DESCRIPTION("PMIC MBG Temperature monitor driver");
  212. MODULE_LICENSE("GPL");