xref: /openbmc/linux/drivers/hwmon/pmbus/zl6100.c (revision 12eb4683)
1 /*
2  * Hardware monitoring driver for ZL6100 and compatibles
3  *
4  * Copyright (c) 2011 Ericsson AB.
5  * Copyright (c) 2012 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 <linux/ktime.h>
29 #include <linux/delay.h>
30 #include "pmbus.h"
31 
32 enum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105,
33 	     zl9101, zl9117 };
34 
35 struct zl6100_data {
36 	int id;
37 	ktime_t access;		/* chip access time */
38 	int delay;		/* Delay between chip accesses in uS */
39 	struct pmbus_driver_info info;
40 };
41 
42 #define to_zl6100_data(x)  container_of(x, struct zl6100_data, info)
43 
44 #define ZL6100_MFR_CONFIG		0xd0
45 #define ZL6100_DEVICE_ID		0xe4
46 
47 #define ZL6100_MFR_XTEMP_ENABLE		(1 << 7)
48 
49 #define MFR_VMON_OV_FAULT_LIMIT		0xf5
50 #define MFR_VMON_UV_FAULT_LIMIT		0xf6
51 #define MFR_READ_VMON			0xf7
52 
53 #define VMON_UV_WARNING			(1 << 5)
54 #define VMON_OV_WARNING			(1 << 4)
55 #define VMON_UV_FAULT			(1 << 1)
56 #define VMON_OV_FAULT			(1 << 0)
57 
58 #define ZL6100_WAIT_TIME		1000	/* uS	*/
59 
60 static ushort delay = ZL6100_WAIT_TIME;
61 module_param(delay, ushort, 0644);
62 MODULE_PARM_DESC(delay, "Delay between chip accesses in uS");
63 
64 /* Convert linear sensor value to milli-units */
65 static long zl6100_l2d(s16 l)
66 {
67 	s16 exponent;
68 	s32 mantissa;
69 	long val;
70 
71 	exponent = l >> 11;
72 	mantissa = ((s16)((l & 0x7ff) << 5)) >> 5;
73 
74 	val = mantissa;
75 
76 	/* scale result to milli-units */
77 	val = val * 1000L;
78 
79 	if (exponent >= 0)
80 		val <<= exponent;
81 	else
82 		val >>= -exponent;
83 
84 	return val;
85 }
86 
87 #define MAX_MANTISSA	(1023 * 1000)
88 #define MIN_MANTISSA	(511 * 1000)
89 
90 static u16 zl6100_d2l(long val)
91 {
92 	s16 exponent = 0, mantissa;
93 	bool negative = false;
94 
95 	/* simple case */
96 	if (val == 0)
97 		return 0;
98 
99 	if (val < 0) {
100 		negative = true;
101 		val = -val;
102 	}
103 
104 	/* Reduce large mantissa until it fits into 10 bit */
105 	while (val >= MAX_MANTISSA && exponent < 15) {
106 		exponent++;
107 		val >>= 1;
108 	}
109 	/* Increase small mantissa to improve precision */
110 	while (val < MIN_MANTISSA && exponent > -15) {
111 		exponent--;
112 		val <<= 1;
113 	}
114 
115 	/* Convert mantissa from milli-units to units */
116 	mantissa = DIV_ROUND_CLOSEST(val, 1000);
117 
118 	/* Ensure that resulting number is within range */
119 	if (mantissa > 0x3ff)
120 		mantissa = 0x3ff;
121 
122 	/* restore sign */
123 	if (negative)
124 		mantissa = -mantissa;
125 
126 	/* Convert to 5 bit exponent, 11 bit mantissa */
127 	return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800);
128 }
129 
130 /* Some chips need a delay between accesses */
131 static inline void zl6100_wait(const struct zl6100_data *data)
132 {
133 	if (data->delay) {
134 		s64 delta = ktime_us_delta(ktime_get(), data->access);
135 		if (delta < data->delay)
136 			udelay(data->delay - delta);
137 	}
138 }
139 
140 static int zl6100_read_word_data(struct i2c_client *client, int page, int reg)
141 {
142 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
143 	struct zl6100_data *data = to_zl6100_data(info);
144 	int ret, vreg;
145 
146 	if (page > 0)
147 		return -ENXIO;
148 
149 	if (data->id == zl2005) {
150 		/*
151 		 * Limit register detection is not reliable on ZL2005.
152 		 * Make sure registers are not erroneously detected.
153 		 */
154 		switch (reg) {
155 		case PMBUS_VOUT_OV_WARN_LIMIT:
156 		case PMBUS_VOUT_UV_WARN_LIMIT:
157 		case PMBUS_IOUT_OC_WARN_LIMIT:
158 			return -ENXIO;
159 		}
160 	}
161 
162 	switch (reg) {
163 	case PMBUS_VIRT_READ_VMON:
164 		vreg = MFR_READ_VMON;
165 		break;
166 	case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
167 	case PMBUS_VIRT_VMON_OV_FAULT_LIMIT:
168 		vreg = MFR_VMON_OV_FAULT_LIMIT;
169 		break;
170 	case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
171 	case PMBUS_VIRT_VMON_UV_FAULT_LIMIT:
172 		vreg = MFR_VMON_UV_FAULT_LIMIT;
173 		break;
174 	default:
175 		if (reg >= PMBUS_VIRT_BASE)
176 			return -ENXIO;
177 		vreg = reg;
178 		break;
179 	}
180 
181 	zl6100_wait(data);
182 	ret = pmbus_read_word_data(client, page, vreg);
183 	data->access = ktime_get();
184 	if (ret < 0)
185 		return ret;
186 
187 	switch (reg) {
188 	case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
189 		ret = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(ret) * 9, 10));
190 		break;
191 	case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
192 		ret = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(ret) * 11, 10));
193 		break;
194 	}
195 
196 	return ret;
197 }
198 
199 static int zl6100_read_byte_data(struct i2c_client *client, int page, int reg)
200 {
201 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
202 	struct zl6100_data *data = to_zl6100_data(info);
203 	int ret, status;
204 
205 	if (page > 0)
206 		return -ENXIO;
207 
208 	zl6100_wait(data);
209 
210 	switch (reg) {
211 	case PMBUS_VIRT_STATUS_VMON:
212 		ret = pmbus_read_byte_data(client, 0,
213 					   PMBUS_STATUS_MFR_SPECIFIC);
214 		if (ret < 0)
215 			break;
216 
217 		status = 0;
218 		if (ret & VMON_UV_WARNING)
219 			status |= PB_VOLTAGE_UV_WARNING;
220 		if (ret & VMON_OV_WARNING)
221 			status |= PB_VOLTAGE_OV_WARNING;
222 		if (ret & VMON_UV_FAULT)
223 			status |= PB_VOLTAGE_UV_FAULT;
224 		if (ret & VMON_OV_FAULT)
225 			status |= PB_VOLTAGE_OV_FAULT;
226 		ret = status;
227 		break;
228 	default:
229 		ret = pmbus_read_byte_data(client, page, reg);
230 		break;
231 	}
232 	data->access = ktime_get();
233 
234 	return ret;
235 }
236 
237 static int zl6100_write_word_data(struct i2c_client *client, int page, int reg,
238 				  u16 word)
239 {
240 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
241 	struct zl6100_data *data = to_zl6100_data(info);
242 	int ret, vreg;
243 
244 	if (page > 0)
245 		return -ENXIO;
246 
247 	switch (reg) {
248 	case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
249 		word = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(word) * 10, 9));
250 		vreg = MFR_VMON_OV_FAULT_LIMIT;
251 		pmbus_clear_cache(client);
252 		break;
253 	case PMBUS_VIRT_VMON_OV_FAULT_LIMIT:
254 		vreg = MFR_VMON_OV_FAULT_LIMIT;
255 		pmbus_clear_cache(client);
256 		break;
257 	case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
258 		word = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(word) * 10, 11));
259 		vreg = MFR_VMON_UV_FAULT_LIMIT;
260 		pmbus_clear_cache(client);
261 		break;
262 	case PMBUS_VIRT_VMON_UV_FAULT_LIMIT:
263 		vreg = MFR_VMON_UV_FAULT_LIMIT;
264 		pmbus_clear_cache(client);
265 		break;
266 	default:
267 		if (reg >= PMBUS_VIRT_BASE)
268 			return -ENXIO;
269 		vreg = reg;
270 	}
271 
272 	zl6100_wait(data);
273 	ret = pmbus_write_word_data(client, page, vreg, word);
274 	data->access = ktime_get();
275 
276 	return ret;
277 }
278 
279 static int zl6100_write_byte(struct i2c_client *client, int page, u8 value)
280 {
281 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
282 	struct zl6100_data *data = to_zl6100_data(info);
283 	int ret;
284 
285 	if (page > 0)
286 		return -ENXIO;
287 
288 	zl6100_wait(data);
289 	ret = pmbus_write_byte(client, page, value);
290 	data->access = ktime_get();
291 
292 	return ret;
293 }
294 
295 static const struct i2c_device_id zl6100_id[] = {
296 	{"bmr450", zl2005},
297 	{"bmr451", zl2005},
298 	{"bmr462", zl2008},
299 	{"bmr463", zl2008},
300 	{"bmr464", zl2008},
301 	{"zl2004", zl2004},
302 	{"zl2005", zl2005},
303 	{"zl2006", zl2006},
304 	{"zl2008", zl2008},
305 	{"zl2105", zl2105},
306 	{"zl2106", zl2106},
307 	{"zl6100", zl6100},
308 	{"zl6105", zl6105},
309 	{"zl9101", zl9101},
310 	{"zl9117", zl9117},
311 	{ }
312 };
313 MODULE_DEVICE_TABLE(i2c, zl6100_id);
314 
315 static int zl6100_probe(struct i2c_client *client,
316 			const struct i2c_device_id *id)
317 {
318 	int ret;
319 	struct zl6100_data *data;
320 	struct pmbus_driver_info *info;
321 	u8 device_id[I2C_SMBUS_BLOCK_MAX + 1];
322 	const struct i2c_device_id *mid;
323 
324 	if (!i2c_check_functionality(client->adapter,
325 				     I2C_FUNC_SMBUS_READ_WORD_DATA
326 				     | I2C_FUNC_SMBUS_READ_BLOCK_DATA))
327 		return -ENODEV;
328 
329 	ret = i2c_smbus_read_block_data(client, ZL6100_DEVICE_ID,
330 					device_id);
331 	if (ret < 0) {
332 		dev_err(&client->dev, "Failed to read device ID\n");
333 		return ret;
334 	}
335 	device_id[ret] = '\0';
336 	dev_info(&client->dev, "Device ID %s\n", device_id);
337 
338 	mid = NULL;
339 	for (mid = zl6100_id; mid->name[0]; mid++) {
340 		if (!strncasecmp(mid->name, device_id, strlen(mid->name)))
341 			break;
342 	}
343 	if (!mid->name[0]) {
344 		dev_err(&client->dev, "Unsupported device\n");
345 		return -ENODEV;
346 	}
347 	if (id->driver_data != mid->driver_data)
348 		dev_notice(&client->dev,
349 			   "Device mismatch: Configured %s, detected %s\n",
350 			   id->name, mid->name);
351 
352 	data = devm_kzalloc(&client->dev, sizeof(struct zl6100_data),
353 			    GFP_KERNEL);
354 	if (!data)
355 		return -ENOMEM;
356 
357 	data->id = mid->driver_data;
358 
359 	/*
360 	 * According to information from the chip vendor, all currently
361 	 * supported chips are known to require a wait time between I2C
362 	 * accesses.
363 	 */
364 	data->delay = delay;
365 
366 	/*
367 	 * Since there was a direct I2C device access above, wait before
368 	 * accessing the chip again.
369 	 */
370 	data->access = ktime_get();
371 	zl6100_wait(data);
372 
373 	info = &data->info;
374 
375 	info->pages = 1;
376 	info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
377 	  | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
378 	  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
379 	  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
380 
381 	/*
382 	 * ZL2004, ZL9101M, and ZL9117M support monitoring an extra voltage
383 	 * (VMON for ZL2004, VDRV for ZL9101M and ZL9117M). Report it as vmon.
384 	 */
385 	if (data->id == zl2004 || data->id == zl9101 || data->id == zl9117)
386 		info->func[0] |= PMBUS_HAVE_VMON | PMBUS_HAVE_STATUS_VMON;
387 
388 	ret = i2c_smbus_read_word_data(client, ZL6100_MFR_CONFIG);
389 	if (ret < 0)
390 		return ret;
391 
392 	if (ret & ZL6100_MFR_XTEMP_ENABLE)
393 		info->func[0] |= PMBUS_HAVE_TEMP2;
394 
395 	data->access = ktime_get();
396 	zl6100_wait(data);
397 
398 	info->read_word_data = zl6100_read_word_data;
399 	info->read_byte_data = zl6100_read_byte_data;
400 	info->write_word_data = zl6100_write_word_data;
401 	info->write_byte = zl6100_write_byte;
402 
403 	return pmbus_do_probe(client, mid, info);
404 }
405 
406 static struct i2c_driver zl6100_driver = {
407 	.driver = {
408 		   .name = "zl6100",
409 		   },
410 	.probe = zl6100_probe,
411 	.remove = pmbus_do_remove,
412 	.id_table = zl6100_id,
413 };
414 
415 module_i2c_driver(zl6100_driver);
416 
417 MODULE_AUTHOR("Guenter Roeck");
418 MODULE_DESCRIPTION("PMBus driver for ZL6100 and compatibles");
419 MODULE_LICENSE("GPL");
420