hs3001.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * This is a non-complete driver implementation for the
  4. * HS3001 humidity and temperature sensor and compatibles. It does not include
  5. * the configuration possibilities, where it needs to be set to 'programming mode'
  6. * during power-up.
  7. *
  8. *
  9. * Copyright (C) 2023 SYS TEC electronic AG
  10. * Author: Andre Werner <andre.werner@systec-electronic.com>
  11. */
  12. #include <linux/bitfield.h>
  13. #include <linux/delay.h>
  14. #include <linux/err.h>
  15. #include <linux/hwmon.h>
  16. #include <linux/i2c.h>
  17. #include <linux/init.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/of_device.h>
  21. #include <linux/slab.h>
  22. #include <linux/types.h>
  23. /* Measurement times */
  24. #define HS3001_WAKEUP_TIME 100 /* us */
  25. #define HS3001_8BIT_RESOLUTION 550 /* us */
  26. #define HS3001_10BIT_RESOLUTION 1310 /* us */
  27. #define HS3001_12BIT_RESOLUTION 4500 /* us */
  28. #define HS3001_14BIT_RESOLUTION 16900 /* us */
  29. #define HS3001_RESPONSE_LENGTH 4
  30. #define HS3001_FIXPOINT_ARITH 1000U
  31. #define HS3001_MASK_HUMIDITY_0X3FFF GENMASK(13, 0)
  32. #define HS3001_MASK_STATUS_0XC0 GENMASK(7, 6)
  33. /* Definitions for Status Bits of A/D Data */
  34. #define HS3001_DATA_VALID 0x00 /* Valid Data */
  35. #define HS3001_DATA_STALE 0x01 /* Stale Data */
  36. struct hs3001_data {
  37. struct i2c_client *client;
  38. u32 wait_time; /* in us */
  39. int temperature; /* in milli degree */
  40. u32 humidity; /* in milli % */
  41. };
  42. static int hs3001_extract_temperature(u16 raw)
  43. {
  44. /* fixpoint arithmetic 1 digit */
  45. u32 temp = (raw >> 2) * HS3001_FIXPOINT_ARITH * 165;
  46. temp /= (1 << 14) - 1;
  47. return (int)temp - 40 * HS3001_FIXPOINT_ARITH;
  48. }
  49. static u32 hs3001_extract_humidity(u16 raw)
  50. {
  51. u32 hum = (raw & HS3001_MASK_HUMIDITY_0X3FFF) * HS3001_FIXPOINT_ARITH * 100;
  52. return hum / (1 << 14) - 1;
  53. }
  54. static int hs3001_data_fetch_command(struct i2c_client *client,
  55. struct hs3001_data *data)
  56. {
  57. int ret;
  58. u8 buf[HS3001_RESPONSE_LENGTH];
  59. u8 hs3001_status;
  60. ret = i2c_master_recv(client, buf, HS3001_RESPONSE_LENGTH);
  61. if (ret != HS3001_RESPONSE_LENGTH) {
  62. ret = ret < 0 ? ret : -EIO;
  63. dev_dbg(&client->dev,
  64. "Error in i2c communication. Error code: %d.\n", ret);
  65. return ret;
  66. }
  67. hs3001_status = FIELD_GET(HS3001_MASK_STATUS_0XC0, buf[0]);
  68. if (hs3001_status == HS3001_DATA_STALE) {
  69. dev_dbg(&client->dev, "Sensor busy.\n");
  70. return -EBUSY;
  71. }
  72. if (hs3001_status != HS3001_DATA_VALID) {
  73. dev_dbg(&client->dev, "Data invalid.\n");
  74. return -EIO;
  75. }
  76. data->humidity =
  77. hs3001_extract_humidity(be16_to_cpup((__be16 *)&buf[0]));
  78. data->temperature =
  79. hs3001_extract_temperature(be16_to_cpup((__be16 *)&buf[2]));
  80. return 0;
  81. }
  82. static umode_t hs3001_is_visible(const void *data, enum hwmon_sensor_types type,
  83. u32 attr, int channel)
  84. {
  85. /* Both, humidity and temperature can only be read. */
  86. return 0444;
  87. }
  88. static int hs3001_read(struct device *dev, enum hwmon_sensor_types type,
  89. u32 attr, int channel, long *val)
  90. {
  91. struct hs3001_data *data = dev_get_drvdata(dev);
  92. struct i2c_client *client = data->client;
  93. int ret;
  94. ret = i2c_master_send(client, NULL, 0);
  95. if (ret < 0)
  96. return ret;
  97. /*
  98. * Sensor needs some time to process measurement depending on
  99. * resolution (ref. datasheet)
  100. */
  101. fsleep(data->wait_time);
  102. ret = hs3001_data_fetch_command(client, data);
  103. if (ret < 0)
  104. return ret;
  105. switch (type) {
  106. case hwmon_temp:
  107. switch (attr) {
  108. case hwmon_temp_input:
  109. *val = data->temperature;
  110. break;
  111. default:
  112. return -EINVAL;
  113. }
  114. break;
  115. case hwmon_humidity:
  116. switch (attr) {
  117. case hwmon_humidity_input:
  118. *val = data->humidity;
  119. break;
  120. default:
  121. return -EINVAL;
  122. }
  123. break;
  124. default:
  125. return -EINVAL;
  126. }
  127. return 0;
  128. }
  129. static const struct hwmon_channel_info *hs3001_info[] = {
  130. HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
  131. HWMON_CHANNEL_INFO(humidity, HWMON_H_INPUT),
  132. NULL
  133. };
  134. static const struct hwmon_ops hs3001_hwmon_ops = {
  135. .is_visible = hs3001_is_visible,
  136. .read = hs3001_read,
  137. };
  138. static const struct hwmon_chip_info hs3001_chip_info = {
  139. .ops = &hs3001_hwmon_ops,
  140. .info = hs3001_info,
  141. };
  142. /* device ID table */
  143. static const struct i2c_device_id hs3001_ids[] = {
  144. { "hs3001" },
  145. { },
  146. };
  147. MODULE_DEVICE_TABLE(i2c, hs3001_ids);
  148. static const struct of_device_id hs3001_of_match[] = {
  149. {.compatible = "renesas,hs3001"},
  150. { },
  151. };
  152. MODULE_DEVICE_TABLE(of, hs3001_of_match);
  153. static int hs3001_probe(struct i2c_client *client)
  154. {
  155. struct hs3001_data *data;
  156. struct device *hwmon_dev;
  157. struct device *dev = &client->dev;
  158. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
  159. return -EOPNOTSUPP;
  160. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  161. if (!data)
  162. return -ENOMEM;
  163. data->client = client;
  164. /*
  165. * Measurement time = wake-up time + measurement time temperature
  166. * + measurement time humidity. This is currently static, because
  167. * enabling programming mode is not supported, yet.
  168. */
  169. data->wait_time = (HS3001_WAKEUP_TIME + HS3001_14BIT_RESOLUTION +
  170. HS3001_14BIT_RESOLUTION);
  171. hwmon_dev = devm_hwmon_device_register_with_info(dev,
  172. client->name,
  173. data,
  174. &hs3001_chip_info,
  175. NULL);
  176. if (IS_ERR(hwmon_dev))
  177. return dev_err_probe(dev, PTR_ERR(hwmon_dev),
  178. "Unable to register hwmon device.\n");
  179. return 0;
  180. }
  181. static struct i2c_driver hs3001_i2c_driver = {
  182. .driver = {
  183. .name = "hs3001",
  184. .of_match_table = hs3001_of_match,
  185. },
  186. .probe = hs3001_probe,
  187. .id_table = hs3001_ids,
  188. };
  189. module_i2c_driver(hs3001_i2c_driver);
  190. MODULE_AUTHOR("Andre Werner <andre.werner@systec-electronic.com>");
  191. MODULE_DESCRIPTION("HS3001 humidity and temperature sensor base driver");
  192. MODULE_LICENSE("GPL");