1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Hardware monitoring driver for Maxim MAX16601
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Implementation notes:
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Ths chip supports two rails, VCORE and VSA. Telemetry information for the
8*4882a593Smuzhiyun * two rails is reported in two subsequent I2C addresses. The driver
9*4882a593Smuzhiyun * instantiates a dummy I2C client at the second I2C address to report
10*4882a593Smuzhiyun * information for the VSA rail in a single instance of the driver.
11*4882a593Smuzhiyun * Telemetry for the VSA rail is reported to the PMBus core in PMBus page 2.
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * The chip reports input current using two separate methods. The input current
14*4882a593Smuzhiyun * reported with the standard READ_IIN command is derived from the output
15*4882a593Smuzhiyun * current. The first method is reported to the PMBus core with PMBus page 0,
16*4882a593Smuzhiyun * the second method is reported with PMBus page 1.
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * The chip supports reading per-phase temperatures and per-phase input/output
19*4882a593Smuzhiyun * currents for VCORE. Telemetry is reported in vendor specific registers.
20*4882a593Smuzhiyun * The driver translates the vendor specific register values to PMBus standard
21*4882a593Smuzhiyun * register values and reports per-phase information in PMBus page 0.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * Copyright 2019, 2020 Google LLC.
24*4882a593Smuzhiyun */
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #include <linux/bits.h>
27*4882a593Smuzhiyun #include <linux/i2c.h>
28*4882a593Smuzhiyun #include <linux/init.h>
29*4882a593Smuzhiyun #include <linux/kernel.h>
30*4882a593Smuzhiyun #include <linux/module.h>
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #include "pmbus.h"
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define REG_SETPT_DVID 0xd1
35*4882a593Smuzhiyun #define DAC_10MV_MODE BIT(4)
36*4882a593Smuzhiyun #define REG_IOUT_AVG_PK 0xee
37*4882a593Smuzhiyun #define REG_IIN_SENSOR 0xf1
38*4882a593Smuzhiyun #define REG_TOTAL_INPUT_POWER 0xf2
39*4882a593Smuzhiyun #define REG_PHASE_ID 0xf3
40*4882a593Smuzhiyun #define CORE_RAIL_INDICATOR BIT(7)
41*4882a593Smuzhiyun #define REG_PHASE_REPORTING 0xf4
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun struct max16601_data {
44*4882a593Smuzhiyun struct pmbus_driver_info info;
45*4882a593Smuzhiyun struct i2c_client *vsa;
46*4882a593Smuzhiyun int iout_avg_pkg;
47*4882a593Smuzhiyun };
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #define to_max16601_data(x) container_of(x, struct max16601_data, info)
50*4882a593Smuzhiyun
max16601_read_byte(struct i2c_client * client,int page,int reg)51*4882a593Smuzhiyun static int max16601_read_byte(struct i2c_client *client, int page, int reg)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
54*4882a593Smuzhiyun struct max16601_data *data = to_max16601_data(info);
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun if (page > 0) {
57*4882a593Smuzhiyun if (page == 2) /* VSA */
58*4882a593Smuzhiyun return i2c_smbus_read_byte_data(data->vsa, reg);
59*4882a593Smuzhiyun return -EOPNOTSUPP;
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun return -ENODATA;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
max16601_read_word(struct i2c_client * client,int page,int phase,int reg)64*4882a593Smuzhiyun static int max16601_read_word(struct i2c_client *client, int page, int phase,
65*4882a593Smuzhiyun int reg)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
68*4882a593Smuzhiyun struct max16601_data *data = to_max16601_data(info);
69*4882a593Smuzhiyun u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
70*4882a593Smuzhiyun int ret;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun switch (page) {
73*4882a593Smuzhiyun case 0: /* VCORE */
74*4882a593Smuzhiyun if (phase == 0xff)
75*4882a593Smuzhiyun return -ENODATA;
76*4882a593Smuzhiyun switch (reg) {
77*4882a593Smuzhiyun case PMBUS_READ_IIN:
78*4882a593Smuzhiyun case PMBUS_READ_IOUT:
79*4882a593Smuzhiyun case PMBUS_READ_TEMPERATURE_1:
80*4882a593Smuzhiyun ret = i2c_smbus_write_byte_data(client, REG_PHASE_ID,
81*4882a593Smuzhiyun phase);
82*4882a593Smuzhiyun if (ret)
83*4882a593Smuzhiyun return ret;
84*4882a593Smuzhiyun ret = i2c_smbus_read_block_data(client,
85*4882a593Smuzhiyun REG_PHASE_REPORTING,
86*4882a593Smuzhiyun buf);
87*4882a593Smuzhiyun if (ret < 0)
88*4882a593Smuzhiyun return ret;
89*4882a593Smuzhiyun if (ret < 6)
90*4882a593Smuzhiyun return -EIO;
91*4882a593Smuzhiyun switch (reg) {
92*4882a593Smuzhiyun case PMBUS_READ_TEMPERATURE_1:
93*4882a593Smuzhiyun return buf[1] << 8 | buf[0];
94*4882a593Smuzhiyun case PMBUS_READ_IOUT:
95*4882a593Smuzhiyun return buf[3] << 8 | buf[2];
96*4882a593Smuzhiyun case PMBUS_READ_IIN:
97*4882a593Smuzhiyun return buf[5] << 8 | buf[4];
98*4882a593Smuzhiyun default:
99*4882a593Smuzhiyun break;
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun return -EOPNOTSUPP;
103*4882a593Smuzhiyun case 1: /* VCORE, read IIN/PIN from sensor element */
104*4882a593Smuzhiyun switch (reg) {
105*4882a593Smuzhiyun case PMBUS_READ_IIN:
106*4882a593Smuzhiyun return i2c_smbus_read_word_data(client, REG_IIN_SENSOR);
107*4882a593Smuzhiyun case PMBUS_READ_PIN:
108*4882a593Smuzhiyun return i2c_smbus_read_word_data(client,
109*4882a593Smuzhiyun REG_TOTAL_INPUT_POWER);
110*4882a593Smuzhiyun default:
111*4882a593Smuzhiyun break;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun return -EOPNOTSUPP;
114*4882a593Smuzhiyun case 2: /* VSA */
115*4882a593Smuzhiyun switch (reg) {
116*4882a593Smuzhiyun case PMBUS_VIRT_READ_IOUT_MAX:
117*4882a593Smuzhiyun ret = i2c_smbus_read_word_data(data->vsa,
118*4882a593Smuzhiyun REG_IOUT_AVG_PK);
119*4882a593Smuzhiyun if (ret < 0)
120*4882a593Smuzhiyun return ret;
121*4882a593Smuzhiyun if (sign_extend32(ret, 10) >
122*4882a593Smuzhiyun sign_extend32(data->iout_avg_pkg, 10))
123*4882a593Smuzhiyun data->iout_avg_pkg = ret;
124*4882a593Smuzhiyun return data->iout_avg_pkg;
125*4882a593Smuzhiyun case PMBUS_VIRT_RESET_IOUT_HISTORY:
126*4882a593Smuzhiyun return 0;
127*4882a593Smuzhiyun case PMBUS_IOUT_OC_FAULT_LIMIT:
128*4882a593Smuzhiyun case PMBUS_IOUT_OC_WARN_LIMIT:
129*4882a593Smuzhiyun case PMBUS_OT_FAULT_LIMIT:
130*4882a593Smuzhiyun case PMBUS_OT_WARN_LIMIT:
131*4882a593Smuzhiyun case PMBUS_READ_IIN:
132*4882a593Smuzhiyun case PMBUS_READ_IOUT:
133*4882a593Smuzhiyun case PMBUS_READ_TEMPERATURE_1:
134*4882a593Smuzhiyun case PMBUS_STATUS_WORD:
135*4882a593Smuzhiyun return i2c_smbus_read_word_data(data->vsa, reg);
136*4882a593Smuzhiyun default:
137*4882a593Smuzhiyun return -EOPNOTSUPP;
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun default:
140*4882a593Smuzhiyun return -EOPNOTSUPP;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
max16601_write_byte(struct i2c_client * client,int page,u8 reg)144*4882a593Smuzhiyun static int max16601_write_byte(struct i2c_client *client, int page, u8 reg)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
147*4882a593Smuzhiyun struct max16601_data *data = to_max16601_data(info);
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun if (page == 2) {
150*4882a593Smuzhiyun if (reg == PMBUS_CLEAR_FAULTS)
151*4882a593Smuzhiyun return i2c_smbus_write_byte(data->vsa, reg);
152*4882a593Smuzhiyun return -EOPNOTSUPP;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun return -ENODATA;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
max16601_write_word(struct i2c_client * client,int page,int reg,u16 value)157*4882a593Smuzhiyun static int max16601_write_word(struct i2c_client *client, int page, int reg,
158*4882a593Smuzhiyun u16 value)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
161*4882a593Smuzhiyun struct max16601_data *data = to_max16601_data(info);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun switch (page) {
164*4882a593Smuzhiyun case 0: /* VCORE */
165*4882a593Smuzhiyun return -ENODATA;
166*4882a593Smuzhiyun case 1: /* VCORE IIN/PIN from sensor element */
167*4882a593Smuzhiyun default:
168*4882a593Smuzhiyun return -EOPNOTSUPP;
169*4882a593Smuzhiyun case 2: /* VSA */
170*4882a593Smuzhiyun switch (reg) {
171*4882a593Smuzhiyun case PMBUS_VIRT_RESET_IOUT_HISTORY:
172*4882a593Smuzhiyun data->iout_avg_pkg = 0xfc00;
173*4882a593Smuzhiyun return 0;
174*4882a593Smuzhiyun case PMBUS_IOUT_OC_FAULT_LIMIT:
175*4882a593Smuzhiyun case PMBUS_IOUT_OC_WARN_LIMIT:
176*4882a593Smuzhiyun case PMBUS_OT_FAULT_LIMIT:
177*4882a593Smuzhiyun case PMBUS_OT_WARN_LIMIT:
178*4882a593Smuzhiyun return i2c_smbus_write_word_data(data->vsa, reg, value);
179*4882a593Smuzhiyun default:
180*4882a593Smuzhiyun return -EOPNOTSUPP;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
max16601_identify(struct i2c_client * client,struct pmbus_driver_info * info)185*4882a593Smuzhiyun static int max16601_identify(struct i2c_client *client,
186*4882a593Smuzhiyun struct pmbus_driver_info *info)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun int reg;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun reg = i2c_smbus_read_byte_data(client, REG_SETPT_DVID);
191*4882a593Smuzhiyun if (reg < 0)
192*4882a593Smuzhiyun return reg;
193*4882a593Smuzhiyun if (reg & DAC_10MV_MODE)
194*4882a593Smuzhiyun info->vrm_version[0] = vr13;
195*4882a593Smuzhiyun else
196*4882a593Smuzhiyun info->vrm_version[0] = vr12;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun return 0;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun static struct pmbus_driver_info max16601_info = {
202*4882a593Smuzhiyun .pages = 3,
203*4882a593Smuzhiyun .format[PSC_VOLTAGE_IN] = linear,
204*4882a593Smuzhiyun .format[PSC_VOLTAGE_OUT] = vid,
205*4882a593Smuzhiyun .format[PSC_CURRENT_IN] = linear,
206*4882a593Smuzhiyun .format[PSC_CURRENT_OUT] = linear,
207*4882a593Smuzhiyun .format[PSC_TEMPERATURE] = linear,
208*4882a593Smuzhiyun .format[PSC_POWER] = linear,
209*4882a593Smuzhiyun .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
210*4882a593Smuzhiyun PMBUS_HAVE_STATUS_INPUT |
211*4882a593Smuzhiyun PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
212*4882a593Smuzhiyun PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
213*4882a593Smuzhiyun PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
214*4882a593Smuzhiyun PMBUS_HAVE_POUT | PMBUS_PAGE_VIRTUAL | PMBUS_PHASE_VIRTUAL,
215*4882a593Smuzhiyun .func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_PAGE_VIRTUAL,
216*4882a593Smuzhiyun .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT |
217*4882a593Smuzhiyun PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
218*4882a593Smuzhiyun PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_PAGE_VIRTUAL,
219*4882a593Smuzhiyun .phases[0] = 8,
220*4882a593Smuzhiyun .pfunc[0] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP,
221*4882a593Smuzhiyun .pfunc[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT,
222*4882a593Smuzhiyun .pfunc[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP,
223*4882a593Smuzhiyun .pfunc[3] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT,
224*4882a593Smuzhiyun .pfunc[4] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP,
225*4882a593Smuzhiyun .pfunc[5] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT,
226*4882a593Smuzhiyun .pfunc[6] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP,
227*4882a593Smuzhiyun .pfunc[7] = PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT,
228*4882a593Smuzhiyun .identify = max16601_identify,
229*4882a593Smuzhiyun .read_byte_data = max16601_read_byte,
230*4882a593Smuzhiyun .read_word_data = max16601_read_word,
231*4882a593Smuzhiyun .write_byte = max16601_write_byte,
232*4882a593Smuzhiyun .write_word_data = max16601_write_word,
233*4882a593Smuzhiyun };
234*4882a593Smuzhiyun
max16601_remove(void * _data)235*4882a593Smuzhiyun static void max16601_remove(void *_data)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun struct max16601_data *data = _data;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun i2c_unregister_device(data->vsa);
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
max16601_probe(struct i2c_client * client)242*4882a593Smuzhiyun static int max16601_probe(struct i2c_client *client)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun struct device *dev = &client->dev;
245*4882a593Smuzhiyun u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
246*4882a593Smuzhiyun struct max16601_data *data;
247*4882a593Smuzhiyun int ret;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun if (!i2c_check_functionality(client->adapter,
250*4882a593Smuzhiyun I2C_FUNC_SMBUS_READ_BYTE_DATA |
251*4882a593Smuzhiyun I2C_FUNC_SMBUS_READ_BLOCK_DATA))
252*4882a593Smuzhiyun return -ENODEV;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf);
255*4882a593Smuzhiyun if (ret < 0)
256*4882a593Smuzhiyun return -ENODEV;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /* PMBUS_IC_DEVICE_ID is expected to return "MAX16601y.xx" */
259*4882a593Smuzhiyun if (ret < 11 || strncmp(buf, "MAX16601", 8)) {
260*4882a593Smuzhiyun buf[ret] = '\0';
261*4882a593Smuzhiyun dev_err(dev, "Unsupported chip '%s'\n", buf);
262*4882a593Smuzhiyun return -ENODEV;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun ret = i2c_smbus_read_byte_data(client, REG_PHASE_ID);
266*4882a593Smuzhiyun if (ret < 0)
267*4882a593Smuzhiyun return ret;
268*4882a593Smuzhiyun if (!(ret & CORE_RAIL_INDICATOR)) {
269*4882a593Smuzhiyun dev_err(dev,
270*4882a593Smuzhiyun "Driver must be instantiated on CORE rail I2C address\n");
271*4882a593Smuzhiyun return -ENODEV;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
275*4882a593Smuzhiyun if (!data)
276*4882a593Smuzhiyun return -ENOMEM;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun data->iout_avg_pkg = 0xfc00;
279*4882a593Smuzhiyun data->vsa = i2c_new_dummy_device(client->adapter, client->addr + 1);
280*4882a593Smuzhiyun if (IS_ERR(data->vsa)) {
281*4882a593Smuzhiyun dev_err(dev, "Failed to register VSA client\n");
282*4882a593Smuzhiyun return PTR_ERR(data->vsa);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun ret = devm_add_action_or_reset(dev, max16601_remove, data);
285*4882a593Smuzhiyun if (ret)
286*4882a593Smuzhiyun return ret;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun data->info = max16601_info;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun return pmbus_do_probe(client, &data->info);
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun static const struct i2c_device_id max16601_id[] = {
294*4882a593Smuzhiyun {"max16601", 0},
295*4882a593Smuzhiyun {}
296*4882a593Smuzhiyun };
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, max16601_id);
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun static struct i2c_driver max16601_driver = {
301*4882a593Smuzhiyun .driver = {
302*4882a593Smuzhiyun .name = "max16601",
303*4882a593Smuzhiyun },
304*4882a593Smuzhiyun .probe_new = max16601_probe,
305*4882a593Smuzhiyun .remove = pmbus_do_remove,
306*4882a593Smuzhiyun .id_table = max16601_id,
307*4882a593Smuzhiyun };
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun module_i2c_driver(max16601_driver);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
312*4882a593Smuzhiyun MODULE_DESCRIPTION("PMBus driver for Maxim MAX16601");
313*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
314