forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[dps200] Add dps200 PSU module driver (#207)
Fix sonic-net#6602 This change is add new dps200 PSU module driver for fix this issue sonic-net#6602 I have try to use the generic pmbus driver, but it not support. [ 5733.051510] pmbus 12-005a: Chip identification failed [ 5733.112598] i2c i2c-12: new_device: Instantiated device pmbus at 0x5a [ 5748.459851] pmbus 13-005b: Chip identification failed [ 5748.520975] i2c i2c-13: new_device: Instantiated device pmbus at 0x5b
- Loading branch information
Showing
2 changed files
with
159 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,158 @@ | ||
From 966db1e756443757cf74b7d0ba56a3254e35fd79 Mon Sep 17 00:00:00 2001 | ||
|
||
From: Saranpong Chobtrong <schobtr@celestica.com> | ||
|
||
Subject: [PATCH] hwmon: (pmbus/dps200): Support DPS200 PSU module | ||
|
||
The generic PMBUS driver does not support the chip that uses direct mode yet. | ||
This driver supports dps200 which uses coefficients defined in the datasheet. | ||
Ref: datasheet is DPS200PB184E-ES002.pdf [not public access datasheet] | ||
|
||
DP200 does not support pmbus coefficient commands. | ||
Each field of direct mode has a conversion definition defined by the datasheet. | ||
|
||
Add dps200 device to the dps1900 driver. | ||
|
||
Signed-off-by: Saranpong Chobtrong <schobtr@celestica.com> | ||
--- | ||
drivers/hwmon/pmbus/dps1900.c | 104 +++++++++++++++++++++++++++++++++++++++-- | ||
1 file changed, 98 insertions(+), 6 deletions(-) | ||
|
||
diff --git a/drivers/hwmon/pmbus/dps1900.c b/drivers/hwmon/pmbus/dps1900.c | ||
index f737f6480..d60c48e2c 100644 | ||
--- a/drivers/hwmon/pmbus/dps1900.c | ||
+++ b/drivers/hwmon/pmbus/dps1900.c | ||
@@ -1,3 +1,5 @@ | ||
+// SPDX-License-Identifier: GPL-2.0-or-later | ||
+ | ||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/init.h> | ||
@@ -7,6 +9,8 @@ | ||
#include <linux/pmbus.h> | ||
#include "pmbus.h" | ||
|
||
+enum chips { dps1900, dps200 }; | ||
+ | ||
static int dps1900_read_word_data(struct i2c_client *client, int page, int reg) | ||
{ | ||
if (reg >= PMBUS_VIRT_BASE || | ||
@@ -30,24 +34,112 @@ static int dps1900_read_word_data(struct i2c_client *client, int page, int reg) | ||
return pmbus_read_word_data(client, page, reg); | ||
} | ||
|
||
+static int dps200_read_word_data(struct i2c_client *client, int page, int reg) | ||
+{ | ||
+ | ||
+ if (reg >= PMBUS_VIRT_BASE || | ||
+ reg == PMBUS_VOUT_OV_FAULT_LIMIT || | ||
+ reg == PMBUS_VOUT_OV_WARN_LIMIT || | ||
+ reg == PMBUS_VOUT_UV_WARN_LIMIT || | ||
+ reg == PMBUS_VOUT_UV_FAULT_LIMIT || | ||
+ reg == PMBUS_IOUT_OC_LV_FAULT_LIMIT || | ||
+ reg == PMBUS_IOUT_UC_FAULT_LIMIT || | ||
+ reg == PMBUS_UT_WARN_LIMIT || | ||
+ reg == PMBUS_UT_FAULT_LIMIT || | ||
+ reg == PMBUS_VIN_OV_FAULT_LIMIT || | ||
+ reg == PMBUS_VIN_OV_WARN_LIMIT || | ||
+ reg == PMBUS_IIN_OC_FAULT_LIMIT || | ||
+ reg == PMBUS_POUT_MAX) | ||
+ return -ENXIO; | ||
+ | ||
+ /* | ||
+ * NOTE: The following field have constant driver value. | ||
+ * If the register are PMBUS_IOUT_OC_WARN_LIMIT or | ||
+ * PMBUS_IOUT_OC_FAULT_LIMIT convert the constant value from linear | ||
+ * to direct format. | ||
+ */ | ||
+ if (reg == PMBUS_IOUT_OC_WARN_LIMIT) | ||
+ return 0xb4; | ||
+ else if (reg == PMBUS_IOUT_OC_FAULT_LIMIT) | ||
+ return 0xc8; | ||
+ else | ||
+ return pmbus_read_word_data(client, page, reg); | ||
+} | ||
+ | ||
static struct pmbus_driver_info dps1900_info = { | ||
.pages = 1, | ||
.func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
- | PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ||
- | PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 | ||
- | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP | ||
- | PMBUS_HAVE_STATUS_INPUT, | ||
+ | PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ||
+ | PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 | ||
+ | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP | ||
+ | PMBUS_HAVE_STATUS_INPUT, | ||
.read_word_data = dps1900_read_word_data, | ||
}; | ||
|
||
+/* | ||
+ * From DPS-200 datasheet the supported sensors format defined as: | ||
+ * VOUT: direct mode with one decimal place. | ||
+ * | ||
+ * Other sensors: | ||
+ * IOUT: direct mode with one decimal place. | ||
+ * IOUT Limits: linear mode, which difference from IOUT. | ||
+ * VIN, IIN, POWER, TEMP, & FAN: linear mode. | ||
+ */ | ||
+static struct pmbus_driver_info dps200_info = { | ||
+ .pages = 1, | ||
+ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
+ | PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ||
+ | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | ||
+ | PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 | ||
+ | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | ||
+ | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_INPUT, | ||
+ .format = { | ||
+ [PSC_VOLTAGE_OUT] = direct, | ||
+ [PSC_CURRENT_OUT] = direct, | ||
+ }, | ||
+ .m = { | ||
+ [PSC_VOLTAGE_OUT] = 10, | ||
+ [PSC_CURRENT_OUT] = 10, | ||
+ }, | ||
+ .b = { | ||
+ [PSC_VOLTAGE_OUT] = 0, | ||
+ [PSC_CURRENT_OUT] = 0, | ||
+ }, | ||
+ .R = { | ||
+ [PSC_VOLTAGE_OUT] = 0, | ||
+ [PSC_CURRENT_OUT] = 0, | ||
+ }, | ||
+ .read_word_data = dps200_read_word_data, | ||
+}; | ||
+ | ||
static int dps1900_probe(struct i2c_client *client, | ||
const struct i2c_device_id *id) | ||
{ | ||
- return pmbus_do_probe(client, id, &dps1900_info); | ||
+ struct pmbus_driver_info *info; | ||
+ | ||
+ info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), | ||
+ GFP_KERNEL); | ||
+ if (!info) | ||
+ return -ENOMEM; | ||
+ | ||
+ switch (id->driver_data) { | ||
+ case dps1900: | ||
+ info = &dps1900_info; | ||
+ break; | ||
+ case dps200: | ||
+ info = &dps200_info; | ||
+ break; | ||
+ default: | ||
+ dev_err(&client->dev, "Unsupported device\n"); | ||
+ return -ENODEV; | ||
+ } | ||
+ | ||
+ return pmbus_do_probe(client, id, info); | ||
} | ||
|
||
static const struct i2c_device_id dps1900_id[] = { | ||
- {"dps1900", 0}, | ||
+ {"dps1900", dps1900}, | ||
+ {"dps200", dps200}, | ||
{} | ||
}; | ||
|
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