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

Configure Feed

Select the types of activity you want to include in your feed.

at master 538 lines 15 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Fan Control HDL CORE driver 4 * 5 * Copyright 2019 Analog Devices Inc. 6 */ 7#include <linux/adi-axi-common.h> 8#include <linux/bits.h> 9#include <linux/clk.h> 10#include <linux/hwmon.h> 11#include <linux/hwmon-sysfs.h> 12#include <linux/interrupt.h> 13#include <linux/io.h> 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/mod_devicetable.h> 17#include <linux/platform_device.h> 18#include <linux/property.h> 19 20/* register map */ 21#define ADI_REG_RSTN 0x0080 22#define ADI_REG_PWM_WIDTH 0x0084 23#define ADI_REG_TACH_PERIOD 0x0088 24#define ADI_REG_TACH_TOLERANCE 0x008c 25#define ADI_REG_PWM_PERIOD 0x00c0 26#define ADI_REG_TACH_MEASUR 0x00c4 27#define ADI_REG_TEMPERATURE 0x00c8 28#define ADI_REG_TEMP_00_H 0x0100 29#define ADI_REG_TEMP_25_L 0x0104 30#define ADI_REG_TEMP_25_H 0x0108 31#define ADI_REG_TEMP_50_L 0x010c 32#define ADI_REG_TEMP_50_H 0x0110 33#define ADI_REG_TEMP_75_L 0x0114 34#define ADI_REG_TEMP_75_H 0x0118 35#define ADI_REG_TEMP_100_L 0x011c 36 37#define ADI_REG_IRQ_MASK 0x0040 38#define ADI_REG_IRQ_PENDING 0x0044 39#define ADI_REG_IRQ_SRC 0x0048 40 41/* IRQ sources */ 42#define ADI_IRQ_SRC_PWM_CHANGED BIT(0) 43#define ADI_IRQ_SRC_TACH_ERR BIT(1) 44#define ADI_IRQ_SRC_TEMP_INCREASE BIT(2) 45#define ADI_IRQ_SRC_NEW_MEASUR BIT(3) 46#define ADI_IRQ_SRC_MASK GENMASK(3, 0) 47#define ADI_IRQ_MASK_OUT_ALL 0xFFFFFFFFU 48 49#define SYSFS_PWM_MAX 255 50 51struct axi_fan_control_data { 52 void __iomem *base; 53 struct device *hdev; 54 unsigned long clk_rate; 55 int irq; 56 /* pulses per revolution */ 57 u32 ppr; 58 bool hw_pwm_req; 59 bool update_tacho_params; 60 u8 fan_fault; 61}; 62 63static inline void axi_iowrite(const u32 val, const u32 reg, 64 const struct axi_fan_control_data *ctl) 65{ 66 iowrite32(val, ctl->base + reg); 67} 68 69static inline u32 axi_ioread(const u32 reg, 70 const struct axi_fan_control_data *ctl) 71{ 72 return ioread32(ctl->base + reg); 73} 74 75/* 76 * The core calculates the temperature as: 77 * T = /raw * 509.3140064 / 65535) - 280.2308787 78 */ 79static ssize_t axi_fan_control_show(struct device *dev, struct device_attribute *da, char *buf) 80{ 81 struct axi_fan_control_data *ctl = dev_get_drvdata(dev); 82 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 83 u32 temp = axi_ioread(attr->index, ctl); 84 85 temp = DIV_ROUND_CLOSEST_ULL(temp * 509314ULL, 65535) - 280230; 86 87 return sysfs_emit(buf, "%u\n", temp); 88} 89 90static ssize_t axi_fan_control_store(struct device *dev, struct device_attribute *da, 91 const char *buf, size_t count) 92{ 93 struct axi_fan_control_data *ctl = dev_get_drvdata(dev); 94 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 95 u32 temp; 96 int ret; 97 98 ret = kstrtou32(buf, 10, &temp); 99 if (ret) 100 return ret; 101 102 temp = DIV_ROUND_CLOSEST_ULL((temp + 280230) * 65535ULL, 509314); 103 axi_iowrite(temp, attr->index, ctl); 104 105 return count; 106} 107 108static long axi_fan_control_get_pwm_duty(const struct axi_fan_control_data *ctl) 109{ 110 u32 pwm_width = axi_ioread(ADI_REG_PWM_WIDTH, ctl); 111 u32 pwm_period = axi_ioread(ADI_REG_PWM_PERIOD, ctl); 112 /* 113 * PWM_PERIOD is a RO register set by the core. It should never be 0. 114 * For now we are trusting the HW... 115 */ 116 return DIV_ROUND_CLOSEST(pwm_width * SYSFS_PWM_MAX, pwm_period); 117} 118 119static int axi_fan_control_set_pwm_duty(const long val, 120 struct axi_fan_control_data *ctl) 121{ 122 u32 pwm_period = axi_ioread(ADI_REG_PWM_PERIOD, ctl); 123 u32 new_width; 124 long __val = clamp_val(val, 0, SYSFS_PWM_MAX); 125 126 new_width = DIV_ROUND_CLOSEST(__val * pwm_period, SYSFS_PWM_MAX); 127 128 axi_iowrite(new_width, ADI_REG_PWM_WIDTH, ctl); 129 130 return 0; 131} 132 133static long axi_fan_control_get_fan_rpm(const struct axi_fan_control_data *ctl) 134{ 135 const u32 tach = axi_ioread(ADI_REG_TACH_MEASUR, ctl); 136 137 if (tach == 0) 138 /* should we return error, EAGAIN maybe? */ 139 return 0; 140 /* 141 * The tacho period should be: 142 * TACH = 60/(ppr * rpm), where rpm is revolutions per second 143 * and ppr is pulses per revolution. 144 * Given the tacho period, we can multiply it by the input clock 145 * so that we know how many clocks we need to have this period. 146 * From this, we can derive the RPM value. 147 */ 148 return DIV_ROUND_CLOSEST(60 * ctl->clk_rate, ctl->ppr * tach); 149} 150 151static int axi_fan_control_read_temp(struct device *dev, u32 attr, long *val) 152{ 153 struct axi_fan_control_data *ctl = dev_get_drvdata(dev); 154 long raw_temp; 155 156 switch (attr) { 157 case hwmon_temp_input: 158 raw_temp = axi_ioread(ADI_REG_TEMPERATURE, ctl); 159 /* 160 * The formula for the temperature is: 161 * T = (ADC * 501.3743 / 2^bits) - 273.6777 162 * It's multiplied by 1000 to have millidegrees as 163 * specified by the hwmon sysfs interface. 164 */ 165 *val = ((raw_temp * 501374) >> 16) - 273677; 166 return 0; 167 default: 168 return -ENOTSUPP; 169 } 170} 171 172static int axi_fan_control_read_fan(struct device *dev, u32 attr, long *val) 173{ 174 struct axi_fan_control_data *ctl = dev_get_drvdata(dev); 175 176 switch (attr) { 177 case hwmon_fan_fault: 178 *val = ctl->fan_fault; 179 /* clear it now */ 180 ctl->fan_fault = 0; 181 return 0; 182 case hwmon_fan_input: 183 *val = axi_fan_control_get_fan_rpm(ctl); 184 return 0; 185 default: 186 return -ENOTSUPP; 187 } 188} 189 190static int axi_fan_control_read_pwm(struct device *dev, u32 attr, long *val) 191{ 192 struct axi_fan_control_data *ctl = dev_get_drvdata(dev); 193 194 switch (attr) { 195 case hwmon_pwm_input: 196 *val = axi_fan_control_get_pwm_duty(ctl); 197 return 0; 198 default: 199 return -ENOTSUPP; 200 } 201} 202 203static int axi_fan_control_write_pwm(struct device *dev, u32 attr, long val) 204{ 205 struct axi_fan_control_data *ctl = dev_get_drvdata(dev); 206 207 switch (attr) { 208 case hwmon_pwm_input: 209 return axi_fan_control_set_pwm_duty(val, ctl); 210 default: 211 return -ENOTSUPP; 212 } 213} 214 215static int axi_fan_control_read_labels(struct device *dev, 216 enum hwmon_sensor_types type, 217 u32 attr, int channel, const char **str) 218{ 219 switch (type) { 220 case hwmon_fan: 221 *str = "FAN"; 222 return 0; 223 case hwmon_temp: 224 *str = "SYSMON4"; 225 return 0; 226 default: 227 return -ENOTSUPP; 228 } 229} 230 231static int axi_fan_control_read(struct device *dev, 232 enum hwmon_sensor_types type, 233 u32 attr, int channel, long *val) 234{ 235 switch (type) { 236 case hwmon_fan: 237 return axi_fan_control_read_fan(dev, attr, val); 238 case hwmon_pwm: 239 return axi_fan_control_read_pwm(dev, attr, val); 240 case hwmon_temp: 241 return axi_fan_control_read_temp(dev, attr, val); 242 default: 243 return -ENOTSUPP; 244 } 245} 246 247static int axi_fan_control_write(struct device *dev, 248 enum hwmon_sensor_types type, 249 u32 attr, int channel, long val) 250{ 251 switch (type) { 252 case hwmon_pwm: 253 return axi_fan_control_write_pwm(dev, attr, val); 254 default: 255 return -ENOTSUPP; 256 } 257} 258 259static umode_t axi_fan_control_fan_is_visible(const u32 attr) 260{ 261 switch (attr) { 262 case hwmon_fan_input: 263 case hwmon_fan_fault: 264 case hwmon_fan_label: 265 return 0444; 266 default: 267 return 0; 268 } 269} 270 271static umode_t axi_fan_control_pwm_is_visible(const u32 attr) 272{ 273 switch (attr) { 274 case hwmon_pwm_input: 275 return 0644; 276 default: 277 return 0; 278 } 279} 280 281static umode_t axi_fan_control_temp_is_visible(const u32 attr) 282{ 283 switch (attr) { 284 case hwmon_temp_input: 285 case hwmon_temp_label: 286 return 0444; 287 default: 288 return 0; 289 } 290} 291 292static umode_t axi_fan_control_is_visible(const void *data, 293 enum hwmon_sensor_types type, 294 u32 attr, int channel) 295{ 296 switch (type) { 297 case hwmon_fan: 298 return axi_fan_control_fan_is_visible(attr); 299 case hwmon_pwm: 300 return axi_fan_control_pwm_is_visible(attr); 301 case hwmon_temp: 302 return axi_fan_control_temp_is_visible(attr); 303 default: 304 return 0; 305 } 306} 307 308/* 309 * This core has two main ways of changing the PWM duty cycle. It is done, 310 * either by a request from userspace (writing on pwm1_input) or by the 311 * core itself. When the change is done by the core, it will use predefined 312 * parameters to evaluate the tach signal and, on that case we cannot set them. 313 * On the other hand, when the request is done by the user, with some arbitrary 314 * value that the core does not now about, we have to provide the tach 315 * parameters so that, the core can evaluate the signal. On the IRQ handler we 316 * distinguish this by using the ADI_IRQ_SRC_TEMP_INCREASE interrupt. This tell 317 * us that the CORE requested a new duty cycle. After this, there is 5s delay 318 * on which the core waits for the fan rotation speed to stabilize. After this 319 * we get ADI_IRQ_SRC_PWM_CHANGED irq where we will decide if we need to set 320 * the tach parameters or not on the next tach measurement cycle (corresponding 321 * already to the ney duty cycle) based on the %ctl->hw_pwm_req flag. 322 */ 323static irqreturn_t axi_fan_control_irq_handler(int irq, void *data) 324{ 325 struct axi_fan_control_data *ctl = (struct axi_fan_control_data *)data; 326 u32 irq_pending = axi_ioread(ADI_REG_IRQ_PENDING, ctl); 327 u32 clear_mask; 328 329 if (irq_pending & ADI_IRQ_SRC_TEMP_INCREASE) 330 /* hardware requested a new pwm */ 331 ctl->hw_pwm_req = true; 332 333 if (irq_pending & ADI_IRQ_SRC_PWM_CHANGED) { 334 /* 335 * if the pwm changes on behalf of software, 336 * we need to provide new tacho parameters to the core. 337 * Wait for the next measurement for that... 338 */ 339 if (!ctl->hw_pwm_req) { 340 ctl->update_tacho_params = true; 341 } else { 342 ctl->hw_pwm_req = false; 343 hwmon_notify_event(ctl->hdev, hwmon_pwm, 344 hwmon_pwm_input, 0); 345 } 346 } 347 348 if (irq_pending & ADI_IRQ_SRC_NEW_MEASUR) { 349 if (ctl->update_tacho_params) { 350 u32 new_tach = axi_ioread(ADI_REG_TACH_MEASUR, ctl); 351 /* get 25% tolerance */ 352 u32 tach_tol = DIV_ROUND_CLOSEST(new_tach * 25, 100); 353 354 /* set new tacho parameters */ 355 axi_iowrite(new_tach, ADI_REG_TACH_PERIOD, ctl); 356 axi_iowrite(tach_tol, ADI_REG_TACH_TOLERANCE, ctl); 357 ctl->update_tacho_params = false; 358 } 359 } 360 361 if (irq_pending & ADI_IRQ_SRC_TACH_ERR) 362 ctl->fan_fault = 1; 363 364 /* clear all interrupts */ 365 clear_mask = irq_pending & ADI_IRQ_SRC_MASK; 366 axi_iowrite(clear_mask, ADI_REG_IRQ_PENDING, ctl); 367 368 return IRQ_HANDLED; 369} 370 371static int axi_fan_control_init(struct axi_fan_control_data *ctl, 372 const struct device *dev) 373{ 374 int ret; 375 376 /* get fan pulses per revolution */ 377 ret = device_property_read_u32(dev, "pulses-per-revolution", &ctl->ppr); 378 if (ret) 379 return ret; 380 381 /* 1, 2 and 4 are the typical and accepted values */ 382 if (ctl->ppr != 1 && ctl->ppr != 2 && ctl->ppr != 4) 383 return -EINVAL; 384 /* 385 * Enable all IRQs 386 */ 387 axi_iowrite(ADI_IRQ_MASK_OUT_ALL & 388 ~(ADI_IRQ_SRC_NEW_MEASUR | ADI_IRQ_SRC_TACH_ERR | 389 ADI_IRQ_SRC_PWM_CHANGED | ADI_IRQ_SRC_TEMP_INCREASE), 390 ADI_REG_IRQ_MASK, ctl); 391 392 /* bring the device out of reset */ 393 axi_iowrite(0x01, ADI_REG_RSTN, ctl); 394 395 return ret; 396} 397 398static const struct hwmon_channel_info * const axi_fan_control_info[] = { 399 HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT), 400 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_LABEL), 401 HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_LABEL), 402 NULL 403}; 404 405static const struct hwmon_ops axi_fan_control_hwmon_ops = { 406 .is_visible = axi_fan_control_is_visible, 407 .read = axi_fan_control_read, 408 .write = axi_fan_control_write, 409 .read_string = axi_fan_control_read_labels, 410}; 411 412static const struct hwmon_chip_info axi_chip_info = { 413 .ops = &axi_fan_control_hwmon_ops, 414 .info = axi_fan_control_info, 415}; 416 417/* temperature threshold below which PWM should be 0% */ 418static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point1_temp_hyst, axi_fan_control, ADI_REG_TEMP_00_H); 419/* temperature threshold above which PWM should be 25% */ 420static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point1_temp, axi_fan_control, ADI_REG_TEMP_25_L); 421/* temperature threshold below which PWM should be 25% */ 422static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_temp_hyst, axi_fan_control, ADI_REG_TEMP_25_H); 423/* temperature threshold above which PWM should be 50% */ 424static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_temp, axi_fan_control, ADI_REG_TEMP_50_L); 425/* temperature threshold below which PWM should be 50% */ 426static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point3_temp_hyst, axi_fan_control, ADI_REG_TEMP_50_H); 427/* temperature threshold above which PWM should be 75% */ 428static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point3_temp, axi_fan_control, ADI_REG_TEMP_75_L); 429/* temperature threshold below which PWM should be 75% */ 430static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point4_temp_hyst, axi_fan_control, ADI_REG_TEMP_75_H); 431/* temperature threshold above which PWM should be 100% */ 432static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point4_temp, axi_fan_control, ADI_REG_TEMP_100_L); 433 434static struct attribute *axi_fan_control_attrs[] = { 435 &sensor_dev_attr_pwm1_auto_point1_temp_hyst.dev_attr.attr, 436 &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, 437 &sensor_dev_attr_pwm1_auto_point2_temp_hyst.dev_attr.attr, 438 &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, 439 &sensor_dev_attr_pwm1_auto_point3_temp_hyst.dev_attr.attr, 440 &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, 441 &sensor_dev_attr_pwm1_auto_point4_temp_hyst.dev_attr.attr, 442 &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, 443 NULL, 444}; 445ATTRIBUTE_GROUPS(axi_fan_control); 446 447static int axi_fan_control_probe(struct platform_device *pdev) 448{ 449 struct axi_fan_control_data *ctl; 450 struct clk *clk; 451 const unsigned int *id; 452 const char *name = "axi_fan_control"; 453 u32 version; 454 int ret; 455 456 id = device_get_match_data(&pdev->dev); 457 if (!id) 458 return -EINVAL; 459 460 ctl = devm_kzalloc(&pdev->dev, sizeof(*ctl), GFP_KERNEL); 461 if (!ctl) 462 return -ENOMEM; 463 464 ctl->base = devm_platform_ioremap_resource(pdev, 0); 465 if (IS_ERR(ctl->base)) 466 return PTR_ERR(ctl->base); 467 468 clk = devm_clk_get_enabled(&pdev->dev, NULL); 469 if (IS_ERR(clk)) 470 return dev_err_probe(&pdev->dev, PTR_ERR(clk), 471 "clk_get failed\n"); 472 473 ctl->clk_rate = clk_get_rate(clk); 474 if (!ctl->clk_rate) 475 return -EINVAL; 476 477 version = axi_ioread(ADI_AXI_REG_VERSION, ctl); 478 if (ADI_AXI_PCORE_VER_MAJOR(version) != 479 ADI_AXI_PCORE_VER_MAJOR((*id))) 480 return dev_err_probe(&pdev->dev, -ENODEV, 481 "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", 482 ADI_AXI_PCORE_VER_MAJOR(*id), 483 ADI_AXI_PCORE_VER_MINOR(*id), 484 ADI_AXI_PCORE_VER_PATCH(*id), 485 ADI_AXI_PCORE_VER_MAJOR(version), 486 ADI_AXI_PCORE_VER_MINOR(version), 487 ADI_AXI_PCORE_VER_PATCH(version)); 488 489 ret = axi_fan_control_init(ctl, &pdev->dev); 490 if (ret) 491 return dev_err_probe(&pdev->dev, ret, 492 "Failed to initialize device\n"); 493 494 ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, 495 name, 496 ctl, 497 &axi_chip_info, 498 axi_fan_control_groups); 499 500 if (IS_ERR(ctl->hdev)) 501 return PTR_ERR(ctl->hdev); 502 503 ctl->irq = platform_get_irq(pdev, 0); 504 if (ctl->irq < 0) 505 return ctl->irq; 506 507 ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL, 508 axi_fan_control_irq_handler, 509 IRQF_ONESHOT | IRQF_TRIGGER_HIGH, 510 NULL, ctl); 511 if (ret) 512 return dev_err_probe(&pdev->dev, ret, 513 "failed to request an irq\n"); 514 515 return 0; 516} 517 518static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); 519 520static const struct of_device_id axi_fan_control_of_match[] = { 521 { .compatible = "adi,axi-fan-control-1.00.a", 522 .data = (void *)&version_1_0_0}, 523 {}, 524}; 525MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); 526 527static struct platform_driver axi_fan_control_driver = { 528 .driver = { 529 .name = "axi_fan_control_driver", 530 .of_match_table = axi_fan_control_of_match, 531 }, 532 .probe = axi_fan_control_probe, 533}; 534module_platform_driver(axi_fan_control_driver); 535 536MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); 537MODULE_DESCRIPTION("Analog Devices Fan Control HDL CORE driver"); 538MODULE_LICENSE("GPL");