Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Texas Instruments TMP108 SMBus temperature sensor driver
0003  *
0004  * Copyright (C) 2016 John Muir <john@jmuir.com>
0005  */
0006 
0007 #include <linux/delay.h>
0008 #include <linux/device.h>
0009 #include <linux/err.h>
0010 #include <linux/hwmon.h>
0011 #include <linux/hwmon-sysfs.h>
0012 #include <linux/module.h>
0013 #include <linux/mutex.h>
0014 #include <linux/of.h>
0015 #include <linux/i2c.h>
0016 #include <linux/init.h>
0017 #include <linux/jiffies.h>
0018 #include <linux/regmap.h>
0019 #include <linux/slab.h>
0020 
0021 #define DRIVER_NAME "tmp108"
0022 
0023 #define TMP108_REG_TEMP     0x00
0024 #define TMP108_REG_CONF     0x01
0025 #define TMP108_REG_TLOW     0x02
0026 #define TMP108_REG_THIGH    0x03
0027 
0028 #define TMP108_TEMP_MIN_MC  -50000 /* Minimum millicelcius. */
0029 #define TMP108_TEMP_MAX_MC  127937 /* Maximum millicelcius. */
0030 
0031 /* Configuration register bits.
0032  * Note: these bit definitions are byte swapped.
0033  */
0034 #define TMP108_CONF_M0      0x0100 /* Sensor mode. */
0035 #define TMP108_CONF_M1      0x0200
0036 #define TMP108_CONF_TM      0x0400 /* Thermostat mode. */
0037 #define TMP108_CONF_FL      0x0800 /* Watchdog flag - TLOW */
0038 #define TMP108_CONF_FH      0x1000 /* Watchdog flag - THIGH */
0039 #define TMP108_CONF_CR0     0x2000 /* Conversion rate. */
0040 #define TMP108_CONF_CR1     0x4000
0041 #define TMP108_CONF_ID      0x8000
0042 #define TMP108_CONF_HYS0    0x0010 /* Hysteresis. */
0043 #define TMP108_CONF_HYS1    0x0020
0044 #define TMP108_CONF_POL     0x0080 /* Polarity of alert. */
0045 
0046 /* Defaults set by the hardware upon reset. */
0047 #define TMP108_CONF_DEFAULTS        (TMP108_CONF_CR0 | TMP108_CONF_TM |\
0048                      TMP108_CONF_HYS0 | TMP108_CONF_M1)
0049 /* These bits are read-only. */
0050 #define TMP108_CONF_READ_ONLY       (TMP108_CONF_FL | TMP108_CONF_FH |\
0051                      TMP108_CONF_ID)
0052 
0053 #define TMP108_CONF_MODE_MASK       (TMP108_CONF_M0|TMP108_CONF_M1)
0054 #define TMP108_MODE_SHUTDOWN        0x0000
0055 #define TMP108_MODE_ONE_SHOT        TMP108_CONF_M0
0056 #define TMP108_MODE_CONTINUOUS      TMP108_CONF_M1      /* Default */
0057                     /* When M1 is set, M0 is ignored. */
0058 
0059 #define TMP108_CONF_CONVRATE_MASK   (TMP108_CONF_CR0|TMP108_CONF_CR1)
0060 #define TMP108_CONVRATE_0P25HZ      0x0000
0061 #define TMP108_CONVRATE_1HZ     TMP108_CONF_CR0     /* Default */
0062 #define TMP108_CONVRATE_4HZ     TMP108_CONF_CR1
0063 #define TMP108_CONVRATE_16HZ        (TMP108_CONF_CR0|TMP108_CONF_CR1)
0064 
0065 #define TMP108_CONF_HYSTERESIS_MASK (TMP108_CONF_HYS0|TMP108_CONF_HYS1)
0066 #define TMP108_HYSTERESIS_0C        0x0000
0067 #define TMP108_HYSTERESIS_1C        TMP108_CONF_HYS0    /* Default */
0068 #define TMP108_HYSTERESIS_2C        TMP108_CONF_HYS1
0069 #define TMP108_HYSTERESIS_4C        (TMP108_CONF_HYS0|TMP108_CONF_HYS1)
0070 
0071 #define TMP108_CONVERSION_TIME_MS   30  /* in milli-seconds */
0072 
0073 struct tmp108 {
0074     struct regmap *regmap;
0075     u16 orig_config;
0076     unsigned long ready_time;
0077 };
0078 
0079 /* convert 12-bit TMP108 register value to milliCelsius */
0080 static inline int tmp108_temp_reg_to_mC(s16 val)
0081 {
0082     return (val & ~0x0f) * 1000 / 256;
0083 }
0084 
0085 /* convert milliCelsius to left adjusted 12-bit TMP108 register value */
0086 static inline u16 tmp108_mC_to_temp_reg(int val)
0087 {
0088     return (val * 256) / 1000;
0089 }
0090 
0091 static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,
0092                u32 attr, int channel, long *temp)
0093 {
0094     struct tmp108 *tmp108 = dev_get_drvdata(dev);
0095     unsigned int regval;
0096     int err, hyst;
0097 
0098     if (type == hwmon_chip) {
0099         if (attr == hwmon_chip_update_interval) {
0100             err = regmap_read(tmp108->regmap, TMP108_REG_CONF,
0101                       &regval);
0102             if (err < 0)
0103                 return err;
0104             switch (regval & TMP108_CONF_CONVRATE_MASK) {
0105             case TMP108_CONVRATE_0P25HZ:
0106             default:
0107                 *temp = 4000;
0108                 break;
0109             case TMP108_CONVRATE_1HZ:
0110                 *temp = 1000;
0111                 break;
0112             case TMP108_CONVRATE_4HZ:
0113                 *temp = 250;
0114                 break;
0115             case TMP108_CONVRATE_16HZ:
0116                 *temp = 63;
0117                 break;
0118             }
0119             return 0;
0120         }
0121         return -EOPNOTSUPP;
0122     }
0123 
0124     switch (attr) {
0125     case hwmon_temp_input:
0126         /* Is it too early to return a conversion ? */
0127         if (time_before(jiffies, tmp108->ready_time)) {
0128             dev_dbg(dev, "%s: Conversion not ready yet..\n",
0129                 __func__);
0130             return -EAGAIN;
0131         }
0132         err = regmap_read(tmp108->regmap, TMP108_REG_TEMP, &regval);
0133         if (err < 0)
0134             return err;
0135         *temp = tmp108_temp_reg_to_mC(regval);
0136         break;
0137     case hwmon_temp_min:
0138     case hwmon_temp_max:
0139         err = regmap_read(tmp108->regmap, attr == hwmon_temp_min ?
0140                   TMP108_REG_TLOW : TMP108_REG_THIGH, &regval);
0141         if (err < 0)
0142             return err;
0143         *temp = tmp108_temp_reg_to_mC(regval);
0144         break;
0145     case hwmon_temp_min_alarm:
0146     case hwmon_temp_max_alarm:
0147         err = regmap_read(tmp108->regmap, TMP108_REG_CONF, &regval);
0148         if (err < 0)
0149             return err;
0150         *temp = !!(regval & (attr == hwmon_temp_min_alarm ?
0151                      TMP108_CONF_FL : TMP108_CONF_FH));
0152         break;
0153     case hwmon_temp_min_hyst:
0154     case hwmon_temp_max_hyst:
0155         err = regmap_read(tmp108->regmap, TMP108_REG_CONF, &regval);
0156         if (err < 0)
0157             return err;
0158         switch (regval & TMP108_CONF_HYSTERESIS_MASK) {
0159         case TMP108_HYSTERESIS_0C:
0160         default:
0161             hyst = 0;
0162             break;
0163         case TMP108_HYSTERESIS_1C:
0164             hyst = 1000;
0165             break;
0166         case TMP108_HYSTERESIS_2C:
0167             hyst = 2000;
0168             break;
0169         case TMP108_HYSTERESIS_4C:
0170             hyst = 4000;
0171             break;
0172         }
0173         err = regmap_read(tmp108->regmap, attr == hwmon_temp_min_hyst ?
0174                   TMP108_REG_TLOW : TMP108_REG_THIGH, &regval);
0175         if (err < 0)
0176             return err;
0177         *temp = tmp108_temp_reg_to_mC(regval);
0178         if (attr == hwmon_temp_min_hyst)
0179             *temp += hyst;
0180         else
0181             *temp -= hyst;
0182         break;
0183     default:
0184         return -EOPNOTSUPP;
0185     }
0186 
0187     return 0;
0188 }
0189 
0190 static int tmp108_write(struct device *dev, enum hwmon_sensor_types type,
0191             u32 attr, int channel, long temp)
0192 {
0193     struct tmp108 *tmp108 = dev_get_drvdata(dev);
0194     u32 regval, mask;
0195     int err;
0196 
0197     if (type == hwmon_chip) {
0198         if (attr == hwmon_chip_update_interval) {
0199             if (temp < 156)
0200                 mask = TMP108_CONVRATE_16HZ;
0201             else if (temp < 625)
0202                 mask = TMP108_CONVRATE_4HZ;
0203             else if (temp < 2500)
0204                 mask = TMP108_CONVRATE_1HZ;
0205             else
0206                 mask = TMP108_CONVRATE_0P25HZ;
0207             return regmap_update_bits(tmp108->regmap,
0208                           TMP108_REG_CONF,
0209                           TMP108_CONF_CONVRATE_MASK,
0210                           mask);
0211         }
0212         return -EOPNOTSUPP;
0213     }
0214 
0215     switch (attr) {
0216     case hwmon_temp_min:
0217     case hwmon_temp_max:
0218         temp = clamp_val(temp, TMP108_TEMP_MIN_MC, TMP108_TEMP_MAX_MC);
0219         return regmap_write(tmp108->regmap,
0220                     attr == hwmon_temp_min ?
0221                     TMP108_REG_TLOW : TMP108_REG_THIGH,
0222                     tmp108_mC_to_temp_reg(temp));
0223     case hwmon_temp_min_hyst:
0224     case hwmon_temp_max_hyst:
0225         temp = clamp_val(temp, TMP108_TEMP_MIN_MC, TMP108_TEMP_MAX_MC);
0226         err = regmap_read(tmp108->regmap,
0227                   attr == hwmon_temp_min_hyst ?
0228                     TMP108_REG_TLOW : TMP108_REG_THIGH,
0229                   &regval);
0230         if (err < 0)
0231             return err;
0232         if (attr == hwmon_temp_min_hyst)
0233             temp -= tmp108_temp_reg_to_mC(regval);
0234         else
0235             temp = tmp108_temp_reg_to_mC(regval) - temp;
0236         if (temp < 500)
0237             mask = TMP108_HYSTERESIS_0C;
0238         else if (temp < 1500)
0239             mask = TMP108_HYSTERESIS_1C;
0240         else if (temp < 3000)
0241             mask = TMP108_HYSTERESIS_2C;
0242         else
0243             mask = TMP108_HYSTERESIS_4C;
0244         return regmap_update_bits(tmp108->regmap, TMP108_REG_CONF,
0245                       TMP108_CONF_HYSTERESIS_MASK, mask);
0246     default:
0247         return -EOPNOTSUPP;
0248     }
0249 }
0250 
0251 static umode_t tmp108_is_visible(const void *data, enum hwmon_sensor_types type,
0252                  u32 attr, int channel)
0253 {
0254     if (type == hwmon_chip && attr == hwmon_chip_update_interval)
0255         return 0644;
0256 
0257     if (type != hwmon_temp)
0258         return 0;
0259 
0260     switch (attr) {
0261     case hwmon_temp_input:
0262     case hwmon_temp_min_alarm:
0263     case hwmon_temp_max_alarm:
0264         return 0444;
0265     case hwmon_temp_min:
0266     case hwmon_temp_max:
0267     case hwmon_temp_min_hyst:
0268     case hwmon_temp_max_hyst:
0269         return 0644;
0270     default:
0271         return 0;
0272     }
0273 }
0274 
0275 static const struct hwmon_channel_info *tmp108_info[] = {
0276     HWMON_CHANNEL_INFO(chip,
0277                HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL),
0278     HWMON_CHANNEL_INFO(temp,
0279                HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN |
0280                HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
0281                HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM),
0282     NULL
0283 };
0284 
0285 static const struct hwmon_ops tmp108_hwmon_ops = {
0286     .is_visible = tmp108_is_visible,
0287     .read = tmp108_read,
0288     .write = tmp108_write,
0289 };
0290 
0291 static const struct hwmon_chip_info tmp108_chip_info = {
0292     .ops = &tmp108_hwmon_ops,
0293     .info = tmp108_info,
0294 };
0295 
0296 static void tmp108_restore_config(void *data)
0297 {
0298     struct tmp108 *tmp108 = data;
0299 
0300     regmap_write(tmp108->regmap, TMP108_REG_CONF, tmp108->orig_config);
0301 }
0302 
0303 static bool tmp108_is_writeable_reg(struct device *dev, unsigned int reg)
0304 {
0305     return reg != TMP108_REG_TEMP;
0306 }
0307 
0308 static bool tmp108_is_volatile_reg(struct device *dev, unsigned int reg)
0309 {
0310     /* Configuration register must be volatile to enable FL and FH. */
0311     return reg == TMP108_REG_TEMP || reg == TMP108_REG_CONF;
0312 }
0313 
0314 static const struct regmap_config tmp108_regmap_config = {
0315     .reg_bits = 8,
0316     .val_bits = 16,
0317     .max_register = TMP108_REG_THIGH,
0318     .writeable_reg = tmp108_is_writeable_reg,
0319     .volatile_reg = tmp108_is_volatile_reg,
0320     .val_format_endian = REGMAP_ENDIAN_BIG,
0321     .cache_type = REGCACHE_RBTREE,
0322     .use_single_read = true,
0323     .use_single_write = true,
0324 };
0325 
0326 static int tmp108_probe(struct i2c_client *client)
0327 {
0328     struct device *dev = &client->dev;
0329     struct device *hwmon_dev;
0330     struct tmp108 *tmp108;
0331     int err;
0332     u32 config;
0333 
0334     if (!i2c_check_functionality(client->adapter,
0335                      I2C_FUNC_SMBUS_WORD_DATA)) {
0336         dev_err(dev,
0337             "adapter doesn't support SMBus word transactions\n");
0338         return -ENODEV;
0339     }
0340 
0341     tmp108 = devm_kzalloc(dev, sizeof(*tmp108), GFP_KERNEL);
0342     if (!tmp108)
0343         return -ENOMEM;
0344 
0345     dev_set_drvdata(dev, tmp108);
0346 
0347     tmp108->regmap = devm_regmap_init_i2c(client, &tmp108_regmap_config);
0348     if (IS_ERR(tmp108->regmap)) {
0349         err = PTR_ERR(tmp108->regmap);
0350         dev_err(dev, "regmap init failed: %d", err);
0351         return err;
0352     }
0353 
0354     err = regmap_read(tmp108->regmap, TMP108_REG_CONF, &config);
0355     if (err < 0) {
0356         dev_err(dev, "error reading config register: %d", err);
0357         return err;
0358     }
0359     tmp108->orig_config = config;
0360 
0361     /* Only continuous mode is supported. */
0362     config &= ~TMP108_CONF_MODE_MASK;
0363     config |= TMP108_MODE_CONTINUOUS;
0364 
0365     /* Only comparator mode is supported. */
0366     config &= ~TMP108_CONF_TM;
0367 
0368     err = regmap_write(tmp108->regmap, TMP108_REG_CONF, config);
0369     if (err < 0) {
0370         dev_err(dev, "error writing config register: %d", err);
0371         return err;
0372     }
0373 
0374     tmp108->ready_time = jiffies;
0375     if ((tmp108->orig_config & TMP108_CONF_MODE_MASK) ==
0376         TMP108_MODE_SHUTDOWN)
0377         tmp108->ready_time +=
0378             msecs_to_jiffies(TMP108_CONVERSION_TIME_MS);
0379 
0380     err = devm_add_action_or_reset(dev, tmp108_restore_config, tmp108);
0381     if (err) {
0382         dev_err(dev, "add action or reset failed: %d", err);
0383         return err;
0384     }
0385 
0386     hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
0387                              tmp108,
0388                              &tmp108_chip_info,
0389                              NULL);
0390     return PTR_ERR_OR_ZERO(hwmon_dev);
0391 }
0392 
0393 static int __maybe_unused tmp108_suspend(struct device *dev)
0394 {
0395     struct tmp108 *tmp108 = dev_get_drvdata(dev);
0396 
0397     return regmap_update_bits(tmp108->regmap, TMP108_REG_CONF,
0398                   TMP108_CONF_MODE_MASK, TMP108_MODE_SHUTDOWN);
0399 }
0400 
0401 static int __maybe_unused tmp108_resume(struct device *dev)
0402 {
0403     struct tmp108 *tmp108 = dev_get_drvdata(dev);
0404     int err;
0405 
0406     err = regmap_update_bits(tmp108->regmap, TMP108_REG_CONF,
0407                  TMP108_CONF_MODE_MASK, TMP108_MODE_CONTINUOUS);
0408     tmp108->ready_time = jiffies +
0409                  msecs_to_jiffies(TMP108_CONVERSION_TIME_MS);
0410     return err;
0411 }
0412 
0413 static SIMPLE_DEV_PM_OPS(tmp108_dev_pm_ops, tmp108_suspend, tmp108_resume);
0414 
0415 static const struct i2c_device_id tmp108_i2c_ids[] = {
0416     { "tmp108", 0 },
0417     { }
0418 };
0419 MODULE_DEVICE_TABLE(i2c, tmp108_i2c_ids);
0420 
0421 #ifdef CONFIG_OF
0422 static const struct of_device_id tmp108_of_ids[] = {
0423     { .compatible = "ti,tmp108", },
0424     {}
0425 };
0426 MODULE_DEVICE_TABLE(of, tmp108_of_ids);
0427 #endif
0428 
0429 static struct i2c_driver tmp108_driver = {
0430     .driver = {
0431         .name   = DRIVER_NAME,
0432         .pm = &tmp108_dev_pm_ops,
0433         .of_match_table = of_match_ptr(tmp108_of_ids),
0434     },
0435     .probe_new  = tmp108_probe,
0436     .id_table   = tmp108_i2c_ids,
0437 };
0438 
0439 module_i2c_driver(tmp108_driver);
0440 
0441 MODULE_AUTHOR("John Muir <john@jmuir.com>");
0442 MODULE_DESCRIPTION("Texas Instruments TMP108 temperature sensor driver");
0443 MODULE_LICENSE("GPL");