1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * adt7x10.c - Part of lm_sensors, Linux kernel modules for hardware 4 * monitoring 5 * This driver handles the ADT7410 and compatible digital temperature sensors. 6 * Hartmut Knaack <knaack.h@gmx.de> 2012-07-22 7 * based on lm75.c by Frodo Looijaard <frodol@dds.nl> 8 * and adt7410.c from iio-staging by Sonic Zhang <sonic.zhang@analog.com> 9 */ 10 11 #include <linux/module.h> 12 #include <linux/init.h> 13 #include <linux/slab.h> 14 #include <linux/jiffies.h> 15 #include <linux/hwmon.h> 16 #include <linux/hwmon-sysfs.h> 17 #include <linux/err.h> 18 #include <linux/mutex.h> 19 #include <linux/delay.h> 20 #include <linux/interrupt.h> 21 22 #include "adt7x10.h" 23 24 /* 25 * ADT7X10 status 26 */ 27 #define ADT7X10_STAT_T_LOW (1 << 4) 28 #define ADT7X10_STAT_T_HIGH (1 << 5) 29 #define ADT7X10_STAT_T_CRIT (1 << 6) 30 #define ADT7X10_STAT_NOT_RDY (1 << 7) 31 32 /* 33 * ADT7X10 config 34 */ 35 #define ADT7X10_FAULT_QUEUE_MASK (1 << 0 | 1 << 1) 36 #define ADT7X10_CT_POLARITY (1 << 2) 37 #define ADT7X10_INT_POLARITY (1 << 3) 38 #define ADT7X10_EVENT_MODE (1 << 4) 39 #define ADT7X10_MODE_MASK (1 << 5 | 1 << 6) 40 #define ADT7X10_FULL (0 << 5 | 0 << 6) 41 #define ADT7X10_PD (1 << 5 | 1 << 6) 42 #define ADT7X10_RESOLUTION (1 << 7) 43 44 /* 45 * ADT7X10 masks 46 */ 47 #define ADT7X10_T13_VALUE_MASK 0xFFF8 48 #define ADT7X10_T_HYST_MASK 0xF 49 50 /* straight from the datasheet */ 51 #define ADT7X10_TEMP_MIN (-55000) 52 #define ADT7X10_TEMP_MAX 150000 53 54 /* Each client has this additional data */ 55 struct adt7x10_data { 56 const struct adt7x10_ops *ops; 57 const char *name; 58 struct device *hwmon_dev; 59 struct mutex update_lock; 60 u8 config; 61 u8 oldconfig; 62 bool valid; /* true if registers valid */ 63 unsigned long last_updated; /* In jiffies */ 64 s16 temp[4]; /* Register values, 65 0 = input 66 1 = high 67 2 = low 68 3 = critical */ 69 u8 hyst; /* hysteresis offset */ 70 }; 71 72 static int adt7x10_read_byte(struct device *dev, u8 reg) 73 { 74 struct adt7x10_data *d = dev_get_drvdata(dev); 75 return d->ops->read_byte(dev, reg); 76 } 77 78 static int adt7x10_write_byte(struct device *dev, u8 reg, u8 data) 79 { 80 struct adt7x10_data *d = dev_get_drvdata(dev); 81 return d->ops->write_byte(dev, reg, data); 82 } 83 84 static int adt7x10_read_word(struct device *dev, u8 reg) 85 { 86 struct adt7x10_data *d = dev_get_drvdata(dev); 87 return d->ops->read_word(dev, reg); 88 } 89 90 static int adt7x10_write_word(struct device *dev, u8 reg, u16 data) 91 { 92 struct adt7x10_data *d = dev_get_drvdata(dev); 93 return d->ops->write_word(dev, reg, data); 94 } 95 96 static const u8 ADT7X10_REG_TEMP[4] = { 97 ADT7X10_TEMPERATURE, /* input */ 98 ADT7X10_T_ALARM_HIGH, /* high */ 99 ADT7X10_T_ALARM_LOW, /* low */ 100 ADT7X10_T_CRIT, /* critical */ 101 }; 102 103 static irqreturn_t adt7x10_irq_handler(int irq, void *private) 104 { 105 struct device *dev = private; 106 int status; 107 108 status = adt7x10_read_byte(dev, ADT7X10_STATUS); 109 if (status < 0) 110 return IRQ_HANDLED; 111 112 if (status & ADT7X10_STAT_T_HIGH) 113 sysfs_notify(&dev->kobj, NULL, "temp1_max_alarm"); 114 if (status & ADT7X10_STAT_T_LOW) 115 sysfs_notify(&dev->kobj, NULL, "temp1_min_alarm"); 116 if (status & ADT7X10_STAT_T_CRIT) 117 sysfs_notify(&dev->kobj, NULL, "temp1_crit_alarm"); 118 119 return IRQ_HANDLED; 120 } 121 122 static int adt7x10_temp_ready(struct device *dev) 123 { 124 int i, status; 125 126 for (i = 0; i < 6; i++) { 127 status = adt7x10_read_byte(dev, ADT7X10_STATUS); 128 if (status < 0) 129 return status; 130 if (!(status & ADT7X10_STAT_NOT_RDY)) 131 return 0; 132 msleep(60); 133 } 134 return -ETIMEDOUT; 135 } 136 137 static int adt7x10_update_temp(struct device *dev) 138 { 139 struct adt7x10_data *data = dev_get_drvdata(dev); 140 int ret = 0; 141 142 mutex_lock(&data->update_lock); 143 144 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 145 || !data->valid) { 146 int temp; 147 148 dev_dbg(dev, "Starting update\n"); 149 150 ret = adt7x10_temp_ready(dev); /* check for new value */ 151 if (ret) 152 goto abort; 153 154 temp = adt7x10_read_word(dev, ADT7X10_REG_TEMP[0]); 155 if (temp < 0) { 156 ret = temp; 157 dev_dbg(dev, "Failed to read value: reg %d, error %d\n", 158 ADT7X10_REG_TEMP[0], ret); 159 goto abort; 160 } 161 data->temp[0] = temp; 162 data->last_updated = jiffies; 163 data->valid = true; 164 } 165 166 abort: 167 mutex_unlock(&data->update_lock); 168 return ret; 169 } 170 171 static int adt7x10_fill_cache(struct device *dev) 172 { 173 struct adt7x10_data *data = dev_get_drvdata(dev); 174 int ret; 175 int i; 176 177 for (i = 1; i < ARRAY_SIZE(data->temp); i++) { 178 ret = adt7x10_read_word(dev, ADT7X10_REG_TEMP[i]); 179 if (ret < 0) { 180 dev_dbg(dev, "Failed to read value: reg %d, error %d\n", 181 ADT7X10_REG_TEMP[i], ret); 182 return ret; 183 } 184 data->temp[i] = ret; 185 } 186 187 ret = adt7x10_read_byte(dev, ADT7X10_T_HYST); 188 if (ret < 0) { 189 dev_dbg(dev, "Failed to read value: reg %d, error %d\n", 190 ADT7X10_T_HYST, ret); 191 return ret; 192 } 193 data->hyst = ret; 194 195 return 0; 196 } 197 198 static s16 ADT7X10_TEMP_TO_REG(long temp) 199 { 200 return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7X10_TEMP_MIN, 201 ADT7X10_TEMP_MAX) * 128, 1000); 202 } 203 204 static int ADT7X10_REG_TO_TEMP(struct adt7x10_data *data, s16 reg) 205 { 206 /* in 13 bit mode, bits 0-2 are status flags - mask them out */ 207 if (!(data->config & ADT7X10_RESOLUTION)) 208 reg &= ADT7X10_T13_VALUE_MASK; 209 /* 210 * temperature is stored in twos complement format, in steps of 211 * 1/128°C 212 */ 213 return DIV_ROUND_CLOSEST(reg * 1000, 128); 214 } 215 216 /*-----------------------------------------------------------------------*/ 217 218 /* sysfs attributes for hwmon */ 219 220 static ssize_t adt7x10_temp_show(struct device *dev, 221 struct device_attribute *da, char *buf) 222 { 223 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 224 struct adt7x10_data *data = dev_get_drvdata(dev); 225 226 227 if (attr->index == 0) { 228 int ret; 229 230 ret = adt7x10_update_temp(dev); 231 if (ret) 232 return ret; 233 } 234 235 return sprintf(buf, "%d\n", ADT7X10_REG_TO_TEMP(data, 236 data->temp[attr->index])); 237 } 238 239 static ssize_t adt7x10_temp_store(struct device *dev, 240 struct device_attribute *da, 241 const char *buf, size_t count) 242 { 243 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 244 struct adt7x10_data *data = dev_get_drvdata(dev); 245 int nr = attr->index; 246 long temp; 247 int ret; 248 249 ret = kstrtol(buf, 10, &temp); 250 if (ret) 251 return ret; 252 253 mutex_lock(&data->update_lock); 254 data->temp[nr] = ADT7X10_TEMP_TO_REG(temp); 255 ret = adt7x10_write_word(dev, ADT7X10_REG_TEMP[nr], data->temp[nr]); 256 if (ret) 257 count = ret; 258 mutex_unlock(&data->update_lock); 259 return count; 260 } 261 262 static ssize_t adt7x10_t_hyst_show(struct device *dev, 263 struct device_attribute *da, char *buf) 264 { 265 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 266 struct adt7x10_data *data = dev_get_drvdata(dev); 267 int nr = attr->index; 268 int hyst; 269 270 hyst = (data->hyst & ADT7X10_T_HYST_MASK) * 1000; 271 272 /* 273 * hysteresis is stored as a 4 bit offset in the device, convert it 274 * to an absolute value 275 */ 276 if (nr == 2) /* min has positive offset, others have negative */ 277 hyst = -hyst; 278 return sprintf(buf, "%d\n", 279 ADT7X10_REG_TO_TEMP(data, data->temp[nr]) - hyst); 280 } 281 282 static ssize_t adt7x10_t_hyst_store(struct device *dev, 283 struct device_attribute *da, 284 const char *buf, size_t count) 285 { 286 struct adt7x10_data *data = dev_get_drvdata(dev); 287 int limit, ret; 288 long hyst; 289 290 ret = kstrtol(buf, 10, &hyst); 291 if (ret) 292 return ret; 293 /* convert absolute hysteresis value to a 4 bit delta value */ 294 limit = ADT7X10_REG_TO_TEMP(data, data->temp[1]); 295 hyst = clamp_val(hyst, ADT7X10_TEMP_MIN, ADT7X10_TEMP_MAX); 296 data->hyst = clamp_val(DIV_ROUND_CLOSEST(limit - hyst, 1000), 297 0, ADT7X10_T_HYST_MASK); 298 ret = adt7x10_write_byte(dev, ADT7X10_T_HYST, data->hyst); 299 if (ret) 300 return ret; 301 302 return count; 303 } 304 305 static ssize_t adt7x10_alarm_show(struct device *dev, 306 struct device_attribute *da, char *buf) 307 { 308 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 309 int ret; 310 311 ret = adt7x10_read_byte(dev, ADT7X10_STATUS); 312 if (ret < 0) 313 return ret; 314 315 return sprintf(buf, "%d\n", !!(ret & attr->index)); 316 } 317 318 static ssize_t name_show(struct device *dev, struct device_attribute *da, 319 char *buf) 320 { 321 struct adt7x10_data *data = dev_get_drvdata(dev); 322 323 return sprintf(buf, "%s\n", data->name); 324 } 325 326 static SENSOR_DEVICE_ATTR_RO(temp1_input, adt7x10_temp, 0); 327 static SENSOR_DEVICE_ATTR_RW(temp1_max, adt7x10_temp, 1); 328 static SENSOR_DEVICE_ATTR_RW(temp1_min, adt7x10_temp, 2); 329 static SENSOR_DEVICE_ATTR_RW(temp1_crit, adt7x10_temp, 3); 330 static SENSOR_DEVICE_ATTR_RW(temp1_max_hyst, adt7x10_t_hyst, 1); 331 static SENSOR_DEVICE_ATTR_RO(temp1_min_hyst, adt7x10_t_hyst, 2); 332 static SENSOR_DEVICE_ATTR_RO(temp1_crit_hyst, adt7x10_t_hyst, 3); 333 static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, adt7x10_alarm, 334 ADT7X10_STAT_T_LOW); 335 static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, adt7x10_alarm, 336 ADT7X10_STAT_T_HIGH); 337 static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, adt7x10_alarm, 338 ADT7X10_STAT_T_CRIT); 339 static DEVICE_ATTR_RO(name); 340 341 static struct attribute *adt7x10_attributes[] = { 342 &sensor_dev_attr_temp1_input.dev_attr.attr, 343 &sensor_dev_attr_temp1_max.dev_attr.attr, 344 &sensor_dev_attr_temp1_min.dev_attr.attr, 345 &sensor_dev_attr_temp1_crit.dev_attr.attr, 346 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, 347 &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, 348 &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, 349 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, 350 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 351 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, 352 NULL 353 }; 354 355 static const struct attribute_group adt7x10_group = { 356 .attrs = adt7x10_attributes, 357 }; 358 359 int adt7x10_probe(struct device *dev, const char *name, int irq, 360 const struct adt7x10_ops *ops) 361 { 362 struct adt7x10_data *data; 363 int ret; 364 365 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 366 if (!data) 367 return -ENOMEM; 368 369 data->ops = ops; 370 data->name = name; 371 372 dev_set_drvdata(dev, data); 373 mutex_init(&data->update_lock); 374 375 /* configure as specified */ 376 ret = adt7x10_read_byte(dev, ADT7X10_CONFIG); 377 if (ret < 0) { 378 dev_dbg(dev, "Can't read config? %d\n", ret); 379 return ret; 380 } 381 data->oldconfig = ret; 382 383 /* 384 * Set to 16 bit resolution, continous conversion and comparator mode. 385 */ 386 data->config = data->oldconfig; 387 data->config &= ~(ADT7X10_MODE_MASK | ADT7X10_CT_POLARITY | 388 ADT7X10_INT_POLARITY); 389 data->config |= ADT7X10_FULL | ADT7X10_RESOLUTION | ADT7X10_EVENT_MODE; 390 391 if (data->config != data->oldconfig) { 392 ret = adt7x10_write_byte(dev, ADT7X10_CONFIG, data->config); 393 if (ret) 394 return ret; 395 } 396 dev_dbg(dev, "Config %02x\n", data->config); 397 398 ret = adt7x10_fill_cache(dev); 399 if (ret) 400 goto exit_restore; 401 402 /* Register sysfs hooks */ 403 ret = sysfs_create_group(&dev->kobj, &adt7x10_group); 404 if (ret) 405 goto exit_restore; 406 407 /* 408 * The I2C device will already have it's own 'name' attribute, but for 409 * the SPI device we need to register it. name will only be non NULL if 410 * the device doesn't register the 'name' attribute on its own. 411 */ 412 if (name) { 413 ret = device_create_file(dev, &dev_attr_name); 414 if (ret) 415 goto exit_remove; 416 } 417 418 data->hwmon_dev = hwmon_device_register(dev); 419 if (IS_ERR(data->hwmon_dev)) { 420 ret = PTR_ERR(data->hwmon_dev); 421 goto exit_remove_name; 422 } 423 424 if (irq > 0) { 425 ret = request_threaded_irq(irq, NULL, adt7x10_irq_handler, 426 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 427 dev_name(dev), dev); 428 if (ret) 429 goto exit_hwmon_device_unregister; 430 } 431 432 return 0; 433 434 exit_hwmon_device_unregister: 435 hwmon_device_unregister(data->hwmon_dev); 436 exit_remove_name: 437 if (name) 438 device_remove_file(dev, &dev_attr_name); 439 exit_remove: 440 sysfs_remove_group(&dev->kobj, &adt7x10_group); 441 exit_restore: 442 adt7x10_write_byte(dev, ADT7X10_CONFIG, data->oldconfig); 443 return ret; 444 } 445 EXPORT_SYMBOL_GPL(adt7x10_probe); 446 447 void adt7x10_remove(struct device *dev, int irq) 448 { 449 struct adt7x10_data *data = dev_get_drvdata(dev); 450 451 if (irq > 0) 452 free_irq(irq, dev); 453 454 hwmon_device_unregister(data->hwmon_dev); 455 if (data->name) 456 device_remove_file(dev, &dev_attr_name); 457 sysfs_remove_group(&dev->kobj, &adt7x10_group); 458 if (data->oldconfig != data->config) 459 adt7x10_write_byte(dev, ADT7X10_CONFIG, data->oldconfig); 460 } 461 EXPORT_SYMBOL_GPL(adt7x10_remove); 462 463 #ifdef CONFIG_PM_SLEEP 464 465 static int adt7x10_suspend(struct device *dev) 466 { 467 struct adt7x10_data *data = dev_get_drvdata(dev); 468 469 return adt7x10_write_byte(dev, ADT7X10_CONFIG, 470 data->config | ADT7X10_PD); 471 } 472 473 static int adt7x10_resume(struct device *dev) 474 { 475 struct adt7x10_data *data = dev_get_drvdata(dev); 476 477 return adt7x10_write_byte(dev, ADT7X10_CONFIG, data->config); 478 } 479 480 SIMPLE_DEV_PM_OPS(adt7x10_dev_pm_ops, adt7x10_suspend, adt7x10_resume); 481 EXPORT_SYMBOL_GPL(adt7x10_dev_pm_ops); 482 483 #endif /* CONFIG_PM_SLEEP */ 484 485 MODULE_AUTHOR("Hartmut Knaack"); 486 MODULE_DESCRIPTION("ADT7410/ADT7420, ADT7310/ADT7320 common code"); 487 MODULE_LICENSE("GPL"); 488