1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * max31827.c - Support for Maxim Low-Power Switch 4 * 5 * Copyright (c) 2023 Daniel Matyas <daniel.matyas@analog.com> 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/bitops.h> 10 #include <linux/delay.h> 11 #include <linux/hwmon.h> 12 #include <linux/i2c.h> 13 #include <linux/mutex.h> 14 #include <linux/regmap.h> 15 16 #define MAX31827_T_REG 0x0 17 #define MAX31827_CONFIGURATION_REG 0x2 18 #define MAX31827_TH_REG 0x4 19 #define MAX31827_TL_REG 0x6 20 #define MAX31827_TH_HYST_REG 0x8 21 #define MAX31827_TL_HYST_REG 0xA 22 23 #define MAX31827_CONFIGURATION_1SHOT_MASK BIT(0) 24 #define MAX31827_CONFIGURATION_CNV_RATE_MASK GENMASK(3, 1) 25 #define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK BIT(14) 26 #define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK BIT(15) 27 28 #define MAX31827_12_BIT_CNV_TIME 140 29 30 #define MAX31827_16_BIT_TO_M_DGR(x) (sign_extend32(x, 15) * 1000 / 16) 31 #define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000) 32 #define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0) 33 34 enum max31827_cnv { 35 MAX31827_CNV_1_DIV_64_HZ = 1, 36 MAX31827_CNV_1_DIV_32_HZ, 37 MAX31827_CNV_1_DIV_16_HZ, 38 MAX31827_CNV_1_DIV_4_HZ, 39 MAX31827_CNV_1_HZ, 40 MAX31827_CNV_4_HZ, 41 MAX31827_CNV_8_HZ, 42 }; 43 44 static const u16 max31827_conversions[] = { 45 [MAX31827_CNV_1_DIV_64_HZ] = 64000, 46 [MAX31827_CNV_1_DIV_32_HZ] = 32000, 47 [MAX31827_CNV_1_DIV_16_HZ] = 16000, 48 [MAX31827_CNV_1_DIV_4_HZ] = 4000, 49 [MAX31827_CNV_1_HZ] = 1000, 50 [MAX31827_CNV_4_HZ] = 250, 51 [MAX31827_CNV_8_HZ] = 125, 52 }; 53 54 struct max31827_state { 55 /* 56 * Prevent simultaneous access to the i2c client. 57 */ 58 struct mutex lock; 59 struct regmap *regmap; 60 bool enable; 61 }; 62 63 static const struct regmap_config max31827_regmap = { 64 .reg_bits = 8, 65 .val_bits = 16, 66 .max_register = 0xA, 67 }; 68 69 static int shutdown_write(struct max31827_state *st, unsigned int reg, 70 unsigned int val) 71 { 72 unsigned int cfg; 73 unsigned int cnv_rate; 74 int ret; 75 76 /* 77 * Before the Temperature Threshold Alarm and Alarm Hysteresis Threshold 78 * register values are changed over I2C, the part must be in shutdown 79 * mode. 80 * 81 * Mutex is used to ensure, that some other process doesn't change the 82 * configuration register. 83 */ 84 mutex_lock(&st->lock); 85 86 if (!st->enable) { 87 ret = regmap_write(st->regmap, reg, val); 88 goto unlock; 89 } 90 91 ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &cfg); 92 if (ret) 93 goto unlock; 94 95 cnv_rate = MAX31827_CONFIGURATION_CNV_RATE_MASK & cfg; 96 cfg = cfg & ~(MAX31827_CONFIGURATION_1SHOT_MASK | 97 MAX31827_CONFIGURATION_CNV_RATE_MASK); 98 ret = regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, cfg); 99 if (ret) 100 goto unlock; 101 102 ret = regmap_write(st->regmap, reg, val); 103 if (ret) 104 goto unlock; 105 106 ret = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, 107 MAX31827_CONFIGURATION_CNV_RATE_MASK, 108 cnv_rate); 109 110 unlock: 111 mutex_unlock(&st->lock); 112 return ret; 113 } 114 115 static int write_alarm_val(struct max31827_state *st, unsigned int reg, 116 long val) 117 { 118 val = MAX31827_M_DGR_TO_16_BIT(val); 119 120 return shutdown_write(st, reg, val); 121 } 122 123 static umode_t max31827_is_visible(const void *state, 124 enum hwmon_sensor_types type, u32 attr, 125 int channel) 126 { 127 if (type == hwmon_temp) { 128 switch (attr) { 129 case hwmon_temp_enable: 130 case hwmon_temp_max: 131 case hwmon_temp_min: 132 case hwmon_temp_max_hyst: 133 case hwmon_temp_min_hyst: 134 return 0644; 135 case hwmon_temp_input: 136 case hwmon_temp_min_alarm: 137 case hwmon_temp_max_alarm: 138 return 0444; 139 default: 140 return 0; 141 } 142 } else if (type == hwmon_chip) { 143 if (attr == hwmon_chip_update_interval) 144 return 0644; 145 } 146 147 return 0; 148 } 149 150 static int max31827_read(struct device *dev, enum hwmon_sensor_types type, 151 u32 attr, int channel, long *val) 152 { 153 struct max31827_state *st = dev_get_drvdata(dev); 154 unsigned int uval; 155 int ret = 0; 156 157 switch (type) { 158 case hwmon_temp: 159 switch (attr) { 160 case hwmon_temp_enable: 161 ret = regmap_read(st->regmap, 162 MAX31827_CONFIGURATION_REG, &uval); 163 if (ret) 164 break; 165 166 uval = FIELD_GET(MAX31827_CONFIGURATION_1SHOT_MASK | 167 MAX31827_CONFIGURATION_CNV_RATE_MASK, 168 uval); 169 *val = !!uval; 170 171 break; 172 case hwmon_temp_input: 173 mutex_lock(&st->lock); 174 175 if (!st->enable) { 176 /* 177 * This operation requires mutex protection, 178 * because the chip configuration should not 179 * be changed during the conversion process. 180 */ 181 182 ret = regmap_update_bits(st->regmap, 183 MAX31827_CONFIGURATION_REG, 184 MAX31827_CONFIGURATION_1SHOT_MASK, 185 1); 186 if (ret) { 187 mutex_unlock(&st->lock); 188 return ret; 189 } 190 191 msleep(MAX31827_12_BIT_CNV_TIME); 192 } 193 ret = regmap_read(st->regmap, MAX31827_T_REG, &uval); 194 195 mutex_unlock(&st->lock); 196 197 if (ret) 198 break; 199 200 *val = MAX31827_16_BIT_TO_M_DGR(uval); 201 202 break; 203 case hwmon_temp_max: 204 ret = regmap_read(st->regmap, MAX31827_TH_REG, &uval); 205 if (ret) 206 break; 207 208 *val = MAX31827_16_BIT_TO_M_DGR(uval); 209 break; 210 case hwmon_temp_max_hyst: 211 ret = regmap_read(st->regmap, MAX31827_TH_HYST_REG, 212 &uval); 213 if (ret) 214 break; 215 216 *val = MAX31827_16_BIT_TO_M_DGR(uval); 217 break; 218 case hwmon_temp_max_alarm: 219 ret = regmap_read(st->regmap, 220 MAX31827_CONFIGURATION_REG, &uval); 221 if (ret) 222 break; 223 224 *val = FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK, 225 uval); 226 break; 227 case hwmon_temp_min: 228 ret = regmap_read(st->regmap, MAX31827_TL_REG, &uval); 229 if (ret) 230 break; 231 232 *val = MAX31827_16_BIT_TO_M_DGR(uval); 233 break; 234 case hwmon_temp_min_hyst: 235 ret = regmap_read(st->regmap, MAX31827_TL_HYST_REG, 236 &uval); 237 if (ret) 238 break; 239 240 *val = MAX31827_16_BIT_TO_M_DGR(uval); 241 break; 242 case hwmon_temp_min_alarm: 243 ret = regmap_read(st->regmap, 244 MAX31827_CONFIGURATION_REG, &uval); 245 if (ret) 246 break; 247 248 *val = FIELD_GET(MAX31827_CONFIGURATION_U_TEMP_STAT_MASK, 249 uval); 250 break; 251 default: 252 ret = -EOPNOTSUPP; 253 break; 254 } 255 256 break; 257 258 case hwmon_chip: 259 if (attr == hwmon_chip_update_interval) { 260 ret = regmap_read(st->regmap, 261 MAX31827_CONFIGURATION_REG, &uval); 262 if (ret) 263 break; 264 265 uval = FIELD_GET(MAX31827_CONFIGURATION_CNV_RATE_MASK, 266 uval); 267 *val = max31827_conversions[uval]; 268 } 269 break; 270 271 default: 272 ret = -EOPNOTSUPP; 273 break; 274 } 275 276 return ret; 277 } 278 279 static int max31827_write(struct device *dev, enum hwmon_sensor_types type, 280 u32 attr, int channel, long val) 281 { 282 struct max31827_state *st = dev_get_drvdata(dev); 283 int res = 1; 284 int ret; 285 286 switch (type) { 287 case hwmon_temp: 288 switch (attr) { 289 case hwmon_temp_enable: 290 if (val >> 1) 291 return -EINVAL; 292 293 mutex_lock(&st->lock); 294 /** 295 * The chip should not be enabled while a conversion is 296 * performed. Neither should the chip be enabled when 297 * the alarm values are changed. 298 */ 299 300 st->enable = val; 301 302 ret = regmap_update_bits(st->regmap, 303 MAX31827_CONFIGURATION_REG, 304 MAX31827_CONFIGURATION_1SHOT_MASK | 305 MAX31827_CONFIGURATION_CNV_RATE_MASK, 306 MAX31827_DEVICE_ENABLE(val)); 307 308 mutex_unlock(&st->lock); 309 310 return ret; 311 312 case hwmon_temp_max: 313 return write_alarm_val(st, MAX31827_TH_REG, val); 314 315 case hwmon_temp_max_hyst: 316 return write_alarm_val(st, MAX31827_TH_HYST_REG, val); 317 318 case hwmon_temp_min: 319 return write_alarm_val(st, MAX31827_TL_REG, val); 320 321 case hwmon_temp_min_hyst: 322 return write_alarm_val(st, MAX31827_TL_HYST_REG, val); 323 324 default: 325 return -EOPNOTSUPP; 326 } 327 328 case hwmon_chip: 329 if (attr == hwmon_chip_update_interval) { 330 if (!st->enable) 331 return -EINVAL; 332 333 /* 334 * Convert the desired conversion rate into register 335 * bits. res is already initialized with 1. 336 * 337 * This was inspired by lm73 driver. 338 */ 339 while (res < ARRAY_SIZE(max31827_conversions) && 340 val < max31827_conversions[res]) 341 res++; 342 343 if (res == ARRAY_SIZE(max31827_conversions) || 344 val != max31827_conversions[res]) 345 return -EINVAL; 346 347 res = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK, 348 res); 349 350 return regmap_update_bits(st->regmap, 351 MAX31827_CONFIGURATION_REG, 352 MAX31827_CONFIGURATION_CNV_RATE_MASK, 353 res); 354 } 355 break; 356 357 default: 358 return -EOPNOTSUPP; 359 } 360 361 return -EOPNOTSUPP; 362 } 363 364 static int max31827_init_client(struct max31827_state *st) 365 { 366 st->enable = true; 367 368 return regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, 369 MAX31827_CONFIGURATION_1SHOT_MASK | 370 MAX31827_CONFIGURATION_CNV_RATE_MASK, 371 MAX31827_DEVICE_ENABLE(1)); 372 } 373 374 static const struct hwmon_channel_info *max31827_info[] = { 375 HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN | 376 HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM | 377 HWMON_T_MAX | HWMON_T_MAX_HYST | 378 HWMON_T_MAX_ALARM), 379 HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL), 380 NULL, 381 }; 382 383 static const struct hwmon_ops max31827_hwmon_ops = { 384 .is_visible = max31827_is_visible, 385 .read = max31827_read, 386 .write = max31827_write, 387 }; 388 389 static const struct hwmon_chip_info max31827_chip_info = { 390 .ops = &max31827_hwmon_ops, 391 .info = max31827_info, 392 }; 393 394 static int max31827_probe(struct i2c_client *client) 395 { 396 struct device *dev = &client->dev; 397 struct device *hwmon_dev; 398 struct max31827_state *st; 399 int err; 400 401 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) 402 return -EOPNOTSUPP; 403 404 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 405 if (!st) 406 return -ENOMEM; 407 408 mutex_init(&st->lock); 409 410 st->regmap = devm_regmap_init_i2c(client, &max31827_regmap); 411 if (IS_ERR(st->regmap)) 412 return dev_err_probe(dev, PTR_ERR(st->regmap), 413 "Failed to allocate regmap.\n"); 414 415 err = devm_regulator_get_enable(dev, "vref"); 416 if (err) 417 return dev_err_probe(dev, err, "failed to enable regulator\n"); 418 419 err = max31827_init_client(st); 420 if (err) 421 return err; 422 423 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st, 424 &max31827_chip_info, 425 NULL); 426 427 return PTR_ERR_OR_ZERO(hwmon_dev); 428 } 429 430 static const struct i2c_device_id max31827_i2c_ids[] = { 431 { "max31827", 0 }, 432 { } 433 }; 434 MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids); 435 436 static const struct of_device_id max31827_of_match[] = { 437 { .compatible = "adi,max31827" }, 438 { } 439 }; 440 MODULE_DEVICE_TABLE(of, max31827_of_match); 441 442 static struct i2c_driver max31827_driver = { 443 .class = I2C_CLASS_HWMON, 444 .driver = { 445 .name = "max31827", 446 .of_match_table = max31827_of_match, 447 }, 448 .probe = max31827_probe, 449 .id_table = max31827_i2c_ids, 450 }; 451 module_i2c_driver(max31827_driver); 452 453 MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>"); 454 MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver"); 455 MODULE_LICENSE("GPL"); 456