-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pmbus: Add driver for Maxim MAX31785 Intelligent Fan Controller
The Maxim MAX31785 is a PMBus device providing closed-loop, multi-channel fan management with temperature and remote voltage sensing. It supports various fan control features, including PWM frequency control, temperature hysteresis, dual tachometer measurements, and fan health monitoring. This patch presents a basic driver using only the existing features of the PMBus subsystem. Signed-off-by: Andrew Jeffery <andrew@aj.id.au> [groeck: Modified description to clarify that fan control is not yet provided] Signed-off-by: Guenter Roeck <linux@roeck-us.net>
- Loading branch information
Andrew Jeffery
authored and
Guenter Roeck
committed
Nov 5, 2017
1 parent
54b943e
commit 4d420a6
Showing
4 changed files
with
178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
Kernel driver max31785 | ||
====================== | ||
|
||
Supported chips: | ||
* Maxim MAX31785, MAX31785A | ||
Prefix: 'max31785' or 'max31785a' | ||
Addresses scanned: - | ||
Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf | ||
|
||
Author: Andrew Jeffery <andrew@aj.id.au> | ||
|
||
Description | ||
----------- | ||
|
||
The Maxim MAX31785 is a PMBus device providing closed-loop, multi-channel fan | ||
management with temperature and remote voltage sensing. Various fan control | ||
features are provided, including PWM frequency control, temperature hysteresis, | ||
dual tachometer measurements, and fan health monitoring. | ||
|
||
For dual rotor fan configuration, the MAX31785 exposes the slowest rotor of the | ||
two in the fan[1-4]_input attributes. | ||
|
||
Usage Notes | ||
----------- | ||
|
||
This driver does not probe for PMBus devices. You will have to instantiate | ||
devices explicitly. | ||
|
||
Sysfs attributes | ||
---------------- | ||
|
||
fan[1-4]_alarm Fan alarm. | ||
fan[1-4]_fault Fan fault. | ||
fan[1-4]_input Fan RPM. | ||
|
||
in[1-6]_crit Critical maximum output voltage | ||
in[1-6]_crit_alarm Output voltage critical high alarm | ||
in[1-6]_input Measured output voltage | ||
in[1-6]_label "vout[18-23]" | ||
in[1-6]_lcrit Critical minimum output voltage | ||
in[1-6]_lcrit_alarm Output voltage critical low alarm | ||
in[1-6]_max Maximum output voltage | ||
in[1-6]_max_alarm Output voltage high alarm | ||
in[1-6]_min Minimum output voltage | ||
in[1-6]_min_alarm Output voltage low alarm | ||
|
||
temp[1-11]_crit Critical high temperature | ||
temp[1-11]_crit_alarm Chip temperature critical high alarm | ||
temp[1-11]_input Measured temperature | ||
temp[1-11]_max Maximum temperature | ||
temp[1-11]_max_alarm Chip temperature high alarm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* Copyright (C) 2017 IBM Corp. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/init.h> | ||
#include <linux/err.h> | ||
#include <linux/i2c.h> | ||
#include "pmbus.h" | ||
|
||
enum max31785_regs { | ||
MFR_REVISION = 0x9b, | ||
}; | ||
|
||
#define MAX31785_NR_PAGES 23 | ||
|
||
#define MAX31785_FAN_FUNCS \ | ||
(PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12) | ||
|
||
#define MAX31785_TEMP_FUNCS \ | ||
(PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP) | ||
|
||
#define MAX31785_VOUT_FUNCS \ | ||
(PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT) | ||
|
||
static const struct pmbus_driver_info max31785_info = { | ||
.pages = MAX31785_NR_PAGES, | ||
|
||
/* RPM */ | ||
.format[PSC_FAN] = direct, | ||
.m[PSC_FAN] = 1, | ||
.b[PSC_FAN] = 0, | ||
.R[PSC_FAN] = 0, | ||
.func[0] = MAX31785_FAN_FUNCS, | ||
.func[1] = MAX31785_FAN_FUNCS, | ||
.func[2] = MAX31785_FAN_FUNCS, | ||
.func[3] = MAX31785_FAN_FUNCS, | ||
.func[4] = MAX31785_FAN_FUNCS, | ||
.func[5] = MAX31785_FAN_FUNCS, | ||
|
||
.format[PSC_TEMPERATURE] = direct, | ||
.m[PSC_TEMPERATURE] = 1, | ||
.b[PSC_TEMPERATURE] = 0, | ||
.R[PSC_TEMPERATURE] = 2, | ||
.func[6] = MAX31785_TEMP_FUNCS, | ||
.func[7] = MAX31785_TEMP_FUNCS, | ||
.func[8] = MAX31785_TEMP_FUNCS, | ||
.func[9] = MAX31785_TEMP_FUNCS, | ||
.func[10] = MAX31785_TEMP_FUNCS, | ||
.func[11] = MAX31785_TEMP_FUNCS, | ||
.func[12] = MAX31785_TEMP_FUNCS, | ||
.func[13] = MAX31785_TEMP_FUNCS, | ||
.func[14] = MAX31785_TEMP_FUNCS, | ||
.func[15] = MAX31785_TEMP_FUNCS, | ||
.func[16] = MAX31785_TEMP_FUNCS, | ||
|
||
.format[PSC_VOLTAGE_OUT] = direct, | ||
.m[PSC_VOLTAGE_OUT] = 1, | ||
.b[PSC_VOLTAGE_OUT] = 0, | ||
.R[PSC_VOLTAGE_OUT] = 0, | ||
.func[17] = MAX31785_VOUT_FUNCS, | ||
.func[18] = MAX31785_VOUT_FUNCS, | ||
.func[19] = MAX31785_VOUT_FUNCS, | ||
.func[20] = MAX31785_VOUT_FUNCS, | ||
.func[21] = MAX31785_VOUT_FUNCS, | ||
.func[22] = MAX31785_VOUT_FUNCS, | ||
}; | ||
|
||
static int max31785_probe(struct i2c_client *client, | ||
const struct i2c_device_id *id) | ||
{ | ||
struct device *dev = &client->dev; | ||
struct pmbus_driver_info *info; | ||
s64 ret; | ||
|
||
info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); | ||
if (!info) | ||
return -ENOMEM; | ||
|
||
*info = max31785_info; | ||
|
||
ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 255); | ||
if (ret < 0) | ||
return ret; | ||
|
||
return pmbus_do_probe(client, id, info); | ||
} | ||
|
||
static const struct i2c_device_id max31785_id[] = { | ||
{ "max31785", 0 }, | ||
{ "max31785a", 0 }, | ||
{ }, | ||
}; | ||
|
||
MODULE_DEVICE_TABLE(i2c, max31785_id); | ||
|
||
static struct i2c_driver max31785_driver = { | ||
.driver = { | ||
.name = "max31785", | ||
}, | ||
.probe = max31785_probe, | ||
.remove = pmbus_do_remove, | ||
.id_table = max31785_id, | ||
}; | ||
|
||
module_i2c_driver(max31785_driver); | ||
|
||
MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>"); | ||
MODULE_DESCRIPTION("PMBus driver for the Maxim MAX31785"); | ||
MODULE_LICENSE("GPL"); |