Skip to content

Commit 626bb2f

Browse files
tao-rengroeck
authored andcommitted
hwmon: (pmbus) add driver for BEL PFE1100 and PFE3000
Add "bel-pfe" pmbus driver to support hardware monitoring for BEL PFE1100 and PFE3000 power supplies. Signed-off-by: Tao Ren <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]>
1 parent 8ae93ea commit 626bb2f

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

drivers/hwmon/pmbus/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ config SENSORS_ADM1275
3636
This driver can also be built as a module. If so, the module will
3737
be called adm1275.
3838

39+
config SENSORS_BEL_PFE
40+
tristate "Bel PFE Compatible Power Supplies"
41+
help
42+
If you say yes here you get hardware monitoring support for BEL
43+
PFE1100 and PFE3000 Power Supplies.
44+
45+
This driver can also be built as a module. If so, the module will
46+
be called bel-pfe.
47+
3948
config SENSORS_IBM_CFFPS
4049
tristate "IBM Common Form Factor Power Supply"
4150
depends on LEDS_CLASS

drivers/hwmon/pmbus/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
obj-$(CONFIG_PMBUS) += pmbus_core.o
77
obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o
88
obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o
9+
obj-$(CONFIG_SENSORS_BEL_PFE) += bel-pfe.o
910
obj-$(CONFIG_SENSORS_IBM_CFFPS) += ibm-cffps.o
1011
obj-$(CONFIG_SENSORS_INSPUR_IPSPS) += inspur-ipsps.o
1112
obj-$(CONFIG_SENSORS_IR35221) += ir35221.o

drivers/hwmon/pmbus/bel-pfe.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* Hardware monitoring driver for BEL PFE family power supplies.
4+
*
5+
* Copyright (c) 2019 Facebook Inc.
6+
*/
7+
8+
#include <linux/err.h>
9+
#include <linux/i2c.h>
10+
#include <linux/init.h>
11+
#include <linux/kernel.h>
12+
#include <linux/module.h>
13+
#include <linux/pmbus.h>
14+
15+
#include "pmbus.h"
16+
17+
enum chips {pfe1100, pfe3000};
18+
19+
/*
20+
* Disable status check for pfe3000 devices, because some devices report
21+
* communication error (invalid command) for VOUT_MODE command (0x20)
22+
* although correct VOUT_MODE (0x16) is returned: it leads to incorrect
23+
* exponent in linear mode.
24+
*/
25+
static struct pmbus_platform_data pfe3000_plat_data = {
26+
.flags = PMBUS_SKIP_STATUS_CHECK,
27+
};
28+
29+
static struct pmbus_driver_info pfe_driver_info[] = {
30+
[pfe1100] = {
31+
.pages = 1,
32+
.format[PSC_VOLTAGE_IN] = linear,
33+
.format[PSC_VOLTAGE_OUT] = linear,
34+
.format[PSC_CURRENT_IN] = linear,
35+
.format[PSC_CURRENT_OUT] = linear,
36+
.format[PSC_POWER] = linear,
37+
.format[PSC_TEMPERATURE] = linear,
38+
.format[PSC_FAN] = linear,
39+
40+
.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
41+
PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
42+
PMBUS_HAVE_POUT |
43+
PMBUS_HAVE_VIN | PMBUS_HAVE_IIN |
44+
PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT |
45+
PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
46+
PMBUS_HAVE_STATUS_TEMP |
47+
PMBUS_HAVE_FAN12,
48+
},
49+
50+
[pfe3000] = {
51+
.pages = 7,
52+
.format[PSC_VOLTAGE_IN] = linear,
53+
.format[PSC_VOLTAGE_OUT] = linear,
54+
.format[PSC_CURRENT_IN] = linear,
55+
.format[PSC_CURRENT_OUT] = linear,
56+
.format[PSC_POWER] = linear,
57+
.format[PSC_TEMPERATURE] = linear,
58+
.format[PSC_FAN] = linear,
59+
60+
/* Page 0: V1. */
61+
.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
62+
PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
63+
PMBUS_HAVE_POUT | PMBUS_HAVE_FAN12 |
64+
PMBUS_HAVE_VIN | PMBUS_HAVE_IIN |
65+
PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT |
66+
PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
67+
PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP |
68+
PMBUS_HAVE_VCAP,
69+
70+
/* Page 1: Vsb. */
71+
.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
72+
PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
73+
PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT |
74+
PMBUS_HAVE_POUT,
75+
76+
/*
77+
* Page 2: V1 Ishare.
78+
* Page 3: Reserved.
79+
* Page 4: V1 Cathode.
80+
* Page 5: Vsb Cathode.
81+
* Page 6: V1 Sense.
82+
*/
83+
.func[2] = PMBUS_HAVE_VOUT,
84+
.func[4] = PMBUS_HAVE_VOUT,
85+
.func[5] = PMBUS_HAVE_VOUT,
86+
.func[6] = PMBUS_HAVE_VOUT,
87+
},
88+
};
89+
90+
static int pfe_pmbus_probe(struct i2c_client *client,
91+
const struct i2c_device_id *id)
92+
{
93+
int model;
94+
95+
model = (int)id->driver_data;
96+
97+
/*
98+
* PFE3000-12-069RA devices may not stay in page 0 during device
99+
* probe which leads to probe failure (read status word failed).
100+
* So let's set the device to page 0 at the beginning.
101+
*/
102+
if (model == pfe3000) {
103+
client->dev.platform_data = &pfe3000_plat_data;
104+
i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
105+
}
106+
107+
return pmbus_do_probe(client, id, &pfe_driver_info[model]);
108+
}
109+
110+
static const struct i2c_device_id pfe_device_id[] = {
111+
{"pfe1100", pfe1100},
112+
{"pfe3000", pfe3000},
113+
{}
114+
};
115+
116+
MODULE_DEVICE_TABLE(i2c, pfe_device_id);
117+
118+
static struct i2c_driver pfe_pmbus_driver = {
119+
.driver = {
120+
.name = "bel-pfe",
121+
},
122+
.probe = pfe_pmbus_probe,
123+
.remove = pmbus_do_remove,
124+
.id_table = pfe_device_id,
125+
};
126+
127+
module_i2c_driver(pfe_pmbus_driver);
128+
129+
MODULE_AUTHOR("Tao Ren <[email protected]>");
130+
MODULE_DESCRIPTION("PMBus driver for BEL PFE Family Power Supplies");
131+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)