2
0

804-hwmon-tc654-add-thermal_cooling-device.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. From 15ae701189744d321d3a1264ff46f8871e8765ee Mon Sep 17 00:00:00 2001
  2. From: Christian Lamparter <[email protected]>
  3. Date: Sun, 17 Dec 2017 17:29:13 +0100
  4. Subject: [PATCH] hwmon: tc654: add thermal_cooling device
  5. This patch adds a thermaL_cooling device to the tc654 driver.
  6. This allows the chip to be used for DT-based cooling.
  7. Signed-off-by: Christian Lamparter <[email protected]>
  8. ---
  9. drivers/hwmon/tc654.c | 103 +++++++++++++++++++++++++++++++++++++++++---------
  10. 1 file changed, 86 insertions(+), 17 deletions(-)
  11. --- a/drivers/hwmon/tc654.c
  12. +++ b/drivers/hwmon/tc654.c
  13. @@ -24,6 +24,7 @@
  14. #include <linux/module.h>
  15. #include <linux/mutex.h>
  16. #include <linux/slab.h>
  17. +#include <linux/thermal.h>
  18. #include <linux/util_macros.h>
  19. enum tc654_regs {
  20. @@ -141,6 +142,9 @@ struct tc654_data {
  21. * writable register used to control the duty
  22. * cycle of the V OUT output.
  23. */
  24. +
  25. + /* optional cooling device */
  26. + struct thermal_cooling_device *cdev;
  27. };
  28. /* helper to grab and cache data, at most one time per second */
  29. @@ -376,36 +380,30 @@ static ssize_t set_pwm_mode(struct devic
  30. static const int tc654_pwm_map[16] = { 77, 88, 102, 112, 124, 136, 148, 160,
  31. 172, 184, 196, 207, 219, 231, 243, 255};
  32. +static int get_pwm(struct tc654_data *data)
  33. +{
  34. + if (data->config & TC654_REG_CONFIG_SDM)
  35. + return 0;
  36. + else
  37. + return tc654_pwm_map[data->duty_cycle];
  38. +}
  39. +
  40. static ssize_t show_pwm(struct device *dev, struct device_attribute *da,
  41. char *buf)
  42. {
  43. struct tc654_data *data = tc654_update_client(dev);
  44. - int pwm;
  45. if (IS_ERR(data))
  46. return PTR_ERR(data);
  47. - if (data->config & TC654_REG_CONFIG_SDM)
  48. - pwm = 0;
  49. - else
  50. - pwm = tc654_pwm_map[data->duty_cycle];
  51. -
  52. - return sprintf(buf, "%d\n", pwm);
  53. + return sprintf(buf, "%d\n", get_pwm(data));
  54. }
  55. -static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
  56. - const char *buf, size_t count)
  57. +static int _set_pwm(struct tc654_data *data, unsigned long val)
  58. {
  59. - struct tc654_data *data = dev_get_drvdata(dev);
  60. struct i2c_client *client = data->client;
  61. - unsigned long val;
  62. int ret;
  63. - if (kstrtoul(buf, 10, &val))
  64. - return -EINVAL;
  65. - if (val > 255)
  66. - return -EINVAL;
  67. -
  68. mutex_lock(&data->update_lock);
  69. if (val == 0)
  70. @@ -425,6 +423,22 @@ static ssize_t set_pwm(struct device *de
  71. out:
  72. mutex_unlock(&data->update_lock);
  73. + return ret;
  74. +}
  75. +
  76. +static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
  77. + const char *buf, size_t count)
  78. +{
  79. + struct tc654_data *data = dev_get_drvdata(dev);
  80. + unsigned long val;
  81. + int ret;
  82. +
  83. + if (kstrtoul(buf, 10, &val))
  84. + return -EINVAL;
  85. + if (val > 255)
  86. + return -EINVAL;
  87. +
  88. + ret = _set_pwm(data, val);
  89. return ret < 0 ? ret : count;
  90. }
  91. @@ -462,6 +476,47 @@ static struct attribute *tc654_attrs[] =
  92. ATTRIBUTE_GROUPS(tc654);
  93. +/* cooling device */
  94. +
  95. +static int tc654_get_max_state(struct thermal_cooling_device *cdev,
  96. + unsigned long *state)
  97. +{
  98. + *state = 255;
  99. + return 0;
  100. +}
  101. +
  102. +static int tc654_get_cur_state(struct thermal_cooling_device *cdev,
  103. + unsigned long *state)
  104. +{
  105. + struct tc654_data *data = tc654_update_client(cdev->devdata);
  106. +
  107. + if (IS_ERR(data))
  108. + return PTR_ERR(data);
  109. +
  110. + *state = get_pwm(data);
  111. + return 0;
  112. +}
  113. +
  114. +static int tc654_set_cur_state(struct thermal_cooling_device *cdev,
  115. + unsigned long state)
  116. +{
  117. + struct tc654_data *data = tc654_update_client(cdev->devdata);
  118. +
  119. + if (IS_ERR(data))
  120. + return PTR_ERR(data);
  121. +
  122. + if (state > 255)
  123. + return -EINVAL;
  124. +
  125. + return _set_pwm(data, state);
  126. +}
  127. +
  128. +static const struct thermal_cooling_device_ops tc654_fan_cool_ops = {
  129. + .get_max_state = tc654_get_max_state,
  130. + .get_cur_state = tc654_get_cur_state,
  131. + .set_cur_state = tc654_set_cur_state,
  132. +};
  133. +
  134. /*
  135. * device probe and removal
  136. */
  137. @@ -493,7 +548,21 @@ static int tc654_probe(struct i2c_client
  138. hwmon_dev =
  139. devm_hwmon_device_register_with_groups(dev, client->name, data,
  140. tc654_groups);
  141. - return PTR_ERR_OR_ZERO(hwmon_dev);
  142. + if (IS_ERR(hwmon_dev))
  143. + return PTR_ERR(hwmon_dev);
  144. +
  145. +#if IS_ENABLED(CONFIG_OF)
  146. + /* Optional cooling device register for Device tree platforms */
  147. + data->cdev = thermal_of_cooling_device_register(client->dev.of_node,
  148. + "tc654", hwmon_dev,
  149. + &tc654_fan_cool_ops);
  150. +#else /* CONFIG_OF */
  151. + /* Optional cooling device register for non Device tree platforms */
  152. + data->cdev = thermal_cooling_device_register("tc654", hwmon_dev,
  153. + &tc654_fan_cool_ops);
  154. +#endif /* CONFIG_OF */
  155. +
  156. + return PTR_ERR_OR_ZERO(data->cdev);
  157. }
  158. static const struct i2c_device_id tc654_id[] = {