Skip to content

Commit 669cf16

Browse files
Vasileios Amoiridisgroeck
authored andcommitted
hwmon: Add support for HiTRON HAC300S PSU
Add Support for HiTRON HAC300S PSU. This is a AC/DC hot-swappable CompactPCI Serial Dual output active current sharing switching power supply with a 312W rating. Signed-off-by: Vasileios Amoiridis <vasileios.amoiridis@cern.ch> Link: https://lore.kernel.org/r/20260119190806.35276-3-vassilisamir@gmail.com [groeck: Fix whitespace / alignment problems; return -ENODATA from hac300s_read_byte_data() if the PMBus core can handle the operation] Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent 438921d commit 669cf16

6 files changed

Lines changed: 187 additions & 0 deletions

File tree

Documentation/hwmon/hac300s.rst

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
Kernel driver hac300s
4+
=====================
5+
6+
Supported chips:
7+
8+
* HiTRON HAC300S
9+
10+
Prefix: 'hac300s'
11+
12+
Datasheet: Publicly available at HiTRON website.
13+
14+
Author:
15+
16+
- Vasileios Amoiridis <vasileios.amoiridis@cern.ch>
17+
18+
Description
19+
-----------
20+
21+
This driver supports the HiTRON HAC300S PSU. It is a Universal AC input
22+
harmonic correction AC-DC hot-swappable CompactPCI Serial Dual output
23+
(with 5V standby) 312 Watts active current sharing switching power supply.
24+
25+
The device has an input of 90-264VAC and 2 nominal output voltaged at 12V and
26+
5V which they can supplu up to 25A and 2.5A respectively.
27+
28+
Sysfs entries
29+
-------------
30+
31+
======= ==========================================
32+
curr1 Output current
33+
in1 Output voltage
34+
power1 Output power
35+
temp1 Ambient temperature inside the module
36+
temp2 Internal secondary component's temperature
37+
======= ==========================================

Documentation/hwmon/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Hardware Monitoring Kernel Drivers
8484
gl518sm
8585
gpd-fan
8686
gxp-fan-ctrl
87+
hac300s
8788
hih6130
8889
hp-wmi-sensors
8990
hs3001

MAINTAINERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11259,6 +11259,13 @@ F: kernel/time/timer_list.c
1125911259
F: kernel/time/timer_migration.*
1126011260
F: tools/testing/selftests/timers/
1126111261

11262+
HITRON HAC300S PSU DRIVER
11263+
M: Vasileios Amoiridis <vasileios.amoiridis@cern.ch>
11264+
L: linux-hwmon@vger.kernel.org
11265+
S: Maintained
11266+
F: Documentation/hwmon/hac300s.rst
11267+
F: drivers/hwmon/pmbus/hac300s.c
11268+
1126211269
DELAY, SLEEP, TIMEKEEPING, TIMERS [RUST]
1126311270
M: Andreas Hindborg <a.hindborg@kernel.org>
1126411271
R: Boqun Feng <boqun.feng@gmail.com>

drivers/hwmon/pmbus/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@ config SENSORS_FSP_3Y
124124
This driver can also be built as a module. If so, the module will
125125
be called fsp-3y.
126126

127+
config SENSORS_HAC300S
128+
tristate "Hitron HAC300S-D120E PSU"
129+
help
130+
If you say yes here you get hardware monitoring support for the
131+
Hitron HAC300S-D120E Power Supply.
132+
133+
This driver can also be built as a module. If so, the module will
134+
be called hac300s.
135+
127136
config SENSORS_IBM_CFFPS
128137
tristate "IBM Common Form Factor Power Supply"
129138
depends on LEDS_CLASS

drivers/hwmon/pmbus/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_BEL_PFE) += bel-pfe.o
1313
obj-$(CONFIG_SENSORS_BPA_RS600) += bpa-rs600.o
1414
obj-$(CONFIG_SENSORS_DELTA_AHE50DC_FAN) += delta-ahe50dc-fan.o
1515
obj-$(CONFIG_SENSORS_FSP_3Y) += fsp-3y.o
16+
obj-$(CONFIG_SENSORS_HAC300S) += hac300s.o
1617
obj-$(CONFIG_SENSORS_IBM_CFFPS) += ibm-cffps.o
1718
obj-$(CONFIG_SENSORS_DPS920AB) += dps920ab.o
1819
obj-$(CONFIG_SENSORS_INA233) += ina233.o

