0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/phy.h>
0010 #include <linux/device.h>
0011 #include <linux/ctype.h>
0012 #include <linux/hwmon.h>
0013
0014 #include "aquantia.h"
0015
0016
0017 #define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
0018 #define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
0019 #define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
0020 #define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
0021 #define VEND1_THERMAL_STAT1 0xc820
0022 #define VEND1_THERMAL_STAT2 0xc821
0023 #define VEND1_THERMAL_STAT2_VALID BIT(0)
0024 #define VEND1_GENERAL_STAT1 0xc830
0025 #define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
0026 #define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
0027 #define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
0028 #define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
0029
0030 #if IS_REACHABLE(CONFIG_HWMON)
0031
0032 static umode_t aqr_hwmon_is_visible(const void *data,
0033 enum hwmon_sensor_types type,
0034 u32 attr, int channel)
0035 {
0036 if (type != hwmon_temp)
0037 return 0;
0038
0039 switch (attr) {
0040 case hwmon_temp_input:
0041 case hwmon_temp_min_alarm:
0042 case hwmon_temp_max_alarm:
0043 case hwmon_temp_lcrit_alarm:
0044 case hwmon_temp_crit_alarm:
0045 return 0444;
0046 case hwmon_temp_min:
0047 case hwmon_temp_max:
0048 case hwmon_temp_lcrit:
0049 case hwmon_temp_crit:
0050 return 0644;
0051 default:
0052 return 0;
0053 }
0054 }
0055
0056 static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value)
0057 {
0058 int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
0059
0060 if (temp < 0)
0061 return temp;
0062
0063
0064 *value = (s16)temp * 1000 / 256;
0065
0066 return 0;
0067 }
0068
0069 static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value)
0070 {
0071 int temp;
0072
0073 if (value >= 128000 || value < -128000)
0074 return -ERANGE;
0075
0076 temp = value * 256 / 1000;
0077
0078
0079 return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp);
0080 }
0081
0082 static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit)
0083 {
0084 int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
0085
0086 if (val < 0)
0087 return val;
0088
0089 return !!(val & bit);
0090 }
0091
0092 static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value)
0093 {
0094 int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit);
0095
0096 if (val < 0)
0097 return val;
0098
0099 *value = val;
0100
0101 return 0;
0102 }
0103
0104 static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
0105 u32 attr, int channel, long *value)
0106 {
0107 struct phy_device *phydev = dev_get_drvdata(dev);
0108 int reg;
0109
0110 if (type != hwmon_temp)
0111 return -EOPNOTSUPP;
0112
0113 switch (attr) {
0114 case hwmon_temp_input:
0115 reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2,
0116 VEND1_THERMAL_STAT2_VALID);
0117 if (reg < 0)
0118 return reg;
0119 if (!reg)
0120 return -EBUSY;
0121
0122 return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value);
0123
0124 case hwmon_temp_lcrit:
0125 return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
0126 value);
0127 case hwmon_temp_min:
0128 return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
0129 value);
0130 case hwmon_temp_max:
0131 return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
0132 value);
0133 case hwmon_temp_crit:
0134 return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
0135 value);
0136 case hwmon_temp_lcrit_alarm:
0137 return aqr_hwmon_status1(phydev,
0138 VEND1_GENERAL_STAT1_LOW_TEMP_FAIL,
0139 value);
0140 case hwmon_temp_min_alarm:
0141 return aqr_hwmon_status1(phydev,
0142 VEND1_GENERAL_STAT1_LOW_TEMP_WARN,
0143 value);
0144 case hwmon_temp_max_alarm:
0145 return aqr_hwmon_status1(phydev,
0146 VEND1_GENERAL_STAT1_HIGH_TEMP_WARN,
0147 value);
0148 case hwmon_temp_crit_alarm:
0149 return aqr_hwmon_status1(phydev,
0150 VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL,
0151 value);
0152 default:
0153 return -EOPNOTSUPP;
0154 }
0155 }
0156
0157 static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
0158 u32 attr, int channel, long value)
0159 {
0160 struct phy_device *phydev = dev_get_drvdata(dev);
0161
0162 if (type != hwmon_temp)
0163 return -EOPNOTSUPP;
0164
0165 switch (attr) {
0166 case hwmon_temp_lcrit:
0167 return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
0168 value);
0169 case hwmon_temp_min:
0170 return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
0171 value);
0172 case hwmon_temp_max:
0173 return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
0174 value);
0175 case hwmon_temp_crit:
0176 return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
0177 value);
0178 default:
0179 return -EOPNOTSUPP;
0180 }
0181 }
0182
0183 static const struct hwmon_ops aqr_hwmon_ops = {
0184 .is_visible = aqr_hwmon_is_visible,
0185 .read = aqr_hwmon_read,
0186 .write = aqr_hwmon_write,
0187 };
0188
0189 static u32 aqr_hwmon_chip_config[] = {
0190 HWMON_C_REGISTER_TZ,
0191 0,
0192 };
0193
0194 static const struct hwmon_channel_info aqr_hwmon_chip = {
0195 .type = hwmon_chip,
0196 .config = aqr_hwmon_chip_config,
0197 };
0198
0199 static u32 aqr_hwmon_temp_config[] = {
0200 HWMON_T_INPUT |
0201 HWMON_T_MAX | HWMON_T_MIN |
0202 HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM |
0203 HWMON_T_CRIT | HWMON_T_LCRIT |
0204 HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM,
0205 0,
0206 };
0207
0208 static const struct hwmon_channel_info aqr_hwmon_temp = {
0209 .type = hwmon_temp,
0210 .config = aqr_hwmon_temp_config,
0211 };
0212
0213 static const struct hwmon_channel_info *aqr_hwmon_info[] = {
0214 &aqr_hwmon_chip,
0215 &aqr_hwmon_temp,
0216 NULL,
0217 };
0218
0219 static const struct hwmon_chip_info aqr_hwmon_chip_info = {
0220 .ops = &aqr_hwmon_ops,
0221 .info = aqr_hwmon_info,
0222 };
0223
0224 int aqr_hwmon_probe(struct phy_device *phydev)
0225 {
0226 struct device *dev = &phydev->mdio.dev;
0227 struct device *hwmon_dev;
0228 char *hwmon_name;
0229 int i, j;
0230
0231 hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
0232 if (!hwmon_name)
0233 return -ENOMEM;
0234
0235 for (i = j = 0; hwmon_name[i]; i++) {
0236 if (isalnum(hwmon_name[i])) {
0237 if (i != j)
0238 hwmon_name[j] = hwmon_name[i];
0239 j++;
0240 }
0241 }
0242 hwmon_name[j] = '\0';
0243
0244 hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name,
0245 phydev, &aqr_hwmon_chip_info, NULL);
0246
0247 return PTR_ERR_OR_ZERO(hwmon_dev);
0248 }
0249
0250 #endif