678 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * max31827.c - Support for Maxim Low-Power Switch4 *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/of_device.h>15#include <linux/regmap.h>16#include <linux/regulator/consumer.h>17 18#define MAX31827_T_REG 0x019#define MAX31827_CONFIGURATION_REG 0x220#define MAX31827_TH_REG 0x421#define MAX31827_TL_REG 0x622#define MAX31827_TH_HYST_REG 0x823#define MAX31827_TL_HYST_REG 0xA24 25#define MAX31827_CONFIGURATION_1SHOT_MASK BIT(0)26#define MAX31827_CONFIGURATION_CNV_RATE_MASK GENMASK(3, 1)27#define MAX31827_CONFIGURATION_PEC_EN_MASK BIT(4)28#define MAX31827_CONFIGURATION_TIMEOUT_MASK BIT(5)29#define MAX31827_CONFIGURATION_RESOLUTION_MASK GENMASK(7, 6)30#define MAX31827_CONFIGURATION_ALRM_POL_MASK BIT(8)31#define MAX31827_CONFIGURATION_COMP_INT_MASK BIT(9)32#define MAX31827_CONFIGURATION_FLT_Q_MASK GENMASK(11, 10)33#define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK BIT(14)34#define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK BIT(15)35 36#define MAX31827_ALRM_POL_LOW 0x037#define MAX31827_ALRM_POL_HIGH 0x138#define MAX31827_FLT_Q_1 0x039#define MAX31827_FLT_Q_4 0x240 41#define MAX31827_8_BIT_CNV_TIME 942#define MAX31827_9_BIT_CNV_TIME 1843#define MAX31827_10_BIT_CNV_TIME 3544#define MAX31827_12_BIT_CNV_TIME 14045 46#define MAX31827_16_BIT_TO_M_DGR(x) (sign_extend32(x, 15) * 1000 / 16)47#define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000)48#define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0)49 50/*51 * The enum passed in the .data pointer of struct of_device_id must52 * start with a value != 0 since that is a requirement for using53 * device_get_match_data().54 */55enum chips { max31827 = 1, max31828, max31829 };56 57enum max31827_cnv {58 MAX31827_CNV_1_DIV_64_HZ = 1,59 MAX31827_CNV_1_DIV_32_HZ,60 MAX31827_CNV_1_DIV_16_HZ,61 MAX31827_CNV_1_DIV_4_HZ,62 MAX31827_CNV_1_HZ,63 MAX31827_CNV_4_HZ,64 MAX31827_CNV_8_HZ,65};66 67static const u16 max31827_conversions[] = {68 [MAX31827_CNV_1_DIV_64_HZ] = 64000,69 [MAX31827_CNV_1_DIV_32_HZ] = 32000,70 [MAX31827_CNV_1_DIV_16_HZ] = 16000,71 [MAX31827_CNV_1_DIV_4_HZ] = 4000,72 [MAX31827_CNV_1_HZ] = 1000,73 [MAX31827_CNV_4_HZ] = 250,74 [MAX31827_CNV_8_HZ] = 125,75};76 77enum max31827_resolution {78 MAX31827_RES_8_BIT = 0,79 MAX31827_RES_9_BIT,80 MAX31827_RES_10_BIT,81 MAX31827_RES_12_BIT,82};83 84static const u16 max31827_resolutions[] = {85 [MAX31827_RES_8_BIT] = 1000,86 [MAX31827_RES_9_BIT] = 500,87 [MAX31827_RES_10_BIT] = 250,88 [MAX31827_RES_12_BIT] = 62,89};90 91static const u16 max31827_conv_times[] = {92 [MAX31827_RES_8_BIT] = MAX31827_8_BIT_CNV_TIME,93 [MAX31827_RES_9_BIT] = MAX31827_9_BIT_CNV_TIME,94 [MAX31827_RES_10_BIT] = MAX31827_10_BIT_CNV_TIME,95 [MAX31827_RES_12_BIT] = MAX31827_12_BIT_CNV_TIME,96};97 98struct max31827_state {99 /*100 * Prevent simultaneous access to the i2c client.101 */102 struct mutex lock;103 struct regmap *regmap;104 bool enable;105 unsigned int resolution;106 unsigned int update_interval;107};108 109static const struct regmap_config max31827_regmap = {110 .reg_bits = 8,111 .val_bits = 16,112 .max_register = 0xA,113};114 115static int shutdown_write(struct max31827_state *st, unsigned int reg,116 unsigned int mask, unsigned int val)117{118 unsigned int cfg;119 unsigned int cnv_rate;120 int ret;121 122 /*123 * Before the Temperature Threshold Alarm, Alarm Hysteresis Threshold124 * and Resolution bits from Configuration register are changed over I2C,125 * the part must be in shutdown mode.126 *127 * Mutex is used to ensure, that some other process doesn't change the128 * configuration register.129 */130 mutex_lock(&st->lock);131 132 if (!st->enable) {133 if (!mask)134 ret = regmap_write(st->regmap, reg, val);135 else136 ret = regmap_update_bits(st->regmap, reg, mask, val);137 goto unlock;138 }139 140 ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &cfg);141 if (ret)142 goto unlock;143 144 cnv_rate = MAX31827_CONFIGURATION_CNV_RATE_MASK & cfg;145 cfg = cfg & ~(MAX31827_CONFIGURATION_1SHOT_MASK |146 MAX31827_CONFIGURATION_CNV_RATE_MASK);147 ret = regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, cfg);148 if (ret)149 goto unlock;150 151 if (!mask)152 ret = regmap_write(st->regmap, reg, val);153 else154 ret = regmap_update_bits(st->regmap, reg, mask, val);155 156 if (ret)157 goto unlock;158 159 ret = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG,160 MAX31827_CONFIGURATION_CNV_RATE_MASK,161 cnv_rate);162 163unlock:164 mutex_unlock(&st->lock);165 return ret;166}167 168static int write_alarm_val(struct max31827_state *st, unsigned int reg,169 long val)170{171 val = MAX31827_M_DGR_TO_16_BIT(val);172 173 return shutdown_write(st, reg, 0, val);174}175 176static umode_t max31827_is_visible(const void *state,177 enum hwmon_sensor_types type, u32 attr,178 int channel)179{180 if (type == hwmon_temp) {181 switch (attr) {182 case hwmon_temp_enable:183 case hwmon_temp_max:184 case hwmon_temp_min:185 case hwmon_temp_max_hyst:186 case hwmon_temp_min_hyst:187 return 0644;188 case hwmon_temp_input:189 case hwmon_temp_min_alarm:190 case hwmon_temp_max_alarm:191 return 0444;192 default:193 return 0;194 }195 } else if (type == hwmon_chip) {196 if (attr == hwmon_chip_update_interval)197 return 0644;198 }199 200 return 0;201}202 203static int max31827_read(struct device *dev, enum hwmon_sensor_types type,204 u32 attr, int channel, long *val)205{206 struct max31827_state *st = dev_get_drvdata(dev);207 unsigned int uval;208 int ret = 0;209 210 switch (type) {211 case hwmon_temp:212 switch (attr) {213 case hwmon_temp_enable:214 ret = regmap_read(st->regmap,215 MAX31827_CONFIGURATION_REG, &uval);216 if (ret)217 break;218 219 uval = FIELD_GET(MAX31827_CONFIGURATION_1SHOT_MASK |220 MAX31827_CONFIGURATION_CNV_RATE_MASK,221 uval);222 *val = !!uval;223 224 break;225 case hwmon_temp_input:226 mutex_lock(&st->lock);227 228 if (!st->enable) {229 /*230 * This operation requires mutex protection,231 * because the chip configuration should not232 * be changed during the conversion process.233 */234 235 ret = regmap_update_bits(st->regmap,236 MAX31827_CONFIGURATION_REG,237 MAX31827_CONFIGURATION_1SHOT_MASK,238 1);239 if (ret) {240 mutex_unlock(&st->lock);241 return ret;242 }243 msleep(max31827_conv_times[st->resolution]);244 }245 246 /*247 * For 12-bit resolution the conversion time is 140 ms,248 * thus an additional 15 ms is needed to complete the249 * conversion: 125 ms + 15 ms = 140 ms250 */251 if (max31827_resolutions[st->resolution] == 12 &&252 st->update_interval == 125)253 usleep_range(15000, 20000);254 255 ret = regmap_read(st->regmap, MAX31827_T_REG, &uval);256 257 mutex_unlock(&st->lock);258 259 if (ret)260 break;261 262 *val = MAX31827_16_BIT_TO_M_DGR(uval);263 264 break;265 case hwmon_temp_max:266 ret = regmap_read(st->regmap, MAX31827_TH_REG, &uval);267 if (ret)268 break;269 270 *val = MAX31827_16_BIT_TO_M_DGR(uval);271 break;272 case hwmon_temp_max_hyst:273 ret = regmap_read(st->regmap, MAX31827_TH_HYST_REG,274 &uval);275 if (ret)276 break;277 278 *val = MAX31827_16_BIT_TO_M_DGR(uval);279 break;280 case hwmon_temp_max_alarm:281 ret = regmap_read(st->regmap,282 MAX31827_CONFIGURATION_REG, &uval);283 if (ret)284 break;285 286 *val = FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK,287 uval);288 break;289 case hwmon_temp_min:290 ret = regmap_read(st->regmap, MAX31827_TL_REG, &uval);291 if (ret)292 break;293 294 *val = MAX31827_16_BIT_TO_M_DGR(uval);295 break;296 case hwmon_temp_min_hyst:297 ret = regmap_read(st->regmap, MAX31827_TL_HYST_REG,298 &uval);299 if (ret)300 break;301 302 *val = MAX31827_16_BIT_TO_M_DGR(uval);303 break;304 case hwmon_temp_min_alarm:305 ret = regmap_read(st->regmap,306 MAX31827_CONFIGURATION_REG, &uval);307 if (ret)308 break;309 310 *val = FIELD_GET(MAX31827_CONFIGURATION_U_TEMP_STAT_MASK,311 uval);312 break;313 default:314 ret = -EOPNOTSUPP;315 break;316 }317 318 break;319 320 case hwmon_chip:321 if (attr == hwmon_chip_update_interval) {322 ret = regmap_read(st->regmap,323 MAX31827_CONFIGURATION_REG, &uval);324 if (ret)325 break;326 327 uval = FIELD_GET(MAX31827_CONFIGURATION_CNV_RATE_MASK,328 uval);329 *val = max31827_conversions[uval];330 }331 break;332 333 default:334 ret = -EOPNOTSUPP;335 break;336 }337 338 return ret;339}340 341static int max31827_write(struct device *dev, enum hwmon_sensor_types type,342 u32 attr, int channel, long val)343{344 struct max31827_state *st = dev_get_drvdata(dev);345 int res = 1;346 int ret;347 348 switch (type) {349 case hwmon_temp:350 switch (attr) {351 case hwmon_temp_enable:352 if (val >> 1)353 return -EINVAL;354 355 mutex_lock(&st->lock);356 /**357 * The chip should not be enabled while a conversion is358 * performed. Neither should the chip be enabled when359 * the alarm values are changed.360 */361 362 st->enable = val;363 364 ret = regmap_update_bits(st->regmap,365 MAX31827_CONFIGURATION_REG,366 MAX31827_CONFIGURATION_1SHOT_MASK |367 MAX31827_CONFIGURATION_CNV_RATE_MASK,368 MAX31827_DEVICE_ENABLE(val));369 370 mutex_unlock(&st->lock);371 372 return ret;373 374 case hwmon_temp_max:375 return write_alarm_val(st, MAX31827_TH_REG, val);376 377 case hwmon_temp_max_hyst:378 return write_alarm_val(st, MAX31827_TH_HYST_REG, val);379 380 case hwmon_temp_min:381 return write_alarm_val(st, MAX31827_TL_REG, val);382 383 case hwmon_temp_min_hyst:384 return write_alarm_val(st, MAX31827_TL_HYST_REG, val);385 386 default:387 return -EOPNOTSUPP;388 }389 390 case hwmon_chip:391 switch (attr) {392 case hwmon_chip_update_interval:393 if (!st->enable)394 return -EINVAL;395 396 /*397 * Convert the desired conversion rate into register398 * bits. res is already initialized with 1.399 *400 * This was inspired by lm73 driver.401 */402 while (res < ARRAY_SIZE(max31827_conversions) &&403 val < max31827_conversions[res])404 res++;405 406 if (res == ARRAY_SIZE(max31827_conversions))407 res = ARRAY_SIZE(max31827_conversions) - 1;408 409 res = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK,410 res);411 412 ret = regmap_update_bits(st->regmap,413 MAX31827_CONFIGURATION_REG,414 MAX31827_CONFIGURATION_CNV_RATE_MASK,415 res);416 if (ret)417 return ret;418 419 st->update_interval = val;420 421 return 0;422 case hwmon_chip_pec:423 return regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG,424 MAX31827_CONFIGURATION_PEC_EN_MASK,425 val ? MAX31827_CONFIGURATION_PEC_EN_MASK : 0);426 default:427 return -EOPNOTSUPP;428 }429 default:430 return -EOPNOTSUPP;431 }432}433 434static ssize_t temp1_resolution_show(struct device *dev,435 struct device_attribute *devattr,436 char *buf)437{438 struct max31827_state *st = dev_get_drvdata(dev);439 unsigned int val;440 int ret;441 442 ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &val);443 if (ret)444 return ret;445 446 val = FIELD_GET(MAX31827_CONFIGURATION_RESOLUTION_MASK, val);447 448 return scnprintf(buf, PAGE_SIZE, "%u\n", max31827_resolutions[val]);449}450 451static ssize_t temp1_resolution_store(struct device *dev,452 struct device_attribute *devattr,453 const char *buf, size_t count)454{455 struct max31827_state *st = dev_get_drvdata(dev);456 unsigned int idx = 0;457 unsigned int val;458 int ret;459 460 ret = kstrtouint(buf, 10, &val);461 if (ret)462 return ret;463 464 /*465 * Convert the desired resolution into register466 * bits. idx is already initialized with 0.467 *468 * This was inspired by lm73 driver.469 */470 while (idx < ARRAY_SIZE(max31827_resolutions) &&471 val < max31827_resolutions[idx])472 idx++;473 474 if (idx == ARRAY_SIZE(max31827_resolutions))475 idx = ARRAY_SIZE(max31827_resolutions) - 1;476 477 st->resolution = idx;478 479 ret = shutdown_write(st, MAX31827_CONFIGURATION_REG,480 MAX31827_CONFIGURATION_RESOLUTION_MASK,481 FIELD_PREP(MAX31827_CONFIGURATION_RESOLUTION_MASK,482 idx));483 484 return ret ? ret : count;485}486 487static DEVICE_ATTR_RW(temp1_resolution);488 489static struct attribute *max31827_attrs[] = {490 &dev_attr_temp1_resolution.attr,491 NULL492};493ATTRIBUTE_GROUPS(max31827);494 495static const struct i2c_device_id max31827_i2c_ids[] = {496 { "max31827", max31827 },497 { "max31828", max31828 },498 { "max31829", max31829 },499 { }500};501MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids);502 503static int max31827_init_client(struct max31827_state *st,504 struct device *dev)505{506 struct fwnode_handle *fwnode;507 unsigned int res = 0;508 u32 data, lsb_idx;509 enum chips type;510 bool prop;511 int ret;512 513 fwnode = dev_fwnode(dev);514 515 st->enable = true;516 res |= MAX31827_DEVICE_ENABLE(1);517 518 res |= MAX31827_CONFIGURATION_RESOLUTION_MASK;519 520 prop = fwnode_property_read_bool(fwnode, "adi,comp-int");521 res |= FIELD_PREP(MAX31827_CONFIGURATION_COMP_INT_MASK, prop);522 523 prop = fwnode_property_read_bool(fwnode, "adi,timeout-enable");524 res |= FIELD_PREP(MAX31827_CONFIGURATION_TIMEOUT_MASK, !prop);525 526 type = (enum chips)(uintptr_t)device_get_match_data(dev);527 528 if (fwnode_property_present(fwnode, "adi,alarm-pol")) {529 ret = fwnode_property_read_u32(fwnode, "adi,alarm-pol", &data);530 if (ret)531 return ret;532 533 res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, !!data);534 } else {535 /*536 * Set default value.537 */538 switch (type) {539 case max31827:540 case max31828:541 res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK,542 MAX31827_ALRM_POL_LOW);543 break;544 case max31829:545 res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK,546 MAX31827_ALRM_POL_HIGH);547 break;548 default:549 return -EOPNOTSUPP;550 }551 }552 553 if (fwnode_property_present(fwnode, "adi,fault-q")) {554 ret = fwnode_property_read_u32(fwnode, "adi,fault-q", &data);555 if (ret)556 return ret;557 558 /*559 * Convert the desired fault queue into register bits.560 */561 if (data != 0)562 lsb_idx = __ffs(data);563 564 if (hweight32(data) != 1 || lsb_idx > 4) {565 dev_err(dev, "Invalid data in adi,fault-q\n");566 return -EINVAL;567 }568 569 res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, lsb_idx);570 } else {571 /*572 * Set default value.573 */574 switch (type) {575 case max31827:576 res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK,577 MAX31827_FLT_Q_1);578 break;579 case max31828:580 case max31829:581 res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK,582 MAX31827_FLT_Q_4);583 break;584 default:585 return -EOPNOTSUPP;586 }587 }588 589 return regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, res);590}591 592static const struct hwmon_channel_info *max31827_info[] = {593 HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN |594 HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM |595 HWMON_T_MAX | HWMON_T_MAX_HYST |596 HWMON_T_MAX_ALARM),597 HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL | HWMON_C_PEC),598 NULL,599};600 601static const struct hwmon_ops max31827_hwmon_ops = {602 .is_visible = max31827_is_visible,603 .read = max31827_read,604 .write = max31827_write,605};606 607static const struct hwmon_chip_info max31827_chip_info = {608 .ops = &max31827_hwmon_ops,609 .info = max31827_info,610};611 612static int max31827_probe(struct i2c_client *client)613{614 struct device *dev = &client->dev;615 struct device *hwmon_dev;616 struct max31827_state *st;617 int err;618 619 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))620 return -EOPNOTSUPP;621 622 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);623 if (!st)624 return -ENOMEM;625 626 mutex_init(&st->lock);627 628 st->regmap = devm_regmap_init_i2c(client, &max31827_regmap);629 if (IS_ERR(st->regmap))630 return dev_err_probe(dev, PTR_ERR(st->regmap),631 "Failed to allocate regmap.\n");632 633 err = devm_regulator_get_enable(dev, "vref");634 if (err)635 return dev_err_probe(dev, err, "failed to enable regulator\n");636 637 err = max31827_init_client(st, dev);638 if (err)639 return err;640 641 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st,642 &max31827_chip_info,643 max31827_groups);644 645 return PTR_ERR_OR_ZERO(hwmon_dev);646}647 648static const struct of_device_id max31827_of_match[] = {649 {650 .compatible = "adi,max31827",651 .data = (void *)max31827652 },653 {654 .compatible = "adi,max31828",655 .data = (void *)max31828656 },657 {658 .compatible = "adi,max31829",659 .data = (void *)max31829660 },661 { }662};663MODULE_DEVICE_TABLE(of, max31827_of_match);664 665static struct i2c_driver max31827_driver = {666 .driver = {667 .name = "max31827",668 .of_match_table = max31827_of_match,669 },670 .probe = max31827_probe,671 .id_table = max31827_i2c_ids,672};673module_i2c_driver(max31827_driver);674 675MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>");676MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver");677MODULE_LICENSE("GPL");678