summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Sloyko <maxims@google.com>2019-04-15 18:28:07 -0400
committerGuenter Roeck <linux@roeck-us.net>2019-04-15 20:19:53 -0400
commit038a9c3d1e42420943c60f879fdb00b62f207f9c (patch)
treed7f5e84bd3bbb79c8038f2ac47f445281415b062
parent991d679951f0df27db170036080746b84115e1e7 (diff)
hwmon: (pmbus/isl68137) Add driver for Intersil ISL68137 PWM Controller
Intersil ISL68137 is a digital output 7-phase configurable PWM controller with an AVSBus interface. Signed-off-by: Maxim Sloyko <maxims@google.com> Signed-off-by: Robert Lippert <rlippert@google.com> Signed-off-by: Patrick Venture <venture@google.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--Documentation/hwmon/isl6813772
-rw-r--r--drivers/hwmon/pmbus/Kconfig9
-rw-r--r--drivers/hwmon/pmbus/Makefile1
-rw-r--r--drivers/hwmon/pmbus/isl68137.c169
4 files changed, 251 insertions, 0 deletions
diff --git a/Documentation/hwmon/isl68137 b/Documentation/hwmon/isl68137
new file mode 100644
index 000000000000..92e5c5fc5b77
--- /dev/null
+++ b/Documentation/hwmon/isl68137
@@ -0,0 +1,72 @@
1Kernel driver isl68137
2======================
3
4Supported chips:
5 * Intersil ISL68137
6 Prefix: 'isl68137'
7 Addresses scanned: -
8 Datasheet: Publicly available at the Intersil website
9 https://www.intersil.com/content/dam/Intersil/documents/isl6/isl68137.pdf
10
11Authors:
12 Maxim Sloyko <maxims@google.com>
13 Robert Lippert <rlippert@google.com>
14 Patrick Venture <venture@google.com>
15
16Description
17-----------
18
19Intersil ISL68137 is a digital output 7-phase configurable PWM
20controller with an AVSBus interface.
21
22Usage Notes
23-----------
24
25This driver does not probe for PMBus devices. You will have to instantiate
26devices explicitly.
27
28The ISL68137 AVS operation mode must be enabled/disabled at runtime.
29
30Beyond the normal sysfs pmbus attributes, the driver exposes a control attribute.
31
32Additional Sysfs attributes
33---------------------------
34
35avs(0|1)_enable Controls the AVS state of each rail.
36
37curr1_label "iin"
38curr1_input Measured input current
39curr1_crit Critical maximum current
40curr1_crit_alarm Current critical high alarm
41
42curr[2-3]_label "iout[1-2]"
43curr[2-3]_input Measured output current
44curr[2-3]_crit Critical maximum current
45curr[2-3]_crit_alarm Current critical high alarm
46
47in1_label "vin"
48in1_input Measured input voltage
49in1_lcrit Critical minimum input voltage
50in1_lcrit_alarm Input voltage critical low alarm
51in1_crit Critical maximum input voltage
52in1_crit_alarm Input voltage critical high alarm
53
54in[2-3]_label "vout[1-2]"
55in[2-3]_input Measured output voltage
56in[2-3]_lcrit Critical minimum output voltage
57in[2-3]_lcrit_alarm Output voltage critical low alarm
58in[2-3]_crit Critical maximum output voltage
59in[2-3]_crit_alarm Output voltage critical high alarm
60
61power1_label "pin"
62power1_input Measured input power
63power1_alarm Input power high alarm
64
65power[2-3]_label "pout[1-2]"
66power[2-3]_input Measured output power
67
68temp[1-3]_input Measured temperature
69temp[1-3]_crit Critical high temperature
70temp[1-3]_crit_alarm Chip temperature critical high alarm
71temp[1-3]_max Maximum temperature
72temp[1-3]_max_alarm Chip temperature high alarm
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index de87abab990e..7edab7e30eaf 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -63,6 +63,15 @@ config SENSORS_IR38064
63 This driver can also be built as a module. If so, the module will 63 This driver can also be built as a module. If so, the module will
64 be called ir38064. 64 be called ir38064.
65 65
66config SENSORS_ISL68137
67 tristate "Intersil ISL68137"
68 help
69 If you say yes here you get hardware monitoring support for Intersil
70 ISL68137.
71
72 This driver can also be built as a module. If so, the module will
73 be called isl68137.
74
66config SENSORS_LM25066 75config SENSORS_LM25066
67 tristate "National Semiconductor LM25066 and compatibles" 76 tristate "National Semiconductor LM25066 and compatibles"
68 help 77 help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 7d1fa6b3c8c9..2219b9300316 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o
9obj-$(CONFIG_SENSORS_IBM_CFFPS) += ibm-cffps.o 9obj-$(CONFIG_SENSORS_IBM_CFFPS) += ibm-cffps.o
10obj-$(CONFIG_SENSORS_IR35221) += ir35221.o 10obj-$(CONFIG_SENSORS_IR35221) += ir35221.o
11obj-$(CONFIG_SENSORS_IR38064) += ir38064.o 11obj-$(CONFIG_SENSORS_IR38064) += ir38064.o
12obj-$(CONFIG_SENSORS_ISL68137) += isl68137.o
12obj-$(CONFIG_SENSORS_LM25066) += lm25066.o 13obj-$(CONFIG_SENSORS_LM25066) += lm25066.o
13obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o 14obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o
14obj-$(CONFIG_SENSORS_LTC3815) += ltc3815.o 15obj-$(CONFIG_SENSORS_LTC3815) += ltc3815.o
diff --git a/drivers/hwmon/pmbus/isl68137.c b/drivers/hwmon/pmbus/isl68137.c
new file mode 100644
index 000000000000..515596c92fe1
--- /dev/null
+++ b/drivers/hwmon/pmbus/isl68137.c
@@ -0,0 +1,169 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Hardware monitoring driver for Intersil ISL68137
4 *
5 * Copyright (c) 2017 Google Inc
6 *
7 */
8
9#include <linux/err.h>
10#include <linux/hwmon-sysfs.h>
11#include <linux/i2c.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/string.h>
16#include <linux/sysfs.h>
17#include "pmbus.h"
18
19#define ISL68137_VOUT_AVS 0x30
20
21static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client,
22 int page,
23 char *buf)
24{
25 int val = pmbus_read_byte_data(client, page, PMBUS_OPERATION);
26
27 return sprintf(buf, "%d\n",
28 (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS ? 1 : 0);
29}
30
31static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client,
32 int page,
33 const char *buf, size_t count)
34{
35 int rc, op_val;
36 bool result;
37
38 rc = kstrtobool(buf, &result);
39 if (rc)
40 return rc;
41
42 op_val = result ? ISL68137_VOUT_AVS : 0;
43
44 /*
45 * Writes to VOUT setpoint over AVSBus will persist after the VRM is
46 * switched to PMBus control. Switching back to AVSBus control
47 * restores this persisted setpoint rather than re-initializing to
48 * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before
49 * enabling AVS control is the workaround.
50 */
51 if (op_val == ISL68137_VOUT_AVS) {
52 rc = pmbus_read_word_data(client, page, PMBUS_VOUT_COMMAND);
53 if (rc < 0)
54 return rc;
55
56 rc = pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND,
57 rc);
58 if (rc < 0)
59 return rc;
60 }
61
62 rc = pmbus_update_byte_data(client, page, PMBUS_OPERATION,
63 ISL68137_VOUT_AVS, op_val);
64
65 return (rc < 0) ? rc : count;
66}
67
68static ssize_t isl68137_avs_enable_show(struct device *dev,
69 struct device_attribute *devattr,
70 char *buf)
71{
72 struct i2c_client *client = to_i2c_client(dev->parent);
73 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
74
75 return isl68137_avs_enable_show_page(client, attr->index, buf);
76}
77
78static ssize_t isl68137_avs_enable_store(struct device *dev,
79 struct device_attribute *devattr,
80 const char *buf, size_t count)
81{
82 struct i2c_client *client = to_i2c_client(dev->parent);
83 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
84
85 return isl68137_avs_enable_store_page(client, attr->index, buf, count);
86}
87
88static SENSOR_DEVICE_ATTR_RW(avs0_enable, isl68137_avs_enable, 0);
89static SENSOR_DEVICE_ATTR_RW(avs1_enable, isl68137_avs_enable, 1);
90
91static struct attribute *enable_attrs[] = {
92 &sensor_dev_attr_avs0_enable.dev_attr.attr,
93 &sensor_dev_attr_avs1_enable.dev_attr.attr,
94 NULL,
95};
96
97static const struct attribute_group enable_group = {
98 .attrs = enable_attrs,
99};
100
101static const struct attribute_group *attribute_groups[] = {
102 &enable_group,
103 NULL,
104};
105
106static struct pmbus_driver_info isl68137_info = {
107 .pages = 2,
108 .format[PSC_VOLTAGE_IN] = direct,
109 .format[PSC_VOLTAGE_OUT] = direct,
110 .format[PSC_CURRENT_IN] = direct,
111 .format[PSC_CURRENT_OUT] = direct,
112 .format[PSC_POWER] = direct,
113 .format[PSC_TEMPERATURE] = direct,
114 .m[PSC_VOLTAGE_IN] = 1,
115 .b[PSC_VOLTAGE_IN] = 0,
116 .R[PSC_VOLTAGE_IN] = 3,
117 .m[PSC_VOLTAGE_OUT] = 1,
118 .b[PSC_VOLTAGE_OUT] = 0,
119 .R[PSC_VOLTAGE_OUT] = 3,
120 .m[PSC_CURRENT_IN] = 1,
121 .b[PSC_CURRENT_IN] = 0,
122 .R[PSC_CURRENT_IN] = 2,
123 .m[PSC_CURRENT_OUT] = 1,
124 .b[PSC_CURRENT_OUT] = 0,
125 .R[PSC_CURRENT_OUT] = 1,
126 .m[PSC_POWER] = 1,
127 .b[PSC_POWER] = 0,
128 .R[PSC_POWER] = 0,
129 .m[PSC_TEMPERATURE] = 1,
130 .b[PSC_TEMPERATURE] = 0,
131 .R[PSC_TEMPERATURE] = 0,
132 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN
133 | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
134 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
135 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
136 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
137 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
138 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
139 .groups = attribute_groups,
140};
141
142static int isl68137_probe(struct i2c_client *client,
143 const struct i2c_device_id *id)
144{
145 return pmbus_do_probe(client, id, &isl68137_info);
146}
147
148static const struct i2c_device_id isl68137_id[] = {
149 {"isl68137", 0},
150 {}
151};
152
153MODULE_DEVICE_TABLE(i2c, isl68137_id);
154
155/* This is the driver that will be inserted */
156static struct i2c_driver isl68137_driver = {
157 .driver = {
158 .name = "isl68137",
159 },
160 .probe = isl68137_probe,
161 .remove = pmbus_do_remove,
162 .id_table = isl68137_id,
163};
164
165module_i2c_driver(isl68137_driver);
166
167MODULE_AUTHOR("Maxim Sloyko <maxims@google.com>");
168MODULE_DESCRIPTION("PMBus driver for Intersil ISL68137");
169MODULE_LICENSE("GPL");