aht10.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * aht10.c - Linux hwmon driver for AHT10 Temperature and Humidity sensor
  4. * Copyright (C) 2020 Johannes Cornelis Draaijer
  5. */
  6. #include <linux/delay.h>
  7. #include <linux/hwmon.h>
  8. #include <linux/i2c.h>
  9. #include <linux/ktime.h>
  10. #include <linux/module.h>
  11. #define AHT10_MEAS_SIZE 6
  12. /*
  13. * Poll intervals (in milliseconds)
  14. */
  15. #define AHT10_DEFAULT_MIN_POLL_INTERVAL 2000
  16. #define AHT10_MIN_POLL_INTERVAL 2000
  17. /*
  18. * I2C command delays (in microseconds)
  19. */
  20. #define AHT10_MEAS_DELAY 80000
  21. #define AHT10_CMD_DELAY 350000
  22. #define AHT10_DELAY_EXTRA 100000
  23. /*
  24. * Command bytes
  25. */
  26. #define AHT10_CMD_INIT 0b11100001
  27. #define AHT10_CMD_MEAS 0b10101100
  28. #define AHT10_CMD_RST 0b10111010
  29. /*
  30. * Flags in the answer byte/command
  31. */
  32. #define AHT10_CAL_ENABLED BIT(3)
  33. #define AHT10_BUSY BIT(7)
  34. #define AHT10_MODE_NOR (BIT(5) | BIT(6))
  35. #define AHT10_MODE_CYC BIT(5)
  36. #define AHT10_MODE_CMD BIT(6)
  37. #define AHT10_MAX_POLL_INTERVAL_LEN 30
  38. /**
  39. * struct aht10_data - All the data required to operate an AHT10 chip
  40. * @client: the i2c client associated with the AHT10
  41. * @lock: a mutex that is used to prevent parallel access to the
  42. * i2c client
  43. * @min_poll_interval: the minimum poll interval
  44. * While the poll rate limit is not 100% necessary,
  45. * the datasheet recommends that a measurement
  46. * is not performed too often to prevent
  47. * the chip from warming up due to the heat it generates.
  48. * If it's unwanted, it can be ignored setting it to
  49. * it to 0. Default value is 2000 ms
  50. * @previous_poll_time: the previous time that the AHT10
  51. * was polled
  52. * @temperature: the latest temperature value received from
  53. * the AHT10
  54. * @humidity: the latest humidity value received from the
  55. * AHT10
  56. */
  57. struct aht10_data {
  58. struct i2c_client *client;
  59. /*
  60. * Prevent simultaneous access to the i2c
  61. * client and previous_poll_time
  62. */
  63. struct mutex lock;
  64. ktime_t min_poll_interval;
  65. ktime_t previous_poll_time;
  66. int temperature;
  67. int humidity;
  68. };
  69. /**
  70. * aht10_init() - Initialize an AHT10 chip
  71. * @client: the i2c client associated with the AHT10
  72. * @data: the data associated with this AHT10 chip
  73. * Return: 0 if succesfull, 1 if not
  74. */
  75. static int aht10_init(struct aht10_data *data)
  76. {
  77. const u8 cmd_init[] = {AHT10_CMD_INIT, AHT10_CAL_ENABLED | AHT10_MODE_CYC,
  78. 0x00};
  79. int res;
  80. u8 status;
  81. struct i2c_client *client = data->client;
  82. res = i2c_master_send(client, cmd_init, 3);
  83. if (res < 0)
  84. return res;
  85. usleep_range(AHT10_CMD_DELAY, AHT10_CMD_DELAY +
  86. AHT10_DELAY_EXTRA);
  87. res = i2c_master_recv(client, &status, 1);
  88. if (res != 1)
  89. return -ENODATA;
  90. if (status & AHT10_BUSY)
  91. return -EBUSY;
  92. return 0;
  93. }
  94. /**
  95. * aht10_polltime_expired() - check if the minimum poll interval has
  96. * expired
  97. * @data: the data containing the time to compare
  98. * Return: 1 if the minimum poll interval has expired, 0 if not
  99. */
  100. static int aht10_polltime_expired(struct aht10_data *data)
  101. {
  102. ktime_t current_time = ktime_get_boottime();
  103. ktime_t difference = ktime_sub(current_time, data->previous_poll_time);
  104. return ktime_after(difference, data->min_poll_interval);
  105. }
  106. /**
  107. * aht10_read_values() - read and parse the raw data from the AHT10
  108. * @aht10_data: the struct aht10_data to use for the lock
  109. * Return: 0 if succesfull, 1 if not
  110. */
  111. static int aht10_read_values(struct aht10_data *data)
  112. {
  113. const u8 cmd_meas[] = {AHT10_CMD_MEAS, 0x33, 0x00};
  114. u32 temp, hum;
  115. int res;
  116. u8 raw_data[AHT10_MEAS_SIZE];
  117. struct i2c_client *client = data->client;
  118. mutex_lock(&data->lock);
  119. if (aht10_polltime_expired(data)) {
  120. res = i2c_master_send(client, cmd_meas, sizeof(cmd_meas));
  121. if (res < 0) {
  122. mutex_unlock(&data->lock);
  123. return res;
  124. }
  125. usleep_range(AHT10_MEAS_DELAY,
  126. AHT10_MEAS_DELAY + AHT10_DELAY_EXTRA);
  127. res = i2c_master_recv(client, raw_data, AHT10_MEAS_SIZE);
  128. if (res != AHT10_MEAS_SIZE) {
  129. mutex_unlock(&data->lock);
  130. if (res >= 0)
  131. return -ENODATA;
  132. else
  133. return res;
  134. }
  135. hum = ((u32)raw_data[1] << 12u) |
  136. ((u32)raw_data[2] << 4u) |
  137. ((raw_data[3] & 0xF0u) >> 4u);
  138. temp = ((u32)(raw_data[3] & 0x0Fu) << 16u) |
  139. ((u32)raw_data[4] << 8u) |
  140. raw_data[5];
  141. temp = ((temp * 625) >> 15u) * 10;
  142. hum = ((hum * 625) >> 16u) * 10;
  143. data->temperature = (int)temp - 50000;
  144. data->humidity = hum;
  145. data->previous_poll_time = ktime_get_boottime();
  146. }
  147. mutex_unlock(&data->lock);
  148. return 0;
  149. }
  150. /**
  151. * aht10_interval_write() - store the given minimum poll interval.
  152. * Return: 0 on success, -EINVAL if a value lower than the
  153. * AHT10_MIN_POLL_INTERVAL is given
  154. */
  155. static ssize_t aht10_interval_write(struct aht10_data *data,
  156. long val)
  157. {
  158. data->min_poll_interval = ms_to_ktime(clamp_val(val, 2000, LONG_MAX));
  159. return 0;
  160. }
  161. /**
  162. * aht10_interval_read() - read the minimum poll interval
  163. * in milliseconds
  164. */
  165. static ssize_t aht10_interval_read(struct aht10_data *data,
  166. long *val)
  167. {
  168. *val = ktime_to_ms(data->min_poll_interval);
  169. return 0;
  170. }
  171. /**
  172. * aht10_temperature1_read() - read the temperature in millidegrees
  173. */
  174. static int aht10_temperature1_read(struct aht10_data *data, long *val)
  175. {
  176. int res;
  177. res = aht10_read_values(data);
  178. if (res < 0)
  179. return res;
  180. *val = data->temperature;
  181. return 0;
  182. }
  183. /**
  184. * aht10_humidity1_read() - read the relative humidity in millipercent
  185. */
  186. static int aht10_humidity1_read(struct aht10_data *data, long *val)
  187. {
  188. int res;
  189. res = aht10_read_values(data);
  190. if (res < 0)
  191. return res;
  192. *val = data->humidity;
  193. return 0;
  194. }
  195. static umode_t aht10_hwmon_visible(const void *data, enum hwmon_sensor_types type,
  196. u32 attr, int channel)
  197. {
  198. switch (type) {
  199. case hwmon_temp:
  200. case hwmon_humidity:
  201. return 0444;
  202. case hwmon_chip:
  203. return 0644;
  204. default:
  205. return 0;
  206. }
  207. }
  208. static int aht10_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
  209. u32 attr, int channel, long *val)
  210. {
  211. struct aht10_data *data = dev_get_drvdata(dev);
  212. switch (type) {
  213. case hwmon_temp:
  214. return aht10_temperature1_read(data, val);
  215. case hwmon_humidity:
  216. return aht10_humidity1_read(data, val);
  217. case hwmon_chip:
  218. return aht10_interval_read(data, val);
  219. default:
  220. return -EOPNOTSUPP;
  221. }
  222. }
  223. static int aht10_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
  224. u32 attr, int channel, long val)
  225. {
  226. struct aht10_data *data = dev_get_drvdata(dev);
  227. switch (type) {
  228. case hwmon_chip:
  229. return aht10_interval_write(data, val);
  230. default:
  231. return -EOPNOTSUPP;
  232. }
  233. }
  234. static const struct hwmon_channel_info *aht10_info[] = {
  235. HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
  236. HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
  237. HWMON_CHANNEL_INFO(humidity, HWMON_H_INPUT),
  238. NULL,
  239. };
  240. static const struct hwmon_ops aht10_hwmon_ops = {
  241. .is_visible = aht10_hwmon_visible,
  242. .read = aht10_hwmon_read,
  243. .write = aht10_hwmon_write,
  244. };
  245. static const struct hwmon_chip_info aht10_chip_info = {
  246. .ops = &aht10_hwmon_ops,
  247. .info = aht10_info,
  248. };
  249. static int aht10_probe(struct i2c_client *client,
  250. const struct i2c_device_id *aht10_id)
  251. {
  252. struct device *device = &client->dev;
  253. struct device *hwmon_dev;
  254. struct aht10_data *data;
  255. int res;
  256. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
  257. return -ENOENT;
  258. data = devm_kzalloc(device, sizeof(*data), GFP_KERNEL);
  259. if (!data)
  260. return -ENOMEM;
  261. data->min_poll_interval = ms_to_ktime(AHT10_DEFAULT_MIN_POLL_INTERVAL);
  262. data->client = client;
  263. mutex_init(&data->lock);
  264. res = aht10_init(data);
  265. if (res < 0)
  266. return res;
  267. res = aht10_read_values(data);
  268. if (res < 0)
  269. return res;
  270. hwmon_dev = devm_hwmon_device_register_with_info(device,
  271. client->name,
  272. data,
  273. &aht10_chip_info,
  274. NULL);
  275. return PTR_ERR_OR_ZERO(hwmon_dev);
  276. }
  277. static const struct i2c_device_id aht10_id[] = {
  278. { "aht10", 0 },
  279. { },
  280. };
  281. MODULE_DEVICE_TABLE(i2c, aht10_id);
  282. static struct i2c_driver aht10_driver = {
  283. .driver = {
  284. .name = "aht10",
  285. },
  286. .probe = aht10_probe,
  287. .id_table = aht10_id,
  288. };
  289. module_i2c_driver(aht10_driver);
  290. MODULE_AUTHOR("Johannes Cornelis Draaijer <[email protected]>");
  291. MODULE_DESCRIPTION("AHT10 Temperature and Humidity sensor driver");
  292. MODULE_VERSION("1.0");
  293. MODULE_LICENSE("GPL v2");