1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * hdc3020.c - Support for the TI HDC3020,HDC3021 and HDC3022 4 * temperature + relative humidity sensors 5 * 6 * Copyright (C) 2023 7 * 8 * Datasheet: https://www.ti.com/lit/ds/symlink/hdc3020.pdf 9 */ 10 11 #include <linux/bitops.h> 12 #include <linux/cleanup.h> 13 #include <linux/crc8.h> 14 #include <linux/delay.h> 15 #include <linux/i2c.h> 16 #include <linux/init.h> 17 #include <linux/module.h> 18 #include <linux/mutex.h> 19 20 #include <asm/unaligned.h> 21 22 #include <linux/iio/iio.h> 23 24 #define HDC3020_HEATER_CMD_MSB 0x30 /* shared by all heater commands */ 25 #define HDC3020_HEATER_ENABLE 0x6D 26 #define HDC3020_HEATER_DISABLE 0x66 27 #define HDC3020_HEATER_CONFIG 0x6E 28 29 #define HDC3020_READ_RETRY_TIMES 10 30 #define HDC3020_BUSY_DELAY_MS 10 31 32 #define HDC3020_CRC8_POLYNOMIAL 0x31 33 34 static const u8 HDC3020_S_AUTO_10HZ_MOD0[2] = { 0x27, 0x37 }; 35 36 static const u8 HDC3020_EXIT_AUTO[2] = { 0x30, 0x93 }; 37 38 static const u8 HDC3020_R_T_RH_AUTO[2] = { 0xE0, 0x00 }; 39 static const u8 HDC3020_R_T_LOW_AUTO[2] = { 0xE0, 0x02 }; 40 static const u8 HDC3020_R_T_HIGH_AUTO[2] = { 0xE0, 0x03 }; 41 static const u8 HDC3020_R_RH_LOW_AUTO[2] = { 0xE0, 0x04 }; 42 static const u8 HDC3020_R_RH_HIGH_AUTO[2] = { 0xE0, 0x05 }; 43 44 struct hdc3020_data { 45 struct i2c_client *client; 46 /* 47 * Ensure that the sensor configuration (currently only heater is 48 * supported) will not be changed during the process of reading 49 * sensor data (this driver will try HDC3020_READ_RETRY_TIMES times 50 * if the device does not respond). 51 */ 52 struct mutex lock; 53 }; 54 55 static const int hdc3020_heater_vals[] = {0, 1, 0x3FFF}; 56 57 static const struct iio_chan_spec hdc3020_channels[] = { 58 { 59 .type = IIO_TEMP, 60 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 61 BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_PEAK) | 62 BIT(IIO_CHAN_INFO_TROUGH) | BIT(IIO_CHAN_INFO_OFFSET), 63 }, 64 { 65 .type = IIO_HUMIDITYRELATIVE, 66 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 67 BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_PEAK) | 68 BIT(IIO_CHAN_INFO_TROUGH), 69 }, 70 { 71 /* 72 * For setting the internal heater, which can be switched on to 73 * prevent or remove any condensation that may develop when the 74 * ambient environment approaches its dew point temperature. 75 */ 76 .type = IIO_CURRENT, 77 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 78 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW), 79 .output = 1, 80 }, 81 }; 82 83 DECLARE_CRC8_TABLE(hdc3020_crc8_table); 84 85 static int hdc3020_write_bytes(struct hdc3020_data *data, const u8 *buf, u8 len) 86 { 87 struct i2c_client *client = data->client; 88 struct i2c_msg msg; 89 int ret, cnt; 90 91 msg.addr = client->addr; 92 msg.flags = 0; 93 msg.buf = (char *)buf; 94 msg.len = len; 95 96 /* 97 * During the measurement process, HDC3020 will not return data. 98 * So wait for a while and try again 99 */ 100 for (cnt = 0; cnt < HDC3020_READ_RETRY_TIMES; cnt++) { 101 ret = i2c_transfer(client->adapter, &msg, 1); 102 if (ret == 1) 103 return 0; 104 105 mdelay(HDC3020_BUSY_DELAY_MS); 106 } 107 dev_err(&client->dev, "Could not write sensor command\n"); 108 109 return -ETIMEDOUT; 110 } 111 112 static int hdc3020_read_bytes(struct hdc3020_data *data, const u8 *buf, 113 void *val, int len) 114 { 115 int ret, cnt; 116 struct i2c_client *client = data->client; 117 struct i2c_msg msg[2] = { 118 [0] = { 119 .addr = client->addr, 120 .flags = 0, 121 .buf = (char *)buf, 122 .len = 2, 123 }, 124 [1] = { 125 .addr = client->addr, 126 .flags = I2C_M_RD, 127 .buf = val, 128 .len = len, 129 }, 130 }; 131 132 /* 133 * During the measurement process, HDC3020 will not return data. 134 * So wait for a while and try again 135 */ 136 for (cnt = 0; cnt < HDC3020_READ_RETRY_TIMES; cnt++) { 137 ret = i2c_transfer(client->adapter, msg, 2); 138 if (ret == 2) 139 return 0; 140 141 mdelay(HDC3020_BUSY_DELAY_MS); 142 } 143 dev_err(&client->dev, "Could not read sensor data\n"); 144 145 return -ETIMEDOUT; 146 } 147 148 static int hdc3020_read_measurement(struct hdc3020_data *data, 149 enum iio_chan_type type, int *val) 150 { 151 u8 crc, buf[6]; 152 int ret; 153 154 ret = hdc3020_read_bytes(data, HDC3020_R_T_RH_AUTO, buf, 6); 155 if (ret < 0) 156 return ret; 157 158 /* CRC check of the temperature measurement */ 159 crc = crc8(hdc3020_crc8_table, buf, 2, CRC8_INIT_VALUE); 160 if (crc != buf[2]) 161 return -EINVAL; 162 163 /* CRC check of the relative humidity measurement */ 164 crc = crc8(hdc3020_crc8_table, buf + 3, 2, CRC8_INIT_VALUE); 165 if (crc != buf[5]) 166 return -EINVAL; 167 168 if (type == IIO_TEMP) 169 *val = get_unaligned_be16(buf); 170 else if (type == IIO_HUMIDITYRELATIVE) 171 *val = get_unaligned_be16(&buf[3]); 172 else 173 return -EINVAL; 174 175 return 0; 176 } 177 178 /* 179 * After exiting the automatic measurement mode or resetting, the peak 180 * value will be reset to the default value 181 * This method is used to get the highest temp measured during automatic 182 * measurement 183 */ 184 static int hdc3020_read_high_peak_t(struct hdc3020_data *data, int *val) 185 { 186 u8 crc, buf[3]; 187 int ret; 188 189 ret = hdc3020_read_bytes(data, HDC3020_R_T_HIGH_AUTO, buf, 3); 190 if (ret < 0) 191 return ret; 192 193 crc = crc8(hdc3020_crc8_table, buf, 2, CRC8_INIT_VALUE); 194 if (crc != buf[2]) 195 return -EINVAL; 196 197 *val = get_unaligned_be16(buf); 198 199 return 0; 200 } 201 202 /* 203 * This method is used to get the lowest temp measured during automatic 204 * measurement 205 */ 206 static int hdc3020_read_low_peak_t(struct hdc3020_data *data, int *val) 207 { 208 u8 crc, buf[3]; 209 int ret; 210 211 ret = hdc3020_read_bytes(data, HDC3020_R_T_LOW_AUTO, buf, 3); 212 if (ret < 0) 213 return ret; 214 215 crc = crc8(hdc3020_crc8_table, buf, 2, CRC8_INIT_VALUE); 216 if (crc != buf[2]) 217 return -EINVAL; 218 219 *val = get_unaligned_be16(buf); 220 221 return 0; 222 } 223 224 /* 225 * This method is used to get the highest humidity measured during automatic 226 * measurement 227 */ 228 static int hdc3020_read_high_peak_rh(struct hdc3020_data *data, int *val) 229 { 230 u8 crc, buf[3]; 231 int ret; 232 233 ret = hdc3020_read_bytes(data, HDC3020_R_RH_HIGH_AUTO, buf, 3); 234 if (ret < 0) 235 return ret; 236 237 crc = crc8(hdc3020_crc8_table, buf, 2, CRC8_INIT_VALUE); 238 if (crc != buf[2]) 239 return -EINVAL; 240 241 *val = get_unaligned_be16(buf); 242 243 return 0; 244 } 245 246 /* 247 * This method is used to get the lowest humidity measured during automatic 248 * measurement 249 */ 250 static int hdc3020_read_low_peak_rh(struct hdc3020_data *data, int *val) 251 { 252 u8 crc, buf[3]; 253 int ret; 254 255 ret = hdc3020_read_bytes(data, HDC3020_R_RH_LOW_AUTO, buf, 3); 256 if (ret < 0) 257 return ret; 258 259 crc = crc8(hdc3020_crc8_table, buf, 2, CRC8_INIT_VALUE); 260 if (crc != buf[2]) 261 return -EINVAL; 262 263 *val = get_unaligned_be16(buf); 264 265 return 0; 266 } 267 268 static int hdc3020_read_raw(struct iio_dev *indio_dev, 269 struct iio_chan_spec const *chan, int *val, 270 int *val2, long mask) 271 { 272 struct hdc3020_data *data = iio_priv(indio_dev); 273 int ret; 274 275 if (chan->type != IIO_TEMP && chan->type != IIO_HUMIDITYRELATIVE) 276 return -EINVAL; 277 278 switch (mask) { 279 case IIO_CHAN_INFO_RAW: { 280 guard(mutex)(&data->lock); 281 ret = hdc3020_read_measurement(data, chan->type, val); 282 if (ret < 0) 283 return ret; 284 285 return IIO_VAL_INT; 286 } 287 case IIO_CHAN_INFO_PEAK: { 288 guard(mutex)(&data->lock); 289 if (chan->type == IIO_TEMP) { 290 ret = hdc3020_read_high_peak_t(data, val); 291 if (ret < 0) 292 return ret; 293 } else { 294 ret = hdc3020_read_high_peak_rh(data, val); 295 if (ret < 0) 296 return ret; 297 } 298 return IIO_VAL_INT; 299 } 300 case IIO_CHAN_INFO_TROUGH: { 301 guard(mutex)(&data->lock); 302 if (chan->type == IIO_TEMP) { 303 ret = hdc3020_read_low_peak_t(data, val); 304 if (ret < 0) 305 return ret; 306 } else { 307 ret = hdc3020_read_low_peak_rh(data, val); 308 if (ret < 0) 309 return ret; 310 } 311 return IIO_VAL_INT; 312 } 313 case IIO_CHAN_INFO_SCALE: 314 *val2 = 65536; 315 if (chan->type == IIO_TEMP) 316 *val = 175; 317 else 318 *val = 100; 319 return IIO_VAL_FRACTIONAL; 320 321 case IIO_CHAN_INFO_OFFSET: 322 if (chan->type != IIO_TEMP) 323 return -EINVAL; 324 325 *val = -16852; 326 return IIO_VAL_INT; 327 328 default: 329 return -EINVAL; 330 } 331 } 332 333 static int hdc3020_read_available(struct iio_dev *indio_dev, 334 struct iio_chan_spec const *chan, 335 const int **vals, 336 int *type, int *length, long mask) 337 { 338 if (mask != IIO_CHAN_INFO_RAW || chan->type != IIO_CURRENT) 339 return -EINVAL; 340 341 *vals = hdc3020_heater_vals; 342 *type = IIO_VAL_INT; 343 344 return IIO_AVAIL_RANGE; 345 } 346 347 static int hdc3020_update_heater(struct hdc3020_data *data, int val) 348 { 349 u8 buf[5]; 350 int ret; 351 352 if (val < hdc3020_heater_vals[0] || val > hdc3020_heater_vals[2]) 353 return -EINVAL; 354 355 buf[0] = HDC3020_HEATER_CMD_MSB; 356 357 if (!val) { 358 buf[1] = HDC3020_HEATER_DISABLE; 359 return hdc3020_write_bytes(data, buf, 2); 360 } 361 362 buf[1] = HDC3020_HEATER_CONFIG; 363 put_unaligned_be16(val & GENMASK(13, 0), &buf[2]); 364 buf[4] = crc8(hdc3020_crc8_table, buf + 2, 2, CRC8_INIT_VALUE); 365 ret = hdc3020_write_bytes(data, buf, 5); 366 if (ret < 0) 367 return ret; 368 369 buf[1] = HDC3020_HEATER_ENABLE; 370 371 return hdc3020_write_bytes(data, buf, 2); 372 } 373 374 static int hdc3020_write_raw(struct iio_dev *indio_dev, 375 struct iio_chan_spec const *chan, 376 int val, int val2, long mask) 377 { 378 struct hdc3020_data *data = iio_priv(indio_dev); 379 380 switch (mask) { 381 case IIO_CHAN_INFO_RAW: 382 if (chan->type != IIO_CURRENT) 383 return -EINVAL; 384 385 guard(mutex)(&data->lock); 386 return hdc3020_update_heater(data, val); 387 } 388 389 return -EINVAL; 390 } 391 392 static const struct iio_info hdc3020_info = { 393 .read_raw = hdc3020_read_raw, 394 .write_raw = hdc3020_write_raw, 395 .read_avail = hdc3020_read_available, 396 }; 397 398 static void hdc3020_stop(void *data) 399 { 400 hdc3020_write_bytes((struct hdc3020_data *)data, HDC3020_EXIT_AUTO, 2); 401 } 402 403 static int hdc3020_probe(struct i2c_client *client) 404 { 405 struct iio_dev *indio_dev; 406 struct hdc3020_data *data; 407 int ret; 408 409 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 410 return -EOPNOTSUPP; 411 412 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 413 if (!indio_dev) 414 return -ENOMEM; 415 416 data = iio_priv(indio_dev); 417 data->client = client; 418 mutex_init(&data->lock); 419 420 crc8_populate_msb(hdc3020_crc8_table, HDC3020_CRC8_POLYNOMIAL); 421 422 indio_dev->name = "hdc3020"; 423 indio_dev->modes = INDIO_DIRECT_MODE; 424 indio_dev->info = &hdc3020_info; 425 indio_dev->channels = hdc3020_channels; 426 indio_dev->num_channels = ARRAY_SIZE(hdc3020_channels); 427 428 ret = hdc3020_write_bytes(data, HDC3020_S_AUTO_10HZ_MOD0, 2); 429 if (ret) 430 return dev_err_probe(&client->dev, ret, 431 "Unable to set up measurement\n"); 432 433 ret = devm_add_action_or_reset(&data->client->dev, hdc3020_stop, data); 434 if (ret) 435 return ret; 436 437 ret = devm_iio_device_register(&data->client->dev, indio_dev); 438 if (ret) 439 return dev_err_probe(&client->dev, ret, "Failed to add device"); 440 441 return 0; 442 } 443 444 static const struct i2c_device_id hdc3020_id[] = { 445 { "hdc3020" }, 446 { "hdc3021" }, 447 { "hdc3022" }, 448 { } 449 }; 450 MODULE_DEVICE_TABLE(i2c, hdc3020_id); 451 452 static const struct of_device_id hdc3020_dt_ids[] = { 453 { .compatible = "ti,hdc3020" }, 454 { .compatible = "ti,hdc3021" }, 455 { .compatible = "ti,hdc3022" }, 456 { } 457 }; 458 MODULE_DEVICE_TABLE(of, hdc3020_dt_ids); 459 460 static struct i2c_driver hdc3020_driver = { 461 .driver = { 462 .name = "hdc3020", 463 .of_match_table = hdc3020_dt_ids, 464 }, 465 .probe = hdc3020_probe, 466 .id_table = hdc3020_id, 467 }; 468 module_i2c_driver(hdc3020_driver); 469 470 MODULE_AUTHOR("Javier Carrasco <javier.carrasco.cruz@gmail.com>"); 471 MODULE_AUTHOR("Li peiyu <579lpy@gmail.com>"); 472 MODULE_DESCRIPTION("TI HDC3020 humidity and temperature sensor driver"); 473 MODULE_LICENSE("GPL"); 474