625 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * jc42.c - driver for Jedec JC42.4 compliant temperature sensors4 *5 * Copyright (c) 2010 Ericsson AB.6 *7 * Derived from lm77.c by Andras BALI <drewie@freemail.hu>.8 *9 * JC42.4 compliant temperature sensors are typically used on memory modules.10 */11 12#include <linux/bitops.h>13#include <linux/bitfield.h>14#include <linux/module.h>15#include <linux/init.h>16#include <linux/slab.h>17#include <linux/jiffies.h>18#include <linux/i2c.h>19#include <linux/hwmon.h>20#include <linux/err.h>21#include <linux/mutex.h>22#include <linux/of.h>23#include <linux/regmap.h>24 25/* Addresses to scan */26static const unsigned short normal_i2c[] = {27 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, I2C_CLIENT_END };28 29/* JC42 registers. All registers are 16 bit. */30#define JC42_REG_CAP 0x0031#define JC42_REG_CONFIG 0x0132#define JC42_REG_TEMP_UPPER 0x0233#define JC42_REG_TEMP_LOWER 0x0334#define JC42_REG_TEMP_CRITICAL 0x0435#define JC42_REG_TEMP 0x0536#define JC42_REG_MANID 0x0637#define JC42_REG_DEVICEID 0x0738#define JC42_REG_SMBUS 0x22 /* NXP and Atmel, possibly others? */39 40/* Status bits in temperature register */41#define JC42_ALARM_CRIT BIT(15)42#define JC42_ALARM_MAX BIT(14)43#define JC42_ALARM_MIN BIT(13)44 45/* Configuration register defines */46#define JC42_CFG_CRIT_ONLY BIT(2)47#define JC42_CFG_TCRIT_LOCK BIT(6)48#define JC42_CFG_EVENT_LOCK BIT(7)49#define JC42_CFG_SHUTDOWN BIT(8)50#define JC42_CFG_HYST_MASK GENMASK(10, 9)51 52/* Capabilities */53#define JC42_CAP_RANGE BIT(2)54 55/* Manufacturer IDs */56#define ADT_MANID 0x11d4 /* Analog Devices */57#define ATMEL_MANID 0x001f /* Atmel */58#define ATMEL_MANID2 0x1114 /* Atmel */59#define MAX_MANID 0x004d /* Maxim */60#define IDT_MANID 0x00b3 /* IDT */61#define MCP_MANID 0x0054 /* Microchip */62#define NXP_MANID 0x1131 /* NXP Semiconductors */63#define ONS_MANID 0x1b09 /* ON Semiconductor */64#define STM_MANID 0x104a /* ST Microelectronics */65#define GT_MANID 0x1c68 /* Giantec */66#define GT_MANID2 0x132d /* Giantec, 2nd mfg ID */67#define SI_MANID 0x1c85 /* Seiko Instruments */68 69/* SMBUS register */70#define SMBUS_STMOUT BIT(7) /* SMBus time-out, active low */71 72/* Supported chips */73 74/* Analog Devices */75#define ADT7408_DEVID 0x080176#define ADT7408_DEVID_MASK 0xffff77 78/* Atmel */79#define AT30TS00_DEVID 0x820180#define AT30TS00_DEVID_MASK 0xffff81 82#define GT34TS02_DEVID 0x330083#define GT34TS02_DEVID_MASK 0xff0084 85#define TS3000_DEVID 0x2900 /* Also matches TSE2002 */86#define TS3000_DEVID_MASK 0xff0087 88#define TS3001_DEVID 0x300089#define TS3001_DEVID_MASK 0xff0090 91/* Maxim */92#define MAX6604_DEVID 0x3e0093#define MAX6604_DEVID_MASK 0xffff94 95/* Microchip */96#define MCP9804_DEVID 0x020097#define MCP9804_DEVID_MASK 0xfffc98 99#define MCP9808_DEVID 0x0400100#define MCP9808_DEVID_MASK 0xfffc101 102#define MCP98242_DEVID 0x2000103#define MCP98242_DEVID_MASK 0xfffc104 105#define MCP98243_DEVID 0x2100106#define MCP98243_DEVID_MASK 0xfffc107 108#define MCP9843_DEVID 0x0000 /* Also matches mcp9805 */109#define MCP9843_DEVID_MASK 0xfffe110 111/* NXP */112#define SE97_DEVID 0xa200113#define SE97_DEVID_MASK 0xfffc114 115#define SE98_DEVID 0xa100116#define SE98_DEVID_MASK 0xfffc117 118/* ON Semiconductor */119#define CAT6095_DEVID 0x0800 /* Also matches CAT34TS02 */120#define CAT6095_DEVID_MASK 0xffe0121 122#define CAT34TS02C_DEVID 0x0a00123#define CAT34TS02C_DEVID_MASK 0xfff0124 125/* ST Microelectronics */126#define STTS424_DEVID 0x0101127#define STTS424_DEVID_MASK 0xffff128 129#define STTS424E_DEVID 0x0000130#define STTS424E_DEVID_MASK 0xfffe131 132#define STTS2002_DEVID 0x0300133#define STTS2002_DEVID_MASK 0xffff134 135#define STTS3000_DEVID 0x0200136#define STTS3000_DEVID_MASK 0xffff137 138/* TSE2004 compliant sensors */139#define TSE2004_DEVID 0x2200140#define TSE2004_DEVID_MASK 0xff00141 142static u16 jc42_hysteresis[] = { 0, 1500, 3000, 6000 };143 144struct jc42_chips {145 u16 manid;146 u16 devid;147 u16 devid_mask;148};149 150static struct jc42_chips jc42_chips[] = {151 { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK },152 { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK },153 { ATMEL_MANID2, TSE2004_DEVID, TSE2004_DEVID_MASK },154 { GT_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },155 { GT_MANID2, GT34TS02_DEVID, GT34TS02_DEVID_MASK },156 { IDT_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },157 { IDT_MANID, TS3000_DEVID, TS3000_DEVID_MASK },158 { IDT_MANID, TS3001_DEVID, TS3001_DEVID_MASK },159 { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK },160 { MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK },161 { MCP_MANID, MCP9808_DEVID, MCP9808_DEVID_MASK },162 { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK },163 { MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK },164 { MCP_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },165 { MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK },166 { NXP_MANID, SE97_DEVID, SE97_DEVID_MASK },167 { ONS_MANID, CAT6095_DEVID, CAT6095_DEVID_MASK },168 { ONS_MANID, CAT34TS02C_DEVID, CAT34TS02C_DEVID_MASK },169 { ONS_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },170 { ONS_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },171 { NXP_MANID, SE98_DEVID, SE98_DEVID_MASK },172 { SI_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },173 { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK },174 { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK },175 { STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK },176 { STM_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },177 { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK },178};179 180/* Each client has this additional data */181struct jc42_data {182 struct mutex update_lock; /* protect register access */183 struct regmap *regmap;184 bool extended; /* true if extended range supported */185 bool valid;186 u16 orig_config; /* original configuration */187 u16 config; /* current configuration */188};189 190#define JC42_TEMP_MIN_EXTENDED (-40000)191#define JC42_TEMP_MIN 0192#define JC42_TEMP_MAX 125000193 194static u16 jc42_temp_to_reg(long temp, bool extended)195{196 int ntemp = clamp_val(temp,197 extended ? JC42_TEMP_MIN_EXTENDED :198 JC42_TEMP_MIN, JC42_TEMP_MAX);199 200 /* convert from 0.001 to 0.0625 resolution */201 return (ntemp * 2 / 125) & 0x1fff;202}203 204static int jc42_temp_from_reg(s16 reg)205{206 reg = sign_extend32(reg, 12);207 208 /* convert from 0.0625 to 0.001 resolution */209 return reg * 125 / 2;210}211 212static int jc42_read(struct device *dev, enum hwmon_sensor_types type,213 u32 attr, int channel, long *val)214{215 struct jc42_data *data = dev_get_drvdata(dev);216 unsigned int regval;217 int ret, temp, hyst;218 219 mutex_lock(&data->update_lock);220 221 switch (attr) {222 case hwmon_temp_input:223 ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val);224 if (ret)225 break;226 227 *val = jc42_temp_from_reg(regval);228 break;229 case hwmon_temp_min:230 ret = regmap_read(data->regmap, JC42_REG_TEMP_LOWER, ®val);231 if (ret)232 break;233 234 *val = jc42_temp_from_reg(regval);235 break;236 case hwmon_temp_max:237 ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val);238 if (ret)239 break;240 241 *val = jc42_temp_from_reg(regval);242 break;243 case hwmon_temp_crit:244 ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,245 ®val);246 if (ret)247 break;248 249 *val = jc42_temp_from_reg(regval);250 break;251 case hwmon_temp_max_hyst:252 ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val);253 if (ret)254 break;255 256 temp = jc42_temp_from_reg(regval);257 hyst = jc42_hysteresis[FIELD_GET(JC42_CFG_HYST_MASK,258 data->config)];259 *val = temp - hyst;260 break;261 case hwmon_temp_crit_hyst:262 ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,263 ®val);264 if (ret)265 break;266 267 temp = jc42_temp_from_reg(regval);268 hyst = jc42_hysteresis[FIELD_GET(JC42_CFG_HYST_MASK,269 data->config)];270 *val = temp - hyst;271 break;272 case hwmon_temp_min_alarm:273 ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val);274 if (ret)275 break;276 277 *val = FIELD_GET(JC42_ALARM_MIN, regval);278 break;279 case hwmon_temp_max_alarm:280 ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val);281 if (ret)282 break;283 284 *val = FIELD_GET(JC42_ALARM_MAX, regval);285 break;286 case hwmon_temp_crit_alarm:287 ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val);288 if (ret)289 break;290 291 *val = FIELD_GET(JC42_ALARM_CRIT, regval);292 break;293 default:294 ret = -EOPNOTSUPP;295 break;296 }297 298 mutex_unlock(&data->update_lock);299 300 return ret;301}302 303static int jc42_write(struct device *dev, enum hwmon_sensor_types type,304 u32 attr, int channel, long val)305{306 struct jc42_data *data = dev_get_drvdata(dev);307 unsigned int regval;308 int diff, hyst;309 int ret;310 311 mutex_lock(&data->update_lock);312 313 switch (attr) {314 case hwmon_temp_min:315 ret = regmap_write(data->regmap, JC42_REG_TEMP_LOWER,316 jc42_temp_to_reg(val, data->extended));317 break;318 case hwmon_temp_max:319 ret = regmap_write(data->regmap, JC42_REG_TEMP_UPPER,320 jc42_temp_to_reg(val, data->extended));321 break;322 case hwmon_temp_crit:323 ret = regmap_write(data->regmap, JC42_REG_TEMP_CRITICAL,324 jc42_temp_to_reg(val, data->extended));325 break;326 case hwmon_temp_crit_hyst:327 ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,328 ®val);329 if (ret)330 break;331 332 /*333 * JC42.4 compliant chips only support four hysteresis values.334 * Pick best choice and go from there.335 */336 val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED337 : JC42_TEMP_MIN) - 6000,338 JC42_TEMP_MAX);339 diff = jc42_temp_from_reg(regval) - val;340 hyst = 0;341 if (diff > 0) {342 if (diff < 2250)343 hyst = 1; /* 1.5 degrees C */344 else if (diff < 4500)345 hyst = 2; /* 3.0 degrees C */346 else347 hyst = 3; /* 6.0 degrees C */348 }349 data->config = (data->config & ~JC42_CFG_HYST_MASK) |350 FIELD_PREP(JC42_CFG_HYST_MASK, hyst);351 ret = regmap_write(data->regmap, JC42_REG_CONFIG,352 data->config);353 break;354 default:355 ret = -EOPNOTSUPP;356 break;357 }358 359 mutex_unlock(&data->update_lock);360 361 return ret;362}363 364static umode_t jc42_is_visible(const void *_data, enum hwmon_sensor_types type,365 u32 attr, int channel)366{367 const struct jc42_data *data = _data;368 unsigned int config = data->config;369 umode_t mode = 0444;370 371 switch (attr) {372 case hwmon_temp_min:373 case hwmon_temp_max:374 if (!(config & JC42_CFG_EVENT_LOCK))375 mode |= 0200;376 break;377 case hwmon_temp_crit:378 if (!(config & JC42_CFG_TCRIT_LOCK))379 mode |= 0200;380 break;381 case hwmon_temp_crit_hyst:382 if (!(config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK)))383 mode |= 0200;384 break;385 case hwmon_temp_input:386 case hwmon_temp_max_hyst:387 case hwmon_temp_min_alarm:388 case hwmon_temp_max_alarm:389 case hwmon_temp_crit_alarm:390 break;391 default:392 mode = 0;393 break;394 }395 return mode;396}397 398/* Return 0 if detection is successful, -ENODEV otherwise */399static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info)400{401 struct i2c_adapter *adapter = client->adapter;402 int i, config, cap, manid, devid;403 404 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |405 I2C_FUNC_SMBUS_WORD_DATA))406 return -ENODEV;407 408 cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP);409 config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG);410 manid = i2c_smbus_read_word_swapped(client, JC42_REG_MANID);411 devid = i2c_smbus_read_word_swapped(client, JC42_REG_DEVICEID);412 413 if (cap < 0 || config < 0 || manid < 0 || devid < 0)414 return -ENODEV;415 416 if ((cap & 0xff00) || (config & 0xf820))417 return -ENODEV;418 419 if ((devid & TSE2004_DEVID_MASK) == TSE2004_DEVID &&420 (cap & 0x0062) != 0x0062)421 return -ENODEV;422 423 for (i = 0; i < ARRAY_SIZE(jc42_chips); i++) {424 struct jc42_chips *chip = &jc42_chips[i];425 if (manid == chip->manid &&426 (devid & chip->devid_mask) == chip->devid) {427 strscpy(info->type, "jc42", I2C_NAME_SIZE);428 return 0;429 }430 }431 return -ENODEV;432}433 434static const struct hwmon_channel_info * const jc42_info[] = {435 HWMON_CHANNEL_INFO(chip,436 HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL),437 HWMON_CHANNEL_INFO(temp,438 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |439 HWMON_T_CRIT | HWMON_T_MAX_HYST |440 HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |441 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM),442 NULL443};444 445static const struct hwmon_ops jc42_hwmon_ops = {446 .is_visible = jc42_is_visible,447 .read = jc42_read,448 .write = jc42_write,449};450 451static const struct hwmon_chip_info jc42_chip_info = {452 .ops = &jc42_hwmon_ops,453 .info = jc42_info,454};455 456static bool jc42_readable_reg(struct device *dev, unsigned int reg)457{458 return (reg >= JC42_REG_CAP && reg <= JC42_REG_DEVICEID) ||459 reg == JC42_REG_SMBUS;460}461 462static bool jc42_writable_reg(struct device *dev, unsigned int reg)463{464 return (reg >= JC42_REG_CONFIG && reg <= JC42_REG_TEMP_CRITICAL) ||465 reg == JC42_REG_SMBUS;466}467 468static bool jc42_volatile_reg(struct device *dev, unsigned int reg)469{470 return reg == JC42_REG_CONFIG || reg == JC42_REG_TEMP;471}472 473static const struct regmap_config jc42_regmap_config = {474 .reg_bits = 8,475 .val_bits = 16,476 .val_format_endian = REGMAP_ENDIAN_BIG,477 .max_register = JC42_REG_SMBUS,478 .writeable_reg = jc42_writable_reg,479 .readable_reg = jc42_readable_reg,480 .volatile_reg = jc42_volatile_reg,481 .cache_type = REGCACHE_MAPLE,482};483 484static int jc42_probe(struct i2c_client *client)485{486 struct device *dev = &client->dev;487 struct device *hwmon_dev;488 unsigned int config, cap;489 struct jc42_data *data;490 int ret;491 492 data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL);493 if (!data)494 return -ENOMEM;495 496 data->regmap = devm_regmap_init_i2c(client, &jc42_regmap_config);497 if (IS_ERR(data->regmap))498 return PTR_ERR(data->regmap);499 500 i2c_set_clientdata(client, data);501 mutex_init(&data->update_lock);502 503 ret = regmap_read(data->regmap, JC42_REG_CAP, &cap);504 if (ret)505 return ret;506 507 data->extended = !!(cap & JC42_CAP_RANGE);508 509 if (device_property_read_bool(dev, "smbus-timeout-disable")) {510 /*511 * Not all chips support this register, but from a512 * quick read of various datasheets no chip appears513 * incompatible with the below attempt to disable514 * the timeout. And the whole thing is opt-in...515 */516 ret = regmap_set_bits(data->regmap, JC42_REG_SMBUS,517 SMBUS_STMOUT);518 if (ret)519 return ret;520 }521 522 ret = regmap_read(data->regmap, JC42_REG_CONFIG, &config);523 if (ret)524 return ret;525 526 data->orig_config = config;527 if (config & JC42_CFG_SHUTDOWN) {528 config &= ~JC42_CFG_SHUTDOWN;529 regmap_write(data->regmap, JC42_REG_CONFIG, config);530 }531 data->config = config;532 533 hwmon_dev = devm_hwmon_device_register_with_info(dev, "jc42",534 data, &jc42_chip_info,535 NULL);536 return PTR_ERR_OR_ZERO(hwmon_dev);537}538 539static void jc42_remove(struct i2c_client *client)540{541 struct jc42_data *data = i2c_get_clientdata(client);542 543 /* Restore original configuration except hysteresis */544 if ((data->config & ~JC42_CFG_HYST_MASK) !=545 (data->orig_config & ~JC42_CFG_HYST_MASK)) {546 int config;547 548 config = (data->orig_config & ~JC42_CFG_HYST_MASK)549 | (data->config & JC42_CFG_HYST_MASK);550 regmap_write(data->regmap, JC42_REG_CONFIG, config);551 }552}553 554#ifdef CONFIG_PM555 556static int jc42_suspend(struct device *dev)557{558 struct jc42_data *data = dev_get_drvdata(dev);559 560 data->config |= JC42_CFG_SHUTDOWN;561 regmap_write(data->regmap, JC42_REG_CONFIG, data->config);562 563 regcache_cache_only(data->regmap, true);564 regcache_mark_dirty(data->regmap);565 566 return 0;567}568 569static int jc42_resume(struct device *dev)570{571 struct jc42_data *data = dev_get_drvdata(dev);572 573 regcache_cache_only(data->regmap, false);574 575 data->config &= ~JC42_CFG_SHUTDOWN;576 regmap_write(data->regmap, JC42_REG_CONFIG, data->config);577 578 /* Restore cached register values to hardware */579 return regcache_sync(data->regmap);580}581 582static const struct dev_pm_ops jc42_dev_pm_ops = {583 .suspend = jc42_suspend,584 .resume = jc42_resume,585};586 587#define JC42_DEV_PM_OPS (&jc42_dev_pm_ops)588#else589#define JC42_DEV_PM_OPS NULL590#endif /* CONFIG_PM */591 592static const struct i2c_device_id jc42_id[] = {593 { "jc42" },594 { }595};596MODULE_DEVICE_TABLE(i2c, jc42_id);597 598#ifdef CONFIG_OF599static const struct of_device_id jc42_of_ids[] = {600 { .compatible = "jedec,jc-42.4-temp", },601 { }602};603MODULE_DEVICE_TABLE(of, jc42_of_ids);604#endif605 606static struct i2c_driver jc42_driver = {607 .class = I2C_CLASS_HWMON,608 .driver = {609 .name = "jc42",610 .pm = JC42_DEV_PM_OPS,611 .of_match_table = of_match_ptr(jc42_of_ids),612 },613 .probe = jc42_probe,614 .remove = jc42_remove,615 .id_table = jc42_id,616 .detect = jc42_detect,617 .address_list = normal_i2c,618};619 620module_i2c_driver(jc42_driver);621 622MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");623MODULE_DESCRIPTION("JC42 driver");624MODULE_LICENSE("GPL");625