2 * Hardware monitoring driver for LTC2978
4 * Copyright (c) 2011 Ericsson AB.
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.
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.
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.
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>
29 enum chips
{ ltc2978
};
31 #define LTC2978_MFR_VOUT_PEAK 0xdd
32 #define LTC2978_MFR_VIN_PEAK 0xde
33 #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf
34 #define LTC2978_MFR_SPECIAL_ID 0xe7
36 #define LTC2978_MFR_VOUT_MIN 0xfb
37 #define LTC2978_MFR_VIN_MIN 0xfc
38 #define LTC2978_MFR_TEMPERATURE_MIN 0xfd
40 #define LTC2978_ID_REV1 0x0121
41 #define LTC2978_ID_REV2 0x0122
44 * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
45 * happens pretty much each time chip data is updated. Raw peak data therefore
46 * does not provide much value. To be able to provide useful peak data, keep an
47 * internal cache of measured peak data, which is only cleared if an explicit
48 * "clear peak" command is executed for the sensor in question.
53 int temp_min
, temp_max
;
54 int vout_min
[8], vout_max
[8];
55 struct pmbus_driver_info info
;
58 #define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info)
60 static inline int lin11_to_val(int data
)
62 s16 e
= ((s16
)data
) >> 11;
63 s32 m
= (((s16
)(data
<< 5)) >> 5);
66 * mantissa is 10 bit + sign, exponent adds up to 15 bit.
67 * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31).
70 return (e
< 0 ? m
>> -e
: m
<< e
);
73 static int ltc2978_read_word_data(struct i2c_client
*client
, int page
, int reg
)
75 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
76 struct ltc2978_data
*data
= to_ltc2978_data(info
);
80 case PMBUS_VIRT_READ_VIN_MAX
:
81 ret
= pmbus_read_word_data(client
, page
, LTC2978_MFR_VIN_PEAK
);
83 if (lin11_to_val(ret
) > lin11_to_val(data
->vin_max
))
88 case PMBUS_VIRT_READ_VOUT_MAX
:
89 ret
= pmbus_read_word_data(client
, page
, LTC2978_MFR_VOUT_PEAK
);
92 * VOUT is 16 bit unsigned with fixed exponent,
93 * so we can compare it directly
95 if (ret
> data
->vout_max
[page
])
96 data
->vout_max
[page
] = ret
;
97 ret
= data
->vout_max
[page
];
100 case PMBUS_VIRT_READ_TEMP_MAX
:
101 ret
= pmbus_read_word_data(client
, page
,
102 LTC2978_MFR_TEMPERATURE_PEAK
);
104 if (lin11_to_val(ret
) > lin11_to_val(data
->temp_max
))
105 data
->temp_max
= ret
;
106 ret
= data
->temp_max
;
109 case PMBUS_VIRT_READ_VIN_MIN
:
110 ret
= pmbus_read_word_data(client
, page
, LTC2978_MFR_VIN_MIN
);
112 if (lin11_to_val(ret
) < lin11_to_val(data
->vin_min
))
117 case PMBUS_VIRT_READ_VOUT_MIN
:
118 ret
= pmbus_read_word_data(client
, page
, LTC2978_MFR_VOUT_MIN
);
121 * VOUT_MIN is known to not be supported on some lots
122 * of LTC2978 revision 1, and will return the maximum
123 * possible voltage if read. If VOUT_MAX is valid and
124 * lower than the reading of VOUT_MIN, use it instead.
126 if (data
->vout_max
[page
] && ret
> data
->vout_max
[page
])
127 ret
= data
->vout_max
[page
];
128 if (ret
< data
->vout_min
[page
])
129 data
->vout_min
[page
] = ret
;
130 ret
= data
->vout_min
[page
];
133 case PMBUS_VIRT_READ_TEMP_MIN
:
134 ret
= pmbus_read_word_data(client
, page
,
135 LTC2978_MFR_TEMPERATURE_MIN
);
137 if (lin11_to_val(ret
)
138 < lin11_to_val(data
->temp_min
))
139 data
->temp_min
= ret
;
140 ret
= data
->temp_min
;
143 case PMBUS_VIRT_RESET_VOUT_HISTORY
:
144 case PMBUS_VIRT_RESET_VIN_HISTORY
:
145 case PMBUS_VIRT_RESET_TEMP_HISTORY
:
155 static int ltc2978_write_word_data(struct i2c_client
*client
, int page
,
158 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
159 struct ltc2978_data
*data
= to_ltc2978_data(info
);
163 case PMBUS_VIRT_RESET_VOUT_HISTORY
:
164 data
->vout_min
[page
] = 0xffff;
165 data
->vout_max
[page
] = 0;
166 ret
= pmbus_write_byte(client
, page
, PMBUS_CLEAR_FAULTS
);
168 case PMBUS_VIRT_RESET_VIN_HISTORY
:
169 data
->vin_min
= 0x7bff;
171 ret
= pmbus_write_byte(client
, page
, PMBUS_CLEAR_FAULTS
);
173 case PMBUS_VIRT_RESET_TEMP_HISTORY
:
174 data
->temp_min
= 0x7bff;
175 data
->temp_max
= 0x7fff;
176 ret
= pmbus_write_byte(client
, page
, PMBUS_CLEAR_FAULTS
);
185 static const struct i2c_device_id ltc2978_id
[] = {
186 {"ltc2978", ltc2978
},
189 MODULE_DEVICE_TABLE(i2c
, ltc2978_id
);
191 static int ltc2978_probe(struct i2c_client
*client
,
192 const struct i2c_device_id
*id
)
195 struct ltc2978_data
*data
;
196 struct pmbus_driver_info
*info
;
198 if (!i2c_check_functionality(client
->adapter
,
199 I2C_FUNC_SMBUS_READ_WORD_DATA
))
202 data
= kzalloc(sizeof(struct ltc2978_data
), GFP_KERNEL
);
206 chip_id
= i2c_smbus_read_word_data(client
, LTC2978_MFR_SPECIAL_ID
);
212 if (chip_id
== LTC2978_ID_REV1
|| chip_id
== LTC2978_ID_REV2
) {
215 dev_err(&client
->dev
, "Unsupported chip ID 0x%x\n", chip_id
);
219 if (data
->id
!= id
->driver_data
)
220 dev_warn(&client
->dev
,
221 "Device mismatch: Configured %s, detected %s\n",
223 ltc2978_id
[data
->id
].name
);
226 info
->read_word_data
= ltc2978_read_word_data
;
227 info
->write_word_data
= ltc2978_write_word_data
;
229 data
->vout_min
[0] = 0xffff;
230 data
->vin_min
= 0x7bff;
231 data
->temp_min
= 0x7bff;
232 data
->temp_max
= 0x7fff;
234 switch (id
->driver_data
) {
237 info
->func
[0] = PMBUS_HAVE_VIN
| PMBUS_HAVE_STATUS_INPUT
238 | PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
239 | PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
;
240 for (i
= 1; i
< 8; i
++) {
241 info
->func
[i
] = PMBUS_HAVE_VOUT
242 | PMBUS_HAVE_STATUS_VOUT
;
243 data
->vout_min
[i
] = 0xffff;
251 ret
= pmbus_do_probe(client
, id
, info
);
261 static int ltc2978_remove(struct i2c_client
*client
)
263 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
264 const struct ltc2978_data
*data
= to_ltc2978_data(info
);
266 pmbus_do_remove(client
);
271 /* This is the driver that will be inserted */
272 static struct i2c_driver ltc2978_driver
= {
276 .probe
= ltc2978_probe
,
277 .remove
= ltc2978_remove
,
278 .id_table
= ltc2978_id
,
281 static int __init
ltc2978_init(void)
283 return i2c_add_driver(<c2978_driver
);
286 static void __exit
ltc2978_exit(void)
288 i2c_del_driver(<c2978_driver
);
291 MODULE_AUTHOR("Guenter Roeck");
292 MODULE_DESCRIPTION("PMBus driver for LTC2978");
293 MODULE_LICENSE("GPL");
294 module_init(ltc2978_init
);
295 module_exit(ltc2978_exit
);