xref: /OK3568_Linux_fs/kernel/drivers/hwmon/pmbus/max16601.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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