linux/drivers/hwmon/tmp102.c
<<
>>
Prefs
   1/* Texas Instruments TMP102 SMBus temperature sensor driver
   2 *
   3 * Copyright (C) 2010 Steven King <sfking@fdwdc.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#include <linux/delay.h>
  17#include <linux/module.h>
  18#include <linux/init.h>
  19#include <linux/slab.h>
  20#include <linux/i2c.h>
  21#include <linux/hwmon.h>
  22#include <linux/hwmon-sysfs.h>
  23#include <linux/err.h>
  24#include <linux/mutex.h>
  25#include <linux/device.h>
  26#include <linux/jiffies.h>
  27#include <linux/regmap.h>
  28#include <linux/of.h>
  29
  30#define DRIVER_NAME "tmp102"
  31
  32#define TMP102_TEMP_REG                 0x00
  33#define TMP102_CONF_REG                 0x01
  34/* note: these bit definitions are byte swapped */
  35#define         TMP102_CONF_SD          0x0100
  36#define         TMP102_CONF_TM          0x0200
  37#define         TMP102_CONF_POL         0x0400
  38#define         TMP102_CONF_F0          0x0800
  39#define         TMP102_CONF_F1          0x1000
  40#define         TMP102_CONF_R0          0x2000
  41#define         TMP102_CONF_R1          0x4000
  42#define         TMP102_CONF_OS          0x8000
  43#define         TMP102_CONF_EM          0x0010
  44#define         TMP102_CONF_AL          0x0020
  45#define         TMP102_CONF_CR0         0x0040
  46#define         TMP102_CONF_CR1         0x0080
  47#define TMP102_TLOW_REG                 0x02
  48#define TMP102_THIGH_REG                0x03
  49
  50#define TMP102_CONFREG_MASK     (TMP102_CONF_SD | TMP102_CONF_TM | \
  51                                 TMP102_CONF_POL | TMP102_CONF_F0 | \
  52                                 TMP102_CONF_F1 | TMP102_CONF_OS | \
  53                                 TMP102_CONF_EM | TMP102_CONF_AL | \
  54                                 TMP102_CONF_CR0 | TMP102_CONF_CR1)
  55
  56#define TMP102_CONFIG_CLEAR     (TMP102_CONF_SD | TMP102_CONF_OS | \
  57                                 TMP102_CONF_CR0)
  58#define TMP102_CONFIG_SET       (TMP102_CONF_TM | TMP102_CONF_EM | \
  59                                 TMP102_CONF_CR1)
  60
  61#define CONVERSION_TIME_MS              35      /* in milli-seconds */
  62
  63struct tmp102 {
  64        struct regmap *regmap;
  65        u16 config_orig;
  66        unsigned long ready_time;
  67};
  68
  69/* convert left adjusted 13-bit TMP102 register value to milliCelsius */
  70static inline int tmp102_reg_to_mC(s16 val)
  71{
  72        return ((val & ~0x01) * 1000) / 128;
  73}
  74
  75/* convert milliCelsius to left adjusted 13-bit TMP102 register value */
  76static inline u16 tmp102_mC_to_reg(int val)
  77{
  78        return (val * 128) / 1000;
  79}
  80
  81static int tmp102_read(struct device *dev, enum hwmon_sensor_types type,
  82                       u32 attr, int channel, long *temp)
  83{
  84        struct tmp102 *tmp102 = dev_get_drvdata(dev);
  85        unsigned int regval;
  86        int err, reg;
  87
  88        switch (attr) {
  89        case hwmon_temp_input:
  90                /* Is it too early to return a conversion ? */
  91                if (time_before(jiffies, tmp102->ready_time)) {
  92                        dev_dbg(dev, "%s: Conversion not ready yet..\n", __func__);
  93                        return -EAGAIN;
  94                }
  95                reg = TMP102_TEMP_REG;
  96                break;
  97        case hwmon_temp_max_hyst:
  98                reg = TMP102_TLOW_REG;
  99                break;
 100        case hwmon_temp_max:
 101                reg = TMP102_THIGH_REG;
 102                break;
 103        default:
 104                return -EOPNOTSUPP;
 105        }
 106
 107        err = regmap_read(tmp102->regmap, reg, &regval);
 108        if (err < 0)
 109                return err;
 110        *temp = tmp102_reg_to_mC(regval);
 111
 112        return 0;
 113}
 114
 115static int tmp102_write(struct device *dev, enum hwmon_sensor_types type,
 116                        u32 attr, int channel, long temp)
 117{
 118        struct tmp102 *tmp102 = dev_get_drvdata(dev);
 119        int reg;
 120
 121        switch (attr) {
 122        case hwmon_temp_max_hyst:
 123                reg = TMP102_TLOW_REG;
 124                break;
 125        case hwmon_temp_max:
 126                reg = TMP102_THIGH_REG;
 127                break;
 128        default:
 129                return -EOPNOTSUPP;
 130        }
 131
 132        temp = clamp_val(temp, -256000, 255000);
 133        return regmap_write(tmp102->regmap, reg, tmp102_mC_to_reg(temp));
 134}
 135
 136static umode_t tmp102_is_visible(const void *data, enum hwmon_sensor_types type,
 137                                 u32 attr, int channel)
 138{
 139        if (type != hwmon_temp)
 140                return 0;
 141
 142        switch (attr) {
 143        case hwmon_temp_input:
 144                return S_IRUGO;
 145        case hwmon_temp_max_hyst:
 146        case hwmon_temp_max:
 147                return S_IRUGO | S_IWUSR;
 148        default:
 149                return 0;
 150        }
 151}
 152
 153static u32 tmp102_chip_config[] = {
 154        HWMON_C_REGISTER_TZ,
 155        0
 156};
 157
 158static const struct hwmon_channel_info tmp102_chip = {
 159        .type = hwmon_chip,
 160        .config = tmp102_chip_config,
 161};
 162
 163static u32 tmp102_temp_config[] = {
 164        HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST,
 165        0
 166};
 167
 168static const struct hwmon_channel_info tmp102_temp = {
 169        .type = hwmon_temp,
 170        .config = tmp102_temp_config,
 171};
 172
 173static const struct hwmon_channel_info *tmp102_info[] = {
 174        &tmp102_chip,
 175        &tmp102_temp,
 176        NULL
 177};
 178
 179static const struct hwmon_ops tmp102_hwmon_ops = {
 180        .is_visible = tmp102_is_visible,
 181        .read = tmp102_read,
 182        .write = tmp102_write,
 183};
 184
 185static const struct hwmon_chip_info tmp102_chip_info = {
 186        .ops = &tmp102_hwmon_ops,
 187        .info = tmp102_info,
 188};
 189
 190static void tmp102_restore_config(void *data)
 191{
 192        struct tmp102 *tmp102 = data;
 193
 194        regmap_write(tmp102->regmap, TMP102_CONF_REG, tmp102->config_orig);
 195}
 196
 197static bool tmp102_is_writeable_reg(struct device *dev, unsigned int reg)
 198{
 199        return reg != TMP102_TEMP_REG;
 200}
 201
 202static bool tmp102_is_volatile_reg(struct device *dev, unsigned int reg)
 203{
 204        return reg == TMP102_TEMP_REG;
 205}
 206
 207static const struct regmap_config tmp102_regmap_config = {
 208        .reg_bits = 8,
 209        .val_bits = 16,
 210        .max_register = TMP102_THIGH_REG,
 211        .writeable_reg = tmp102_is_writeable_reg,
 212        .volatile_reg = tmp102_is_volatile_reg,
 213        .val_format_endian = REGMAP_ENDIAN_BIG,
 214        .cache_type = REGCACHE_RBTREE,
 215        .use_single_rw = true,
 216};
 217
 218static int tmp102_probe(struct i2c_client *client,
 219                        const struct i2c_device_id *id)
 220{
 221        struct device *dev = &client->dev;
 222        struct device *hwmon_dev;
 223        struct tmp102 *tmp102;
 224        unsigned int regval;
 225        int err;
 226
 227        if (!i2c_check_functionality(client->adapter,
 228                                     I2C_FUNC_SMBUS_WORD_DATA)) {
 229                dev_err(dev,
 230                        "adapter doesn't support SMBus word transactions\n");
 231                return -ENODEV;
 232        }
 233
 234        tmp102 = devm_kzalloc(dev, sizeof(*tmp102), GFP_KERNEL);
 235        if (!tmp102)
 236                return -ENOMEM;
 237
 238        i2c_set_clientdata(client, tmp102);
 239
 240        tmp102->regmap = devm_regmap_init_i2c(client, &tmp102_regmap_config);
 241        if (IS_ERR(tmp102->regmap))
 242                return PTR_ERR(tmp102->regmap);
 243
 244        err = regmap_read(tmp102->regmap, TMP102_CONF_REG, &regval);
 245        if (err < 0) {
 246                dev_err(dev, "error reading config register\n");
 247                return err;
 248        }
 249
 250        if ((regval & ~TMP102_CONFREG_MASK) !=
 251            (TMP102_CONF_R0 | TMP102_CONF_R1)) {
 252                dev_err(dev, "unexpected config register value\n");
 253                return -ENODEV;
 254        }
 255
 256        tmp102->config_orig = regval;
 257
 258        err = devm_add_action_or_reset(dev, tmp102_restore_config, tmp102);
 259        if (err)
 260                return err;
 261
 262        regval &= ~TMP102_CONFIG_CLEAR;
 263        regval |= TMP102_CONFIG_SET;
 264
 265        err = regmap_write(tmp102->regmap, TMP102_CONF_REG, regval);
 266        if (err < 0) {
 267                dev_err(dev, "error writing config register\n");
 268                return err;
 269        }
 270
 271        tmp102->ready_time = jiffies;
 272        if (tmp102->config_orig & TMP102_CONF_SD) {
 273                /*
 274                 * Mark that we are not ready with data until the first
 275                 * conversion is complete
 276                 */
 277                tmp102->ready_time += msecs_to_jiffies(CONVERSION_TIME_MS);
 278        }
 279
 280        hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
 281                                                         tmp102,
 282                                                         &tmp102_chip_info,
 283                                                         NULL);
 284        if (IS_ERR(hwmon_dev)) {
 285                dev_dbg(dev, "unable to register hwmon device\n");
 286                return PTR_ERR(hwmon_dev);
 287        }
 288        dev_info(dev, "initialized\n");
 289
 290        return 0;
 291}
 292
 293#ifdef CONFIG_PM_SLEEP
 294static int tmp102_suspend(struct device *dev)
 295{
 296        struct i2c_client *client = to_i2c_client(dev);
 297        struct tmp102 *tmp102 = i2c_get_clientdata(client);
 298
 299        return regmap_update_bits(tmp102->regmap, TMP102_CONF_REG,
 300                                  TMP102_CONF_SD, TMP102_CONF_SD);
 301}
 302
 303static int tmp102_resume(struct device *dev)
 304{
 305        struct i2c_client *client = to_i2c_client(dev);
 306        struct tmp102 *tmp102 = i2c_get_clientdata(client);
 307        int err;
 308
 309        err = regmap_update_bits(tmp102->regmap, TMP102_CONF_REG,
 310                                 TMP102_CONF_SD, 0);
 311
 312        tmp102->ready_time = jiffies + msecs_to_jiffies(CONVERSION_TIME_MS);
 313
 314        return err;
 315}
 316#endif /* CONFIG_PM */
 317
 318static SIMPLE_DEV_PM_OPS(tmp102_dev_pm_ops, tmp102_suspend, tmp102_resume);
 319
 320static const struct i2c_device_id tmp102_id[] = {
 321        { "tmp102", 0 },
 322        { }
 323};
 324MODULE_DEVICE_TABLE(i2c, tmp102_id);
 325
 326static struct i2c_driver tmp102_driver = {
 327        .driver.name    = DRIVER_NAME,
 328        .driver.pm      = &tmp102_dev_pm_ops,
 329        .probe          = tmp102_probe,
 330        .id_table       = tmp102_id,
 331};
 332
 333module_i2c_driver(tmp102_driver);
 334
 335MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
 336MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver");
 337MODULE_LICENSE("GPL");
 338