1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/bitfield.h> 4 #include <linux/clk.h> 5 #include <linux/hwmon.h> 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/mod_devicetable.h> 9 #include <linux/platform_device.h> 10 #include <linux/polynomial.h> 11 #include <linux/regmap.h> 12 13 /* 14 * The original translation formulae of the temperature (in degrees of Celsius) 15 * are as follows: 16 * 17 * T = -3.4627e-11*(N^4) + 1.1023e-7*(N^3) + -1.9165e-4*(N^2) + 18 * 3.0604e-1*(N^1) + -5.6197e1 19 * 20 * where [-56.197, 136.402]C and N = [0, 1023]. 21 * 22 * They must be accordingly altered to be suitable for the integer arithmetics. 23 * The technique is called 'factor redistribution', which just makes sure the 24 * multiplications and divisions are made so to have a result of the operations 25 * within the integer numbers limit. In addition we need to translate the 26 * formulae to accept millidegrees of Celsius. Here what it looks like after 27 * the alterations: 28 * 29 * T = -34627e-12*(N^4) + 110230e-9*(N^3) + -191650e-6*(N^2) + 30 * 306040e-3*(N^1) + -56197 31 * 32 * where T = [-56197, 136402]mC and N = [0, 1023]. 33 */ 34 35 static const struct polynomial poly_N_to_temp = { 36 .terms = { 37 {4, -34627, 1000, 1}, 38 {3, 110230, 1000, 1}, 39 {2, -191650, 1000, 1}, 40 {1, 306040, 1000, 1}, 41 {0, -56197, 1, 1} 42 } 43 }; 44 45 #define PVT_SENSOR_CTRL 0x0 /* unused */ 46 #define PVT_SENSOR_CFG 0x4 47 #define SENSOR_CFG_CLK_CFG GENMASK(27, 20) 48 #define SENSOR_CFG_TRIM_VAL GENMASK(13, 9) 49 #define SENSOR_CFG_SAMPLE_ENA BIT(8) 50 #define SENSOR_CFG_START_CAPTURE BIT(7) 51 #define SENSOR_CFG_CONTINIOUS_MODE BIT(6) 52 #define SENSOR_CFG_PSAMPLE_ENA GENMASK(1, 0) 53 #define PVT_SENSOR_STAT 0x8 54 #define SENSOR_STAT_DATA_VALID BIT(10) 55 #define SENSOR_STAT_DATA GENMASK(9, 0) 56 57 #define FAN_CFG 0x0 58 #define FAN_CFG_DUTY_CYCLE GENMASK(23, 16) 59 #define INV_POL BIT(3) 60 #define GATE_ENA BIT(2) 61 #define PWM_OPEN_COL_ENA BIT(1) 62 #define FAN_STAT_CFG BIT(0) 63 #define FAN_PWM_FREQ 0x4 64 #define FAN_PWM_CYC_10US GENMASK(25, 15) 65 #define FAN_PWM_FREQ_FREQ GENMASK(14, 0) 66 #define FAN_CNT 0xc 67 #define FAN_CNT_DATA GENMASK(15, 0) 68 69 #define LAN966X_PVT_CLK 1200000 /* 1.2 MHz */ 70 71 struct lan966x_hwmon { 72 struct regmap *regmap_pvt; 73 struct regmap *regmap_fan; 74 struct clk *clk; 75 unsigned long clk_rate; 76 }; 77 78 static int lan966x_hwmon_read_temp(struct device *dev, long *val) 79 { 80 struct lan966x_hwmon *hwmon = dev_get_drvdata(dev); 81 unsigned int data; 82 int ret; 83 84 ret = regmap_read(hwmon->regmap_pvt, PVT_SENSOR_STAT, &data); 85 if (ret < 0) 86 return ret; 87 88 if (!(data & SENSOR_STAT_DATA_VALID)) 89 return -ENODATA; 90 91 *val = polynomial_calc(&poly_N_to_temp, 92 FIELD_GET(SENSOR_STAT_DATA, data)); 93 94 return 0; 95 } 96 97 static int lan966x_hwmon_read_fan(struct device *dev, long *val) 98 { 99 struct lan966x_hwmon *hwmon = dev_get_drvdata(dev); 100 unsigned int data; 101 int ret; 102 103 ret = regmap_read(hwmon->regmap_fan, FAN_CNT, &data); 104 if (ret < 0) 105 return ret; 106 107 /* 108 * Data is given in pulses per second. Assume two pulses 109 * per revolution. 110 */ 111 *val = FIELD_GET(FAN_CNT_DATA, data) * 60 / 2; 112 113 return 0; 114 } 115 116 static int lan966x_hwmon_read_pwm(struct device *dev, long *val) 117 { 118 struct lan966x_hwmon *hwmon = dev_get_drvdata(dev); 119 unsigned int data; 120 int ret; 121 122 ret = regmap_read(hwmon->regmap_fan, FAN_CFG, &data); 123 if (ret < 0) 124 return ret; 125 126 *val = FIELD_GET(FAN_CFG_DUTY_CYCLE, data); 127 128 return 0; 129 } 130 131 static int lan966x_hwmon_read_pwm_freq(struct device *dev, long *val) 132 { 133 struct lan966x_hwmon *hwmon = dev_get_drvdata(dev); 134 unsigned long tmp; 135 unsigned int data; 136 int ret; 137 138 ret = regmap_read(hwmon->regmap_fan, FAN_PWM_FREQ, &data); 139 if (ret < 0) 140 return ret; 141 142 /* 143 * Datasheet says it is sys_clk / 256 / pwm_freq. But in reality 144 * it is sys_clk / 256 / (pwm_freq + 1). 145 */ 146 data = FIELD_GET(FAN_PWM_FREQ_FREQ, data) + 1; 147 tmp = DIV_ROUND_CLOSEST(hwmon->clk_rate, 256); 148 *val = DIV_ROUND_CLOSEST(tmp, data); 149 150 return 0; 151 } 152 153 static int lan966x_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 154 u32 attr, int channel, long *val) 155 { 156 switch (type) { 157 case hwmon_temp: 158 return lan966x_hwmon_read_temp(dev, val); 159 case hwmon_fan: 160 return lan966x_hwmon_read_fan(dev, val); 161 case hwmon_pwm: 162 switch (attr) { 163 case hwmon_pwm_input: 164 return lan966x_hwmon_read_pwm(dev, val); 165 case hwmon_pwm_freq: 166 return lan966x_hwmon_read_pwm_freq(dev, val); 167 default: 168 return -EOPNOTSUPP; 169 } 170 default: 171 return -EOPNOTSUPP; 172 } 173 } 174 175 static int lan966x_hwmon_write_pwm(struct device *dev, long val) 176 { 177 struct lan966x_hwmon *hwmon = dev_get_drvdata(dev); 178 179 if (val < 0 || val > 255) 180 return -EINVAL; 181 182 return regmap_update_bits(hwmon->regmap_fan, FAN_CFG, 183 FAN_CFG_DUTY_CYCLE, 184 FIELD_PREP(FAN_CFG_DUTY_CYCLE, val)); 185 } 186 187 static int lan966x_hwmon_write_pwm_freq(struct device *dev, long val) 188 { 189 struct lan966x_hwmon *hwmon = dev_get_drvdata(dev); 190 191 if (val <= 0) 192 return -EINVAL; 193 194 val = DIV_ROUND_CLOSEST(hwmon->clk_rate, val); 195 val = DIV_ROUND_CLOSEST(val, 256) - 1; 196 val = clamp_val(val, 0, FAN_PWM_FREQ_FREQ); 197 198 return regmap_update_bits(hwmon->regmap_fan, FAN_PWM_FREQ, 199 FAN_PWM_FREQ_FREQ, 200 FIELD_PREP(FAN_PWM_FREQ_FREQ, val)); 201 } 202 203 static int lan966x_hwmon_write(struct device *dev, enum hwmon_sensor_types type, 204 u32 attr, int channel, long val) 205 { 206 switch (type) { 207 case hwmon_pwm: 208 switch (attr) { 209 case hwmon_pwm_input: 210 return lan966x_hwmon_write_pwm(dev, val); 211 case hwmon_pwm_freq: 212 return lan966x_hwmon_write_pwm_freq(dev, val); 213 default: 214 return -EOPNOTSUPP; 215 } 216 default: 217 return -EOPNOTSUPP; 218 } 219 } 220 221 static umode_t lan966x_hwmon_is_visible(const void *data, 222 enum hwmon_sensor_types type, 223 u32 attr, int channel) 224 { 225 umode_t mode = 0; 226 227 switch (type) { 228 case hwmon_temp: 229 switch (attr) { 230 case hwmon_temp_input: 231 mode = 0444; 232 break; 233 default: 234 break; 235 } 236 break; 237 case hwmon_fan: 238 switch (attr) { 239 case hwmon_fan_input: 240 mode = 0444; 241 break; 242 default: 243 break; 244 } 245 break; 246 case hwmon_pwm: 247 switch (attr) { 248 case hwmon_pwm_input: 249 case hwmon_pwm_freq: 250 mode = 0644; 251 break; 252 default: 253 break; 254 } 255 break; 256 default: 257 break; 258 } 259 260 return mode; 261 } 262 263 static const struct hwmon_channel_info * const lan966x_hwmon_info[] = { 264 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), 265 HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), 266 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT), 267 HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_FREQ), 268 NULL 269 }; 270 271 static const struct hwmon_ops lan966x_hwmon_ops = { 272 .is_visible = lan966x_hwmon_is_visible, 273 .read = lan966x_hwmon_read, 274 .write = lan966x_hwmon_write, 275 }; 276 277 static const struct hwmon_chip_info lan966x_hwmon_chip_info = { 278 .ops = &lan966x_hwmon_ops, 279 .info = lan966x_hwmon_info, 280 }; 281 282 static void lan966x_hwmon_disable(void *data) 283 { 284 struct lan966x_hwmon *hwmon = data; 285 286 regmap_update_bits(hwmon->regmap_pvt, PVT_SENSOR_CFG, 287 SENSOR_CFG_SAMPLE_ENA | SENSOR_CFG_CONTINIOUS_MODE, 288 0); 289 } 290 291 static int lan966x_hwmon_enable(struct device *dev, 292 struct lan966x_hwmon *hwmon) 293 { 294 unsigned int mask = SENSOR_CFG_CLK_CFG | 295 SENSOR_CFG_SAMPLE_ENA | 296 SENSOR_CFG_START_CAPTURE | 297 SENSOR_CFG_CONTINIOUS_MODE | 298 SENSOR_CFG_PSAMPLE_ENA; 299 unsigned int val; 300 unsigned int div; 301 int ret; 302 303 /* enable continuous mode */ 304 val = SENSOR_CFG_SAMPLE_ENA | SENSOR_CFG_CONTINIOUS_MODE; 305 306 /* set PVT clock to be between 1.15 and 1.25 MHz */ 307 div = DIV_ROUND_CLOSEST(hwmon->clk_rate, LAN966X_PVT_CLK); 308 val |= FIELD_PREP(SENSOR_CFG_CLK_CFG, div); 309 310 ret = regmap_update_bits(hwmon->regmap_pvt, PVT_SENSOR_CFG, 311 mask, val); 312 if (ret) 313 return ret; 314 315 return devm_add_action_or_reset(dev, lan966x_hwmon_disable, hwmon); 316 } 317 318 static struct regmap *lan966x_init_regmap(struct platform_device *pdev, 319 const char *name) 320 { 321 struct regmap_config regmap_config = { 322 .reg_bits = 32, 323 .reg_stride = 4, 324 .val_bits = 32, 325 }; 326 void __iomem *base; 327 328 base = devm_platform_ioremap_resource_byname(pdev, name); 329 if (IS_ERR(base)) 330 return ERR_CAST(base); 331 332 regmap_config.name = name; 333 334 return devm_regmap_init_mmio(&pdev->dev, base, ®map_config); 335 } 336 337 static int lan966x_hwmon_probe(struct platform_device *pdev) 338 { 339 struct device *dev = &pdev->dev; 340 struct lan966x_hwmon *hwmon; 341 struct device *hwmon_dev; 342 int ret; 343 344 hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL); 345 if (!hwmon) 346 return -ENOMEM; 347 348 hwmon->clk = devm_clk_get_enabled(dev, NULL); 349 if (IS_ERR(hwmon->clk)) 350 return dev_err_probe(dev, PTR_ERR(hwmon->clk), 351 "failed to get clock\n"); 352 353 hwmon->clk_rate = clk_get_rate(hwmon->clk); 354 355 hwmon->regmap_pvt = lan966x_init_regmap(pdev, "pvt"); 356 if (IS_ERR(hwmon->regmap_pvt)) 357 return dev_err_probe(dev, PTR_ERR(hwmon->regmap_pvt), 358 "failed to get regmap for PVT registers\n"); 359 360 hwmon->regmap_fan = lan966x_init_regmap(pdev, "fan"); 361 if (IS_ERR(hwmon->regmap_fan)) 362 return dev_err_probe(dev, PTR_ERR(hwmon->regmap_fan), 363 "failed to get regmap for fan registers\n"); 364 365 ret = lan966x_hwmon_enable(dev, hwmon); 366 if (ret) 367 return dev_err_probe(dev, ret, "failed to enable sensor\n"); 368 369 hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, 370 "lan966x_hwmon", hwmon, 371 &lan966x_hwmon_chip_info, NULL); 372 if (IS_ERR(hwmon_dev)) 373 return dev_err_probe(dev, PTR_ERR(hwmon_dev), 374 "failed to register hwmon device\n"); 375 376 return 0; 377 } 378 379 static const struct of_device_id lan966x_hwmon_of_match[] = { 380 { .compatible = "microchip,lan9668-hwmon" }, 381 {} 382 }; 383 MODULE_DEVICE_TABLE(of, lan966x_hwmon_of_match); 384 385 static struct platform_driver lan966x_hwmon_driver = { 386 .probe = lan966x_hwmon_probe, 387 .driver = { 388 .name = "lan966x-hwmon", 389 .of_match_table = lan966x_hwmon_of_match, 390 }, 391 }; 392 module_platform_driver(lan966x_hwmon_driver); 393 394 MODULE_DESCRIPTION("LAN966x Hardware Monitoring Driver"); 395 MODULE_AUTHOR("Michael Walle <michael@walle.cc>"); 396 MODULE_LICENSE("GPL"); 397