19d2ecfb7SGuenter Roeck /* 29d2ecfb7SGuenter Roeck * Hardware monitoring driver for Maxim MAX34440/MAX34441 39d2ecfb7SGuenter Roeck * 49d2ecfb7SGuenter Roeck * Copyright (c) 2011 Ericsson AB. 5*50115ac9SGuenter Roeck * Copyright (c) 2012 Guenter Roeck 69d2ecfb7SGuenter Roeck * 79d2ecfb7SGuenter Roeck * This program is free software; you can redistribute it and/or modify 89d2ecfb7SGuenter Roeck * it under the terms of the GNU General Public License as published by 99d2ecfb7SGuenter Roeck * the Free Software Foundation; either version 2 of the License, or 109d2ecfb7SGuenter Roeck * (at your option) any later version. 119d2ecfb7SGuenter Roeck * 129d2ecfb7SGuenter Roeck * This program is distributed in the hope that it will be useful, 139d2ecfb7SGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 149d2ecfb7SGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 159d2ecfb7SGuenter Roeck * GNU General Public License for more details. 169d2ecfb7SGuenter Roeck * 179d2ecfb7SGuenter Roeck * You should have received a copy of the GNU General Public License 189d2ecfb7SGuenter Roeck * along with this program; if not, write to the Free Software 199d2ecfb7SGuenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 209d2ecfb7SGuenter Roeck */ 219d2ecfb7SGuenter Roeck 229d2ecfb7SGuenter Roeck #include <linux/kernel.h> 239d2ecfb7SGuenter Roeck #include <linux/module.h> 249d2ecfb7SGuenter Roeck #include <linux/init.h> 259d2ecfb7SGuenter Roeck #include <linux/err.h> 269d2ecfb7SGuenter Roeck #include <linux/i2c.h> 279d2ecfb7SGuenter Roeck #include "pmbus.h" 289d2ecfb7SGuenter Roeck 29*50115ac9SGuenter Roeck enum chips { max34440, max34441, max34446, max34460, max34461 }; 309d2ecfb7SGuenter Roeck 3198591dbeSGuenter Roeck #define MAX34440_MFR_VOUT_PEAK 0xd4 3298591dbeSGuenter Roeck #define MAX34440_MFR_IOUT_PEAK 0xd5 3398591dbeSGuenter Roeck #define MAX34440_MFR_TEMPERATURE_PEAK 0xd6 3456aad5d1SGuenter Roeck #define MAX34440_MFR_VOUT_MIN 0xd7 3598591dbeSGuenter Roeck 36590defe5SGuenter Roeck #define MAX34446_MFR_POUT_PEAK 0xe0 37590defe5SGuenter Roeck #define MAX34446_MFR_POUT_AVG 0xe1 38590defe5SGuenter Roeck #define MAX34446_MFR_IOUT_AVG 0xe2 39590defe5SGuenter Roeck #define MAX34446_MFR_TEMPERATURE_AVG 0xe3 40590defe5SGuenter Roeck 419d2ecfb7SGuenter Roeck #define MAX34440_STATUS_OC_WARN (1 << 0) 429d2ecfb7SGuenter Roeck #define MAX34440_STATUS_OC_FAULT (1 << 1) 439d2ecfb7SGuenter Roeck #define MAX34440_STATUS_OT_FAULT (1 << 5) 449d2ecfb7SGuenter Roeck #define MAX34440_STATUS_OT_WARN (1 << 6) 459d2ecfb7SGuenter Roeck 46590defe5SGuenter Roeck struct max34440_data { 47590defe5SGuenter Roeck int id; 48590defe5SGuenter Roeck struct pmbus_driver_info info; 49590defe5SGuenter Roeck }; 50590defe5SGuenter Roeck 51590defe5SGuenter Roeck #define to_max34440_data(x) container_of(x, struct max34440_data, info) 52590defe5SGuenter Roeck 5398591dbeSGuenter Roeck static int max34440_read_word_data(struct i2c_client *client, int page, int reg) 5498591dbeSGuenter Roeck { 5598591dbeSGuenter Roeck int ret; 56590defe5SGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 57590defe5SGuenter Roeck const struct max34440_data *data = to_max34440_data(info); 5898591dbeSGuenter Roeck 5998591dbeSGuenter Roeck switch (reg) { 6056aad5d1SGuenter Roeck case PMBUS_VIRT_READ_VOUT_MIN: 6156aad5d1SGuenter Roeck ret = pmbus_read_word_data(client, page, 6256aad5d1SGuenter Roeck MAX34440_MFR_VOUT_MIN); 6356aad5d1SGuenter Roeck break; 6498591dbeSGuenter Roeck case PMBUS_VIRT_READ_VOUT_MAX: 6598591dbeSGuenter Roeck ret = pmbus_read_word_data(client, page, 6698591dbeSGuenter Roeck MAX34440_MFR_VOUT_PEAK); 6798591dbeSGuenter Roeck break; 68590defe5SGuenter Roeck case PMBUS_VIRT_READ_IOUT_AVG: 69590defe5SGuenter Roeck if (data->id != max34446) 70590defe5SGuenter Roeck return -ENXIO; 71590defe5SGuenter Roeck ret = pmbus_read_word_data(client, page, 72590defe5SGuenter Roeck MAX34446_MFR_IOUT_AVG); 73590defe5SGuenter Roeck break; 7498591dbeSGuenter Roeck case PMBUS_VIRT_READ_IOUT_MAX: 7598591dbeSGuenter Roeck ret = pmbus_read_word_data(client, page, 7698591dbeSGuenter Roeck MAX34440_MFR_IOUT_PEAK); 7798591dbeSGuenter Roeck break; 78590defe5SGuenter Roeck case PMBUS_VIRT_READ_POUT_AVG: 79590defe5SGuenter Roeck if (data->id != max34446) 80590defe5SGuenter Roeck return -ENXIO; 81590defe5SGuenter Roeck ret = pmbus_read_word_data(client, page, 82590defe5SGuenter Roeck MAX34446_MFR_POUT_AVG); 83590defe5SGuenter Roeck break; 84590defe5SGuenter Roeck case PMBUS_VIRT_READ_POUT_MAX: 85590defe5SGuenter Roeck if (data->id != max34446) 86590defe5SGuenter Roeck return -ENXIO; 87590defe5SGuenter Roeck ret = pmbus_read_word_data(client, page, 88590defe5SGuenter Roeck MAX34446_MFR_POUT_PEAK); 89590defe5SGuenter Roeck break; 90590defe5SGuenter Roeck case PMBUS_VIRT_READ_TEMP_AVG: 91*50115ac9SGuenter Roeck if (data->id != max34446 && data->id != max34460 && 92*50115ac9SGuenter Roeck data->id != max34461) 93590defe5SGuenter Roeck return -ENXIO; 94590defe5SGuenter Roeck ret = pmbus_read_word_data(client, page, 95590defe5SGuenter Roeck MAX34446_MFR_TEMPERATURE_AVG); 96590defe5SGuenter Roeck break; 9798591dbeSGuenter Roeck case PMBUS_VIRT_READ_TEMP_MAX: 9898591dbeSGuenter Roeck ret = pmbus_read_word_data(client, page, 9998591dbeSGuenter Roeck MAX34440_MFR_TEMPERATURE_PEAK); 10098591dbeSGuenter Roeck break; 101590defe5SGuenter Roeck case PMBUS_VIRT_RESET_POUT_HISTORY: 102590defe5SGuenter Roeck if (data->id != max34446) 103590defe5SGuenter Roeck return -ENXIO; 104590defe5SGuenter Roeck ret = 0; 105590defe5SGuenter Roeck break; 10698591dbeSGuenter Roeck case PMBUS_VIRT_RESET_VOUT_HISTORY: 10798591dbeSGuenter Roeck case PMBUS_VIRT_RESET_IOUT_HISTORY: 10898591dbeSGuenter Roeck case PMBUS_VIRT_RESET_TEMP_HISTORY: 10998591dbeSGuenter Roeck ret = 0; 11098591dbeSGuenter Roeck break; 11198591dbeSGuenter Roeck default: 11298591dbeSGuenter Roeck ret = -ENODATA; 11398591dbeSGuenter Roeck break; 11498591dbeSGuenter Roeck } 11598591dbeSGuenter Roeck return ret; 11698591dbeSGuenter Roeck } 11798591dbeSGuenter Roeck 11898591dbeSGuenter Roeck static int max34440_write_word_data(struct i2c_client *client, int page, 11998591dbeSGuenter Roeck int reg, u16 word) 12098591dbeSGuenter Roeck { 121590defe5SGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 122590defe5SGuenter Roeck const struct max34440_data *data = to_max34440_data(info); 12398591dbeSGuenter Roeck int ret; 12498591dbeSGuenter Roeck 12598591dbeSGuenter Roeck switch (reg) { 126590defe5SGuenter Roeck case PMBUS_VIRT_RESET_POUT_HISTORY: 127590defe5SGuenter Roeck ret = pmbus_write_word_data(client, page, 128590defe5SGuenter Roeck MAX34446_MFR_POUT_PEAK, 0); 129590defe5SGuenter Roeck if (ret) 130590defe5SGuenter Roeck break; 131590defe5SGuenter Roeck ret = pmbus_write_word_data(client, page, 132590defe5SGuenter Roeck MAX34446_MFR_POUT_AVG, 0); 133590defe5SGuenter Roeck break; 13498591dbeSGuenter Roeck case PMBUS_VIRT_RESET_VOUT_HISTORY: 13598591dbeSGuenter Roeck ret = pmbus_write_word_data(client, page, 13656aad5d1SGuenter Roeck MAX34440_MFR_VOUT_MIN, 0x7fff); 13756aad5d1SGuenter Roeck if (ret) 13856aad5d1SGuenter Roeck break; 13956aad5d1SGuenter Roeck ret = pmbus_write_word_data(client, page, 14098591dbeSGuenter Roeck MAX34440_MFR_VOUT_PEAK, 0); 14198591dbeSGuenter Roeck break; 14298591dbeSGuenter Roeck case PMBUS_VIRT_RESET_IOUT_HISTORY: 14398591dbeSGuenter Roeck ret = pmbus_write_word_data(client, page, 14498591dbeSGuenter Roeck MAX34440_MFR_IOUT_PEAK, 0); 145590defe5SGuenter Roeck if (!ret && data->id == max34446) 146590defe5SGuenter Roeck ret = pmbus_write_word_data(client, page, 147590defe5SGuenter Roeck MAX34446_MFR_IOUT_AVG, 0); 148590defe5SGuenter Roeck 14998591dbeSGuenter Roeck break; 15098591dbeSGuenter Roeck case PMBUS_VIRT_RESET_TEMP_HISTORY: 15198591dbeSGuenter Roeck ret = pmbus_write_word_data(client, page, 15298591dbeSGuenter Roeck MAX34440_MFR_TEMPERATURE_PEAK, 153dc91ad8eSGuenter Roeck 0x8000); 154590defe5SGuenter Roeck if (!ret && data->id == max34446) 155590defe5SGuenter Roeck ret = pmbus_write_word_data(client, page, 156590defe5SGuenter Roeck MAX34446_MFR_TEMPERATURE_AVG, 0); 15798591dbeSGuenter Roeck break; 15898591dbeSGuenter Roeck default: 15998591dbeSGuenter Roeck ret = -ENODATA; 16098591dbeSGuenter Roeck break; 16198591dbeSGuenter Roeck } 16298591dbeSGuenter Roeck return ret; 16398591dbeSGuenter Roeck } 16498591dbeSGuenter Roeck 1659d2ecfb7SGuenter Roeck static int max34440_read_byte_data(struct i2c_client *client, int page, int reg) 1669d2ecfb7SGuenter Roeck { 167da8e48abSGuenter Roeck int ret = 0; 1689d2ecfb7SGuenter Roeck int mfg_status; 1699d2ecfb7SGuenter Roeck 170da8e48abSGuenter Roeck if (page >= 0) { 1719d2ecfb7SGuenter Roeck ret = pmbus_set_page(client, page); 1729d2ecfb7SGuenter Roeck if (ret < 0) 1739d2ecfb7SGuenter Roeck return ret; 174da8e48abSGuenter Roeck } 1759d2ecfb7SGuenter Roeck 1769d2ecfb7SGuenter Roeck switch (reg) { 1779d2ecfb7SGuenter Roeck case PMBUS_STATUS_IOUT: 1789d2ecfb7SGuenter Roeck mfg_status = pmbus_read_word_data(client, 0, 1799d2ecfb7SGuenter Roeck PMBUS_STATUS_MFR_SPECIFIC); 1809d2ecfb7SGuenter Roeck if (mfg_status < 0) 1819d2ecfb7SGuenter Roeck return mfg_status; 1829d2ecfb7SGuenter Roeck if (mfg_status & MAX34440_STATUS_OC_WARN) 1839d2ecfb7SGuenter Roeck ret |= PB_IOUT_OC_WARNING; 1849d2ecfb7SGuenter Roeck if (mfg_status & MAX34440_STATUS_OC_FAULT) 1859d2ecfb7SGuenter Roeck ret |= PB_IOUT_OC_FAULT; 1869d2ecfb7SGuenter Roeck break; 1879d2ecfb7SGuenter Roeck case PMBUS_STATUS_TEMPERATURE: 1889d2ecfb7SGuenter Roeck mfg_status = pmbus_read_word_data(client, 0, 1899d2ecfb7SGuenter Roeck PMBUS_STATUS_MFR_SPECIFIC); 1909d2ecfb7SGuenter Roeck if (mfg_status < 0) 1919d2ecfb7SGuenter Roeck return mfg_status; 1929d2ecfb7SGuenter Roeck if (mfg_status & MAX34440_STATUS_OT_WARN) 1939d2ecfb7SGuenter Roeck ret |= PB_TEMP_OT_WARNING; 1949d2ecfb7SGuenter Roeck if (mfg_status & MAX34440_STATUS_OT_FAULT) 1959d2ecfb7SGuenter Roeck ret |= PB_TEMP_OT_FAULT; 1969d2ecfb7SGuenter Roeck break; 1979d2ecfb7SGuenter Roeck default: 1989d2ecfb7SGuenter Roeck ret = -ENODATA; 1999d2ecfb7SGuenter Roeck break; 2009d2ecfb7SGuenter Roeck } 2019d2ecfb7SGuenter Roeck return ret; 2029d2ecfb7SGuenter Roeck } 2039d2ecfb7SGuenter Roeck 2049d2ecfb7SGuenter Roeck static struct pmbus_driver_info max34440_info[] = { 2059d2ecfb7SGuenter Roeck [max34440] = { 2069d2ecfb7SGuenter Roeck .pages = 14, 2071061d851SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 2081061d851SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 2091061d851SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 2101061d851SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 2119d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_IN] = 1, 2129d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 2139d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_IN] = 3, /* R = 0 in datasheet reflects mV */ 2149d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 2159d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 2169d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, /* R = 0 in datasheet reflects mV */ 2179d2ecfb7SGuenter Roeck .m[PSC_CURRENT_OUT] = 1, 2189d2ecfb7SGuenter Roeck .b[PSC_CURRENT_OUT] = 0, 2199d2ecfb7SGuenter Roeck .R[PSC_CURRENT_OUT] = 3, /* R = 0 in datasheet reflects mA */ 2209d2ecfb7SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 2219d2ecfb7SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 2229d2ecfb7SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 2239d2ecfb7SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2249d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2259d2ecfb7SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2269d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2279d2ecfb7SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2289d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2299d2ecfb7SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2309d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2319d2ecfb7SGuenter Roeck .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2329d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2339d2ecfb7SGuenter Roeck .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2349d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2359d2ecfb7SGuenter Roeck .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2369d2ecfb7SGuenter Roeck .func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2379d2ecfb7SGuenter Roeck .func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2389d2ecfb7SGuenter Roeck .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2399d2ecfb7SGuenter Roeck .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2409d2ecfb7SGuenter Roeck .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2419d2ecfb7SGuenter Roeck .func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2429d2ecfb7SGuenter Roeck .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2439d2ecfb7SGuenter Roeck .read_byte_data = max34440_read_byte_data, 24498591dbeSGuenter Roeck .read_word_data = max34440_read_word_data, 24598591dbeSGuenter Roeck .write_word_data = max34440_write_word_data, 2469d2ecfb7SGuenter Roeck }, 2479d2ecfb7SGuenter Roeck [max34441] = { 2489d2ecfb7SGuenter Roeck .pages = 12, 2491061d851SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 2501061d851SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 2511061d851SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 2521061d851SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 2531061d851SGuenter Roeck .format[PSC_FAN] = direct, 2549d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_IN] = 1, 2559d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 2569d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_IN] = 3, 2579d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 2589d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 2599d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, 2609d2ecfb7SGuenter Roeck .m[PSC_CURRENT_OUT] = 1, 2619d2ecfb7SGuenter Roeck .b[PSC_CURRENT_OUT] = 0, 2629d2ecfb7SGuenter Roeck .R[PSC_CURRENT_OUT] = 3, 2639d2ecfb7SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 2649d2ecfb7SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 2659d2ecfb7SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 2669d2ecfb7SGuenter Roeck .m[PSC_FAN] = 1, 2679d2ecfb7SGuenter Roeck .b[PSC_FAN] = 0, 2689d2ecfb7SGuenter Roeck .R[PSC_FAN] = 0, 2699d2ecfb7SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2709d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2719d2ecfb7SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2729d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2739d2ecfb7SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2749d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2759d2ecfb7SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2769d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2779d2ecfb7SGuenter Roeck .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2789d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2799d2ecfb7SGuenter Roeck .func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12, 2809d2ecfb7SGuenter Roeck .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2819d2ecfb7SGuenter Roeck .func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2829d2ecfb7SGuenter Roeck .func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2839d2ecfb7SGuenter Roeck .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2849d2ecfb7SGuenter Roeck .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2859d2ecfb7SGuenter Roeck .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 2869d2ecfb7SGuenter Roeck .read_byte_data = max34440_read_byte_data, 28798591dbeSGuenter Roeck .read_word_data = max34440_read_word_data, 28898591dbeSGuenter Roeck .write_word_data = max34440_write_word_data, 2899d2ecfb7SGuenter Roeck }, 290590defe5SGuenter Roeck [max34446] = { 291590defe5SGuenter Roeck .pages = 7, 292590defe5SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 293590defe5SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 294590defe5SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 295590defe5SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 296590defe5SGuenter Roeck .format[PSC_POWER] = direct, 297590defe5SGuenter Roeck .m[PSC_VOLTAGE_IN] = 1, 298590defe5SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 299590defe5SGuenter Roeck .R[PSC_VOLTAGE_IN] = 3, 300590defe5SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 301590defe5SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 302590defe5SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, 303590defe5SGuenter Roeck .m[PSC_CURRENT_OUT] = 1, 304590defe5SGuenter Roeck .b[PSC_CURRENT_OUT] = 0, 305590defe5SGuenter Roeck .R[PSC_CURRENT_OUT] = 3, 306590defe5SGuenter Roeck .m[PSC_POWER] = 1, 307590defe5SGuenter Roeck .b[PSC_POWER] = 0, 308590defe5SGuenter Roeck .R[PSC_POWER] = 3, 309590defe5SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 310590defe5SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 311590defe5SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 312590defe5SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 313590defe5SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 314590defe5SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 315590defe5SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 316590defe5SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 317590defe5SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 318590defe5SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 319590defe5SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 320590defe5SGuenter Roeck .func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 321590defe5SGuenter Roeck .func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 322590defe5SGuenter Roeck .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 323590defe5SGuenter Roeck .read_byte_data = max34440_read_byte_data, 324590defe5SGuenter Roeck .read_word_data = max34440_read_word_data, 325590defe5SGuenter Roeck .write_word_data = max34440_write_word_data, 326590defe5SGuenter Roeck }, 327*50115ac9SGuenter Roeck [max34460] = { 328*50115ac9SGuenter Roeck .pages = 18, 329*50115ac9SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 330*50115ac9SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 331*50115ac9SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 332*50115ac9SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 333*50115ac9SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, 334*50115ac9SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 335*50115ac9SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 336*50115ac9SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 337*50115ac9SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 338*50115ac9SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 339*50115ac9SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 340*50115ac9SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 341*50115ac9SGuenter Roeck .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 342*50115ac9SGuenter Roeck .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 343*50115ac9SGuenter Roeck .func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 344*50115ac9SGuenter Roeck .func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 345*50115ac9SGuenter Roeck .func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 346*50115ac9SGuenter Roeck .func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 347*50115ac9SGuenter Roeck .func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 348*50115ac9SGuenter Roeck .func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 349*50115ac9SGuenter Roeck .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 350*50115ac9SGuenter Roeck .func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 351*50115ac9SGuenter Roeck .func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 352*50115ac9SGuenter Roeck .func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 353*50115ac9SGuenter Roeck .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 354*50115ac9SGuenter Roeck .read_byte_data = max34440_read_byte_data, 355*50115ac9SGuenter Roeck .read_word_data = max34440_read_word_data, 356*50115ac9SGuenter Roeck .write_word_data = max34440_write_word_data, 357*50115ac9SGuenter Roeck }, 358*50115ac9SGuenter Roeck [max34461] = { 359*50115ac9SGuenter Roeck .pages = 23, 360*50115ac9SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 361*50115ac9SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 362*50115ac9SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 363*50115ac9SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 364*50115ac9SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, 365*50115ac9SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 366*50115ac9SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 367*50115ac9SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 368*50115ac9SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 369*50115ac9SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 370*50115ac9SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 371*50115ac9SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 372*50115ac9SGuenter Roeck .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 373*50115ac9SGuenter Roeck .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 374*50115ac9SGuenter Roeck .func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 375*50115ac9SGuenter Roeck .func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 376*50115ac9SGuenter Roeck .func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 377*50115ac9SGuenter Roeck .func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 378*50115ac9SGuenter Roeck .func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 379*50115ac9SGuenter Roeck .func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 380*50115ac9SGuenter Roeck .func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 381*50115ac9SGuenter Roeck .func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 382*50115ac9SGuenter Roeck .func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 383*50115ac9SGuenter Roeck .func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 384*50115ac9SGuenter Roeck /* page 16 is reserved */ 385*50115ac9SGuenter Roeck .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 386*50115ac9SGuenter Roeck .func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 387*50115ac9SGuenter Roeck .func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 388*50115ac9SGuenter Roeck .func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 389*50115ac9SGuenter Roeck .func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 390*50115ac9SGuenter Roeck .read_byte_data = max34440_read_byte_data, 391*50115ac9SGuenter Roeck .read_word_data = max34440_read_word_data, 392*50115ac9SGuenter Roeck .write_word_data = max34440_write_word_data, 393*50115ac9SGuenter Roeck }, 3949d2ecfb7SGuenter Roeck }; 3959d2ecfb7SGuenter Roeck 3969d2ecfb7SGuenter Roeck static int max34440_probe(struct i2c_client *client, 3979d2ecfb7SGuenter Roeck const struct i2c_device_id *id) 3989d2ecfb7SGuenter Roeck { 399590defe5SGuenter Roeck struct max34440_data *data; 400590defe5SGuenter Roeck 401590defe5SGuenter Roeck data = devm_kzalloc(&client->dev, sizeof(struct max34440_data), 402590defe5SGuenter Roeck GFP_KERNEL); 403590defe5SGuenter Roeck if (!data) 404590defe5SGuenter Roeck return -ENOMEM; 405590defe5SGuenter Roeck data->id = id->driver_data; 406590defe5SGuenter Roeck data->info = max34440_info[id->driver_data]; 407590defe5SGuenter Roeck 408590defe5SGuenter Roeck return pmbus_do_probe(client, id, &data->info); 4099d2ecfb7SGuenter Roeck } 4109d2ecfb7SGuenter Roeck 4119d2ecfb7SGuenter Roeck static const struct i2c_device_id max34440_id[] = { 4129d2ecfb7SGuenter Roeck {"max34440", max34440}, 4139d2ecfb7SGuenter Roeck {"max34441", max34441}, 414590defe5SGuenter Roeck {"max34446", max34446}, 415*50115ac9SGuenter Roeck {"max34460", max34460}, 416*50115ac9SGuenter Roeck {"max34461", max34461}, 4179d2ecfb7SGuenter Roeck {} 4189d2ecfb7SGuenter Roeck }; 4199d2ecfb7SGuenter Roeck MODULE_DEVICE_TABLE(i2c, max34440_id); 4209d2ecfb7SGuenter Roeck 4219d2ecfb7SGuenter Roeck /* This is the driver that will be inserted */ 4229d2ecfb7SGuenter Roeck static struct i2c_driver max34440_driver = { 4239d2ecfb7SGuenter Roeck .driver = { 4249d2ecfb7SGuenter Roeck .name = "max34440", 4259d2ecfb7SGuenter Roeck }, 4269d2ecfb7SGuenter Roeck .probe = max34440_probe, 427dd285ad7SGuenter Roeck .remove = pmbus_do_remove, 4289d2ecfb7SGuenter Roeck .id_table = max34440_id, 4299d2ecfb7SGuenter Roeck }; 4309d2ecfb7SGuenter Roeck 431f0967eeaSAxel Lin module_i2c_driver(max34440_driver); 4329d2ecfb7SGuenter Roeck 4339d2ecfb7SGuenter Roeck MODULE_AUTHOR("Guenter Roeck"); 4349d2ecfb7SGuenter Roeck MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441"); 4359d2ecfb7SGuenter Roeck MODULE_LICENSE("GPL"); 436