Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ltc2978.c
Go to the documentation of this file.
1 /*
2  * Hardware monitoring driver for LTC2978 and LTC3880
3  *
4  * Copyright (c) 2011 Ericsson AB.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/err.h>
25 #include <linux/slab.h>
26 #include <linux/i2c.h>
27 #include "pmbus.h"
28 
29 enum chips { ltc2978, ltc3880 };
30 
31 /* LTC2978 and LTC3880 */
32 #define LTC2978_MFR_VOUT_PEAK 0xdd
33 #define LTC2978_MFR_VIN_PEAK 0xde
34 #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf
35 #define LTC2978_MFR_SPECIAL_ID 0xe7
36 
37 /* LTC2978 only */
38 #define LTC2978_MFR_VOUT_MIN 0xfb
39 #define LTC2978_MFR_VIN_MIN 0xfc
40 #define LTC2978_MFR_TEMPERATURE_MIN 0xfd
41 
42 /* LTC3880 only */
43 #define LTC3880_MFR_IOUT_PEAK 0xd7
44 #define LTC3880_MFR_CLEAR_PEAKS 0xe3
45 #define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4
46 
47 #define LTC2978_ID_REV1 0x0121
48 #define LTC2978_ID_REV2 0x0122
49 #define LTC3880_ID 0x4000
50 #define LTC3880_ID_MASK 0xff00
51 
52 /*
53  * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
54  * happens pretty much each time chip data is updated. Raw peak data therefore
55  * does not provide much value. To be able to provide useful peak data, keep an
56  * internal cache of measured peak data, which is only cleared if an explicit
57  * "clear peak" command is executed for the sensor in question.
58  */
59 struct ltc2978_data {
60  enum chips id;
63  int vout_min[8], vout_max[8];
64  int iout_max[2];
65  int temp2_max[2];
67 };
68 
69 #define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info)
70 
71 static inline int lin11_to_val(int data)
72 {
73  s16 e = ((s16)data) >> 11;
74  s32 m = (((s16)(data << 5)) >> 5);
75 
76  /*
77  * mantissa is 10 bit + sign, exponent adds up to 15 bit.
78  * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31).
79  */
80  e += 6;
81  return (e < 0 ? m >> -e : m << e);
82 }
83 
84 static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
85  int reg)
86 {
87  const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
88  struct ltc2978_data *data = to_ltc2978_data(info);
89  int ret;
90 
91  switch (reg) {
93  ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_PEAK);
94  if (ret >= 0) {
95  if (lin11_to_val(ret) > lin11_to_val(data->vin_max))
96  data->vin_max = ret;
97  ret = data->vin_max;
98  }
99  break;
101  ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK);
102  if (ret >= 0) {
103  /*
104  * VOUT is 16 bit unsigned with fixed exponent,
105  * so we can compare it directly
106  */
107  if (ret > data->vout_max[page])
108  data->vout_max[page] = ret;
109  ret = data->vout_max[page];
110  }
111  break;
113  ret = pmbus_read_word_data(client, page,
115  if (ret >= 0) {
116  if (lin11_to_val(ret) > lin11_to_val(data->temp_max))
117  data->temp_max = ret;
118  ret = data->temp_max;
119  }
120  break;
124  ret = 0;
125  break;
126  default:
127  ret = -ENODATA;
128  break;
129  }
130  return ret;
131 }
132 
133 static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg)
134 {
135  const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
136  struct ltc2978_data *data = to_ltc2978_data(info);
137  int ret;
138 
139  switch (reg) {
141  ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_MIN);
142  if (ret >= 0) {
143  if (lin11_to_val(ret) < lin11_to_val(data->vin_min))
144  data->vin_min = ret;
145  ret = data->vin_min;
146  }
147  break;
149  ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN);
150  if (ret >= 0) {
151  /*
152  * VOUT_MIN is known to not be supported on some lots
153  * of LTC2978 revision 1, and will return the maximum
154  * possible voltage if read. If VOUT_MAX is valid and
155  * lower than the reading of VOUT_MIN, use it instead.
156  */
157  if (data->vout_max[page] && ret > data->vout_max[page])
158  ret = data->vout_max[page];
159  if (ret < data->vout_min[page])
160  data->vout_min[page] = ret;
161  ret = data->vout_min[page];
162  }
163  break;
165  ret = pmbus_read_word_data(client, page,
167  if (ret >= 0) {
168  if (lin11_to_val(ret)
169  < lin11_to_val(data->temp_min))
170  data->temp_min = ret;
171  ret = data->temp_min;
172  }
173  break;
178  ret = -ENXIO;
179  break;
180  default:
181  ret = ltc2978_read_word_data_common(client, page, reg);
182  break;
183  }
184  return ret;
185 }
186 
187 static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
188 {
189  const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
190  struct ltc2978_data *data = to_ltc2978_data(info);
191  int ret;
192 
193  switch (reg) {
195  ret = pmbus_read_word_data(client, page, LTC3880_MFR_IOUT_PEAK);
196  if (ret >= 0) {
197  if (lin11_to_val(ret)
198  > lin11_to_val(data->iout_max[page]))
199  data->iout_max[page] = ret;
200  ret = data->iout_max[page];
201  }
202  break;
204  ret = pmbus_read_word_data(client, page,
206  if (ret >= 0) {
207  if (lin11_to_val(ret)
208  > lin11_to_val(data->temp2_max[page]))
209  data->temp2_max[page] = ret;
210  ret = data->temp2_max[page];
211  }
212  break;
216  ret = -ENXIO;
217  break;
220  ret = 0;
221  break;
222  default:
223  ret = ltc2978_read_word_data_common(client, page, reg);
224  break;
225  }
226  return ret;
227 }
228 
229 static int ltc2978_clear_peaks(struct i2c_client *client, int page,
230  enum chips id)
231 {
232  int ret;
233 
234  if (id == ltc2978)
235  ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS);
236  else
237  ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS);
238 
239  return ret;
240 }
241 
242 static int ltc2978_write_word_data(struct i2c_client *client, int page,
243  int reg, u16 word)
244 {
245  const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
246  struct ltc2978_data *data = to_ltc2978_data(info);
247  int ret;
248 
249  switch (reg) {
251  data->iout_max[page] = 0x7fff;
252  ret = ltc2978_clear_peaks(client, page, data->id);
253  break;
255  data->temp2_max[page] = 0x7fff;
256  ret = ltc2978_clear_peaks(client, page, data->id);
257  break;
259  data->vout_min[page] = 0xffff;
260  data->vout_max[page] = 0;
261  ret = ltc2978_clear_peaks(client, page, data->id);
262  break;
264  data->vin_min = 0x7bff;
265  data->vin_max = 0;
266  ret = ltc2978_clear_peaks(client, page, data->id);
267  break;
269  data->temp_min = 0x7bff;
270  data->temp_max = 0x7fff;
271  ret = ltc2978_clear_peaks(client, page, data->id);
272  break;
273  default:
274  ret = -ENODATA;
275  break;
276  }
277  return ret;
278 }
279 
280 static const struct i2c_device_id ltc2978_id[] = {
281  {"ltc2978", ltc2978},
282  {"ltc3880", ltc3880},
283  {}
284 };
285 MODULE_DEVICE_TABLE(i2c, ltc2978_id);
286 
287 static int ltc2978_probe(struct i2c_client *client,
288  const struct i2c_device_id *id)
289 {
290  int chip_id, i;
291  struct ltc2978_data *data;
292  struct pmbus_driver_info *info;
293 
294  if (!i2c_check_functionality(client->adapter,
296  return -ENODEV;
297 
298  data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data),
299  GFP_KERNEL);
300  if (!data)
301  return -ENOMEM;
302 
304  if (chip_id < 0)
305  return chip_id;
306 
307  if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) {
308  data->id = ltc2978;
309  } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) {
310  data->id = ltc3880;
311  } else {
312  dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
313  return -ENODEV;
314  }
315  if (data->id != id->driver_data)
316  dev_warn(&client->dev,
317  "Device mismatch: Configured %s, detected %s\n",
318  id->name,
319  ltc2978_id[data->id].name);
320 
321  info = &data->info;
322  info->write_word_data = ltc2978_write_word_data;
323 
324  data->vout_min[0] = 0xffff;
325  data->vin_min = 0x7bff;
326  data->temp_min = 0x7bff;
327  data->temp_max = 0x7fff;
328 
329  switch (id->driver_data) {
330  case ltc2978:
331  info->read_word_data = ltc2978_read_word_data;
332  info->pages = 8;
336  for (i = 1; i < 8; i++) {
337  info->func[i] = PMBUS_HAVE_VOUT
339  data->vout_min[i] = 0xffff;
340  }
341  break;
342  case ltc3880:
343  info->read_word_data = ltc3880_read_word_data;
344  info->pages = 2;
345  info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
355  data->vout_min[1] = 0xffff;
356  break;
357  default:
358  return -ENODEV;
359  }
360 
361  return pmbus_do_probe(client, id, info);
362 }
363 
364 /* This is the driver that will be inserted */
365 static struct i2c_driver ltc2978_driver = {
366  .driver = {
367  .name = "ltc2978",
368  },
369  .probe = ltc2978_probe,
370  .remove = pmbus_do_remove,
371  .id_table = ltc2978_id,
372 };
373 
374 module_i2c_driver(ltc2978_driver);
375 
376 MODULE_AUTHOR("Guenter Roeck");
377 MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880");
378 MODULE_LICENSE("GPL");