drivers/hwmon/pmbus/hac300s.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
// SPDX-FileCopyrightText: 2024 CERN (home.cern)
3+
/*
4+
* Hardware monitoring driver for Hi-Tron HAC300S PSU.
5+
*
6+
* NOTE: The HAC300S device does not support the PMBUS_VOUT_MODE register.
7+
* On top of that, it returns the Voltage output values in Linear11 which is
8+
* not adhering to the PMBus specifications. (PMBus Specification Part II,
9+
* Section 7.1-7.3). For that reason the PMBUS_VOUT_MODE register is being faked
10+
* and returns the exponent value of the READ_VOUT register. The exponent part
11+
* of the VOUT_* registers is being cleared in order to return the mantissa to
12+
* the pmbus core.
13+
*/
14+
15+
#include <linux/bitfield.h>
16+
#include <linux/bits.h>
17+
#include <linux/err.h>
18+
#include <linux/i2c.h>
19+
#include <linux/init.h>
20+
#include <linux/kernel.h>
21+
#include <linux/module.h>
22+
#include <linux/pmbus.h>
23+
24+
#include "pmbus.h"
25+
26+
#define LINEAR11_EXPONENT_MASK GENMASK(15, 11)
27+
#define LINEAR11_MANTISSA_MASK GENMASK(10, 0)
28+
29+
#define to_hac300s_data(x) container_of(x, struct hac300s_data, info)
30+
31+
struct hac300s_data {
32+
struct pmbus_driver_info info;
33+
s8 exponent;
34+
};
35+
36+
static int hac300s_read_byte_data(struct i2c_client *client, int page, int reg)
37+
{
38+
const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
39+
struct hac300s_data *data = to_hac300s_data(info);
40+
41+
if (reg == PMBUS_VOUT_MODE)
42+
return data->exponent;
43+
44+
return -ENODATA;
45+
}
46+
47+
static int hac300s_read_word_data(struct i2c_client *client, int page,
48+
int phase, int reg)
49+
{
50+
int rv;
51+
52+
switch (reg) {
53+
case PMBUS_VOUT_OV_WARN_LIMIT:
54+
case PMBUS_VOUT_UV_WARN_LIMIT:
55+
case PMBUS_VOUT_OV_FAULT_LIMIT:
56+
case PMBUS_VOUT_UV_FAULT_LIMIT:
57+
case PMBUS_MFR_VOUT_MAX:
58+
case PMBUS_MFR_VOUT_MIN:
59+
case PMBUS_READ_VOUT:
60+
rv = pmbus_read_word_data(client, page, phase, reg);
61+
return FIELD_GET(LINEAR11_MANTISSA_MASK, rv);
62+
default:
63+
return -ENODATA;
64+
}
65+
}
66+
67+
static struct pmbus_driver_info hac300s_info = {
68+
.pages = 1,
69+
.func[0] = PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | \
70+
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | \
71+
PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | \
72+
PMBUS_HAVE_POUT | PMBUS_HAVE_STATUS_TEMP,
73+
.read_byte_data = hac300s_read_byte_data,
74+
.read_word_data = hac300s_read_word_data,
75+
.format[PSC_VOLTAGE_OUT] = linear,
76+
};
77+
78+
static struct pmbus_platform_data hac300s_pdata = {
79+
.flags = PMBUS_NO_CAPABILITY,
80+
};
81+
82+
static int hac300s_probe(struct i2c_client *client)
83+
{
84+
struct hac300s_data *data;
85+
int rv;
86+
87+
data = devm_kzalloc(&client->dev, sizeof(struct hac300s_data), GFP_KERNEL);
88+
if (!data)
89+
return -ENOMEM;
90+
91+
if (!i2c_check_functionality(client->adapter,
92+
I2C_FUNC_SMBUS_READ_BYTE_DATA |
93+
I2C_FUNC_SMBUS_READ_WORD_DATA))
94+
return -ENODEV;
95+
96+
rv = i2c_smbus_read_word_data(client, PMBUS_READ_VOUT);
97+
if (rv < 0)
98+
return dev_err_probe(&client->dev, rv, "Failed to read vout_mode\n");
99+
100+
data->exponent = FIELD_GET(LINEAR11_EXPONENT_MASK, rv);
101+
data->info = hac300s_info;
102+
client->dev.platform_data = &hac300s_pdata;
103+
return pmbus_do_probe(client, &data->info);
104+
}
105+
106+
static const struct of_device_id hac300s_of_match[] = {
107+
{ .compatible = "hitron,hac300s" },
108+
{}
109+
};
110+
MODULE_DEVICE_TABLE(of, hac300s_of_match);
111+
112+
static const struct i2c_device_id hac300s_id[] = {
113+
{"hac300s", 0},
114+
{}
115+
};
116+
MODULE_DEVICE_TABLE(i2c, hac300s_id);
117+
118+
static struct i2c_driver hac300s_driver = {
119+
.driver = {
120+
.name = "hac300s",
121+
.of_match_table = hac300s_of_match,
122+
},
123+
.probe = hac300s_probe,
124+
.id_table = hac300s_id,
125+
126+
};
127+
module_i2c_driver(hac300s_driver);
128+
129+
MODULE_AUTHOR("Vasileios Amoiridis");
130+
MODULE_DESCRIPTION("PMBus driver for Hi-Tron HAC300S PSU");
131+
MODULE_LICENSE("GPL");
132+
MODULE_IMPORT_NS("PMBUS");

0 commit comments

Comments
 (0)