root/drivers/hwmon/adt7x10.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. adt7x10_read_byte
  2. adt7x10_write_byte
  3. adt7x10_read_word
  4. adt7x10_write_word
  5. adt7x10_irq_handler
  6. adt7x10_temp_ready
  7. adt7x10_update_temp
  8. adt7x10_fill_cache
  9. ADT7X10_TEMP_TO_REG
  10. ADT7X10_REG_TO_TEMP
  11. adt7x10_temp_show
  12. adt7x10_temp_store
  13. adt7x10_t_hyst_show
  14. adt7x10_t_hyst_store
  15. adt7x10_alarm_show
  16. name_show
  17. adt7x10_probe
  18. adt7x10_remove
  19. adt7x10_suspend
  20. adt7x10_resume

   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 int 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         return 0;
 461 }
 462 EXPORT_SYMBOL_GPL(adt7x10_remove);
 463 
 464 #ifdef CONFIG_PM_SLEEP
 465 
 466 static int adt7x10_suspend(struct device *dev)
 467 {
 468         struct adt7x10_data *data = dev_get_drvdata(dev);
 469 
 470         return adt7x10_write_byte(dev, ADT7X10_CONFIG,
 471                 data->config | ADT7X10_PD);
 472 }
 473 
 474 static int adt7x10_resume(struct device *dev)
 475 {
 476         struct adt7x10_data *data = dev_get_drvdata(dev);
 477 
 478         return adt7x10_write_byte(dev, ADT7X10_CONFIG, data->config);
 479 }
 480 
 481 SIMPLE_DEV_PM_OPS(adt7x10_dev_pm_ops, adt7x10_suspend, adt7x10_resume);
 482 EXPORT_SYMBOL_GPL(adt7x10_dev_pm_ops);
 483 
 484 #endif /* CONFIG_PM_SLEEP */
 485 
 486 MODULE_AUTHOR("Hartmut Knaack");
 487 MODULE_DESCRIPTION("ADT7410/ADT7420, ADT7310/ADT7320 common code");
 488 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */