]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/hwmon/pmbus/ltc2978.c
Merge tag 'iommu-fixes-v3.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / drivers / hwmon / pmbus / ltc2978.c
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;
61         int vin_min, vin_max;
62         int temp_min, temp_max[2];
63         int vout_min[8], vout_max[8];
64         int iout_max[2];
65         int temp2_max;
66         struct pmbus_driver_info info;
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) {
92         case PMBUS_VIRT_READ_VIN_MAX:
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;
100         case PMBUS_VIRT_READ_VOUT_MAX:
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;
112         case PMBUS_VIRT_READ_TEMP_MAX:
113                 ret = pmbus_read_word_data(client, page,
114                                            LTC2978_MFR_TEMPERATURE_PEAK);
115                 if (ret >= 0) {
116                         if (lin11_to_val(ret)
117                             > lin11_to_val(data->temp_max[page]))
118                                 data->temp_max[page] = ret;
119                         ret = data->temp_max[page];
120                 }
121                 break;
122         case PMBUS_VIRT_RESET_VOUT_HISTORY:
123         case PMBUS_VIRT_RESET_VIN_HISTORY:
124         case PMBUS_VIRT_RESET_TEMP_HISTORY:
125                 ret = 0;
126                 break;
127         default:
128                 ret = -ENODATA;
129                 break;
130         }
131         return ret;
132 }
133
134 static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg)
135 {
136         const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
137         struct ltc2978_data *data = to_ltc2978_data(info);
138         int ret;
139
140         switch (reg) {
141         case PMBUS_VIRT_READ_VIN_MIN:
142                 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_MIN);
143                 if (ret >= 0) {
144                         if (lin11_to_val(ret) < lin11_to_val(data->vin_min))
145                                 data->vin_min = ret;
146                         ret = data->vin_min;
147                 }
148                 break;
149         case PMBUS_VIRT_READ_VOUT_MIN:
150                 ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN);
151                 if (ret >= 0) {
152                         /*
153                          * VOUT_MIN is known to not be supported on some lots
154                          * of LTC2978 revision 1, and will return the maximum
155                          * possible voltage if read. If VOUT_MAX is valid and
156                          * lower than the reading of VOUT_MIN, use it instead.
157                          */
158                         if (data->vout_max[page] && ret > data->vout_max[page])
159                                 ret = data->vout_max[page];
160                         if (ret < data->vout_min[page])
161                                 data->vout_min[page] = ret;
162                         ret = data->vout_min[page];
163                 }
164                 break;
165         case PMBUS_VIRT_READ_TEMP_MIN:
166                 ret = pmbus_read_word_data(client, page,
167                                            LTC2978_MFR_TEMPERATURE_MIN);
168                 if (ret >= 0) {
169                         if (lin11_to_val(ret)
170                             < lin11_to_val(data->temp_min))
171                                 data->temp_min = ret;
172                         ret = data->temp_min;
173                 }
174                 break;
175         case PMBUS_VIRT_READ_IOUT_MAX:
176         case PMBUS_VIRT_RESET_IOUT_HISTORY:
177         case PMBUS_VIRT_READ_TEMP2_MAX:
178         case PMBUS_VIRT_RESET_TEMP2_HISTORY:
179                 ret = -ENXIO;
180                 break;
181         default:
182                 ret = ltc2978_read_word_data_common(client, page, reg);
183                 break;
184         }
185         return ret;
186 }
187
188 static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
189 {
190         const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
191         struct ltc2978_data *data = to_ltc2978_data(info);
192         int ret;
193
194         switch (reg) {
195         case PMBUS_VIRT_READ_IOUT_MAX:
196                 ret = pmbus_read_word_data(client, page, LTC3880_MFR_IOUT_PEAK);
197                 if (ret >= 0) {
198                         if (lin11_to_val(ret)
199                             > lin11_to_val(data->iout_max[page]))
200                                 data->iout_max[page] = ret;
201                         ret = data->iout_max[page];
202                 }
203                 break;
204         case PMBUS_VIRT_READ_TEMP2_MAX:
205                 ret = pmbus_read_word_data(client, page,
206                                            LTC3880_MFR_TEMPERATURE2_PEAK);
207                 if (ret >= 0) {
208                         if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
209                                 data->temp2_max = ret;
210                         ret = data->temp2_max;
211                 }
212                 break;
213         case PMBUS_VIRT_READ_VIN_MIN:
214         case PMBUS_VIRT_READ_VOUT_MIN:
215         case PMBUS_VIRT_READ_TEMP_MIN:
216                 ret = -ENXIO;
217                 break;
218         case PMBUS_VIRT_RESET_IOUT_HISTORY:
219         case PMBUS_VIRT_RESET_TEMP2_HISTORY:
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) {
250         case PMBUS_VIRT_RESET_IOUT_HISTORY:
251                 data->iout_max[page] = 0x7c00;
252                 ret = ltc2978_clear_peaks(client, page, data->id);
253                 break;
254         case PMBUS_VIRT_RESET_TEMP2_HISTORY:
255                 data->temp2_max = 0x7c00;
256                 ret = ltc2978_clear_peaks(client, page, data->id);
257                 break;
258         case PMBUS_VIRT_RESET_VOUT_HISTORY:
259                 data->vout_min[page] = 0xffff;
260                 data->vout_max[page] = 0;
261                 ret = ltc2978_clear_peaks(client, page, data->id);
262                 break;
263         case PMBUS_VIRT_RESET_VIN_HISTORY:
264                 data->vin_min = 0x7bff;
265                 data->vin_max = 0x7c00;
266                 ret = ltc2978_clear_peaks(client, page, data->id);
267                 break;
268         case PMBUS_VIRT_RESET_TEMP_HISTORY:
269                 data->temp_min = 0x7bff;
270                 data->temp_max[page] = 0x7c00;
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,
295                                      I2C_FUNC_SMBUS_READ_WORD_DATA))
296                 return -ENODEV;
297
298         data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data),
299                             GFP_KERNEL);
300         if (!data)
301                 return -ENOMEM;
302
303         chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID);
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->vin_min = 0x7bff;
325         data->vin_max = 0x7c00;
326         data->temp_min = 0x7bff;
327         for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
328                 data->temp_max[i] = 0x7c00;
329         data->temp2_max = 0x7c00;
330
331         switch (data->id) {
332         case ltc2978:
333                 info->read_word_data = ltc2978_read_word_data;
334                 info->pages = 8;
335                 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
336                   | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
337                   | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
338                 for (i = 1; i < 8; i++) {
339                         info->func[i] = PMBUS_HAVE_VOUT
340                           | PMBUS_HAVE_STATUS_VOUT;
341                 }
342                 break;
343         case ltc3880:
344                 info->read_word_data = ltc3880_read_word_data;
345                 info->pages = 2;
346                 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
347                   | PMBUS_HAVE_STATUS_INPUT
348                   | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
349                   | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
350                   | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
351                   | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
352                 info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
353                   | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
354                   | PMBUS_HAVE_POUT
355                   | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
356                 data->iout_max[0] = 0x7c00;
357                 data->iout_max[1] = 0x7c00;
358                 break;
359         default:
360                 return -ENODEV;
361         }
362         for (i = 0; i < info->pages; i++)
363                 data->vout_min[i] = 0xffff;
364
365         return pmbus_do_probe(client, id, info);
366 }
367
368 /* This is the driver that will be inserted */
369 static struct i2c_driver ltc2978_driver = {
370         .driver = {
371                    .name = "ltc2978",
372                    },
373         .probe = ltc2978_probe,
374         .remove = pmbus_do_remove,
375         .id_table = ltc2978_id,
376 };
377
378 module_i2c_driver(ltc2978_driver);
379
380 MODULE_AUTHOR("Guenter Roeck");
381 MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880");
382 MODULE_LICENSE("GPL");