1/*
2 * Hardware monitoring driver for LM25056 / LM25063 / LM25066 / LM5064 / LM5066
3 *
4 * Copyright (c) 2011 Ericsson AB.
5 * Copyright (c) 2013 Guenter Roeck
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/err.h>
26#include <linux/slab.h>
27#include <linux/i2c.h>
28#include "pmbus.h"
29
30enum chips { lm25056, lm25063, lm25066, lm5064, lm5066 };
31
32#define LM25066_READ_VAUX		0xd0
33#define LM25066_MFR_READ_IIN		0xd1
34#define LM25066_MFR_READ_PIN		0xd2
35#define LM25066_MFR_IIN_OC_WARN_LIMIT	0xd3
36#define LM25066_MFR_PIN_OP_WARN_LIMIT	0xd4
37#define LM25066_READ_PIN_PEAK		0xd5
38#define LM25066_CLEAR_PIN_PEAK		0xd6
39#define LM25066_DEVICE_SETUP		0xd9
40#define LM25066_READ_AVG_VIN		0xdc
41#define LM25066_READ_AVG_VOUT		0xdd
42#define LM25066_READ_AVG_IIN		0xde
43#define LM25066_READ_AVG_PIN		0xdf
44
45#define LM25066_DEV_SETUP_CL		(1 << 4)	/* Current limit */
46
47/* LM25056 only */
48
49#define LM25056_VAUX_OV_WARN_LIMIT	0xe3
50#define LM25056_VAUX_UV_WARN_LIMIT	0xe4
51
52#define LM25056_MFR_STS_VAUX_OV_WARN	(1 << 1)
53#define LM25056_MFR_STS_VAUX_UV_WARN	(1 << 0)
54
55/* LM25063 only */
56
57#define LM25063_READ_VOUT_MAX		0xe5
58#define LM25063_READ_VOUT_MIN		0xe6
59
60struct __coeff {
61	short m, b, R;
62};
63
64#define PSC_CURRENT_IN_L	(PSC_NUM_CLASSES)
65#define PSC_POWER_L		(PSC_NUM_CLASSES + 1)
66
67static struct __coeff lm25066_coeff[5][PSC_NUM_CLASSES + 2] = {
68	[lm25056] = {
69		[PSC_VOLTAGE_IN] = {
70			.m = 16296,
71			.R = -2,
72		},
73		[PSC_CURRENT_IN] = {
74			.m = 13797,
75			.R = -2,
76		},
77		[PSC_CURRENT_IN_L] = {
78			.m = 6726,
79			.R = -2,
80		},
81		[PSC_POWER] = {
82			.m = 5501,
83			.R = -3,
84		},
85		[PSC_POWER_L] = {
86			.m = 26882,
87			.R = -4,
88		},
89		[PSC_TEMPERATURE] = {
90			.m = 1580,
91			.b = -14500,
92			.R = -2,
93		},
94	},
95	[lm25066] = {
96		[PSC_VOLTAGE_IN] = {
97			.m = 22070,
98			.R = -2,
99		},
100		[PSC_VOLTAGE_OUT] = {
101			.m = 22070,
102			.R = -2,
103		},
104		[PSC_CURRENT_IN] = {
105			.m = 13661,
106			.R = -2,
107		},
108		[PSC_CURRENT_IN_L] = {
109			.m = 6852,
110			.R = -2,
111		},
112		[PSC_POWER] = {
113			.m = 736,
114			.R = -2,
115		},
116		[PSC_POWER_L] = {
117			.m = 369,
118			.R = -2,
119		},
120		[PSC_TEMPERATURE] = {
121			.m = 16,
122		},
123	},
124	[lm25063] = {
125		[PSC_VOLTAGE_IN] = {
126			.m = 16000,
127			.R = -2,
128		},
129		[PSC_VOLTAGE_OUT] = {
130			.m = 16000,
131			.R = -2,
132		},
133		[PSC_CURRENT_IN] = {
134			.m = 10000,
135			.R = -2,
136		},
137		[PSC_CURRENT_IN_L] = {
138			.m = 10000,
139			.R = -2,
140		},
141		[PSC_POWER] = {
142			.m = 5000,
143			.R = -3,
144		},
145		[PSC_POWER_L] = {
146			.m = 5000,
147			.R = -3,
148		},
149		[PSC_TEMPERATURE] = {
150			.m = 15596,
151			.R = -3,
152		},
153	},
154	[lm5064] = {
155		[PSC_VOLTAGE_IN] = {
156			.m = 4611,
157			.R = -2,
158		},
159		[PSC_VOLTAGE_OUT] = {
160			.m = 4621,
161			.R = -2,
162		},
163		[PSC_CURRENT_IN] = {
164			.m = 10742,
165			.R = -2,
166		},
167		[PSC_CURRENT_IN_L] = {
168			.m = 5456,
169			.R = -2,
170		},
171		[PSC_POWER] = {
172			.m = 1204,
173			.R = -3,
174		},
175		[PSC_POWER_L] = {
176			.m = 612,
177			.R = -3,
178		},
179		[PSC_TEMPERATURE] = {
180			.m = 16,
181		},
182	},
183	[lm5066] = {
184		[PSC_VOLTAGE_IN] = {
185			.m = 4587,
186			.R = -2,
187		},
188		[PSC_VOLTAGE_OUT] = {
189			.m = 4587,
190			.R = -2,
191		},
192		[PSC_CURRENT_IN] = {
193			.m = 10753,
194			.R = -2,
195		},
196		[PSC_CURRENT_IN_L] = {
197			.m = 5405,
198			.R = -2,
199		},
200		[PSC_POWER] = {
201			.m = 1204,
202			.R = -3,
203		},
204		[PSC_POWER_L] = {
205			.m = 605,
206			.R = -3,
207		},
208		[PSC_TEMPERATURE] = {
209			.m = 16,
210		},
211	},
212};
213
214struct lm25066_data {
215	int id;
216	u16 rlimit;			/* Maximum register value */
217	struct pmbus_driver_info info;
218};
219
220#define to_lm25066_data(x)  container_of(x, struct lm25066_data, info)
221
222static int lm25066_read_word_data(struct i2c_client *client, int page, int reg)
223{
224	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
225	const struct lm25066_data *data = to_lm25066_data(info);
226	int ret;
227
228	switch (reg) {
229	case PMBUS_VIRT_READ_VMON:
230		ret = pmbus_read_word_data(client, 0, LM25066_READ_VAUX);
231		if (ret < 0)
232			break;
233		/* Adjust returned value to match VIN coefficients */
234		switch (data->id) {
235		case lm25056:
236			/* VIN: 6.14 mV VAUX: 293 uV LSB */
237			ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
238			break;
239		case lm25063:
240			/* VIN: 6.25 mV VAUX: 200.0 uV LSB */
241			ret = DIV_ROUND_CLOSEST(ret * 20, 625);
242			break;
243		case lm25066:
244			/* VIN: 4.54 mV VAUX: 283.2 uV LSB */
245			ret = DIV_ROUND_CLOSEST(ret * 2832, 45400);
246			break;
247		case lm5064:
248			/* VIN: 4.53 mV VAUX: 700 uV LSB */
249			ret = DIV_ROUND_CLOSEST(ret * 70, 453);
250			break;
251		case lm5066:
252			/* VIN: 2.18 mV VAUX: 725 uV LSB */
253			ret = DIV_ROUND_CLOSEST(ret * 725, 2180);
254			break;
255		}
256		break;
257	case PMBUS_READ_IIN:
258		ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN);
259		break;
260	case PMBUS_READ_PIN:
261		ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_PIN);
262		break;
263	case PMBUS_IIN_OC_WARN_LIMIT:
264		ret = pmbus_read_word_data(client, 0,
265					   LM25066_MFR_IIN_OC_WARN_LIMIT);
266		break;
267	case PMBUS_PIN_OP_WARN_LIMIT:
268		ret = pmbus_read_word_data(client, 0,
269					   LM25066_MFR_PIN_OP_WARN_LIMIT);
270		break;
271	case PMBUS_VIRT_READ_VIN_AVG:
272		ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VIN);
273		break;
274	case PMBUS_VIRT_READ_VOUT_AVG:
275		ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VOUT);
276		break;
277	case PMBUS_VIRT_READ_IIN_AVG:
278		ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_IIN);
279		break;
280	case PMBUS_VIRT_READ_PIN_AVG:
281		ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_PIN);
282		break;
283	case PMBUS_VIRT_READ_PIN_MAX:
284		ret = pmbus_read_word_data(client, 0, LM25066_READ_PIN_PEAK);
285		break;
286	case PMBUS_VIRT_RESET_PIN_HISTORY:
287		ret = 0;
288		break;
289	default:
290		ret = -ENODATA;
291		break;
292	}
293	return ret;
294}
295
296static int lm25063_read_word_data(struct i2c_client *client, int page, int reg)
297{
298	int ret;
299
300	switch (reg) {
301	case PMBUS_VIRT_READ_VOUT_MAX:
302		ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MAX);
303		break;
304	case PMBUS_VIRT_READ_VOUT_MIN:
305		ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MIN);
306		break;
307	default:
308		ret = lm25066_read_word_data(client, page, reg);
309		break;
310	}
311	return ret;
312}
313
314static int lm25056_read_word_data(struct i2c_client *client, int page, int reg)
315{
316	int ret;
317
318	switch (reg) {
319	case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
320		ret = pmbus_read_word_data(client, 0,
321					   LM25056_VAUX_UV_WARN_LIMIT);
322		if (ret < 0)
323			break;
324		/* Adjust returned value to match VIN coefficients */
325		ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
326		break;
327	case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
328		ret = pmbus_read_word_data(client, 0,
329					   LM25056_VAUX_OV_WARN_LIMIT);
330		if (ret < 0)
331			break;
332		/* Adjust returned value to match VIN coefficients */
333		ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
334		break;
335	default:
336		ret = lm25066_read_word_data(client, page, reg);
337		break;
338	}
339	return ret;
340}
341
342static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg)
343{
344	int ret, s;
345
346	switch (reg) {
347	case PMBUS_VIRT_STATUS_VMON:
348		ret = pmbus_read_byte_data(client, 0,
349					   PMBUS_STATUS_MFR_SPECIFIC);
350		if (ret < 0)
351			break;
352		s = 0;
353		if (ret & LM25056_MFR_STS_VAUX_UV_WARN)
354			s |= PB_VOLTAGE_UV_WARNING;
355		if (ret & LM25056_MFR_STS_VAUX_OV_WARN)
356			s |= PB_VOLTAGE_OV_WARNING;
357		ret = s;
358		break;
359	default:
360		ret = -ENODATA;
361		break;
362	}
363	return ret;
364}
365
366static int lm25066_write_word_data(struct i2c_client *client, int page, int reg,
367				   u16 word)
368{
369	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
370	const struct lm25066_data *data = to_lm25066_data(info);
371	int ret;
372
373	switch (reg) {
374	case PMBUS_POUT_OP_FAULT_LIMIT:
375	case PMBUS_POUT_OP_WARN_LIMIT:
376	case PMBUS_VOUT_UV_WARN_LIMIT:
377	case PMBUS_OT_FAULT_LIMIT:
378	case PMBUS_OT_WARN_LIMIT:
379	case PMBUS_IIN_OC_FAULT_LIMIT:
380	case PMBUS_VIN_UV_WARN_LIMIT:
381	case PMBUS_VIN_UV_FAULT_LIMIT:
382	case PMBUS_VIN_OV_FAULT_LIMIT:
383	case PMBUS_VIN_OV_WARN_LIMIT:
384		word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
385		ret = pmbus_write_word_data(client, 0, reg, word);
386		pmbus_clear_cache(client);
387		break;
388	case PMBUS_IIN_OC_WARN_LIMIT:
389		word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
390		ret = pmbus_write_word_data(client, 0,
391					    LM25066_MFR_IIN_OC_WARN_LIMIT,
392					    word);
393		pmbus_clear_cache(client);
394		break;
395	case PMBUS_PIN_OP_WARN_LIMIT:
396		word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
397		ret = pmbus_write_word_data(client, 0,
398					    LM25066_MFR_PIN_OP_WARN_LIMIT,
399					    word);
400		pmbus_clear_cache(client);
401		break;
402	case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
403		/* Adjust from VIN coefficients (for LM25056) */
404		word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
405		word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
406		ret = pmbus_write_word_data(client, 0,
407					    LM25056_VAUX_UV_WARN_LIMIT, word);
408		pmbus_clear_cache(client);
409		break;
410	case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
411		/* Adjust from VIN coefficients (for LM25056) */
412		word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
413		word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
414		ret = pmbus_write_word_data(client, 0,
415					    LM25056_VAUX_OV_WARN_LIMIT, word);
416		pmbus_clear_cache(client);
417		break;
418	case PMBUS_VIRT_RESET_PIN_HISTORY:
419		ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK);
420		break;
421	default:
422		ret = -ENODATA;
423		break;
424	}
425	return ret;
426}
427
428static int lm25066_probe(struct i2c_client *client,
429			  const struct i2c_device_id *id)
430{
431	int config;
432	struct lm25066_data *data;
433	struct pmbus_driver_info *info;
434	struct __coeff *coeff;
435
436	if (!i2c_check_functionality(client->adapter,
437				     I2C_FUNC_SMBUS_READ_BYTE_DATA))
438		return -ENODEV;
439
440	data = devm_kzalloc(&client->dev, sizeof(struct lm25066_data),
441			    GFP_KERNEL);
442	if (!data)
443		return -ENOMEM;
444
445	config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP);
446	if (config < 0)
447		return config;
448
449	data->id = id->driver_data;
450	info = &data->info;
451
452	info->pages = 1;
453	info->format[PSC_VOLTAGE_IN] = direct;
454	info->format[PSC_VOLTAGE_OUT] = direct;
455	info->format[PSC_CURRENT_IN] = direct;
456	info->format[PSC_TEMPERATURE] = direct;
457	info->format[PSC_POWER] = direct;
458
459	info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON
460	  | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT
461	  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
462
463	if (data->id == lm25056) {
464		info->func[0] |= PMBUS_HAVE_STATUS_VMON;
465		info->read_word_data = lm25056_read_word_data;
466		info->read_byte_data = lm25056_read_byte_data;
467		data->rlimit = 0x0fff;
468	} else if (data->id == lm25063) {
469		info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
470		  | PMBUS_HAVE_POUT;
471		info->read_word_data = lm25063_read_word_data;
472		data->rlimit = 0xffff;
473	} else {
474		info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
475		info->read_word_data = lm25066_read_word_data;
476		data->rlimit = 0x0fff;
477	}
478	info->write_word_data = lm25066_write_word_data;
479
480	coeff = &lm25066_coeff[data->id][0];
481	info->m[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].m;
482	info->b[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].b;
483	info->R[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].R;
484	info->m[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].m;
485	info->b[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].b;
486	info->R[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].R;
487	info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m;
488	info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b;
489	info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R;
490	info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b;
491	info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R;
492	info->b[PSC_POWER] = coeff[PSC_POWER].b;
493	info->R[PSC_POWER] = coeff[PSC_POWER].R;
494	if (config & LM25066_DEV_SETUP_CL) {
495		info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m;
496		info->m[PSC_POWER] = coeff[PSC_POWER_L].m;
497	} else {
498		info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m;
499		info->m[PSC_POWER] = coeff[PSC_POWER].m;
500	}
501
502	return pmbus_do_probe(client, id, info);
503}
504
505static const struct i2c_device_id lm25066_id[] = {
506	{"lm25056", lm25056},
507	{"lm25063", lm25063},
508	{"lm25066", lm25066},
509	{"lm5064", lm5064},
510	{"lm5066", lm5066},
511	{ }
512};
513
514MODULE_DEVICE_TABLE(i2c, lm25066_id);
515
516/* This is the driver that will be inserted */
517static struct i2c_driver lm25066_driver = {
518	.driver = {
519		   .name = "lm25066",
520		   },
521	.probe = lm25066_probe,
522	.remove = pmbus_do_remove,
523	.id_table = lm25066_id,
524};
525
526module_i2c_driver(lm25066_driver);
527
528MODULE_AUTHOR("Guenter Roeck");
529MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips");
530MODULE_LICENSE("GPL");
531