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