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; 63 int vout_min[8], vout_max[8]; 64 int iout_max[2]; 65 int temp2_max[2]; 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) > lin11_to_val(data->temp_max)) 117 data->temp_max = ret; 118 ret = data->temp_max; 119 } 120 break; 121 case PMBUS_VIRT_RESET_VOUT_HISTORY: 122 case PMBUS_VIRT_RESET_VIN_HISTORY: 123 case PMBUS_VIRT_RESET_TEMP_HISTORY: 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) { 140 case PMBUS_VIRT_READ_VIN_MIN: 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; 148 case PMBUS_VIRT_READ_VOUT_MIN: 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; 164 case PMBUS_VIRT_READ_TEMP_MIN: 165 ret = pmbus_read_word_data(client, page, 166 LTC2978_MFR_TEMPERATURE_MIN); 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; 174 case PMBUS_VIRT_READ_IOUT_MAX: 175 case PMBUS_VIRT_RESET_IOUT_HISTORY: 176 case PMBUS_VIRT_READ_TEMP2_MAX: 177 case PMBUS_VIRT_RESET_TEMP2_HISTORY: 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) { 194 case PMBUS_VIRT_READ_IOUT_MAX: 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; 203 case PMBUS_VIRT_READ_TEMP2_MAX: 204 ret = pmbus_read_word_data(client, page, 205 LTC3880_MFR_TEMPERATURE2_PEAK); 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; 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] = 0x7fff; 252 ret = ltc2978_clear_peaks(client, page, data->id); 253 break; 254 case PMBUS_VIRT_RESET_TEMP2_HISTORY: 255 data->temp2_max[page] = 0x7fff; 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 = 0; 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 = 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, 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->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; 333 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT 334 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 335 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 336 for (i = 1; i < 8; i++) { 337 info->func[i] = PMBUS_HAVE_VOUT 338 | PMBUS_HAVE_STATUS_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 346 | PMBUS_HAVE_STATUS_INPUT 347 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 348 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 349 | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP 350 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; 351 info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 352 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 353 | PMBUS_HAVE_POUT 354 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 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"); 379