max31730.c (11023B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Driver for MAX31730 3-Channel Remote Temperature Sensor 4 * 5 * Copyright (c) 2019 Guenter Roeck <linux@roeck-us.net> 6 */ 7 8#include <linux/bits.h> 9#include <linux/err.h> 10#include <linux/i2c.h> 11#include <linux/init.h> 12#include <linux/hwmon.h> 13#include <linux/module.h> 14#include <linux/of_device.h> 15#include <linux/of.h> 16#include <linux/slab.h> 17 18/* Addresses scanned */ 19static const unsigned short normal_i2c[] = { 0x1c, 0x1d, 0x1e, 0x1f, 0x4c, 20 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 21 22/* The MAX31730 registers */ 23#define MAX31730_REG_TEMP 0x00 24#define MAX31730_REG_CONF 0x13 25#define MAX31730_STOP BIT(7) 26#define MAX31730_EXTRANGE BIT(1) 27#define MAX31730_REG_TEMP_OFFSET 0x16 28#define MAX31730_TEMP_OFFSET_BASELINE 0x77 29#define MAX31730_REG_OFFSET_ENABLE 0x17 30#define MAX31730_REG_TEMP_MAX 0x20 31#define MAX31730_REG_TEMP_MIN 0x30 32#define MAX31730_REG_STATUS_HIGH 0x32 33#define MAX31730_REG_STATUS_LOW 0x33 34#define MAX31730_REG_CHANNEL_ENABLE 0x35 35#define MAX31730_REG_TEMP_FAULT 0x36 36 37#define MAX31730_REG_MFG_ID 0x50 38#define MAX31730_MFG_ID 0x4d 39#define MAX31730_REG_MFG_REV 0x51 40#define MAX31730_MFG_REV 0x01 41 42#define MAX31730_TEMP_MIN (-128000) 43#define MAX31730_TEMP_MAX 127937 44 45/* Each client has this additional data */ 46struct max31730_data { 47 struct i2c_client *client; 48 u8 orig_conf; 49 u8 current_conf; 50 u8 offset_enable; 51 u8 channel_enable; 52}; 53 54/*-----------------------------------------------------------------------*/ 55 56static inline long max31730_reg_to_mc(s16 temp) 57{ 58 return DIV_ROUND_CLOSEST((temp >> 4) * 1000, 16); 59} 60 61static int max31730_write_config(struct max31730_data *data, u8 set_mask, 62 u8 clr_mask) 63{ 64 u8 value; 65 66 clr_mask |= MAX31730_EXTRANGE; 67 value = data->current_conf & ~clr_mask; 68 value |= set_mask; 69 70 if (data->current_conf != value) { 71 s32 err; 72 73 err = i2c_smbus_write_byte_data(data->client, MAX31730_REG_CONF, 74 value); 75 if (err) 76 return err; 77 data->current_conf = value; 78 } 79 return 0; 80} 81 82static int max31730_set_enable(struct i2c_client *client, int reg, 83 u8 *confdata, int channel, bool enable) 84{ 85 u8 regval = *confdata; 86 int err; 87 88 if (enable) 89 regval |= BIT(channel); 90 else 91 regval &= ~BIT(channel); 92 93 if (regval != *confdata) { 94 err = i2c_smbus_write_byte_data(client, reg, regval); 95 if (err) 96 return err; 97 *confdata = regval; 98 } 99 return 0; 100} 101 102static int max31730_set_offset_enable(struct max31730_data *data, int channel, 103 bool enable) 104{ 105 return max31730_set_enable(data->client, MAX31730_REG_OFFSET_ENABLE, 106 &data->offset_enable, channel, enable); 107} 108 109static int max31730_set_channel_enable(struct max31730_data *data, int channel, 110 bool enable) 111{ 112 return max31730_set_enable(data->client, MAX31730_REG_CHANNEL_ENABLE, 113 &data->channel_enable, channel, enable); 114} 115 116static int max31730_read(struct device *dev, enum hwmon_sensor_types type, 117 u32 attr, int channel, long *val) 118{ 119 struct max31730_data *data = dev_get_drvdata(dev); 120 int regval, reg, offset; 121 122 if (type != hwmon_temp) 123 return -EINVAL; 124 125 switch (attr) { 126 case hwmon_temp_input: 127 if (!(data->channel_enable & BIT(channel))) 128 return -ENODATA; 129 reg = MAX31730_REG_TEMP + (channel * 2); 130 break; 131 case hwmon_temp_max: 132 reg = MAX31730_REG_TEMP_MAX + (channel * 2); 133 break; 134 case hwmon_temp_min: 135 reg = MAX31730_REG_TEMP_MIN; 136 break; 137 case hwmon_temp_enable: 138 *val = !!(data->channel_enable & BIT(channel)); 139 return 0; 140 case hwmon_temp_offset: 141 if (!channel) 142 return -EINVAL; 143 if (!(data->offset_enable & BIT(channel))) { 144 *val = 0; 145 return 0; 146 } 147 offset = i2c_smbus_read_byte_data(data->client, 148 MAX31730_REG_TEMP_OFFSET); 149 if (offset < 0) 150 return offset; 151 *val = (offset - MAX31730_TEMP_OFFSET_BASELINE) * 125; 152 return 0; 153 case hwmon_temp_fault: 154 regval = i2c_smbus_read_byte_data(data->client, 155 MAX31730_REG_TEMP_FAULT); 156 if (regval < 0) 157 return regval; 158 *val = !!(regval & BIT(channel)); 159 return 0; 160 case hwmon_temp_min_alarm: 161 regval = i2c_smbus_read_byte_data(data->client, 162 MAX31730_REG_STATUS_LOW); 163 if (regval < 0) 164 return regval; 165 *val = !!(regval & BIT(channel)); 166 return 0; 167 case hwmon_temp_max_alarm: 168 regval = i2c_smbus_read_byte_data(data->client, 169 MAX31730_REG_STATUS_HIGH); 170 if (regval < 0) 171 return regval; 172 *val = !!(regval & BIT(channel)); 173 return 0; 174 default: 175 return -EINVAL; 176 } 177 regval = i2c_smbus_read_word_swapped(data->client, reg); 178 if (regval < 0) 179 return regval; 180 181 *val = max31730_reg_to_mc(regval); 182 183 return 0; 184} 185 186static int max31730_write(struct device *dev, enum hwmon_sensor_types type, 187 u32 attr, int channel, long val) 188{ 189 struct max31730_data *data = dev_get_drvdata(dev); 190 int reg, err; 191 192 if (type != hwmon_temp) 193 return -EINVAL; 194 195 switch (attr) { 196 case hwmon_temp_max: 197 reg = MAX31730_REG_TEMP_MAX + channel * 2; 198 break; 199 case hwmon_temp_min: 200 reg = MAX31730_REG_TEMP_MIN; 201 break; 202 case hwmon_temp_enable: 203 if (val != 0 && val != 1) 204 return -EINVAL; 205 return max31730_set_channel_enable(data, channel, val); 206 case hwmon_temp_offset: 207 val = clamp_val(val, -14875, 17000) + 14875; 208 val = DIV_ROUND_CLOSEST(val, 125); 209 err = max31730_set_offset_enable(data, channel, 210 val != MAX31730_TEMP_OFFSET_BASELINE); 211 if (err) 212 return err; 213 return i2c_smbus_write_byte_data(data->client, 214 MAX31730_REG_TEMP_OFFSET, val); 215 default: 216 return -EINVAL; 217 } 218 219 val = clamp_val(val, MAX31730_TEMP_MIN, MAX31730_TEMP_MAX); 220 val = DIV_ROUND_CLOSEST(val << 4, 1000) << 4; 221 222 return i2c_smbus_write_word_swapped(data->client, reg, (u16)val); 223} 224 225static umode_t max31730_is_visible(const void *data, 226 enum hwmon_sensor_types type, 227 u32 attr, int channel) 228{ 229 switch (type) { 230 case hwmon_temp: 231 switch (attr) { 232 case hwmon_temp_input: 233 case hwmon_temp_min_alarm: 234 case hwmon_temp_max_alarm: 235 case hwmon_temp_fault: 236 return 0444; 237 case hwmon_temp_min: 238 return channel ? 0444 : 0644; 239 case hwmon_temp_offset: 240 case hwmon_temp_enable: 241 case hwmon_temp_max: 242 return 0644; 243 } 244 break; 245 default: 246 break; 247 } 248 return 0; 249} 250 251static const struct hwmon_channel_info *max31730_info[] = { 252 HWMON_CHANNEL_INFO(chip, 253 HWMON_C_REGISTER_TZ), 254 HWMON_CHANNEL_INFO(temp, 255 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 256 HWMON_T_ENABLE | 257 HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM, 258 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 259 HWMON_T_OFFSET | HWMON_T_ENABLE | 260 HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | 261 HWMON_T_FAULT, 262 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 263 HWMON_T_OFFSET | HWMON_T_ENABLE | 264 HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | 265 HWMON_T_FAULT, 266 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 267 HWMON_T_OFFSET | HWMON_T_ENABLE | 268 HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | 269 HWMON_T_FAULT 270 ), 271 NULL 272}; 273 274static const struct hwmon_ops max31730_hwmon_ops = { 275 .is_visible = max31730_is_visible, 276 .read = max31730_read, 277 .write = max31730_write, 278}; 279 280static const struct hwmon_chip_info max31730_chip_info = { 281 .ops = &max31730_hwmon_ops, 282 .info = max31730_info, 283}; 284 285static void max31730_remove(void *data) 286{ 287 struct max31730_data *max31730 = data; 288 struct i2c_client *client = max31730->client; 289 290 i2c_smbus_write_byte_data(client, MAX31730_REG_CONF, 291 max31730->orig_conf); 292} 293 294static int 295max31730_probe(struct i2c_client *client) 296{ 297 struct device *dev = &client->dev; 298 struct device *hwmon_dev; 299 struct max31730_data *data; 300 int status, err; 301 302 if (!i2c_check_functionality(client->adapter, 303 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) 304 return -EIO; 305 306 data = devm_kzalloc(dev, sizeof(struct max31730_data), GFP_KERNEL); 307 if (!data) 308 return -ENOMEM; 309 310 data->client = client; 311 312 /* Cache original configuration and enable status */ 313 status = i2c_smbus_read_byte_data(client, MAX31730_REG_CHANNEL_ENABLE); 314 if (status < 0) 315 return status; 316 data->channel_enable = status; 317 318 status = i2c_smbus_read_byte_data(client, MAX31730_REG_OFFSET_ENABLE); 319 if (status < 0) 320 return status; 321 data->offset_enable = status; 322 323 status = i2c_smbus_read_byte_data(client, MAX31730_REG_CONF); 324 if (status < 0) 325 return status; 326 data->orig_conf = status; 327 data->current_conf = status; 328 329 err = max31730_write_config(data, 330 data->channel_enable ? 0 : MAX31730_STOP, 331 data->channel_enable ? MAX31730_STOP : 0); 332 if (err) 333 return err; 334 335 dev_set_drvdata(dev, data); 336 337 err = devm_add_action_or_reset(dev, max31730_remove, data); 338 if (err) 339 return err; 340 341 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 342 data, 343 &max31730_chip_info, 344 NULL); 345 return PTR_ERR_OR_ZERO(hwmon_dev); 346} 347 348static const struct i2c_device_id max31730_ids[] = { 349 { "max31730", 0, }, 350 { } 351}; 352MODULE_DEVICE_TABLE(i2c, max31730_ids); 353 354static const struct of_device_id __maybe_unused max31730_of_match[] = { 355 { 356 .compatible = "maxim,max31730", 357 }, 358 { }, 359}; 360MODULE_DEVICE_TABLE(of, max31730_of_match); 361 362static bool max31730_check_reg_temp(struct i2c_client *client, 363 int reg) 364{ 365 int regval; 366 367 regval = i2c_smbus_read_byte_data(client, reg + 1); 368 return regval < 0 || (regval & 0x0f); 369} 370 371/* Return 0 if detection is successful, -ENODEV otherwise */ 372static int max31730_detect(struct i2c_client *client, 373 struct i2c_board_info *info) 374{ 375 struct i2c_adapter *adapter = client->adapter; 376 int regval; 377 int i; 378 379 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 380 I2C_FUNC_SMBUS_WORD_DATA)) 381 return -ENODEV; 382 383 regval = i2c_smbus_read_byte_data(client, MAX31730_REG_MFG_ID); 384 if (regval != MAX31730_MFG_ID) 385 return -ENODEV; 386 regval = i2c_smbus_read_byte_data(client, MAX31730_REG_MFG_REV); 387 if (regval != MAX31730_MFG_REV) 388 return -ENODEV; 389 390 /* lower 4 bit of temperature and limit registers must be 0 */ 391 if (max31730_check_reg_temp(client, MAX31730_REG_TEMP_MIN)) 392 return -ENODEV; 393 394 for (i = 0; i < 4; i++) { 395 if (max31730_check_reg_temp(client, MAX31730_REG_TEMP + i * 2)) 396 return -ENODEV; 397 if (max31730_check_reg_temp(client, 398 MAX31730_REG_TEMP_MAX + i * 2)) 399 return -ENODEV; 400 } 401 402 strlcpy(info->type, "max31730", I2C_NAME_SIZE); 403 404 return 0; 405} 406 407static int __maybe_unused max31730_suspend(struct device *dev) 408{ 409 struct max31730_data *data = dev_get_drvdata(dev); 410 411 return max31730_write_config(data, MAX31730_STOP, 0); 412} 413 414static int __maybe_unused max31730_resume(struct device *dev) 415{ 416 struct max31730_data *data = dev_get_drvdata(dev); 417 418 return max31730_write_config(data, 0, MAX31730_STOP); 419} 420 421static SIMPLE_DEV_PM_OPS(max31730_pm_ops, max31730_suspend, max31730_resume); 422 423static struct i2c_driver max31730_driver = { 424 .class = I2C_CLASS_HWMON, 425 .driver = { 426 .name = "max31730", 427 .of_match_table = of_match_ptr(max31730_of_match), 428 .pm = &max31730_pm_ops, 429 }, 430 .probe_new = max31730_probe, 431 .id_table = max31730_ids, 432 .detect = max31730_detect, 433 .address_list = normal_i2c, 434}; 435 436module_i2c_driver(max31730_driver); 437 438MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); 439MODULE_DESCRIPTION("MAX31730 driver"); 440MODULE_LICENSE("GPL");