Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Driver for MAX31730 3-Channel Remote Temperature Sensor
0004  *
0005  * Copyright (c) 2019 Guenter Roeck <linux@roeck-us.net>
0006  */
0007 
0008 #include <linux/bits.h>
0009 #include <linux/err.h>
0010 #include <linux/i2c.h>
0011 #include <linux/init.h>
0012 #include <linux/hwmon.h>
0013 #include <linux/module.h>
0014 #include <linux/of_device.h>
0015 #include <linux/of.h>
0016 #include <linux/slab.h>
0017 
0018 /* Addresses scanned */
0019 static const unsigned short normal_i2c[] = { 0x1c, 0x1d, 0x1e, 0x1f, 0x4c,
0020                          0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
0021 
0022 /* The MAX31730 registers */
0023 #define MAX31730_REG_TEMP       0x00
0024 #define MAX31730_REG_CONF       0x13
0025 #define  MAX31730_STOP          BIT(7)
0026 #define  MAX31730_EXTRANGE      BIT(1)
0027 #define MAX31730_REG_TEMP_OFFSET    0x16
0028 #define  MAX31730_TEMP_OFFSET_BASELINE  0x77
0029 #define MAX31730_REG_OFFSET_ENABLE  0x17
0030 #define MAX31730_REG_TEMP_MAX       0x20
0031 #define MAX31730_REG_TEMP_MIN       0x30
0032 #define MAX31730_REG_STATUS_HIGH    0x32
0033 #define MAX31730_REG_STATUS_LOW     0x33
0034 #define MAX31730_REG_CHANNEL_ENABLE 0x35
0035 #define MAX31730_REG_TEMP_FAULT     0x36
0036 
0037 #define MAX31730_REG_MFG_ID     0x50
0038 #define  MAX31730_MFG_ID        0x4d
0039 #define MAX31730_REG_MFG_REV        0x51
0040 #define  MAX31730_MFG_REV       0x01
0041 
0042 #define MAX31730_TEMP_MIN       (-128000)
0043 #define MAX31730_TEMP_MAX       127937
0044 
0045 /* Each client has this additional data */
0046 struct max31730_data {
0047     struct i2c_client   *client;
0048     u8          orig_conf;
0049     u8          current_conf;
0050     u8          offset_enable;
0051     u8          channel_enable;
0052 };
0053 
0054 /*-----------------------------------------------------------------------*/
0055 
0056 static inline long max31730_reg_to_mc(s16 temp)
0057 {
0058     return DIV_ROUND_CLOSEST((temp >> 4) * 1000, 16);
0059 }
0060 
0061 static int max31730_write_config(struct max31730_data *data, u8 set_mask,
0062                  u8 clr_mask)
0063 {
0064     u8 value;
0065 
0066     clr_mask |= MAX31730_EXTRANGE;
0067     value = data->current_conf & ~clr_mask;
0068     value |= set_mask;
0069 
0070     if (data->current_conf != value) {
0071         s32 err;
0072 
0073         err = i2c_smbus_write_byte_data(data->client, MAX31730_REG_CONF,
0074                         value);
0075         if (err)
0076             return err;
0077         data->current_conf = value;
0078     }
0079     return 0;
0080 }
0081 
0082 static int max31730_set_enable(struct i2c_client *client, int reg,
0083                    u8 *confdata, int channel, bool enable)
0084 {
0085     u8 regval = *confdata;
0086     int err;
0087 
0088     if (enable)
0089         regval |= BIT(channel);
0090     else
0091         regval &= ~BIT(channel);
0092 
0093     if (regval != *confdata) {
0094         err = i2c_smbus_write_byte_data(client, reg, regval);
0095         if (err)
0096             return err;
0097         *confdata = regval;
0098     }
0099     return 0;
0100 }
0101 
0102 static int max31730_set_offset_enable(struct max31730_data *data, int channel,
0103                       bool enable)
0104 {
0105     return max31730_set_enable(data->client, MAX31730_REG_OFFSET_ENABLE,
0106                    &data->offset_enable, channel, enable);
0107 }
0108 
0109 static int max31730_set_channel_enable(struct max31730_data *data, int channel,
0110                        bool enable)
0111 {
0112     return max31730_set_enable(data->client, MAX31730_REG_CHANNEL_ENABLE,
0113                    &data->channel_enable, channel, enable);
0114 }
0115 
0116 static int max31730_read(struct device *dev, enum hwmon_sensor_types type,
0117              u32 attr, int channel, long *val)
0118 {
0119     struct max31730_data *data = dev_get_drvdata(dev);
0120     int regval, reg, offset;
0121 
0122     if (type != hwmon_temp)
0123         return -EINVAL;
0124 
0125     switch (attr) {
0126     case hwmon_temp_input:
0127         if (!(data->channel_enable & BIT(channel)))
0128             return -ENODATA;
0129         reg = MAX31730_REG_TEMP + (channel * 2);
0130         break;
0131     case hwmon_temp_max:
0132         reg = MAX31730_REG_TEMP_MAX + (channel * 2);
0133         break;
0134     case hwmon_temp_min:
0135         reg = MAX31730_REG_TEMP_MIN;
0136         break;
0137     case hwmon_temp_enable:
0138         *val = !!(data->channel_enable & BIT(channel));
0139         return 0;
0140     case hwmon_temp_offset:
0141         if (!channel)
0142             return -EINVAL;
0143         if (!(data->offset_enable & BIT(channel))) {
0144             *val = 0;
0145             return 0;
0146         }
0147         offset = i2c_smbus_read_byte_data(data->client,
0148                           MAX31730_REG_TEMP_OFFSET);
0149         if (offset < 0)
0150             return offset;
0151         *val = (offset - MAX31730_TEMP_OFFSET_BASELINE) * 125;
0152         return 0;
0153     case hwmon_temp_fault:
0154         regval = i2c_smbus_read_byte_data(data->client,
0155                           MAX31730_REG_TEMP_FAULT);
0156         if (regval < 0)
0157             return regval;
0158         *val = !!(regval & BIT(channel));
0159         return 0;
0160     case hwmon_temp_min_alarm:
0161         regval = i2c_smbus_read_byte_data(data->client,
0162                           MAX31730_REG_STATUS_LOW);
0163         if (regval < 0)
0164             return regval;
0165         *val = !!(regval & BIT(channel));
0166         return 0;
0167     case hwmon_temp_max_alarm:
0168         regval = i2c_smbus_read_byte_data(data->client,
0169                           MAX31730_REG_STATUS_HIGH);
0170         if (regval < 0)
0171             return regval;
0172         *val = !!(regval & BIT(channel));
0173         return 0;
0174     default:
0175         return -EINVAL;
0176     }
0177     regval = i2c_smbus_read_word_swapped(data->client, reg);
0178     if (regval < 0)
0179         return regval;
0180 
0181     *val = max31730_reg_to_mc(regval);
0182 
0183     return 0;
0184 }
0185 
0186 static int max31730_write(struct device *dev, enum hwmon_sensor_types type,
0187               u32 attr, int channel, long val)
0188 {
0189     struct max31730_data *data = dev_get_drvdata(dev);
0190     int reg, err;
0191 
0192     if (type != hwmon_temp)
0193         return -EINVAL;
0194 
0195     switch (attr) {
0196     case hwmon_temp_max:
0197         reg = MAX31730_REG_TEMP_MAX + channel * 2;
0198         break;
0199     case hwmon_temp_min:
0200         reg = MAX31730_REG_TEMP_MIN;
0201         break;
0202     case hwmon_temp_enable:
0203         if (val != 0 && val != 1)
0204             return -EINVAL;
0205         return max31730_set_channel_enable(data, channel, val);
0206     case hwmon_temp_offset:
0207         val = clamp_val(val, -14875, 17000) + 14875;
0208         val = DIV_ROUND_CLOSEST(val, 125);
0209         err = max31730_set_offset_enable(data, channel,
0210                     val != MAX31730_TEMP_OFFSET_BASELINE);
0211         if (err)
0212             return err;
0213         return i2c_smbus_write_byte_data(data->client,
0214                          MAX31730_REG_TEMP_OFFSET, val);
0215     default:
0216         return -EINVAL;
0217     }
0218 
0219     val = clamp_val(val, MAX31730_TEMP_MIN, MAX31730_TEMP_MAX);
0220     val = DIV_ROUND_CLOSEST(val << 4, 1000) << 4;
0221 
0222     return i2c_smbus_write_word_swapped(data->client, reg, (u16)val);
0223 }
0224 
0225 static umode_t max31730_is_visible(const void *data,
0226                    enum hwmon_sensor_types type,
0227                    u32 attr, int channel)
0228 {
0229     switch (type) {
0230     case hwmon_temp:
0231         switch (attr) {
0232         case hwmon_temp_input:
0233         case hwmon_temp_min_alarm:
0234         case hwmon_temp_max_alarm:
0235         case hwmon_temp_fault:
0236             return 0444;
0237         case hwmon_temp_min:
0238             return channel ? 0444 : 0644;
0239         case hwmon_temp_offset:
0240         case hwmon_temp_enable:
0241         case hwmon_temp_max:
0242             return 0644;
0243         }
0244         break;
0245     default:
0246         break;
0247     }
0248     return 0;
0249 }
0250 
0251 static const struct hwmon_channel_info *max31730_info[] = {
0252     HWMON_CHANNEL_INFO(chip,
0253                HWMON_C_REGISTER_TZ),
0254     HWMON_CHANNEL_INFO(temp,
0255                HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
0256                HWMON_T_ENABLE |
0257                HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM,
0258                HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
0259                HWMON_T_OFFSET | HWMON_T_ENABLE |
0260                HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
0261                HWMON_T_FAULT,
0262                HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
0263                HWMON_T_OFFSET | HWMON_T_ENABLE |
0264                HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
0265                HWMON_T_FAULT,
0266                HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
0267                HWMON_T_OFFSET | HWMON_T_ENABLE |
0268                HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
0269                HWMON_T_FAULT
0270                ),
0271     NULL
0272 };
0273 
0274 static const struct hwmon_ops max31730_hwmon_ops = {
0275     .is_visible = max31730_is_visible,
0276     .read = max31730_read,
0277     .write = max31730_write,
0278 };
0279 
0280 static const struct hwmon_chip_info max31730_chip_info = {
0281     .ops = &max31730_hwmon_ops,
0282     .info = max31730_info,
0283 };
0284 
0285 static void max31730_remove(void *data)
0286 {
0287     struct max31730_data *max31730 = data;
0288     struct i2c_client *client = max31730->client;
0289 
0290     i2c_smbus_write_byte_data(client, MAX31730_REG_CONF,
0291                   max31730->orig_conf);
0292 }
0293 
0294 static int
0295 max31730_probe(struct i2c_client *client)
0296 {
0297     struct device *dev = &client->dev;
0298     struct device *hwmon_dev;
0299     struct max31730_data *data;
0300     int status, err;
0301 
0302     if (!i2c_check_functionality(client->adapter,
0303             I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
0304         return -EIO;
0305 
0306     data = devm_kzalloc(dev, sizeof(struct max31730_data), GFP_KERNEL);
0307     if (!data)
0308         return -ENOMEM;
0309 
0310     data->client = client;
0311 
0312     /* Cache original configuration and enable status */
0313     status = i2c_smbus_read_byte_data(client, MAX31730_REG_CHANNEL_ENABLE);
0314     if (status < 0)
0315         return status;
0316     data->channel_enable = status;
0317 
0318     status = i2c_smbus_read_byte_data(client, MAX31730_REG_OFFSET_ENABLE);
0319     if (status < 0)
0320         return status;
0321     data->offset_enable = status;
0322 
0323     status = i2c_smbus_read_byte_data(client, MAX31730_REG_CONF);
0324     if (status < 0)
0325         return status;
0326     data->orig_conf = status;
0327     data->current_conf = status;
0328 
0329     err = max31730_write_config(data,
0330                     data->channel_enable ? 0 : MAX31730_STOP,
0331                     data->channel_enable ? MAX31730_STOP : 0);
0332     if (err)
0333         return err;
0334 
0335     dev_set_drvdata(dev, data);
0336 
0337     err = devm_add_action_or_reset(dev, max31730_remove, data);
0338     if (err)
0339         return err;
0340 
0341     hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
0342                              data,
0343                              &max31730_chip_info,
0344                              NULL);
0345     return PTR_ERR_OR_ZERO(hwmon_dev);
0346 }
0347 
0348 static const struct i2c_device_id max31730_ids[] = {
0349     { "max31730", 0, },
0350     { }
0351 };
0352 MODULE_DEVICE_TABLE(i2c, max31730_ids);
0353 
0354 static const struct of_device_id __maybe_unused max31730_of_match[] = {
0355     {
0356         .compatible = "maxim,max31730",
0357     },
0358     { },
0359 };
0360 MODULE_DEVICE_TABLE(of, max31730_of_match);
0361 
0362 static bool max31730_check_reg_temp(struct i2c_client *client,
0363                     int reg)
0364 {
0365     int regval;
0366 
0367     regval = i2c_smbus_read_byte_data(client, reg + 1);
0368     return regval < 0 || (regval & 0x0f);
0369 }
0370 
0371 /* Return 0 if detection is successful, -ENODEV otherwise */
0372 static int max31730_detect(struct i2c_client *client,
0373                struct i2c_board_info *info)
0374 {
0375     struct i2c_adapter *adapter = client->adapter;
0376     int regval;
0377     int i;
0378 
0379     if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
0380                      I2C_FUNC_SMBUS_WORD_DATA))
0381         return -ENODEV;
0382 
0383     regval = i2c_smbus_read_byte_data(client, MAX31730_REG_MFG_ID);
0384     if (regval != MAX31730_MFG_ID)
0385         return -ENODEV;
0386     regval = i2c_smbus_read_byte_data(client, MAX31730_REG_MFG_REV);
0387     if (regval != MAX31730_MFG_REV)
0388         return -ENODEV;
0389 
0390     /* lower 4 bit of temperature and limit registers must be 0 */
0391     if (max31730_check_reg_temp(client, MAX31730_REG_TEMP_MIN))
0392         return -ENODEV;
0393 
0394     for (i = 0; i < 4; i++) {
0395         if (max31730_check_reg_temp(client, MAX31730_REG_TEMP + i * 2))
0396             return -ENODEV;
0397         if (max31730_check_reg_temp(client,
0398                         MAX31730_REG_TEMP_MAX + i * 2))
0399             return -ENODEV;
0400     }
0401 
0402     strlcpy(info->type, "max31730", I2C_NAME_SIZE);
0403 
0404     return 0;
0405 }
0406 
0407 static int __maybe_unused max31730_suspend(struct device *dev)
0408 {
0409     struct max31730_data *data = dev_get_drvdata(dev);
0410 
0411     return max31730_write_config(data, MAX31730_STOP, 0);
0412 }
0413 
0414 static int __maybe_unused max31730_resume(struct device *dev)
0415 {
0416     struct max31730_data *data = dev_get_drvdata(dev);
0417 
0418     return max31730_write_config(data, 0, MAX31730_STOP);
0419 }
0420 
0421 static SIMPLE_DEV_PM_OPS(max31730_pm_ops, max31730_suspend, max31730_resume);
0422 
0423 static struct i2c_driver max31730_driver = {
0424     .class      = I2C_CLASS_HWMON,
0425     .driver = {
0426         .name   = "max31730",
0427         .of_match_table = of_match_ptr(max31730_of_match),
0428         .pm = &max31730_pm_ops,
0429     },
0430     .probe_new  = max31730_probe,
0431     .id_table   = max31730_ids,
0432     .detect     = max31730_detect,
0433     .address_list   = normal_i2c,
0434 };
0435 
0436 module_i2c_driver(max31730_driver);
0437 
0438 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
0439 MODULE_DESCRIPTION("MAX31730 driver");
0440 MODULE_LICENSE("GPL");