^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /***************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) ***************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "sch56xx-common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define DRVNAME "sch5627"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define DEVNAME DRVNAME /* We only support one model */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define SCH5627_HWMON_ID 0xa5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define SCH5627_COMPANY_ID 0x5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define SCH5627_PRIMARY_ID 0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SCH5627_REG_BUILD_CODE 0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SCH5627_REG_BUILD_ID 0x3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SCH5627_REG_HWMON_ID 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SCH5627_REG_HWMON_REV 0x3d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SCH5627_REG_COMPANY_ID 0x3e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SCH5627_REG_PRIMARY_ID 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SCH5627_REG_CTRL 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define SCH5627_NO_TEMPS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define SCH5627_NO_FANS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SCH5627_NO_IN 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static const u16 SCH5627_REG_TEMP_MSB[SCH5627_NO_TEMPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 0x2B, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x180, 0x181 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static const u16 SCH5627_REG_TEMP_LSN[SCH5627_NO_TEMPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 0xE2, 0xE1, 0xE1, 0xE5, 0xE5, 0xE6, 0x182, 0x182 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static const u16 SCH5627_REG_TEMP_HIGH_NIBBLE[SCH5627_NO_TEMPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 0, 0, 1, 1, 0, 0, 0, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static const u16 SCH5627_REG_TEMP_HIGH[SCH5627_NO_TEMPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 0x61, 0x57, 0x59, 0x5B, 0x5D, 0x5F, 0x184, 0x186 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static const u16 SCH5627_REG_TEMP_ABS[SCH5627_NO_TEMPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 0x9B, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x1A8, 0x1A9 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static const u16 SCH5627_REG_FAN[SCH5627_NO_FANS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 0x2C, 0x2E, 0x30, 0x32 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static const u16 SCH5627_REG_FAN_MIN[SCH5627_NO_FANS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 0x62, 0x64, 0x66, 0x68 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static const u16 SCH5627_REG_IN_MSB[SCH5627_NO_IN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 0x22, 0x23, 0x24, 0x25, 0x189 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const u16 SCH5627_REG_IN_LSN[SCH5627_NO_IN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 0xE4, 0xE4, 0xE3, 0xE3, 0x18A };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static const u16 SCH5627_REG_IN_HIGH_NIBBLE[SCH5627_NO_IN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 1, 0, 1, 0, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static const u16 SCH5627_REG_IN_FACTOR[SCH5627_NO_IN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 10745, 3660, 9765, 10745, 3660 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static const char * const SCH5627_IN_LABELS[SCH5627_NO_IN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "VCC", "VTT", "VBAT", "VTR", "V_IN" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct sch5627_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned short addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct sch56xx_watchdog_data *watchdog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u8 control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u8 temp_max[SCH5627_NO_TEMPS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u8 temp_crit[SCH5627_NO_TEMPS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u16 fan_min[SCH5627_NO_FANS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned long last_battery; /* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) char valid; /* !=0 if following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned long last_updated; /* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u16 temp[SCH5627_NO_TEMPS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u16 fan[SCH5627_NO_FANS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u16 in[SCH5627_NO_IN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static struct sch5627_data *sch5627_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct sch5627_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct sch5627_data *ret = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int i, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Trigger a Vbat voltage measurement every 5 minutes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (time_after(jiffies, data->last_battery + 300 * HZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) data->control | 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) data->last_battery = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* Cache the values for 1 second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) for (i = 0; i < SCH5627_NO_TEMPS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) val = sch56xx_read_virtual_reg12(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) SCH5627_REG_TEMP_MSB[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) SCH5627_REG_TEMP_LSN[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) SCH5627_REG_TEMP_HIGH_NIBBLE[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (unlikely(val < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ret = ERR_PTR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) data->temp[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) for (i = 0; i < SCH5627_NO_FANS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) val = sch56xx_read_virtual_reg16(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) SCH5627_REG_FAN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (unlikely(val < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = ERR_PTR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) data->fan[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) for (i = 0; i < SCH5627_NO_IN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) val = sch56xx_read_virtual_reg12(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) SCH5627_REG_IN_MSB[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) SCH5627_REG_IN_LSN[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) SCH5627_REG_IN_HIGH_NIBBLE[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (unlikely(val < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = ERR_PTR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) data->in[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) data->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int sch5627_read_limits(struct sch5627_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int i, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) for (i = 0; i < SCH5627_NO_TEMPS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Note what SMSC calls ABS, is what lm_sensors calls max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * (aka high), and HIGH is what lm_sensors calls crit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) val = sch56xx_read_virtual_reg(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) SCH5627_REG_TEMP_ABS[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) data->temp_max[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) val = sch56xx_read_virtual_reg(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) SCH5627_REG_TEMP_HIGH[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) data->temp_crit[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) for (i = 0; i < SCH5627_NO_FANS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) val = sch56xx_read_virtual_reg16(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) SCH5627_REG_FAN_MIN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) data->fan_min[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int reg_to_temp(u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return (reg * 625) / 10 - 64000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int reg_to_temp_limit(u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return (reg - 64) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int reg_to_rpm(u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (reg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (reg == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return 5400540 / reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static ssize_t name_show(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return snprintf(buf, PAGE_SIZE, "%s\n", DEVNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static ssize_t temp_show(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct sch5627_data *data = sch5627_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) val = reg_to_temp(data->temp[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return snprintf(buf, PAGE_SIZE, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static ssize_t temp_fault_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct sch5627_data *data = sch5627_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return snprintf(buf, PAGE_SIZE, "%d\n", data->temp[attr->index] == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static ssize_t temp_max_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct sch5627_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) val = reg_to_temp_limit(data->temp_max[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return snprintf(buf, PAGE_SIZE, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static ssize_t temp_crit_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct sch5627_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) val = reg_to_temp_limit(data->temp_crit[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return snprintf(buf, PAGE_SIZE, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static ssize_t fan_show(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct sch5627_data *data = sch5627_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) val = reg_to_rpm(data->fan[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return snprintf(buf, PAGE_SIZE, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static ssize_t fan_fault_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct sch5627_data *data = sch5627_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return snprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) data->fan[attr->index] == 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static ssize_t fan_min_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct sch5627_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int val = reg_to_rpm(data->fan_min[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return snprintf(buf, PAGE_SIZE, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static ssize_t in_show(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct sch5627_data *data = sch5627_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) val = DIV_ROUND_CLOSEST(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) data->in[attr->index] * SCH5627_REG_IN_FACTOR[attr->index],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return snprintf(buf, PAGE_SIZE, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static ssize_t in_label_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) SCH5627_IN_LABELS[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static DEVICE_ATTR_RO(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static SENSOR_DEVICE_ATTR_RO(temp4_input, temp, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static SENSOR_DEVICE_ATTR_RO(temp5_input, temp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static SENSOR_DEVICE_ATTR_RO(temp6_input, temp, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static SENSOR_DEVICE_ATTR_RO(temp7_input, temp, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static SENSOR_DEVICE_ATTR_RO(temp8_input, temp, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static SENSOR_DEVICE_ATTR_RO(temp1_fault, temp_fault, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static SENSOR_DEVICE_ATTR_RO(temp2_fault, temp_fault, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static SENSOR_DEVICE_ATTR_RO(temp3_fault, temp_fault, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static SENSOR_DEVICE_ATTR_RO(temp4_fault, temp_fault, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static SENSOR_DEVICE_ATTR_RO(temp5_fault, temp_fault, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static SENSOR_DEVICE_ATTR_RO(temp6_fault, temp_fault, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static SENSOR_DEVICE_ATTR_RO(temp7_fault, temp_fault, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static SENSOR_DEVICE_ATTR_RO(temp8_fault, temp_fault, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static SENSOR_DEVICE_ATTR_RO(temp1_max, temp_max, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static SENSOR_DEVICE_ATTR_RO(temp2_max, temp_max, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static SENSOR_DEVICE_ATTR_RO(temp3_max, temp_max, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static SENSOR_DEVICE_ATTR_RO(temp4_max, temp_max, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static SENSOR_DEVICE_ATTR_RO(temp5_max, temp_max, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static SENSOR_DEVICE_ATTR_RO(temp6_max, temp_max, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static SENSOR_DEVICE_ATTR_RO(temp7_max, temp_max, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static SENSOR_DEVICE_ATTR_RO(temp8_max, temp_max, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static SENSOR_DEVICE_ATTR_RO(temp1_crit, temp_crit, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static SENSOR_DEVICE_ATTR_RO(temp2_crit, temp_crit, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static SENSOR_DEVICE_ATTR_RO(temp3_crit, temp_crit, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static SENSOR_DEVICE_ATTR_RO(temp4_crit, temp_crit, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static SENSOR_DEVICE_ATTR_RO(temp5_crit, temp_crit, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static SENSOR_DEVICE_ATTR_RO(temp6_crit, temp_crit, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static SENSOR_DEVICE_ATTR_RO(temp7_crit, temp_crit, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static SENSOR_DEVICE_ATTR_RO(temp8_crit, temp_crit, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static SENSOR_DEVICE_ATTR_RO(fan3_input, fan, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static SENSOR_DEVICE_ATTR_RO(fan4_input, fan, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static SENSOR_DEVICE_ATTR_RO(fan1_fault, fan_fault, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static SENSOR_DEVICE_ATTR_RO(fan2_fault, fan_fault, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static SENSOR_DEVICE_ATTR_RO(fan3_fault, fan_fault, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static SENSOR_DEVICE_ATTR_RO(fan4_fault, fan_fault, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static SENSOR_DEVICE_ATTR_RO(fan1_min, fan_min, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static SENSOR_DEVICE_ATTR_RO(fan2_min, fan_min, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static SENSOR_DEVICE_ATTR_RO(fan3_min, fan_min, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static SENSOR_DEVICE_ATTR_RO(fan4_min, fan_min, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static SENSOR_DEVICE_ATTR_RO(in0_input, in, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static SENSOR_DEVICE_ATTR_RO(in1_input, in, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static SENSOR_DEVICE_ATTR_RO(in2_input, in, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static SENSOR_DEVICE_ATTR_RO(in3_input, in, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static SENSOR_DEVICE_ATTR_RO(in4_input, in, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static SENSOR_DEVICE_ATTR_RO(in0_label, in_label, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static SENSOR_DEVICE_ATTR_RO(in1_label, in_label, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static SENSOR_DEVICE_ATTR_RO(in2_label, in_label, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static SENSOR_DEVICE_ATTR_RO(in3_label, in_label, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static struct attribute *sch5627_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) &dev_attr_name.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) &sensor_dev_attr_temp1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) &sensor_dev_attr_temp2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) &sensor_dev_attr_temp3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) &sensor_dev_attr_temp4_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) &sensor_dev_attr_temp5_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) &sensor_dev_attr_temp6_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) &sensor_dev_attr_temp7_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) &sensor_dev_attr_temp8_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) &sensor_dev_attr_temp1_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) &sensor_dev_attr_temp2_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) &sensor_dev_attr_temp3_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) &sensor_dev_attr_temp4_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) &sensor_dev_attr_temp5_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) &sensor_dev_attr_temp6_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) &sensor_dev_attr_temp7_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) &sensor_dev_attr_temp8_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) &sensor_dev_attr_temp1_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) &sensor_dev_attr_temp2_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) &sensor_dev_attr_temp3_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) &sensor_dev_attr_temp4_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) &sensor_dev_attr_temp5_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) &sensor_dev_attr_temp6_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) &sensor_dev_attr_temp7_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) &sensor_dev_attr_temp8_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) &sensor_dev_attr_temp1_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) &sensor_dev_attr_temp2_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) &sensor_dev_attr_temp3_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) &sensor_dev_attr_temp4_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) &sensor_dev_attr_temp5_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) &sensor_dev_attr_temp6_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) &sensor_dev_attr_temp7_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) &sensor_dev_attr_temp8_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) &sensor_dev_attr_fan1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) &sensor_dev_attr_fan2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) &sensor_dev_attr_fan3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) &sensor_dev_attr_fan4_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) &sensor_dev_attr_fan1_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) &sensor_dev_attr_fan2_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) &sensor_dev_attr_fan3_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) &sensor_dev_attr_fan4_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) &sensor_dev_attr_fan1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) &sensor_dev_attr_fan2_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) &sensor_dev_attr_fan3_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) &sensor_dev_attr_fan4_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) &sensor_dev_attr_in0_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) &sensor_dev_attr_in1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) &sensor_dev_attr_in2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) &sensor_dev_attr_in3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) &sensor_dev_attr_in4_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) &sensor_dev_attr_in0_label.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) &sensor_dev_attr_in1_label.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) &sensor_dev_attr_in2_label.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) &sensor_dev_attr_in3_label.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* No in4_label as in4 is a generic input pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static const struct attribute_group sch5627_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .attrs = sch5627_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static int sch5627_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct sch5627_data *data = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (data->watchdog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) sch56xx_watchdog_unregister(data->watchdog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (data->hwmon_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) hwmon_device_unregister(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) sysfs_remove_group(&pdev->dev.kobj, &sch5627_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static int sch5627_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct sch5627_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) int err, build_code, build_id, hwmon_rev, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) data = devm_kzalloc(&pdev->dev, sizeof(struct sch5627_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) platform_set_drvdata(pdev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_HWMON_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) err = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (val != SCH5627_HWMON_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "hwmon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) val, SCH5627_HWMON_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_COMPANY_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) err = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (val != SCH5627_COMPANY_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "company",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) val, SCH5627_COMPANY_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_PRIMARY_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) err = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (val != SCH5627_PRIMARY_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "primary",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) val, SCH5627_PRIMARY_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) build_code = sch56xx_read_virtual_reg(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) SCH5627_REG_BUILD_CODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (build_code < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) err = build_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) build_id = sch56xx_read_virtual_reg16(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) SCH5627_REG_BUILD_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (build_id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) err = build_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) hwmon_rev = sch56xx_read_virtual_reg(data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) SCH5627_REG_HWMON_REV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (hwmon_rev < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) err = hwmon_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) err = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) data->control = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (!(data->control & 0x01)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) pr_err("hardware monitoring not enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* Trigger a Vbat voltage measurement, so that we get a valid reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) the first time we read Vbat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) data->control | 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) data->last_battery = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * Read limits, we do this only once as reading a register on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * the sch5627 is quite expensive (and they don't change).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) err = sch5627_read_limits(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) pr_info("found %s chip at %#hx\n", DEVNAME, data->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) build_code, build_id, hwmon_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* Register sysfs interface files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) err = sysfs_create_group(&pdev->dev.kobj, &sch5627_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) data->hwmon_dev = hwmon_device_register(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (IS_ERR(data->hwmon_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) err = PTR_ERR(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) data->hwmon_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* Note failing to register the watchdog is not a fatal error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) data->watchdog = sch56xx_watchdog_register(&pdev->dev, data->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) (build_code << 24) | (build_id << 8) | hwmon_rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) &data->update_lock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) sch5627_remove(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static struct platform_driver sch5627_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .name = DRVNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .probe = sch5627_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .remove = sch5627_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) module_platform_driver(sch5627_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) MODULE_LICENSE("GPL");