File Index
Files and directories
Sign in
FILE

mp29502.c

File preview with syntax highlighting.

linux-6.19.14/drivers/hwmon/pmbus/mp29502.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP29502)
  4 */
  5
  6#include <linux/bitfield.h>
  7#include <linux/i2c.h>
  8#include <linux/module.h>
  9#include <linux/of_device.h>
 10#include "pmbus.h"
 11
 12#define MFR_VOUT_SCALE_LOOP	0x29
 13#define MFR_SVI3_IOUT_PRT	0x67
 14#define MFR_READ_PIN_EST	0x94
 15#define MFR_READ_IIN_EST	0x95
 16#define MFR_VOUT_PROT1	0x3D
 17#define MFR_VOUT_PROT2	0x51
 18#define MFR_SLOPE_CNT_SET	0xA8
 19#define MFR_TSNS_FLT_SET	0xBB
 20
 21#define MP29502_VIN_OV_GAIN	4
 22#define MP29502_TEMP_LIMIT_OFFSET	40
 23#define MP29502_READ_VOUT_DIV	1024
 24#define MP29502_READ_IOUT_DIV	32
 25#define MP29502_IOUT_LIMIT_UINT	8
 26#define MP29502_OVUV_LIMIT_SCALE	10
 27#define MP28502_VOUT_OV_GAIN	512
 28#define MP28502_VOUT_OV_SCALE	40
 29#define MP29502_VOUT_UV_OFFSET	36
 30#define MP29502_PIN_GAIN	2
 31#define MP29502_IIN_DIV	2
 32
 33#define MP29502_PAGE_NUM	1
 34
 35#define MP29502_RAIL_FUNC	(PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | \
 36							PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \
 37							PMBUS_HAVE_TEMP | PMBUS_HAVE_PIN | \
 38							PMBUS_HAVE_IIN | \
 39							PMBUS_HAVE_STATUS_VOUT | \
 40							PMBUS_HAVE_STATUS_IOUT | \
 41							PMBUS_HAVE_STATUS_TEMP | \
 42							PMBUS_HAVE_STATUS_INPUT)
 43
 44struct mp29502_data {
 45	struct pmbus_driver_info info;
 46	int vout_scale;
 47	int vout_bottom_div;
 48	int vout_top_div;
 49	int ovp_div;
 50	int iout_scale;
 51};
 52
 53#define to_mp29502_data(x)	container_of(x, struct mp29502_data, info)
 54
 55static u16 mp29502_reg2data_linear11(u16 word)
 56{
 57	s16 exponent;
 58	s32 mantissa;
 59	s64 val;
 60
 61	exponent = ((s16)word) >> 11;
 62	mantissa = ((s16)((word & 0x7ff) << 5)) >> 5;
 63	val = mantissa;
 64
 65	if (exponent >= 0)
 66		val <<= exponent;
 67	else
 68		val >>= -exponent;
 69
 70	return val;
 71}
 72
 73static int
 74mp29502_identify_vout_scale(struct i2c_client *client, struct pmbus_driver_info *info,
 75			    int page)
 76{
 77	struct mp29502_data *data = to_mp29502_data(info);
 78	int ret;
 79
 80	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
 81	if (ret < 0)
 82		return ret;
 83
 84	ret = i2c_smbus_read_word_data(client, MFR_VOUT_SCALE_LOOP);
 85	if (ret < 0)
 86		return ret;
 87
 88	switch (FIELD_GET(GENMASK(12, 10), ret)) {
 89	case 0:
 90		data->vout_scale = 6400;
 91		break;
 92	case 1:
 93		data->vout_scale = 5120;
 94		break;
 95	case 2:
 96		data->vout_scale = 2560;
 97		break;
 98	case 3:
 99		data->vout_scale = 2048;
100		break;
101	case 4:
102		data->vout_scale = 1024;
103		break;
104	case 5:
105		data->vout_scale = 4;
106		break;
107	case 6:
108		data->vout_scale = 2;
109		break;
110	case 7:
111		data->vout_scale = 1;
112		break;
113	default:
114		data->vout_scale = 1;
115		break;
116	}
117
118	return 0;
119}
120
121static int
122mp29502_identify_vout_divider(struct i2c_client *client, struct pmbus_driver_info *info,
123			      int page)
124{
125	struct mp29502_data *data = to_mp29502_data(info);
126	int ret;
127
128	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
129	if (ret < 0)
130		return ret;
131
132	ret = i2c_smbus_read_word_data(client, MFR_VOUT_PROT1);
133	if (ret < 0)
134		return ret;
135
136	data->vout_bottom_div = FIELD_GET(GENMASK(11, 0), ret);
137
138	ret = i2c_smbus_read_word_data(client, MFR_VOUT_PROT2);
139	if (ret < 0)
140		return ret;
141
142	data->vout_top_div = FIELD_GET(GENMASK(14, 0), ret);
143
144	return 0;
145}
146
147static int
148mp29502_identify_ovp_divider(struct i2c_client *client, struct pmbus_driver_info *info,
149			     int page)
150{
151	struct mp29502_data *data = to_mp29502_data(info);
152	int ret;
153
154	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
155	if (ret < 0)
156		return ret;
157
158	ret = i2c_smbus_read_word_data(client, MFR_SLOPE_CNT_SET);
159	if (ret < 0)
160		return ret;
161
162	data->ovp_div = FIELD_GET(GENMASK(9, 0), ret);
163
164	return 0;
165}
166
167static int
168mp29502_identify_iout_scale(struct i2c_client *client, struct pmbus_driver_info *info,
169			    int page)
170{
171	struct mp29502_data *data = to_mp29502_data(info);
172	int ret;
173
174	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
175	if (ret < 0)
176		return ret;
177
178	ret = i2c_smbus_read_word_data(client, MFR_SVI3_IOUT_PRT);
179	if (ret < 0)
180		return ret;
181
182	switch (ret & GENMASK(2, 0)) {
183	case 0:
184	case 6:
185		data->iout_scale = 32;
186		break;
187	case 1:
188		data->iout_scale = 1;
189		break;
190	case 2:
191		data->iout_scale = 2;
192		break;
193	case 3:
194		data->iout_scale = 4;
195		break;
196	case 4:
197		data->iout_scale = 8;
198		break;
199	case 5:
200		data->iout_scale = 16;
201		break;
202	default:
203		data->iout_scale = 64;
204		break;
205	}
206
207	return 0;
208}
209
210static int mp29502_read_vout_ov_limit(struct i2c_client *client, struct mp29502_data *data)
211{
212	int ret;
213	int ov_value;
214
215	/*
216	 * This is because the vout ov fault limit value comes from
217	 * page1 MFR_TSNS_FLT_SET reg, and other telemetry and limit
218	 * value comes from page0 reg. So the page should be set to
219	 * 0 after the reading of vout ov limit.
220	 */
221	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 1);
222	if (ret < 0)
223		return ret;
224
225	ret = i2c_smbus_read_word_data(client, MFR_TSNS_FLT_SET);
226	if (ret < 0)
227		return ret;
228
229	ov_value = DIV_ROUND_CLOSEST(FIELD_GET(GENMASK(12, 7), ret) *
230						   MP28502_VOUT_OV_GAIN * MP28502_VOUT_OV_SCALE,
231						   data->ovp_div);
232
233	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
234	if (ret < 0)
235		return ret;
236
237	return ov_value;
238}
239
240static int mp29502_write_vout_ov_limit(struct i2c_client *client, u16 word,
241				       struct mp29502_data *data)
242{
243	int ret;
244
245	/*
246	 * This is because the vout ov fault limit value comes from
247	 * page1 MFR_TSNS_FLT_SET reg, and other telemetry and limit
248	 * value comes from page0 reg. So the page should be set to
249	 * 0 after the writing of vout ov limit.
250	 */
251	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 1);
252	if (ret < 0)
253		return ret;
254
255	ret = i2c_smbus_read_word_data(client, MFR_TSNS_FLT_SET);
256	if (ret < 0)
257		return ret;
258
259	ret = i2c_smbus_write_word_data(client, MFR_TSNS_FLT_SET,
260					(ret & ~GENMASK(12, 7)) |
261		FIELD_PREP(GENMASK(12, 7),
262			   DIV_ROUND_CLOSEST(word * data->ovp_div,
263					     MP28502_VOUT_OV_GAIN * MP28502_VOUT_OV_SCALE)));
264
265	return i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
266}
267
268static int mp29502_read_byte_data(struct i2c_client *client, int page, int reg)
269{
270	int ret;
271
272	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
273	if (ret < 0)
274		return ret;
275
276	switch (reg) {
277	case PMBUS_VOUT_MODE:
278		ret = PB_VOUT_MODE_DIRECT;
279		break;
280	default:
281		ret = -ENODATA;
282		break;
283	}
284
285	return ret;
286}
287
288static int mp29502_read_word_data(struct i2c_client *client, int page,
289				  int phase, int reg)
290{
291	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
292	struct mp29502_data *data = to_mp29502_data(info);
293	int ret;
294
295	switch (reg) {
296	case PMBUS_STATUS_WORD:
297		ret = -ENODATA;
298		break;
299	case PMBUS_READ_VIN:
300		/*
301		 * The MP29502 PMBUS_READ_VIN[10:0] is the vin value, the vin scale is
302		 * 125mV/LSB. And the vin scale is set to 125mV/Lsb(using r/m/b scale)
303		 * in MP29502 pmbus_driver_info struct, so the word data bit0-bit10 can
304		 * be returned to pmbus core directly.
305		 */
306		ret = pmbus_read_word_data(client, page, phase, reg);
307		if (ret < 0)
308			return ret;
309
310		ret = FIELD_GET(GENMASK(10, 0), ret);
311		break;
312	case PMBUS_READ_VOUT:
313		/*
314		 * The MP29502 PMBUS_READ_VOUT[11:0] is the vout value, and vout
315		 * value is calculated based on vout scale and vout divider.
316		 */
317		ret = pmbus_read_word_data(client, page, phase, reg);
318		if (ret < 0)
319			return ret;
320
321		ret = DIV_ROUND_CLOSEST((ret &  GENMASK(11, 0)) *
322								data->vout_scale *
323								(data->vout_bottom_div +
324								4 * data->vout_top_div),
325								MP29502_READ_VOUT_DIV *
326								data->vout_bottom_div);
327		break;
328	case PMBUS_READ_IIN:
329		/*
330		 * The MP29502 MFR_READ_IIN_EST register is linear11 format, and the
331		 * exponent is not a constant value. But the iin scale is set to
332		 * 1A/Lsb(using r/m/b scale). As a result, the iin read from MP29502
333		 * should be calculated to A, then return the result to pmbus core.
334		 */
335		ret = pmbus_read_word_data(client, page, phase, MFR_READ_IIN_EST);
336		if (ret < 0)
337			return ret;
338
339		ret = DIV_ROUND_CLOSEST(mp29502_reg2data_linear11(ret),
340					MP29502_IIN_DIV);
341		break;
342	case PMBUS_READ_PIN:
343		/*
344		 * The MP29502 MFR_READ_PIN_EST register is linear11 format, and the
345		 * exponent is not a constant value. But the pin scale is set to
346		 * 1W/Lsb(using r/m/b scale). As a result, the pout read from MP29502
347		 * should be calculated to W, then return the result to pmbus core.
348		 */
349		ret = pmbus_read_word_data(client, page, phase, MFR_READ_PIN_EST);
350		if (ret < 0)
351			return ret;
352
353		ret = mp29502_reg2data_linear11(ret) * MP29502_PIN_GAIN;
354		break;
355	case PMBUS_READ_POUT:
356		/*
357		 * The MP29502 PMBUS_READ_POUT register is linear11 format, and the
358		 * exponent is not a constant value. But the pout scale is set to
359		 * 1W/Lsb(using r/m/b scale). As a result, the pout read from MP29502
360		 * should be calculated to W, then return the result to pmbus core.
361		 * And the pout is calculated based on vout divider.
362		 */
363		ret = pmbus_read_word_data(client, page, phase, reg);
364		if (ret < 0)
365			return ret;
366
367		ret = DIV_ROUND_CLOSEST(mp29502_reg2data_linear11(ret) *
368					(data->vout_bottom_div +
369					4 * data->vout_top_div),
370					data->vout_bottom_div);
371		break;
372	case PMBUS_READ_IOUT:
373		ret = pmbus_read_word_data(client, page, phase, reg);
374		if (ret < 0)
375			return ret;
376
377		ret = DIV_ROUND_CLOSEST((ret & GENMASK(10, 0)) * data->iout_scale,
378					MP29502_READ_IOUT_DIV);
379		break;
380	case PMBUS_READ_TEMPERATURE_1:
381		ret = pmbus_read_word_data(client, page, phase, reg);
382		if (ret < 0)
383			return ret;
384
385		ret = FIELD_GET(GENMASK(10, 0), ret);
386		break;
387	case PMBUS_VIN_OV_FAULT_LIMIT:
388		/*
389		 * The MP29502 PMBUS_VIN_OV_FAULT_LIMIT is 500mV/Lsb, but
390		 * the vin  scale is set to 125mV/Lsb(using r/m/b scale),
391		 * so the word data should multiply by 4.
392		 */
393		ret = pmbus_read_word_data(client, page, phase, reg);
394		if (ret < 0)
395			return ret;
396
397		ret = FIELD_GET(GENMASK(7, 0), ret) * MP29502_VIN_OV_GAIN;
398		break;
399	case PMBUS_VIN_UV_WARN_LIMIT:
400	case PMBUS_VIN_UV_FAULT_LIMIT:
401		/*
402		 * The MP29502 PMBUS_VIN_UV_WARN_LIMIT and PMBUS_VIN_UV_FAULT_LIMIT
403		 * scale is 125mV/Lsb, but the vin scale is set to 125mV/Lsb(using
404		 * r/m/b scale), so the word data bit0-bit9 can be returned to pmbus
405		 * core directly.
406		 */
407		ret = pmbus_read_word_data(client, page, phase, reg);
408		if (ret < 0)
409			return ret;
410
411		ret = FIELD_GET(GENMASK(9, 0), ret);
412		break;
413	case PMBUS_VOUT_OV_FAULT_LIMIT:
414		/*
415		 * The MP29502 vout ov fault limit value comes from
416		 * page1 MFR_TSNS_FLT_SET[12:7].
417		 */
418		ret = mp29502_read_vout_ov_limit(client, data);
419		if (ret < 0)
420			return ret;
421
422		break;
423	case PMBUS_VOUT_UV_FAULT_LIMIT:
424		ret = pmbus_read_word_data(client, page, phase, reg);
425		if (ret < 0)
426			return ret;
427
428		ret = DIV_ROUND_CLOSEST((FIELD_GET(GENMASK(8, 0), ret) *
429								MP29502_OVUV_LIMIT_SCALE -
430								MP29502_VOUT_UV_OFFSET) *
431								(data->vout_bottom_div +
432								4 * data->vout_top_div),
433								data->vout_bottom_div);
434		break;
435	case PMBUS_IOUT_OC_FAULT_LIMIT:
436	case PMBUS_IOUT_OC_WARN_LIMIT:
437		ret = pmbus_read_word_data(client, page, phase, reg);
438		if (ret < 0)
439			return ret;
440
441		ret = DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) *
442								data->iout_scale *
443								MP29502_IOUT_LIMIT_UINT,
444								MP29502_READ_IOUT_DIV);
445		break;
446	case PMBUS_OT_FAULT_LIMIT:
447	case PMBUS_OT_WARN_LIMIT:
448		/*
449		 * The scale of MP29502 PMBUS_OT_FAULT_LIMIT and PMBUS_OT_WARN_LIMIT
450		 * is 1°C/LSB and they have 40°C offset.
451		 */
452		ret = pmbus_read_word_data(client, page, phase, reg);
453		if (ret < 0)
454			return ret;
455
456		ret = (ret & GENMASK(7, 0)) - MP29502_TEMP_LIMIT_OFFSET;
457		break;
458	default:
459		ret = -EINVAL;
460		break;
461	}
462
463	return ret;
464}
465
466static int mp29502_write_word_data(struct i2c_client *client, int page, int reg,
467				   u16 word)
468{
469	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
470	struct mp29502_data *data = to_mp29502_data(info);
471	int ret;
472
473	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
474	if (ret < 0)
475		return ret;
476
477	switch (reg) {
478	case PMBUS_VIN_OV_FAULT_LIMIT:
479		/*
480		 * The PMBUS_VIN_OV_FAULT_LIMIT[7:0] is the limit value,
481		 * and bit8-bit15 should not be changed. The scale of
482		 * PMBUS_VIN_OV_FAULT_LIMIT is 500mV/Lsb, but the vin
483		 * scale is set to 125mV/Lsb(using r/m/b scale), so
484		 * the word data should divide by 4.
485		 */
486		ret = pmbus_read_word_data(client, page, 0xff, reg);
487		if (ret < 0)
488			return ret;
489
490		ret = pmbus_write_word_data(client, page, reg,
491					    (ret & ~GENMASK(7, 0)) |
492				FIELD_PREP(GENMASK(7, 0),
493					   DIV_ROUND_CLOSEST(word,
494							     MP29502_VIN_OV_GAIN)));
495		break;
496	case PMBUS_VIN_UV_WARN_LIMIT:
497	case PMBUS_VIN_UV_FAULT_LIMIT:
498		/*
499		 * The PMBUS_VIN_UV_WARN_LIMIT[9:0] and PMBUS_VIN_UV_FAULT_LIMIT[9:0]
500		 * are the limit value, and bit10-bit15 should not be changed.
501		 */
502		ret = pmbus_read_word_data(client, page, 0xff, reg);
503		if (ret < 0)
504			return ret;
505
506		ret = pmbus_write_word_data(client, page, reg,
507					    (ret & ~GENMASK(9, 0)) |
508							FIELD_PREP(GENMASK(9, 0),
509								   word));
510		break;
511	case PMBUS_VOUT_OV_FAULT_LIMIT:
512		ret = mp29502_write_vout_ov_limit(client, word, data);
513		if (ret < 0)
514			return ret;
515
516		break;
517	case PMBUS_VOUT_UV_FAULT_LIMIT:
518		ret = pmbus_read_word_data(client, page, 0xff, reg);
519		if (ret < 0)
520			return ret;
521
522		ret = pmbus_write_word_data(client, page, reg,
523					    (ret & ~GENMASK(8, 0)) |
524						FIELD_PREP(GENMASK(8, 0),
525							   DIV_ROUND_CLOSEST(word *
526									data->vout_bottom_div +
527									MP29502_VOUT_UV_OFFSET *
528									(data->vout_bottom_div +
529									4 * data->vout_top_div),
530									MP29502_OVUV_LIMIT_SCALE *
531									(data->vout_bottom_div +
532									4 * data->vout_top_div))));
533		break;
534	case PMBUS_IOUT_OC_FAULT_LIMIT:
535	case PMBUS_IOUT_OC_WARN_LIMIT:
536		ret = pmbus_write_word_data(client, page, reg,
537					    DIV_ROUND_CLOSEST(word *
538							MP29502_READ_IOUT_DIV,
539							MP29502_IOUT_LIMIT_UINT *
540							data->iout_scale));
541		break;
542	case PMBUS_OT_FAULT_LIMIT:
543	case PMBUS_OT_WARN_LIMIT:
544		/*
545		 * The PMBUS_OT_FAULT_LIMIT[7:0] and PMBUS_OT_WARN_LIMIT[7:0]
546		 * are the limit value, and bit8-bit15 should not be changed.
547		 */
548		ret = pmbus_read_word_data(client, page, 0xff, reg);
549		if (ret < 0)
550			return ret;
551
552		ret = pmbus_write_word_data(client, page, reg,
553					    (ret & ~GENMASK(7, 0)) |
554					FIELD_PREP(GENMASK(7, 0),
555						   word + MP29502_TEMP_LIMIT_OFFSET));
556		break;
557	default:
558		ret = -EINVAL;
559		break;
560	}
561
562	return ret;
563}
564
565static int mp29502_identify(struct i2c_client *client, struct pmbus_driver_info *info)
566{
567	int ret;
568
569	/* Identify vout scale */
570	ret = mp29502_identify_vout_scale(client, info, 0);
571	if (ret < 0)
572		return ret;
573
574	/* Identify vout divider. */
575	ret = mp29502_identify_vout_divider(client, info, 1);
576	if (ret < 0)
577		return ret;
578
579	/* Identify ovp divider. */
580	ret = mp29502_identify_ovp_divider(client, info, 1);
581	if (ret < 0)
582		return ret;
583
584	/* Identify iout scale */
585	return mp29502_identify_iout_scale(client, info, 0);
586}
587
588static const struct pmbus_driver_info mp29502_info = {
589	.pages = MP29502_PAGE_NUM,
590	.format[PSC_VOLTAGE_IN] = direct,
591	.format[PSC_TEMPERATURE] = direct,
592	.format[PSC_CURRENT_IN] = direct,
593	.format[PSC_CURRENT_OUT] = direct,
594	.format[PSC_VOLTAGE_OUT] = direct,
595	.format[PSC_POWER] = direct,
596
597	.m[PSC_VOLTAGE_IN] = 8,
598	.R[PSC_VOLTAGE_IN] = 0,
599	.b[PSC_VOLTAGE_IN] = 0,
600
601	.m[PSC_VOLTAGE_OUT] = 1,
602	.R[PSC_VOLTAGE_OUT] = 3,
603	.b[PSC_VOLTAGE_OUT] = 0,
604
605	.m[PSC_TEMPERATURE] = 1,
606	.R[PSC_TEMPERATURE] = 0,
607	.b[PSC_TEMPERATURE] = 0,
608
609	.m[PSC_CURRENT_IN] = 1,
610	.R[PSC_CURRENT_IN] = 0,
611	.b[PSC_CURRENT_IN] = 0,
612
613	.m[PSC_CURRENT_OUT] = 1,
614	.R[PSC_CURRENT_OUT] = 0,
615	.b[PSC_CURRENT_OUT] = 0,
616
617	.m[PSC_POWER] = 1,
618	.R[PSC_POWER] = 0,
619	.b[PSC_POWER] = 0,
620
621	.func[0] = MP29502_RAIL_FUNC,
622	.read_word_data = mp29502_read_word_data,
623	.read_byte_data = mp29502_read_byte_data,
624	.write_word_data = mp29502_write_word_data,
625	.identify = mp29502_identify,
626};
627
628static int mp29502_probe(struct i2c_client *client)
629{
630	struct pmbus_driver_info *info;
631	struct mp29502_data *data;
632
633	data = devm_kzalloc(&client->dev, sizeof(struct mp29502_data),
634			    GFP_KERNEL);
635	if (!data)
636		return -ENOMEM;
637
638	memcpy(&data->info, &mp29502_info, sizeof(*info));
639	info = &data->info;
640
641	return pmbus_do_probe(client, info);
642}
643
644static const struct i2c_device_id mp29502_id[] = {
645	{"mp29502", 0},
646	{}
647};
648MODULE_DEVICE_TABLE(i2c, mp29502_id);
649
650static const struct of_device_id __maybe_unused mp29502_of_match[] = {
651	{.compatible = "mps,mp29502"},
652	{}
653};
654MODULE_DEVICE_TABLE(of, mp29502_of_match);
655
656static struct i2c_driver mp29502_driver = {
657	.driver = {
658		.name = "mp29502",
659		.of_match_table = mp29502_of_match,
660	},
661	.probe = mp29502_probe,
662	.id_table = mp29502_id,
663};
664
665module_i2c_driver(mp29502_driver);
666
667MODULE_AUTHOR("Wensheng Wang <wenswang@yeah.net");
668MODULE_DESCRIPTION("PMBus driver for MPS MP29502");
669MODULE_LICENSE("GPL");
670MODULE_IMPORT_NS("PMBUS");
~/ Read-only file preview.