1 /* 2 * Hardware monitoring driver for Maxim MAX34440/MAX34441 3 * 4 * Copyright (c) 2011 Ericsson AB. 5 * Copyright (c) 2012 Guenter Roeck 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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/i2c.h> 28 #include "pmbus.h" 29 30 enum chips { max34440, max34441, max34446, max34460, max34461 }; 31 32 #define MAX34440_MFR_VOUT_PEAK 0xd4 33 #define MAX34440_MFR_IOUT_PEAK 0xd5 34 #define MAX34440_MFR_TEMPERATURE_PEAK 0xd6 35 #define MAX34440_MFR_VOUT_MIN 0xd7 36 37 #define MAX34446_MFR_POUT_PEAK 0xe0 38 #define MAX34446_MFR_POUT_AVG 0xe1 39 #define MAX34446_MFR_IOUT_AVG 0xe2 40 #define MAX34446_MFR_TEMPERATURE_AVG 0xe3 41 42 #define MAX34440_STATUS_OC_WARN BIT(0) 43 #define MAX34440_STATUS_OC_FAULT BIT(1) 44 #define MAX34440_STATUS_OT_FAULT BIT(5) 45 #define MAX34440_STATUS_OT_WARN BIT(6) 46 47 struct max34440_data { 48 int id; 49 struct pmbus_driver_info info; 50 }; 51 52 #define to_max34440_data(x) container_of(x, struct max34440_data, info) 53 54 static int max34440_read_word_data(struct i2c_client *client, int page, int reg) 55 { 56 int ret; 57 const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 58 const struct max34440_data *data = to_max34440_data(info); 59 60 switch (reg) { 61 case PMBUS_VIRT_READ_VOUT_MIN: 62 ret = pmbus_read_word_data(client, page, 63 MAX34440_MFR_VOUT_MIN); 64 break; 65 case PMBUS_VIRT_READ_VOUT_MAX: 66 ret = pmbus_read_word_data(client, page, 67 MAX34440_MFR_VOUT_PEAK); 68 break; 69 case PMBUS_VIRT_READ_IOUT_AVG: 70 if (data->id != max34446) 71 return -ENXIO; 72 ret = pmbus_read_word_data(client, page, 73 MAX34446_MFR_IOUT_AVG); 74 break; 75 case PMBUS_VIRT_READ_IOUT_MAX: 76 ret = pmbus_read_word_data(client, page, 77 MAX34440_MFR_IOUT_PEAK); 78 break; 79 case PMBUS_VIRT_READ_POUT_AVG: 80 if (data->id != max34446) 81 return -ENXIO; 82 ret = pmbus_read_word_data(client, page, 83 MAX34446_MFR_POUT_AVG); 84 break; 85 case PMBUS_VIRT_READ_POUT_MAX: 86 if (data->id != max34446) 87 return -ENXIO; 88 ret = pmbus_read_word_data(client, page, 89 MAX34446_MFR_POUT_PEAK); 90 break; 91 case PMBUS_VIRT_READ_TEMP_AVG: 92 if (data->id != max34446 && data->id != max34460 && 93 data->id != max34461) 94 return -ENXIO; 95 ret = pmbus_read_word_data(client, page, 96 MAX34446_MFR_TEMPERATURE_AVG); 97 break; 98 case PMBUS_VIRT_READ_TEMP_MAX: 99 ret = pmbus_read_word_data(client, page, 100 MAX34440_MFR_TEMPERATURE_PEAK); 101 break; 102 case PMBUS_VIRT_RESET_POUT_HISTORY: 103 if (data->id != max34446) 104 return -ENXIO; 105 ret = 0; 106 break; 107 case PMBUS_VIRT_RESET_VOUT_HISTORY: 108 case PMBUS_VIRT_RESET_IOUT_HISTORY: 109 case PMBUS_VIRT_RESET_TEMP_HISTORY: 110 ret = 0; 111 break; 112 default: 113 ret = -ENODATA; 114 break; 115 } 116 return ret; 117 } 118 119 static int max34440_write_word_data(struct i2c_client *client, int page, 120 int reg, u16 word) 121 { 122 const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 123 const struct max34440_data *data = to_max34440_data(info); 124 int ret; 125 126 switch (reg) { 127 case PMBUS_VIRT_RESET_POUT_HISTORY: 128 ret = pmbus_write_word_data(client, page, 129 MAX34446_MFR_POUT_PEAK, 0); 130 if (ret) 131 break; 132 ret = pmbus_write_word_data(client, page, 133 MAX34446_MFR_POUT_AVG, 0); 134 break; 135 case PMBUS_VIRT_RESET_VOUT_HISTORY: 136 ret = pmbus_write_word_data(client, page, 137 MAX34440_MFR_VOUT_MIN, 0x7fff); 138 if (ret) 139 break; 140 ret = pmbus_write_word_data(client, page, 141 MAX34440_MFR_VOUT_PEAK, 0); 142 break; 143 case PMBUS_VIRT_RESET_IOUT_HISTORY: 144 ret = pmbus_write_word_data(client, page, 145 MAX34440_MFR_IOUT_PEAK, 0); 146 if (!ret && data->id == max34446) 147 ret = pmbus_write_word_data(client, page, 148 MAX34446_MFR_IOUT_AVG, 0); 149 150 break; 151 case PMBUS_VIRT_RESET_TEMP_HISTORY: 152 ret = pmbus_write_word_data(client, page, 153 MAX34440_MFR_TEMPERATURE_PEAK, 154 0x8000); 155 if (!ret && data->id == max34446) 156 ret = pmbus_write_word_data(client, page, 157 MAX34446_MFR_TEMPERATURE_AVG, 0); 158 break; 159 default: 160 ret = -ENODATA; 161 break; 162 } 163 return ret; 164 } 165 166 static int max34440_read_byte_data(struct i2c_client *client, int page, int reg) 167 { 168 int ret = 0; 169 int mfg_status; 170 171 if (page >= 0) { 172 ret = pmbus_set_page(client, page); 173 if (ret < 0) 174 return ret; 175 } 176 177 switch (reg) { 178 case PMBUS_STATUS_IOUT: 179 mfg_status = pmbus_read_word_data(client, 0, 180 PMBUS_STATUS_MFR_SPECIFIC); 181 if (mfg_status < 0) 182 return mfg_status; 183 if (mfg_status & MAX34440_STATUS_OC_WARN) 184 ret |= PB_IOUT_OC_WARNING; 185 if (mfg_status & MAX34440_STATUS_OC_FAULT) 186 ret |= PB_IOUT_OC_FAULT; 187 break; 188 case PMBUS_STATUS_TEMPERATURE: 189 mfg_status = pmbus_read_word_data(client, 0, 190 PMBUS_STATUS_MFR_SPECIFIC); 191 if (mfg_status < 0) 192 return mfg_status; 193 if (mfg_status & MAX34440_STATUS_OT_WARN) 194 ret |= PB_TEMP_OT_WARNING; 195 if (mfg_status & MAX34440_STATUS_OT_FAULT) 196 ret |= PB_TEMP_OT_FAULT; 197 break; 198 default: 199 ret = -ENODATA; 200 break; 201 } 202 return ret; 203 } 204 205 static struct pmbus_driver_info max34440_info[] = { 206 [max34440] = { 207 .pages = 14, 208 .format[PSC_VOLTAGE_IN] = direct, 209 .format[PSC_VOLTAGE_OUT] = direct, 210 .format[PSC_TEMPERATURE] = direct, 211 .format[PSC_CURRENT_OUT] = direct, 212 .m[PSC_VOLTAGE_IN] = 1, 213 .b[PSC_VOLTAGE_IN] = 0, 214 .R[PSC_VOLTAGE_IN] = 3, /* R = 0 in datasheet reflects mV */ 215 .m[PSC_VOLTAGE_OUT] = 1, 216 .b[PSC_VOLTAGE_OUT] = 0, 217 .R[PSC_VOLTAGE_OUT] = 3, /* R = 0 in datasheet reflects mV */ 218 .m[PSC_CURRENT_OUT] = 1, 219 .b[PSC_CURRENT_OUT] = 0, 220 .R[PSC_CURRENT_OUT] = 3, /* R = 0 in datasheet reflects mA */ 221 .m[PSC_TEMPERATURE] = 1, 222 .b[PSC_TEMPERATURE] = 0, 223 .R[PSC_TEMPERATURE] = 2, 224 .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 225 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 226 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 227 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 228 .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 229 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 230 .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 231 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 232 .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 233 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 234 .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 235 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 236 .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 237 .func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 238 .func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 239 .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 240 .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 241 .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 242 .func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 243 .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 244 .read_byte_data = max34440_read_byte_data, 245 .read_word_data = max34440_read_word_data, 246 .write_word_data = max34440_write_word_data, 247 }, 248 [max34441] = { 249 .pages = 12, 250 .format[PSC_VOLTAGE_IN] = direct, 251 .format[PSC_VOLTAGE_OUT] = direct, 252 .format[PSC_TEMPERATURE] = direct, 253 .format[PSC_CURRENT_OUT] = direct, 254 .format[PSC_FAN] = direct, 255 .m[PSC_VOLTAGE_IN] = 1, 256 .b[PSC_VOLTAGE_IN] = 0, 257 .R[PSC_VOLTAGE_IN] = 3, 258 .m[PSC_VOLTAGE_OUT] = 1, 259 .b[PSC_VOLTAGE_OUT] = 0, 260 .R[PSC_VOLTAGE_OUT] = 3, 261 .m[PSC_CURRENT_OUT] = 1, 262 .b[PSC_CURRENT_OUT] = 0, 263 .R[PSC_CURRENT_OUT] = 3, 264 .m[PSC_TEMPERATURE] = 1, 265 .b[PSC_TEMPERATURE] = 0, 266 .R[PSC_TEMPERATURE] = 2, 267 .m[PSC_FAN] = 1, 268 .b[PSC_FAN] = 0, 269 .R[PSC_FAN] = 0, 270 .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 271 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 272 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 273 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 274 .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 275 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 276 .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 277 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 278 .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 279 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 280 .func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12, 281 .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 282 .func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 283 .func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 284 .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 285 .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 286 .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 287 .read_byte_data = max34440_read_byte_data, 288 .read_word_data = max34440_read_word_data, 289 .write_word_data = max34440_write_word_data, 290 }, 291 [max34446] = { 292 .pages = 7, 293 .format[PSC_VOLTAGE_IN] = direct, 294 .format[PSC_VOLTAGE_OUT] = direct, 295 .format[PSC_TEMPERATURE] = direct, 296 .format[PSC_CURRENT_OUT] = direct, 297 .format[PSC_POWER] = direct, 298 .m[PSC_VOLTAGE_IN] = 1, 299 .b[PSC_VOLTAGE_IN] = 0, 300 .R[PSC_VOLTAGE_IN] = 3, 301 .m[PSC_VOLTAGE_OUT] = 1, 302 .b[PSC_VOLTAGE_OUT] = 0, 303 .R[PSC_VOLTAGE_OUT] = 3, 304 .m[PSC_CURRENT_OUT] = 1, 305 .b[PSC_CURRENT_OUT] = 0, 306 .R[PSC_CURRENT_OUT] = 3, 307 .m[PSC_POWER] = 1, 308 .b[PSC_POWER] = 0, 309 .R[PSC_POWER] = 3, 310 .m[PSC_TEMPERATURE] = 1, 311 .b[PSC_TEMPERATURE] = 0, 312 .R[PSC_TEMPERATURE] = 2, 313 .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 314 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 315 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 316 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 317 .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 318 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 319 .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 320 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 321 .func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 322 .func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 323 .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 324 .read_byte_data = max34440_read_byte_data, 325 .read_word_data = max34440_read_word_data, 326 .write_word_data = max34440_write_word_data, 327 }, 328 [max34460] = { 329 .pages = 18, 330 .format[PSC_VOLTAGE_OUT] = direct, 331 .format[PSC_TEMPERATURE] = direct, 332 .m[PSC_VOLTAGE_OUT] = 1, 333 .b[PSC_VOLTAGE_OUT] = 0, 334 .R[PSC_VOLTAGE_OUT] = 3, 335 .m[PSC_TEMPERATURE] = 1, 336 .b[PSC_TEMPERATURE] = 0, 337 .R[PSC_TEMPERATURE] = 2, 338 .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 339 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 340 .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 341 .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 342 .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 343 .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 344 .func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 345 .func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 346 .func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 347 .func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 348 .func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 349 .func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 350 .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 351 .func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 352 .func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 353 .func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 354 .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 355 .read_byte_data = max34440_read_byte_data, 356 .read_word_data = max34440_read_word_data, 357 .write_word_data = max34440_write_word_data, 358 }, 359 [max34461] = { 360 .pages = 23, 361 .format[PSC_VOLTAGE_OUT] = direct, 362 .format[PSC_TEMPERATURE] = direct, 363 .m[PSC_VOLTAGE_OUT] = 1, 364 .b[PSC_VOLTAGE_OUT] = 0, 365 .R[PSC_VOLTAGE_OUT] = 3, 366 .m[PSC_TEMPERATURE] = 1, 367 .b[PSC_TEMPERATURE] = 0, 368 .R[PSC_TEMPERATURE] = 2, 369 .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 370 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 371 .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 372 .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 373 .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 374 .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 375 .func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 376 .func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 377 .func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 378 .func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 379 .func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 380 .func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 381 .func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 382 .func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 383 .func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 384 .func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 385 /* page 16 is reserved */ 386 .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 387 .func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 388 .func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 389 .func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 390 .func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 391 .read_byte_data = max34440_read_byte_data, 392 .read_word_data = max34440_read_word_data, 393 .write_word_data = max34440_write_word_data, 394 }, 395 }; 396 397 static int max34440_probe(struct i2c_client *client, 398 const struct i2c_device_id *id) 399 { 400 struct max34440_data *data; 401 402 data = devm_kzalloc(&client->dev, sizeof(struct max34440_data), 403 GFP_KERNEL); 404 if (!data) 405 return -ENOMEM; 406 data->id = id->driver_data; 407 data->info = max34440_info[id->driver_data]; 408 409 return pmbus_do_probe(client, id, &data->info); 410 } 411 412 static const struct i2c_device_id max34440_id[] = { 413 {"max34440", max34440}, 414 {"max34441", max34441}, 415 {"max34446", max34446}, 416 {"max34460", max34460}, 417 {"max34461", max34461}, 418 {} 419 }; 420 MODULE_DEVICE_TABLE(i2c, max34440_id); 421 422 /* This is the driver that will be inserted */ 423 static struct i2c_driver max34440_driver = { 424 .driver = { 425 .name = "max34440", 426 }, 427 .probe = max34440_probe, 428 .remove = pmbus_do_remove, 429 .id_table = max34440_id, 430 }; 431 432 module_i2c_driver(max34440_driver); 433 434 MODULE_AUTHOR("Guenter Roeck"); 435 MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441"); 436 MODULE_LICENSE("GPL"); 437