Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (emc1403) Add support for EMC1428 and EMC1438.

EMC1428 and EMC1438 are similar to EMC14xx, but have eight temperature
channels, as well as signed data and limit registers. Chips currently
supported by this driver have unsigned registers only.

Signed-off-by: Lars Petter Mostad <larspm@gmail.com>
Link: https://lore.kernel.org/r/20240510142824.824332-1-lars.petter.mostad@appear.net
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Lars Petter Mostad and committed by
Guenter Roeck
c8233784 2fa36597

+124 -14
+14 -3
Documentation/hwmon/emc1403.rst
··· 45 45 46 46 - https://ww1.microchip.com/downloads/en/DeviceDoc/1423_1424.pdf 47 47 48 + * SMSC / Microchip EMC1428, EMC1438 49 + 50 + Addresses scanned: I2C 0x18, 0x4c, 0x4d 51 + 52 + Prefix: 'emc1428', 'emc1438' 53 + 54 + Datasheets: 55 + 56 + - https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005275A.pdf 57 + - https://ww1.microchip.com/downloads/en/DeviceDoc/EMC1438%20DS%20Rev.%201.0%20(04-29-10).pdf 58 + 48 59 Author: 49 60 Kalhan Trisal <kalhan.trisal@intel.com 50 61 ··· 64 53 ----------- 65 54 66 55 The Standard Microsystems Corporation (SMSC) / Microchip EMC14xx chips 67 - contain up to four temperature sensors. EMC14x2 support two sensors 56 + contain up to eight temperature sensors. EMC14x2 support two sensors 68 57 (one internal, one external). EMC14x3 support three sensors (one internal, 69 - two external), and EMC14x4 support four sensors (one internal, three 70 - external). 58 + two external), EMC14x4 support four sensors (one internal, three external), 59 + and EMC14x8 support eight sensors (one internal, seven external). 71 60 72 61 The chips implement three limits for each sensor: low (tempX_min), high 73 62 (tempX_max) and critical (tempX_crit.) The chips also implement an
+110 -11
drivers/hwmon/emc1403.c
··· 25 25 #define THERMAL_SMSC_ID_REG 0xfe 26 26 #define THERMAL_REVISION_REG 0xff 27 27 28 - enum emc1403_chip { emc1402, emc1403, emc1404 }; 28 + enum emc1403_chip { emc1402, emc1403, emc1404, emc1428 }; 29 29 30 30 struct thermal_data { 31 31 enum emc1403_chip chip; ··· 100 100 case 0x27: 101 101 strscpy(info->type, "emc1424", I2C_NAME_SIZE); 102 102 break; 103 + case 0x29: 104 + strscpy(info->type, "emc1428", I2C_NAME_SIZE); 105 + break; 106 + case 0x59: 107 + strscpy(info->type, "emc1438", I2C_NAME_SIZE); 108 + break; 103 109 case 0x60: 104 110 strscpy(info->type, "emc1442", I2C_NAME_SIZE); 105 111 break; ··· 136 130 case 0x35: /* high limit status */ 137 131 case 0x36: /* low limit status */ 138 132 case 0x37: /* therm limit status */ 133 + case 0x41: /* external diode 4 high byte */ 134 + case 0x42: /* external diode 4 low byte */ 135 + case 0x43: /* external diode 5 high byte */ 136 + case 0x44: /* external diode 5 low byte */ 137 + case 0x45: /* external diode 6 high byte */ 138 + case 0x46: /* external diode 6 low byte */ 139 + case 0x47: /* external diode 7 high byte */ 140 + case 0x48: /* external diode 7 low byte */ 139 141 return true; 140 142 default: 141 143 return false; ··· 191 177 [temp_crit] = 0x30, 192 178 [temp_input] = 0x2a, 193 179 }, 180 + [4] = { 181 + [temp_min] = 0x51, 182 + [temp_max] = 0x50, 183 + [temp_crit] = 0x64, 184 + [temp_input] = 0x41, 185 + }, 186 + [5] = { 187 + [temp_min] = 0x55, 188 + [temp_max] = 0x54, 189 + [temp_crit] = 0x65, 190 + [temp_input] = 0x43 191 + }, 192 + [6] = { 193 + [temp_min] = 0x59, 194 + [temp_max] = 0x58, 195 + [temp_crit] = 0x66, 196 + [temp_input] = 0x45, 197 + }, 198 + [7] = { 199 + [temp_min] = 0x5d, 200 + [temp_max] = 0x5c, 201 + [temp_crit] = 0x67, 202 + [temp_input] = 0x47, 203 + }, 194 204 }; 195 205 196 206 static s8 emc1403_temp_regs_low[][4] = { ··· 242 204 [temp_crit] = -1, 243 205 [temp_input] = 0x2b, 244 206 }, 207 + [4] = { 208 + [temp_min] = 0x53, 209 + [temp_max] = 0x52, 210 + [temp_crit] = -1, 211 + [temp_input] = 0x42, 212 + }, 213 + [5] = { 214 + [temp_min] = 0x57, 215 + [temp_max] = 0x56, 216 + [temp_crit] = -1, 217 + [temp_input] = 0x44, 218 + }, 219 + [6] = { 220 + [temp_min] = 0x5b, 221 + [temp_max] = 0x5a, 222 + [temp_crit] = -1, 223 + [temp_input] = 0x46, 224 + }, 225 + [7] = { 226 + [temp_min] = 0x5f, 227 + [temp_max] = 0x5e, 228 + [temp_crit] = -1, 229 + [temp_input] = 0x48, 230 + }, 245 231 }; 246 232 247 233 static int __emc1403_get_temp(struct thermal_data *data, int channel, 248 234 enum emc1403_reg_map map, long *val) 249 235 { 250 - unsigned int regval; 236 + unsigned int regvalh; 237 + unsigned int regvall = 0; 251 238 int ret; 252 239 s8 reg; 253 240 254 - ret = regmap_read(data->regmap, emc1403_temp_regs[channel][map], &regval); 241 + ret = regmap_read(data->regmap, emc1403_temp_regs[channel][map], &regvalh); 255 242 if (ret < 0) 256 243 return ret; 257 - *val = regval * 1000; 258 244 259 245 reg = emc1403_temp_regs_low[channel][map]; 260 246 if (reg >= 0) { 261 - ret = regmap_read(data->regmap, reg, &regval); 247 + ret = regmap_read(data->regmap, reg, &regvall); 262 248 if (ret < 0) 263 249 return ret; 264 - *val += (regval >> 5) * 125; 265 250 } 251 + 252 + if (data->chip == emc1428) 253 + *val = sign_extend32((regvalh << 3) | (regvall >> 5), 10) * 125; 254 + else 255 + *val = ((regvalh << 3) | (regvall >> 5)) * 125; 256 + 266 257 return 0; 267 258 } 268 259 ··· 446 379 int hyst, ret; 447 380 long limit; 448 381 449 - val = clamp_val(val, 0, 255000); 382 + if (data->chip == emc1428) 383 + val = clamp_val(val, -128000, 127000); 384 + else 385 + val = clamp_val(val, 0, 255000); 450 386 451 387 mutex_lock(&data->mutex); 452 388 ret = __emc1403_get_temp(data, 0, temp_crit, &limit); ··· 457 387 goto unlock; 458 388 459 389 hyst = limit - val; 460 - hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 255); 390 + if (data->chip == emc1428) 391 + hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 127); 392 + else 393 + hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 255); 461 394 ret = regmap_write(data->regmap, 0x21, hyst); 462 395 unlock: 463 396 mutex_unlock(&data->mutex); ··· 480 407 481 408 mutex_lock(&data->mutex); 482 409 if (regl >= 0) { 483 - val = clamp_val(val, 0, 255875); 410 + if (data->chip == emc1428) 411 + val = clamp_val(val, -128000, 127875); 412 + else 413 + val = clamp_val(val, 0, 255875); 484 414 regval = DIV_ROUND_CLOSEST(val, 125); 485 - ret = regmap_write(data->regmap, regh, regval >> 3); 415 + ret = regmap_write(data->regmap, regh, (regval >> 3) & 0xff); 486 416 if (ret < 0) 487 417 goto unlock; 488 418 ret = regmap_write(data->regmap, regl, (regval & 0x07) << 5); 489 419 } else { 490 - val = clamp_val(val, 0, 255000); 420 + if (data->chip == emc1428) 421 + val = clamp_val(val, -128000, 127000); 422 + else 423 + val = clamp_val(val, 0, 255000); 491 424 regval = DIV_ROUND_CLOSEST(val, 1000); 492 425 ret = regmap_write(data->regmap, regh, regval); 493 426 } ··· 563 484 return 0; 564 485 if (data->chip == emc1403 && channel > 2) 565 486 return 0; 487 + if (data->chip != emc1428 && channel > 3) 488 + return 0; 566 489 567 490 switch (attr) { 568 491 case hwmon_temp_input: ··· 629 548 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 630 549 HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST | 631 550 HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | 551 + HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT, 552 + HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 553 + HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST | 554 + HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | 555 + HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT, 556 + HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 557 + HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST | 558 + HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | 559 + HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT, 560 + HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 561 + HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST | 562 + HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | 563 + HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT, 564 + HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | 565 + HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST | 566 + HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | 632 567 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT 633 568 ), 634 569 NULL ··· 672 575 { "emc1422", emc1402 }, 673 576 { "emc1423", emc1403 }, 674 577 { "emc1424", emc1404 }, 578 + { "emc1428", emc1428 }, 579 + { "emc1438", emc1428 }, 675 580 { "emc1442", emc1402 }, 676 581 { } 677 582 };