diff options
author | Edward A. James <eajames@us.ibm.com> | 2017-08-21 15:46:12 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2017-08-29 21:06:18 -0400 |
commit | f69316d62c7066edc4693b85c6e9f987eed62772 (patch) | |
tree | 77c8bbb6ab1349f650ada7d50819ee35edadf341 | |
parent | 74560e4a440891649971a11e518681b088c6a1f9 (diff) |
hwmon: (pmbus) Add IBM Common Form Factor (CFF) power supply driver
Add the driver to monitor IBM CFF power supplies with hwmon over
pmbus.
Signed-off-by: Edward A. James <eajames@us.ibm.com>
[groeck: drop 'default n'; include bitops.h instead of jiffies.h]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/pmbus/Kconfig | 9 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/Makefile | 1 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/ibm-cffps.c | 151 |
3 files changed, 161 insertions, 0 deletions
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 68d717a3fd59..522ac37d8a69 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
@@ -37,6 +37,15 @@ config SENSORS_ADM1275 | |||
37 | This driver can also be built as a module. If so, the module will | 37 | This driver can also be built as a module. If so, the module will |
38 | be called adm1275. | 38 | be called adm1275. |
39 | 39 | ||
40 | config SENSORS_IBM_CFFPS | ||
41 | tristate "IBM Common Form Factor Power Supply" | ||
42 | help | ||
43 | If you say yes here you get hardware monitoring support for the IBM | ||
44 | Common Form Factor power supply. | ||
45 | |||
46 | This driver can also be built as a module. If so, the module will | ||
47 | be called ibm-cffps. | ||
48 | |||
40 | config SENSORS_IR35221 | 49 | config SENSORS_IR35221 |
41 | tristate "Infineon IR35221" | 50 | tristate "Infineon IR35221" |
42 | default n | 51 | default n |
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile index 75bb7ca619d9..737fa4efb3cc 100644 --- a/drivers/hwmon/pmbus/Makefile +++ b/drivers/hwmon/pmbus/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | obj-$(CONFIG_PMBUS) += pmbus_core.o | 5 | obj-$(CONFIG_PMBUS) += pmbus_core.o |
6 | obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o | 6 | obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o |
7 | obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o | 7 | obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o |
8 | obj-$(CONFIG_SENSORS_IBM_CFFPS) += ibm-cffps.o | ||
8 | obj-$(CONFIG_SENSORS_IR35221) += ir35221.o | 9 | obj-$(CONFIG_SENSORS_IR35221) += ir35221.o |
9 | obj-$(CONFIG_SENSORS_LM25066) += lm25066.o | 10 | obj-$(CONFIG_SENSORS_LM25066) += lm25066.o |
10 | obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o | 11 | obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o |
diff --git a/drivers/hwmon/pmbus/ibm-cffps.c b/drivers/hwmon/pmbus/ibm-cffps.c new file mode 100644 index 000000000000..cb56da6834e5 --- /dev/null +++ b/drivers/hwmon/pmbus/ibm-cffps.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * Copyright 2017 IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/bitops.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/module.h> | ||
14 | |||
15 | #include "pmbus.h" | ||
16 | |||
17 | /* STATUS_MFR_SPECIFIC bits */ | ||
18 | #define CFFPS_MFR_FAN_FAULT BIT(0) | ||
19 | #define CFFPS_MFR_THERMAL_FAULT BIT(1) | ||
20 | #define CFFPS_MFR_OV_FAULT BIT(2) | ||
21 | #define CFFPS_MFR_UV_FAULT BIT(3) | ||
22 | #define CFFPS_MFR_PS_KILL BIT(4) | ||
23 | #define CFFPS_MFR_OC_FAULT BIT(5) | ||
24 | #define CFFPS_MFR_VAUX_FAULT BIT(6) | ||
25 | #define CFFPS_MFR_CURRENT_SHARE_WARNING BIT(7) | ||
26 | |||
27 | static int ibm_cffps_read_byte_data(struct i2c_client *client, int page, | ||
28 | int reg) | ||
29 | { | ||
30 | int rc, mfr; | ||
31 | |||
32 | switch (reg) { | ||
33 | case PMBUS_STATUS_VOUT: | ||
34 | case PMBUS_STATUS_IOUT: | ||
35 | case PMBUS_STATUS_TEMPERATURE: | ||
36 | case PMBUS_STATUS_FAN_12: | ||
37 | rc = pmbus_read_byte_data(client, page, reg); | ||
38 | if (rc < 0) | ||
39 | return rc; | ||
40 | |||
41 | mfr = pmbus_read_byte_data(client, page, | ||
42 | PMBUS_STATUS_MFR_SPECIFIC); | ||
43 | if (mfr < 0) | ||
44 | /* | ||
45 | * Return the status register instead of an error, | ||
46 | * since we successfully read status. | ||
47 | */ | ||
48 | return rc; | ||
49 | |||
50 | /* Add MFR_SPECIFIC bits to the standard pmbus status regs. */ | ||
51 | if (reg == PMBUS_STATUS_FAN_12) { | ||
52 | if (mfr & CFFPS_MFR_FAN_FAULT) | ||
53 | rc |= PB_FAN_FAN1_FAULT; | ||
54 | } else if (reg == PMBUS_STATUS_TEMPERATURE) { | ||
55 | if (mfr & CFFPS_MFR_THERMAL_FAULT) | ||
56 | rc |= PB_TEMP_OT_FAULT; | ||
57 | } else if (reg == PMBUS_STATUS_VOUT) { | ||
58 | if (mfr & (CFFPS_MFR_OV_FAULT | CFFPS_MFR_VAUX_FAULT)) | ||
59 | rc |= PB_VOLTAGE_OV_FAULT; | ||
60 | if (mfr & CFFPS_MFR_UV_FAULT) | ||
61 | rc |= PB_VOLTAGE_UV_FAULT; | ||
62 | } else if (reg == PMBUS_STATUS_IOUT) { | ||
63 | if (mfr & CFFPS_MFR_OC_FAULT) | ||
64 | rc |= PB_IOUT_OC_FAULT; | ||
65 | if (mfr & CFFPS_MFR_CURRENT_SHARE_WARNING) | ||
66 | rc |= PB_CURRENT_SHARE_FAULT; | ||
67 | } | ||
68 | break; | ||
69 | default: | ||
70 | rc = -ENODATA; | ||
71 | break; | ||
72 | } | ||
73 | |||
74 | return rc; | ||
75 | } | ||
76 | |||
77 | static int ibm_cffps_read_word_data(struct i2c_client *client, int page, | ||
78 | int reg) | ||
79 | { | ||
80 | int rc, mfr; | ||
81 | |||
82 | switch (reg) { | ||
83 | case PMBUS_STATUS_WORD: | ||
84 | rc = pmbus_read_word_data(client, page, reg); | ||
85 | if (rc < 0) | ||
86 | return rc; | ||
87 | |||
88 | mfr = pmbus_read_byte_data(client, page, | ||
89 | PMBUS_STATUS_MFR_SPECIFIC); | ||
90 | if (mfr < 0) | ||
91 | /* | ||
92 | * Return the status register instead of an error, | ||
93 | * since we successfully read status. | ||
94 | */ | ||
95 | return rc; | ||
96 | |||
97 | if (mfr & CFFPS_MFR_PS_KILL) | ||
98 | rc |= PB_STATUS_OFF; | ||
99 | break; | ||
100 | default: | ||
101 | rc = -ENODATA; | ||
102 | break; | ||
103 | } | ||
104 | |||
105 | return rc; | ||
106 | } | ||
107 | |||
108 | static struct pmbus_driver_info ibm_cffps_info = { | ||
109 | .pages = 1, | ||
110 | .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | | ||
111 | PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | | ||
112 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT | | ||
113 | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT | | ||
114 | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12, | ||
115 | .read_byte_data = ibm_cffps_read_byte_data, | ||
116 | .read_word_data = ibm_cffps_read_word_data, | ||
117 | }; | ||
118 | |||
119 | static int ibm_cffps_probe(struct i2c_client *client, | ||
120 | const struct i2c_device_id *id) | ||
121 | { | ||
122 | return pmbus_do_probe(client, id, &ibm_cffps_info); | ||
123 | } | ||
124 | |||
125 | static const struct i2c_device_id ibm_cffps_id[] = { | ||
126 | { "ibm_cffps1", 1 }, | ||
127 | {} | ||
128 | }; | ||
129 | MODULE_DEVICE_TABLE(i2c, ibm_cffps_id); | ||
130 | |||
131 | static const struct of_device_id ibm_cffps_of_match[] = { | ||
132 | { .compatible = "ibm,cffps1" }, | ||
133 | {} | ||
134 | }; | ||
135 | MODULE_DEVICE_TABLE(of, ibm_cffps_of_match); | ||
136 | |||
137 | static struct i2c_driver ibm_cffps_driver = { | ||
138 | .driver = { | ||
139 | .name = "ibm-cffps", | ||
140 | .of_match_table = ibm_cffps_of_match, | ||
141 | }, | ||
142 | .probe = ibm_cffps_probe, | ||
143 | .remove = pmbus_do_remove, | ||
144 | .id_table = ibm_cffps_id, | ||
145 | }; | ||
146 | |||
147 | module_i2c_driver(ibm_cffps_driver); | ||
148 | |||
149 | MODULE_AUTHOR("Eddie James"); | ||
150 | MODULE_DESCRIPTION("PMBus driver for IBM Common Form Factor power supplies"); | ||
151 | MODULE_LICENSE("GPL"); | ||