663 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/***************************************************************************3 * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> *4 * *5 ***************************************************************************/6 7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt8 9#include <linux/bits.h>10#include <linux/minmax.h>11#include <linux/module.h>12#include <linux/mod_devicetable.h>13#include <linux/pm.h>14#include <linux/init.h>15#include <linux/regmap.h>16#include <linux/slab.h>17#include <linux/jiffies.h>18#include <linux/platform_device.h>19#include <linux/hwmon.h>20#include <linux/err.h>21#include <linux/mutex.h>22#include "sch56xx-common.h"23 24#define DRVNAME "sch5627"25#define DEVNAME DRVNAME /* We only support one model */26 27#define SCH5627_HWMON_ID 0xa528#define SCH5627_COMPANY_ID 0x5c29#define SCH5627_PRIMARY_ID 0xa030 31#define SCH5627_REG_BUILD_CODE 0x3932#define SCH5627_REG_BUILD_ID 0x3a33#define SCH5627_REG_HWMON_ID 0x3c34#define SCH5627_REG_HWMON_REV 0x3d35#define SCH5627_REG_COMPANY_ID 0x3e36#define SCH5627_REG_PRIMARY_ID 0x3f37#define SCH5627_REG_CTRL 0x4038 39#define SCH5627_CTRL_START BIT(0)40#define SCH5627_CTRL_LOCK BIT(1)41#define SCH5627_CTRL_VBAT BIT(4)42 43#define SCH5627_NO_TEMPS 844#define SCH5627_NO_FANS 445#define SCH5627_NO_IN 546 47static const u16 SCH5627_REG_TEMP_MSB[SCH5627_NO_TEMPS] = {48 0x2B, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x180, 0x181 };49static const u16 SCH5627_REG_TEMP_LSN[SCH5627_NO_TEMPS] = {50 0xE2, 0xE1, 0xE1, 0xE5, 0xE5, 0xE6, 0x182, 0x182 };51static const u16 SCH5627_REG_TEMP_HIGH_NIBBLE[SCH5627_NO_TEMPS] = {52 0, 0, 1, 1, 0, 0, 0, 1 };53static const u16 SCH5627_REG_TEMP_HIGH[SCH5627_NO_TEMPS] = {54 0x61, 0x57, 0x59, 0x5B, 0x5D, 0x5F, 0x184, 0x186 };55static const u16 SCH5627_REG_TEMP_ABS[SCH5627_NO_TEMPS] = {56 0x9B, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x1A8, 0x1A9 };57 58static const u16 SCH5627_REG_FAN[SCH5627_NO_FANS] = {59 0x2C, 0x2E, 0x30, 0x32 };60static const u16 SCH5627_REG_FAN_MIN[SCH5627_NO_FANS] = {61 0x62, 0x64, 0x66, 0x68 };62 63static const u16 SCH5627_REG_PWM_MAP[SCH5627_NO_FANS] = {64 0xA0, 0xA1, 0xA2, 0xA3 };65 66static const u16 SCH5627_REG_IN_MSB[SCH5627_NO_IN] = {67 0x22, 0x23, 0x24, 0x25, 0x189 };68static const u16 SCH5627_REG_IN_LSN[SCH5627_NO_IN] = {69 0xE4, 0xE4, 0xE3, 0xE3, 0x18A };70static const u16 SCH5627_REG_IN_HIGH_NIBBLE[SCH5627_NO_IN] = {71 1, 0, 1, 0, 1 };72static const u16 SCH5627_REG_IN_FACTOR[SCH5627_NO_IN] = {73 10745, 3660, 9765, 10745, 3660 };74static const char * const SCH5627_IN_LABELS[SCH5627_NO_IN] = {75 "VCC", "VTT", "VBAT", "VTR", "V_IN" };76 77struct sch5627_data {78 struct regmap *regmap;79 unsigned short addr;80 u8 control;81 82 struct mutex update_lock;83 unsigned long last_battery; /* In jiffies */84 char temp_valid; /* !=0 if following fields are valid */85 char fan_valid;86 char in_valid;87 unsigned long temp_last_updated; /* In jiffies */88 unsigned long fan_last_updated;89 unsigned long in_last_updated;90 u16 temp[SCH5627_NO_TEMPS];91 u16 fan[SCH5627_NO_FANS];92 u16 in[SCH5627_NO_IN];93};94 95static const struct regmap_range sch5627_tunables_ranges[] = {96 regmap_reg_range(0x57, 0x57),97 regmap_reg_range(0x59, 0x59),98 regmap_reg_range(0x5B, 0x5B),99 regmap_reg_range(0x5D, 0x5D),100 regmap_reg_range(0x5F, 0x5F),101 regmap_reg_range(0x61, 0x69),102 regmap_reg_range(0x96, 0x9B),103 regmap_reg_range(0xA0, 0xA3),104 regmap_reg_range(0x184, 0x184),105 regmap_reg_range(0x186, 0x186),106 regmap_reg_range(0x1A8, 0x1A9),107};108 109static const struct regmap_access_table sch5627_tunables_table = {110 .yes_ranges = sch5627_tunables_ranges,111 .n_yes_ranges = ARRAY_SIZE(sch5627_tunables_ranges),112};113 114static const struct regmap_config sch5627_regmap_config = {115 .reg_bits = 16,116 .val_bits = 8,117 .wr_table = &sch5627_tunables_table,118 .rd_table = &sch5627_tunables_table,119 .cache_type = REGCACHE_MAPLE,120 .use_single_read = true,121 .use_single_write = true,122 .can_sleep = true,123};124 125static int sch5627_update_temp(struct sch5627_data *data)126{127 int ret = 0;128 int i, val;129 130 mutex_lock(&data->update_lock);131 132 /* Cache the values for 1 second */133 if (time_after(jiffies, data->temp_last_updated + HZ) || !data->temp_valid) {134 for (i = 0; i < SCH5627_NO_TEMPS; i++) {135 val = sch56xx_read_virtual_reg12(data->addr, SCH5627_REG_TEMP_MSB[i],136 SCH5627_REG_TEMP_LSN[i],137 SCH5627_REG_TEMP_HIGH_NIBBLE[i]);138 if (unlikely(val < 0)) {139 ret = val;140 goto abort;141 }142 data->temp[i] = val;143 }144 data->temp_last_updated = jiffies;145 data->temp_valid = 1;146 }147abort:148 mutex_unlock(&data->update_lock);149 return ret;150}151 152static int sch5627_update_fan(struct sch5627_data *data)153{154 int ret = 0;155 int i, val;156 157 mutex_lock(&data->update_lock);158 159 /* Cache the values for 1 second */160 if (time_after(jiffies, data->fan_last_updated + HZ) || !data->fan_valid) {161 for (i = 0; i < SCH5627_NO_FANS; i++) {162 val = sch56xx_read_virtual_reg16(data->addr, SCH5627_REG_FAN[i]);163 if (unlikely(val < 0)) {164 ret = val;165 goto abort;166 }167 data->fan[i] = val;168 }169 data->fan_last_updated = jiffies;170 data->fan_valid = 1;171 }172abort:173 mutex_unlock(&data->update_lock);174 return ret;175}176 177static int sch5627_update_in(struct sch5627_data *data)178{179 int ret = 0;180 int i, val;181 182 mutex_lock(&data->update_lock);183 184 /* Trigger a Vbat voltage measurement every 5 minutes */185 if (time_after(jiffies, data->last_battery + 300 * HZ)) {186 sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL,187 data->control | SCH5627_CTRL_VBAT);188 data->last_battery = jiffies;189 }190 191 /* Cache the values for 1 second */192 if (time_after(jiffies, data->in_last_updated + HZ) || !data->in_valid) {193 for (i = 0; i < SCH5627_NO_IN; i++) {194 val = sch56xx_read_virtual_reg12(data->addr, SCH5627_REG_IN_MSB[i],195 SCH5627_REG_IN_LSN[i],196 SCH5627_REG_IN_HIGH_NIBBLE[i]);197 if (unlikely(val < 0)) {198 ret = val;199 goto abort;200 }201 data->in[i] = val;202 }203 data->in_last_updated = jiffies;204 data->in_valid = 1;205 }206abort:207 mutex_unlock(&data->update_lock);208 return ret;209}210 211static int reg_to_temp(u16 reg)212{213 return (reg * 625) / 10 - 64000;214}215 216static int reg_to_temp_limit(u8 reg)217{218 return (reg - 64) * 1000;219}220 221static int reg_to_rpm(u16 reg)222{223 if (reg == 0)224 return -EIO;225 if (reg == 0xffff)226 return 0;227 228 return 5400540 / reg;229}230 231static u8 sch5627_temp_limit_to_reg(long value)232{233 long limit = (value / 1000) + 64;234 235 return clamp_val(limit, 0, U8_MAX);236}237 238static u16 sch5627_rpm_to_reg(long value)239{240 long pulses;241 242 if (value <= 0)243 return U16_MAX - 1;244 245 pulses = 5400540 / value;246 247 return clamp_val(pulses, 1, U16_MAX - 1);248}249 250static umode_t sch5627_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,251 int channel)252{253 const struct sch5627_data *data = drvdata;254 255 /* Once the lock bit is set, the virtual registers become read-only256 * until the next power cycle.257 */258 if (data->control & SCH5627_CTRL_LOCK)259 return 0444;260 261 switch (type) {262 case hwmon_temp:263 switch (attr) {264 case hwmon_temp_max:265 case hwmon_temp_crit:266 return 0644;267 default:268 break;269 }270 break;271 case hwmon_fan:272 switch (attr) {273 case hwmon_fan_min:274 return 0644;275 default:276 break;277 }278 break;279 case hwmon_pwm:280 switch (attr) {281 case hwmon_pwm_auto_channels_temp:282 return 0644;283 default:284 break;285 }286 break;287 default:288 break;289 }290 291 return 0444;292}293 294static int sch5627_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,295 long *val)296{297 struct sch5627_data *data = dev_get_drvdata(dev);298 int ret, value;299 300 switch (type) {301 case hwmon_temp:302 switch (attr) {303 case hwmon_temp_input:304 ret = sch5627_update_temp(data);305 if (ret < 0)306 return ret;307 308 *val = reg_to_temp(data->temp[channel]);309 return 0;310 case hwmon_temp_max:311 ret = regmap_read(data->regmap, SCH5627_REG_TEMP_ABS[channel], &value);312 if (ret < 0)313 return ret;314 315 *val = reg_to_temp_limit((u8)value);316 return 0;317 case hwmon_temp_crit:318 ret = regmap_read(data->regmap, SCH5627_REG_TEMP_HIGH[channel], &value);319 if (ret < 0)320 return ret;321 322 *val = reg_to_temp_limit((u8)value);323 return 0;324 case hwmon_temp_fault:325 ret = sch5627_update_temp(data);326 if (ret < 0)327 return ret;328 329 *val = (data->temp[channel] == 0);330 return 0;331 default:332 break;333 }334 break;335 case hwmon_fan:336 switch (attr) {337 case hwmon_fan_input:338 ret = sch5627_update_fan(data);339 if (ret < 0)340 return ret;341 342 ret = reg_to_rpm(data->fan[channel]);343 if (ret < 0)344 return ret;345 346 *val = ret;347 return 0;348 case hwmon_fan_min:349 ret = sch56xx_regmap_read16(data->regmap, SCH5627_REG_FAN_MIN[channel],350 &value);351 if (ret < 0)352 return ret;353 354 ret = reg_to_rpm((u16)value);355 if (ret < 0)356 return ret;357 358 *val = ret;359 return 0;360 case hwmon_fan_fault:361 ret = sch5627_update_fan(data);362 if (ret < 0)363 return ret;364 365 *val = (data->fan[channel] == 0xffff);366 return 0;367 default:368 break;369 }370 break;371 case hwmon_pwm:372 switch (attr) {373 case hwmon_pwm_auto_channels_temp:374 ret = regmap_read(data->regmap, SCH5627_REG_PWM_MAP[channel], &value);375 if (ret < 0)376 return ret;377 378 *val = value;379 return 0;380 default:381 break;382 }383 break;384 case hwmon_in:385 ret = sch5627_update_in(data);386 if (ret < 0)387 return ret;388 switch (attr) {389 case hwmon_in_input:390 *val = DIV_ROUND_CLOSEST(data->in[channel] * SCH5627_REG_IN_FACTOR[channel],391 10000);392 return 0;393 default:394 break;395 }396 break;397 default:398 break;399 }400 401 return -EOPNOTSUPP;402}403 404static int sch5627_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,405 int channel, const char **str)406{407 switch (type) {408 case hwmon_in:409 switch (attr) {410 case hwmon_in_label:411 *str = SCH5627_IN_LABELS[channel];412 return 0;413 default:414 break;415 }416 break;417 default:418 break;419 }420 421 return -EOPNOTSUPP;422}423 424static int sch5627_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,425 long val)426{427 struct sch5627_data *data = dev_get_drvdata(dev);428 u16 fan;429 u8 temp;430 431 switch (type) {432 case hwmon_temp:433 temp = sch5627_temp_limit_to_reg(val);434 435 switch (attr) {436 case hwmon_temp_max:437 return regmap_write(data->regmap, SCH5627_REG_TEMP_ABS[channel], temp);438 case hwmon_temp_crit:439 return regmap_write(data->regmap, SCH5627_REG_TEMP_HIGH[channel], temp);440 default:441 break;442 }443 break;444 case hwmon_fan:445 switch (attr) {446 case hwmon_fan_min:447 fan = sch5627_rpm_to_reg(val);448 449 return sch56xx_regmap_write16(data->regmap, SCH5627_REG_FAN_MIN[channel],450 fan);451 default:452 break;453 }454 break;455 case hwmon_pwm:456 switch (attr) {457 case hwmon_pwm_auto_channels_temp:458 /* registers are 8 bit wide */459 if (val > U8_MAX || val < 0)460 return -EINVAL;461 462 return regmap_write(data->regmap, SCH5627_REG_PWM_MAP[channel], val);463 default:464 break;465 }466 break;467 default:468 break;469 }470 471 return -EOPNOTSUPP;472}473 474static const struct hwmon_ops sch5627_ops = {475 .is_visible = sch5627_is_visible,476 .read = sch5627_read,477 .read_string = sch5627_read_string,478 .write = sch5627_write,479};480 481static const struct hwmon_channel_info * const sch5627_info[] = {482 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),483 HWMON_CHANNEL_INFO(temp,484 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT,485 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT,486 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT,487 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT,488 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT,489 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT,490 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT,491 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT492 ),493 HWMON_CHANNEL_INFO(fan,494 HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT,495 HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT,496 HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT,497 HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT498 ),499 HWMON_CHANNEL_INFO(pwm,500 HWMON_PWM_AUTO_CHANNELS_TEMP,501 HWMON_PWM_AUTO_CHANNELS_TEMP,502 HWMON_PWM_AUTO_CHANNELS_TEMP,503 HWMON_PWM_AUTO_CHANNELS_TEMP504 ),505 HWMON_CHANNEL_INFO(in,506 HWMON_I_INPUT | HWMON_I_LABEL,507 HWMON_I_INPUT | HWMON_I_LABEL,508 HWMON_I_INPUT | HWMON_I_LABEL,509 HWMON_I_INPUT | HWMON_I_LABEL,510 HWMON_I_INPUT511 ),512 NULL513};514 515static const struct hwmon_chip_info sch5627_chip_info = {516 .ops = &sch5627_ops,517 .info = sch5627_info,518};519 520static int sch5627_probe(struct platform_device *pdev)521{522 struct sch5627_data *data;523 struct device *hwmon_dev;524 int build_code, build_id, hwmon_rev, val;525 526 data = devm_kzalloc(&pdev->dev, sizeof(struct sch5627_data),527 GFP_KERNEL);528 if (!data)529 return -ENOMEM;530 531 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;532 mutex_init(&data->update_lock);533 platform_set_drvdata(pdev, data);534 535 val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_HWMON_ID);536 if (val < 0)537 return val;538 539 if (val != SCH5627_HWMON_ID) {540 pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "hwmon",541 val, SCH5627_HWMON_ID);542 return -ENODEV;543 }544 545 val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_COMPANY_ID);546 if (val < 0)547 return val;548 549 if (val != SCH5627_COMPANY_ID) {550 pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "company",551 val, SCH5627_COMPANY_ID);552 return -ENODEV;553 }554 555 val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_PRIMARY_ID);556 if (val < 0)557 return val;558 559 if (val != SCH5627_PRIMARY_ID) {560 pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "primary",561 val, SCH5627_PRIMARY_ID);562 return -ENODEV;563 }564 565 build_code = sch56xx_read_virtual_reg(data->addr,566 SCH5627_REG_BUILD_CODE);567 if (build_code < 0)568 return build_code;569 570 build_id = sch56xx_read_virtual_reg16(data->addr,571 SCH5627_REG_BUILD_ID);572 if (build_id < 0)573 return build_id;574 575 hwmon_rev = sch56xx_read_virtual_reg(data->addr,576 SCH5627_REG_HWMON_REV);577 if (hwmon_rev < 0)578 return hwmon_rev;579 580 val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_CTRL);581 if (val < 0)582 return val;583 584 data->control = val;585 if (!(data->control & SCH5627_CTRL_START)) {586 pr_err("hardware monitoring not enabled\n");587 return -ENODEV;588 }589 590 data->regmap = devm_regmap_init_sch56xx(&pdev->dev, &data->update_lock, data->addr,591 &sch5627_regmap_config);592 if (IS_ERR(data->regmap))593 return PTR_ERR(data->regmap);594 595 /* Trigger a Vbat voltage measurement, so that we get a valid reading596 the first time we read Vbat */597 sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | SCH5627_CTRL_VBAT);598 data->last_battery = jiffies;599 600 pr_info("found %s chip at %#hx\n", DEVNAME, data->addr);601 pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n",602 build_code, build_id, hwmon_rev);603 604 hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, DEVNAME, data,605 &sch5627_chip_info, NULL);606 if (IS_ERR(hwmon_dev))607 return PTR_ERR(hwmon_dev);608 609 /* Note failing to register the watchdog is not a fatal error */610 sch56xx_watchdog_register(&pdev->dev, data->addr,611 (build_code << 24) | (build_id << 8) | hwmon_rev,612 &data->update_lock, 1);613 614 return 0;615}616 617static int sch5627_suspend(struct device *dev)618{619 struct sch5627_data *data = dev_get_drvdata(dev);620 621 regcache_cache_only(data->regmap, true);622 regcache_mark_dirty(data->regmap);623 624 return 0;625}626 627static int sch5627_resume(struct device *dev)628{629 struct sch5627_data *data = dev_get_drvdata(dev);630 631 regcache_cache_only(data->regmap, false);632 /* We must not access the virtual registers when the lock bit is set */633 if (data->control & SCH5627_CTRL_LOCK)634 return regcache_drop_region(data->regmap, 0, U16_MAX);635 636 return regcache_sync(data->regmap);637}638 639static DEFINE_SIMPLE_DEV_PM_OPS(sch5627_dev_pm_ops, sch5627_suspend, sch5627_resume);640 641static const struct platform_device_id sch5627_device_id[] = {642 {643 .name = "sch5627",644 },645 { }646};647MODULE_DEVICE_TABLE(platform, sch5627_device_id);648 649static struct platform_driver sch5627_driver = {650 .driver = {651 .name = DRVNAME,652 .pm = pm_sleep_ptr(&sch5627_dev_pm_ops),653 },654 .probe = sch5627_probe,655 .id_table = sch5627_device_id,656};657 658module_platform_driver(sch5627_driver);659 660MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");661MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");662MODULE_LICENSE("GPL");663