647 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (c) 2012 Guenter Roeck <linux@roeck-us.net>4 *5 * based on max1668.c6 * Copyright (c) 2011 David George <david.george@ska.ac.za>7 */8 9#include <linux/bitfield.h>10#include <linux/bits.h>11#include <linux/err.h>12#include <linux/hwmon.h>13#include <linux/i2c.h>14#include <linux/init.h>15#include <linux/module.h>16#include <linux/mutex.h>17#include <linux/of.h>18#include <linux/regmap.h>19#include <linux/slab.h>20 21enum chips { max6581, max6602, max6622, max6636, max6689, max6693, max6694,22 max6697, max6698, max6699 };23 24/* Report local sensor as temp1 */25 26static const u8 MAX6697_REG_TEMP[] = {27 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08 };28static const u8 MAX6697_REG_TEMP_EXT[] = {29 0x57, 0x09, 0x52, 0x53, 0x54, 0x55, 0x56, 0 };30static const u8 MAX6697_REG_MAX[] = {31 0x17, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x18 };32static const u8 MAX6697_REG_CRIT[] = {33 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 };34 35#define MAX6697_REG_MIN 0x3036/*37 * Map device tree / internal register bit map to chip bit map.38 * Applies to alert register and over-temperature register.39 */40 41#define MAX6697_EXTERNAL_MASK_DT GENMASK(7, 1)42#define MAX6697_LOCAL_MASK_DT BIT(0)43#define MAX6697_EXTERNAL_MASK_CHIP GENMASK(6, 0)44#define MAX6697_LOCAL_MASK_CHIP BIT(7)45 46/* alert - local channel is in bit 6 */47#define MAX6697_ALERT_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \48 (((reg) & 0x01) << 6) | ((reg) & 0x80))49 50/* over-temperature - local channel is in bit 7 */51#define MAX6697_OVERT_MAP_BITS(reg) \52 (FIELD_PREP(MAX6697_EXTERNAL_MASK_CHIP, FIELD_GET(MAX6697_EXTERNAL_MASK_DT, reg)) | \53 FIELD_PREP(MAX6697_LOCAL_MASK_CHIP, FIELD_GET(MAX6697_LOCAL_MASK_DT, reg)))54 55#define MAX6697_REG_STAT_ALARM 0x4456#define MAX6697_REG_STAT_CRIT 0x4557#define MAX6697_REG_STAT_FAULT 0x4658#define MAX6697_REG_STAT_MIN_ALARM 0x4759 60#define MAX6697_REG_CONFIG 0x4161#define MAX6581_CONF_EXTENDED BIT(1)62#define MAX6693_CONF_BETA BIT(2)63#define MAX6697_CONF_RESISTANCE BIT(3)64#define MAX6697_CONF_TIMEOUT BIT(5)65#define MAX6697_REG_ALERT_MASK 0x4266#define MAX6697_REG_OVERT_MASK 0x4367 68#define MAX6581_REG_RESISTANCE 0x4a69#define MAX6581_REG_IDEALITY 0x4b70#define MAX6581_REG_IDEALITY_SELECT 0x4c71#define MAX6581_REG_OFFSET 0x4d72#define MAX6581_REG_OFFSET_SELECT 0x4e73#define MAX6581_OFFSET_MIN -3175074#define MAX6581_OFFSET_MAX 3175075 76#define MAX6697_CONV_TIME 156 /* ms per channel, worst case */77 78struct max6697_chip_data {79 int channels;80 u32 have_ext;81 u32 have_crit;82 u32 have_fault;83 u8 valid_conf;84};85 86struct max6697_data {87 struct regmap *regmap;88 89 enum chips type;90 const struct max6697_chip_data *chip;91 92 int temp_offset; /* in degrees C */93 94 struct mutex update_lock;95 96#define MAX6697_TEMP_INPUT 097#define MAX6697_TEMP_EXT 198#define MAX6697_TEMP_MAX 299#define MAX6697_TEMP_CRIT 3100 u32 alarms;101};102 103static const struct max6697_chip_data max6697_chip_data[] = {104 [max6581] = {105 .channels = 8,106 .have_crit = 0xff,107 .have_ext = 0x7f,108 .have_fault = 0xfe,109 .valid_conf = MAX6581_CONF_EXTENDED | MAX6697_CONF_TIMEOUT,110 },111 [max6602] = {112 .channels = 5,113 .have_crit = 0x12,114 .have_ext = 0x02,115 .have_fault = 0x1e,116 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,117 },118 [max6622] = {119 .channels = 5,120 .have_crit = 0x12,121 .have_ext = 0x02,122 .have_fault = 0x1e,123 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,124 },125 [max6636] = {126 .channels = 7,127 .have_crit = 0x72,128 .have_ext = 0x02,129 .have_fault = 0x7e,130 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,131 },132 [max6689] = {133 .channels = 7,134 .have_crit = 0x72,135 .have_ext = 0x02,136 .have_fault = 0x7e,137 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,138 },139 [max6693] = {140 .channels = 7,141 .have_crit = 0x72,142 .have_ext = 0x02,143 .have_fault = 0x7e,144 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6693_CONF_BETA |145 MAX6697_CONF_TIMEOUT,146 },147 [max6694] = {148 .channels = 5,149 .have_crit = 0x12,150 .have_ext = 0x02,151 .have_fault = 0x1e,152 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6693_CONF_BETA |153 MAX6697_CONF_TIMEOUT,154 },155 [max6697] = {156 .channels = 7,157 .have_crit = 0x72,158 .have_ext = 0x02,159 .have_fault = 0x7e,160 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,161 },162 [max6698] = {163 .channels = 7,164 .have_crit = 0x72,165 .have_ext = 0x02,166 .have_fault = 0x0e,167 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,168 },169 [max6699] = {170 .channels = 5,171 .have_crit = 0x12,172 .have_ext = 0x02,173 .have_fault = 0x1e,174 .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,175 },176};177 178static int max6697_alarm_channel_map(int channel)179{180 switch (channel) {181 case 0:182 return 6;183 case 7:184 return 7;185 default:186 return channel - 1;187 }188}189 190static int max6697_read(struct device *dev, enum hwmon_sensor_types type,191 u32 attr, int channel, long *val)192{193 unsigned int offset_regs[2] = { MAX6581_REG_OFFSET_SELECT, MAX6581_REG_OFFSET };194 unsigned int temp_regs[2] = { MAX6697_REG_TEMP[channel],195 MAX6697_REG_TEMP_EXT[channel] };196 struct max6697_data *data = dev_get_drvdata(dev);197 struct regmap *regmap = data->regmap;198 u8 regdata[2] = { };199 u32 regval;200 int ret;201 202 switch (attr) {203 case hwmon_temp_input:204 ret = regmap_multi_reg_read(regmap, temp_regs, regdata,205 data->chip->have_ext & BIT(channel) ? 2 : 1);206 if (ret)207 return ret;208 *val = (((regdata[0] - data->temp_offset) << 3) | (regdata[1] >> 5)) * 125;209 break;210 case hwmon_temp_max:211 ret = regmap_read(regmap, MAX6697_REG_MAX[channel], ®val);212 if (ret)213 return ret;214 *val = ((int)regval - data->temp_offset) * 1000;215 break;216 case hwmon_temp_crit:217 ret = regmap_read(regmap, MAX6697_REG_CRIT[channel], ®val);218 if (ret)219 return ret;220 *val = ((int)regval - data->temp_offset) * 1000;221 break;222 case hwmon_temp_min:223 ret = regmap_read(regmap, MAX6697_REG_MIN, ®val);224 if (ret)225 return ret;226 *val = ((int)regval - data->temp_offset) * 1000;227 break;228 case hwmon_temp_offset:229 ret = regmap_multi_reg_read(regmap, offset_regs, regdata, 2);230 if (ret)231 return ret;232 233 if (!(regdata[0] & BIT(channel - 1)))234 regdata[1] = 0;235 236 *val = sign_extend32(regdata[1], 7) * 250;237 break;238 case hwmon_temp_fault:239 ret = regmap_read(regmap, MAX6697_REG_STAT_FAULT, ®val);240 if (ret)241 return ret;242 if (data->type == max6581)243 *val = !!(regval & BIT(channel - 1));244 else245 *val = !!(regval & BIT(channel));246 break;247 case hwmon_temp_crit_alarm:248 ret = regmap_read(regmap, MAX6697_REG_STAT_CRIT, ®val);249 if (ret)250 return ret;251 /*252 * In the MAX6581 datasheet revision 0 to 3, the local channel253 * overtemperature status is reported in bit 6 of register 0x45,254 * and the overtemperature status for remote channel 7 is255 * reported in bit 7. In Revision 4 and later, the local channel256 * overtemperature status is reported in bit 7, and the remote257 * channel 7 overtemperature status is reported in bit 6. A real258 * chip was found to match the functionality documented in259 * Revision 4 and later.260 */261 *val = !!(regval & BIT(channel ? channel - 1 : 7));262 break;263 case hwmon_temp_max_alarm:264 ret = regmap_read(regmap, MAX6697_REG_STAT_ALARM, ®val);265 if (ret)266 return ret;267 *val = !!(regval & BIT(max6697_alarm_channel_map(channel)));268 break;269 case hwmon_temp_min_alarm:270 ret = regmap_read(regmap, MAX6697_REG_STAT_MIN_ALARM, ®val);271 if (ret)272 return ret;273 *val = !!(regval & BIT(max6697_alarm_channel_map(channel)));274 break;275 default:276 return -EOPNOTSUPP;277 }278 return 0;279}280 281static int max6697_write(struct device *dev, enum hwmon_sensor_types type,282 u32 attr, int channel, long val)283{284 struct max6697_data *data = dev_get_drvdata(dev);285 struct regmap *regmap = data->regmap;286 int ret;287 288 switch (attr) {289 case hwmon_temp_max:290 val = clamp_val(val, -1000000, 1000000); /* prevent underflow */291 val = DIV_ROUND_CLOSEST(val, 1000) + data->temp_offset;292 val = clamp_val(val, 0, data->type == max6581 ? 255 : 127);293 return regmap_write(regmap, MAX6697_REG_MAX[channel], val);294 case hwmon_temp_crit:295 val = clamp_val(val, -1000000, 1000000); /* prevent underflow */296 val = DIV_ROUND_CLOSEST(val, 1000) + data->temp_offset;297 val = clamp_val(val, 0, data->type == max6581 ? 255 : 127);298 return regmap_write(regmap, MAX6697_REG_CRIT[channel], val);299 case hwmon_temp_min:300 val = clamp_val(val, -1000000, 1000000); /* prevent underflow */301 val = DIV_ROUND_CLOSEST(val, 1000) + data->temp_offset;302 val = clamp_val(val, 0, 255);303 return regmap_write(regmap, MAX6697_REG_MIN, val);304 case hwmon_temp_offset:305 mutex_lock(&data->update_lock);306 val = clamp_val(val, MAX6581_OFFSET_MIN, MAX6581_OFFSET_MAX);307 val = DIV_ROUND_CLOSEST(val, 250);308 if (!val) { /* disable this (and only this) channel */309 ret = regmap_clear_bits(regmap, MAX6581_REG_OFFSET_SELECT,310 BIT(channel - 1));311 } else {312 /* enable channel and update offset */313 ret = regmap_set_bits(regmap, MAX6581_REG_OFFSET_SELECT,314 BIT(channel - 1));315 if (ret)316 goto unlock;317 ret = regmap_write(regmap, MAX6581_REG_OFFSET, val);318 }319unlock:320 mutex_unlock(&data->update_lock);321 return ret;322 default:323 return -EOPNOTSUPP;324 }325}326 327static umode_t max6697_is_visible(const void *_data, enum hwmon_sensor_types type,328 u32 attr, int channel)329{330 const struct max6697_data *data = _data;331 const struct max6697_chip_data *chip = data->chip;332 333 if (channel >= chip->channels)334 return 0;335 336 switch (attr) {337 case hwmon_temp_max:338 return 0644;339 case hwmon_temp_input:340 case hwmon_temp_max_alarm:341 return 0444;342 case hwmon_temp_min:343 if (data->type == max6581)344 return channel ? 0444 : 0644;345 break;346 case hwmon_temp_min_alarm:347 if (data->type == max6581)348 return 0444;349 break;350 case hwmon_temp_crit:351 if (chip->have_crit & BIT(channel))352 return 0644;353 break;354 case hwmon_temp_crit_alarm:355 if (chip->have_crit & BIT(channel))356 return 0444;357 break;358 case hwmon_temp_fault:359 if (chip->have_fault & BIT(channel))360 return 0444;361 break;362 case hwmon_temp_offset:363 if (data->type == max6581 && channel)364 return 0644;365 break;366 default:367 break;368 }369 return 0;370}371 372/* Return 0 if detection is successful, -ENODEV otherwise */373static const struct hwmon_channel_info * const max6697_info[] = {374 HWMON_CHANNEL_INFO(temp,375 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |376 HWMON_T_MIN | HWMON_T_MIN_ALARM |377 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM,378 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |379 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |380 HWMON_T_MIN | HWMON_T_MIN_ALARM |381 HWMON_T_FAULT | HWMON_T_OFFSET,382 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |383 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |384 HWMON_T_MIN | HWMON_T_MIN_ALARM |385 HWMON_T_FAULT | HWMON_T_OFFSET,386 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |387 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |388 HWMON_T_MIN | HWMON_T_MIN_ALARM |389 HWMON_T_FAULT | HWMON_T_OFFSET,390 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |391 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |392 HWMON_T_MIN | HWMON_T_MIN_ALARM |393 HWMON_T_FAULT | HWMON_T_OFFSET,394 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |395 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |396 HWMON_T_MIN | HWMON_T_MIN_ALARM |397 HWMON_T_FAULT | HWMON_T_OFFSET,398 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |399 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |400 HWMON_T_MIN | HWMON_T_MIN_ALARM |401 HWMON_T_FAULT | HWMON_T_OFFSET,402 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |403 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |404 HWMON_T_MIN | HWMON_T_MIN_ALARM |405 HWMON_T_FAULT | HWMON_T_OFFSET),406 NULL407};408 409static const struct hwmon_ops max6697_hwmon_ops = {410 .is_visible = max6697_is_visible,411 .read = max6697_read,412 .write = max6697_write,413};414 415static const struct hwmon_chip_info max6697_chip_info = {416 .ops = &max6697_hwmon_ops,417 .info = max6697_info,418};419 420static int max6697_config_of(struct device_node *node, struct max6697_data *data)421{422 const struct max6697_chip_data *chip = data->chip;423 struct regmap *regmap = data->regmap;424 int ret, confreg;425 u32 vals[2];426 427 confreg = 0;428 if (of_property_read_bool(node, "smbus-timeout-disable") &&429 (chip->valid_conf & MAX6697_CONF_TIMEOUT)) {430 confreg |= MAX6697_CONF_TIMEOUT;431 }432 if (of_property_read_bool(node, "extended-range-enable") &&433 (chip->valid_conf & MAX6581_CONF_EXTENDED)) {434 confreg |= MAX6581_CONF_EXTENDED;435 data->temp_offset = 64;436 }437 if (of_property_read_bool(node, "beta-compensation-enable") &&438 (chip->valid_conf & MAX6693_CONF_BETA)) {439 confreg |= MAX6693_CONF_BETA;440 }441 442 if (of_property_read_u32(node, "alert-mask", vals))443 vals[0] = 0;444 ret = regmap_write(regmap, MAX6697_REG_ALERT_MASK,445 MAX6697_ALERT_MAP_BITS(vals[0]));446 if (ret)447 return ret;448 449 if (of_property_read_u32(node, "over-temperature-mask", vals))450 vals[0] = 0;451 ret = regmap_write(regmap, MAX6697_REG_OVERT_MASK,452 MAX6697_OVERT_MAP_BITS(vals[0]));453 if (ret)454 return ret;455 456 if (data->type != max6581) {457 if (of_property_read_bool(node, "resistance-cancellation") &&458 chip->valid_conf & MAX6697_CONF_RESISTANCE) {459 confreg |= MAX6697_CONF_RESISTANCE;460 }461 } else {462 if (of_property_read_u32(node, "resistance-cancellation", &vals[0])) {463 if (of_property_read_bool(node, "resistance-cancellation"))464 vals[0] = 0xfe;465 else466 vals[0] = 0;467 }468 469 vals[0] &= 0xfe;470 ret = regmap_write(regmap, MAX6581_REG_RESISTANCE, vals[0] >> 1);471 if (ret < 0)472 return ret;473 474 if (of_property_read_u32_array(node, "transistor-ideality", vals, 2)) {475 vals[0] = 0;476 vals[1] = 0;477 }478 479 ret = regmap_write(regmap, MAX6581_REG_IDEALITY, vals[1]);480 if (ret < 0)481 return ret;482 ret = regmap_write(regmap, MAX6581_REG_IDEALITY_SELECT,483 (vals[0] & 0xfe) >> 1);484 if (ret < 0)485 return ret;486 }487 return regmap_write(regmap, MAX6697_REG_CONFIG, confreg);488}489 490static int max6697_init_chip(struct device_node *np, struct max6697_data *data)491{492 unsigned int reg;493 int ret;494 495 /*496 * Don't touch configuration if there is no devicetree configuration.497 * If that is the case, use the current chip configuration.498 */499 if (!np) {500 struct regmap *regmap = data->regmap;501 502 ret = regmap_read(regmap, MAX6697_REG_CONFIG, ®);503 if (ret < 0)504 return ret;505 if (data->type == max6581) {506 if (reg & MAX6581_CONF_EXTENDED)507 data->temp_offset = 64;508 ret = regmap_read(regmap, MAX6581_REG_RESISTANCE, ®);509 }510 } else {511 ret = max6697_config_of(np, data);512 }513 514 return ret;515}516 517static bool max6697_volatile_reg(struct device *dev, unsigned int reg)518{519 switch (reg) {520 case 0x00 ... 0x09: /* temperature high bytes */521 case 0x44 ... 0x47: /* status */522 case 0x51 ... 0x58: /* temperature low bytes */523 return true;524 default:525 return false;526 }527}528 529static bool max6697_writeable_reg(struct device *dev, unsigned int reg)530{531 return reg != 0x0a && reg != 0x0f && !max6697_volatile_reg(dev, reg);532}533 534static const struct regmap_config max6697_regmap_config = {535 .reg_bits = 8,536 .val_bits = 8,537 .max_register = 0x58,538 .writeable_reg = max6697_writeable_reg,539 .volatile_reg = max6697_volatile_reg,540 .cache_type = REGCACHE_MAPLE,541};542 543static int max6697_probe(struct i2c_client *client)544{545 struct device *dev = &client->dev;546 struct max6697_data *data;547 struct device *hwmon_dev;548 struct regmap *regmap;549 int err;550 551 regmap = regmap_init_i2c(client, &max6697_regmap_config);552 if (IS_ERR(regmap))553 return PTR_ERR(regmap);554 555 data = devm_kzalloc(dev, sizeof(struct max6697_data), GFP_KERNEL);556 if (!data)557 return -ENOMEM;558 559 data->regmap = regmap;560 data->type = (uintptr_t)i2c_get_match_data(client);561 data->chip = &max6697_chip_data[data->type];562 mutex_init(&data->update_lock);563 564 err = max6697_init_chip(client->dev.of_node, data);565 if (err)566 return err;567 568 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,569 &max6697_chip_info, NULL);570 return PTR_ERR_OR_ZERO(hwmon_dev);571}572 573static const struct i2c_device_id max6697_id[] = {574 { "max6581", max6581 },575 { "max6602", max6602 },576 { "max6622", max6622 },577 { "max6636", max6636 },578 { "max6689", max6689 },579 { "max6693", max6693 },580 { "max6694", max6694 },581 { "max6697", max6697 },582 { "max6698", max6698 },583 { "max6699", max6699 },584 { }585};586MODULE_DEVICE_TABLE(i2c, max6697_id);587 588static const struct of_device_id __maybe_unused max6697_of_match[] = {589 {590 .compatible = "maxim,max6581",591 .data = (void *)max6581592 },593 {594 .compatible = "maxim,max6602",595 .data = (void *)max6602596 },597 {598 .compatible = "maxim,max6622",599 .data = (void *)max6622600 },601 {602 .compatible = "maxim,max6636",603 .data = (void *)max6636604 },605 {606 .compatible = "maxim,max6689",607 .data = (void *)max6689608 },609 {610 .compatible = "maxim,max6693",611 .data = (void *)max6693612 },613 {614 .compatible = "maxim,max6694",615 .data = (void *)max6694616 },617 {618 .compatible = "maxim,max6697",619 .data = (void *)max6697620 },621 {622 .compatible = "maxim,max6698",623 .data = (void *)max6698624 },625 {626 .compatible = "maxim,max6699",627 .data = (void *)max6699628 },629 { },630};631MODULE_DEVICE_TABLE(of, max6697_of_match);632 633static struct i2c_driver max6697_driver = {634 .driver = {635 .name = "max6697",636 .of_match_table = of_match_ptr(max6697_of_match),637 },638 .probe = max6697_probe,639 .id_table = max6697_id,640};641 642module_i2c_driver(max6697_driver);643 644MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");645MODULE_DESCRIPTION("MAX6697 temperature sensor driver");646MODULE_LICENSE("GPL");647