174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 29d2ecfb7SGuenter Roeck /* 39d2ecfb7SGuenter Roeck * Hardware monitoring driver for Maxim MAX34440/MAX34441 49d2ecfb7SGuenter Roeck * 59d2ecfb7SGuenter Roeck * Copyright (c) 2011 Ericsson AB. 650115ac9SGuenter Roeck * Copyright (c) 2012 Guenter Roeck 79d2ecfb7SGuenter Roeck */ 89d2ecfb7SGuenter Roeck 92c052d42SGuenter Roeck #include <linux/bitops.h> 109d2ecfb7SGuenter Roeck #include <linux/kernel.h> 119d2ecfb7SGuenter Roeck #include <linux/module.h> 129d2ecfb7SGuenter Roeck #include <linux/init.h> 139d2ecfb7SGuenter Roeck #include <linux/err.h> 149d2ecfb7SGuenter Roeck #include <linux/i2c.h> 159d2ecfb7SGuenter Roeck #include "pmbus.h" 169d2ecfb7SGuenter Roeck 177a001dbaSKun Yi enum chips { max34440, max34441, max34446, max34451, max34460, max34461 }; 189d2ecfb7SGuenter Roeck 1998591dbeSGuenter Roeck #define MAX34440_MFR_VOUT_PEAK 0xd4 2098591dbeSGuenter Roeck #define MAX34440_MFR_IOUT_PEAK 0xd5 2198591dbeSGuenter Roeck #define MAX34440_MFR_TEMPERATURE_PEAK 0xd6 2256aad5d1SGuenter Roeck #define MAX34440_MFR_VOUT_MIN 0xd7 2398591dbeSGuenter Roeck 24590defe5SGuenter Roeck #define MAX34446_MFR_POUT_PEAK 0xe0 25590defe5SGuenter Roeck #define MAX34446_MFR_POUT_AVG 0xe1 26590defe5SGuenter Roeck #define MAX34446_MFR_IOUT_AVG 0xe2 27590defe5SGuenter Roeck #define MAX34446_MFR_TEMPERATURE_AVG 0xe3 28590defe5SGuenter Roeck 292c052d42SGuenter Roeck #define MAX34440_STATUS_OC_WARN BIT(0) 302c052d42SGuenter Roeck #define MAX34440_STATUS_OC_FAULT BIT(1) 312c052d42SGuenter Roeck #define MAX34440_STATUS_OT_FAULT BIT(5) 322c052d42SGuenter Roeck #define MAX34440_STATUS_OT_WARN BIT(6) 339d2ecfb7SGuenter Roeck 342b522781SSteve Foreman /* 352b522781SSteve Foreman * The whole max344* family have IOUT_OC_WARN_LIMIT and IOUT_OC_FAULT_LIMIT 362b522781SSteve Foreman * swapped from the standard pmbus spec addresses. 372b522781SSteve Foreman */ 382b522781SSteve Foreman #define MAX34440_IOUT_OC_WARN_LIMIT 0x46 392b522781SSteve Foreman #define MAX34440_IOUT_OC_FAULT_LIMIT 0x4A 402b522781SSteve Foreman 417a001dbaSKun Yi #define MAX34451_MFR_CHANNEL_CONFIG 0xe4 427a001dbaSKun Yi #define MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK 0x3f 437a001dbaSKun Yi 44590defe5SGuenter Roeck struct max34440_data { 45590defe5SGuenter Roeck int id; 46590defe5SGuenter Roeck struct pmbus_driver_info info; 47590defe5SGuenter Roeck }; 48590defe5SGuenter Roeck 49590defe5SGuenter Roeck #define to_max34440_data(x) container_of(x, struct max34440_data, info) 50590defe5SGuenter Roeck 51dd431939SStephen Kitt static const struct i2c_device_id max34440_id[]; 52dd431939SStephen Kitt 5343f33b6eSGuenter Roeck static int max34440_read_word_data(struct i2c_client *client, int page, 5443f33b6eSGuenter Roeck int phase, int reg) 5598591dbeSGuenter Roeck { 5698591dbeSGuenter Roeck int ret; 57590defe5SGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 58590defe5SGuenter Roeck const struct max34440_data *data = to_max34440_data(info); 5998591dbeSGuenter Roeck 6098591dbeSGuenter Roeck switch (reg) { 612b522781SSteve Foreman case PMBUS_IOUT_OC_FAULT_LIMIT: 622b522781SSteve Foreman ret = pmbus_read_word_data(client, page, phase, 632b522781SSteve Foreman MAX34440_IOUT_OC_FAULT_LIMIT); 642b522781SSteve Foreman break; 652b522781SSteve Foreman case PMBUS_IOUT_OC_WARN_LIMIT: 662b522781SSteve Foreman ret = pmbus_read_word_data(client, page, phase, 672b522781SSteve Foreman MAX34440_IOUT_OC_WARN_LIMIT); 682b522781SSteve Foreman break; 6956aad5d1SGuenter Roeck case PMBUS_VIRT_READ_VOUT_MIN: 7043f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 7156aad5d1SGuenter Roeck MAX34440_MFR_VOUT_MIN); 7256aad5d1SGuenter Roeck break; 7398591dbeSGuenter Roeck case PMBUS_VIRT_READ_VOUT_MAX: 7443f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 7598591dbeSGuenter Roeck MAX34440_MFR_VOUT_PEAK); 7698591dbeSGuenter Roeck break; 77590defe5SGuenter Roeck case PMBUS_VIRT_READ_IOUT_AVG: 787a001dbaSKun Yi if (data->id != max34446 && data->id != max34451) 79590defe5SGuenter Roeck return -ENXIO; 8043f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 81590defe5SGuenter Roeck MAX34446_MFR_IOUT_AVG); 82590defe5SGuenter Roeck break; 8398591dbeSGuenter Roeck case PMBUS_VIRT_READ_IOUT_MAX: 8443f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 8598591dbeSGuenter Roeck MAX34440_MFR_IOUT_PEAK); 8698591dbeSGuenter Roeck break; 87590defe5SGuenter Roeck case PMBUS_VIRT_READ_POUT_AVG: 88590defe5SGuenter Roeck if (data->id != max34446) 89590defe5SGuenter Roeck return -ENXIO; 9043f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 91590defe5SGuenter Roeck MAX34446_MFR_POUT_AVG); 92590defe5SGuenter Roeck break; 93590defe5SGuenter Roeck case PMBUS_VIRT_READ_POUT_MAX: 94590defe5SGuenter Roeck if (data->id != max34446) 95590defe5SGuenter Roeck return -ENXIO; 9643f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 97590defe5SGuenter Roeck MAX34446_MFR_POUT_PEAK); 98590defe5SGuenter Roeck break; 99590defe5SGuenter Roeck case PMBUS_VIRT_READ_TEMP_AVG: 10050115ac9SGuenter Roeck if (data->id != max34446 && data->id != max34460 && 10150115ac9SGuenter Roeck data->id != max34461) 102590defe5SGuenter Roeck return -ENXIO; 10343f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 104590defe5SGuenter Roeck MAX34446_MFR_TEMPERATURE_AVG); 105590defe5SGuenter Roeck break; 10698591dbeSGuenter Roeck case PMBUS_VIRT_READ_TEMP_MAX: 10743f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 10898591dbeSGuenter Roeck MAX34440_MFR_TEMPERATURE_PEAK); 10998591dbeSGuenter Roeck break; 110590defe5SGuenter Roeck case PMBUS_VIRT_RESET_POUT_HISTORY: 111590defe5SGuenter Roeck if (data->id != max34446) 112590defe5SGuenter Roeck return -ENXIO; 113590defe5SGuenter Roeck ret = 0; 114590defe5SGuenter Roeck break; 11598591dbeSGuenter Roeck case PMBUS_VIRT_RESET_VOUT_HISTORY: 11698591dbeSGuenter Roeck case PMBUS_VIRT_RESET_IOUT_HISTORY: 11798591dbeSGuenter Roeck case PMBUS_VIRT_RESET_TEMP_HISTORY: 11898591dbeSGuenter Roeck ret = 0; 11998591dbeSGuenter Roeck break; 12098591dbeSGuenter Roeck default: 12198591dbeSGuenter Roeck ret = -ENODATA; 12298591dbeSGuenter Roeck break; 12398591dbeSGuenter Roeck } 12498591dbeSGuenter Roeck return ret; 12598591dbeSGuenter Roeck } 12698591dbeSGuenter Roeck 12798591dbeSGuenter Roeck static int max34440_write_word_data(struct i2c_client *client, int page, 12898591dbeSGuenter Roeck int reg, u16 word) 12998591dbeSGuenter Roeck { 130590defe5SGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 131590defe5SGuenter Roeck const struct max34440_data *data = to_max34440_data(info); 13298591dbeSGuenter Roeck int ret; 13398591dbeSGuenter Roeck 13498591dbeSGuenter Roeck switch (reg) { 1352b522781SSteve Foreman case PMBUS_IOUT_OC_FAULT_LIMIT: 1362b522781SSteve Foreman ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_FAULT_LIMIT, 1372b522781SSteve Foreman word); 1382b522781SSteve Foreman break; 1392b522781SSteve Foreman case PMBUS_IOUT_OC_WARN_LIMIT: 1402b522781SSteve Foreman ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_WARN_LIMIT, 1412b522781SSteve Foreman word); 1422b522781SSteve Foreman break; 143590defe5SGuenter Roeck case PMBUS_VIRT_RESET_POUT_HISTORY: 144590defe5SGuenter Roeck ret = pmbus_write_word_data(client, page, 145590defe5SGuenter Roeck MAX34446_MFR_POUT_PEAK, 0); 146590defe5SGuenter Roeck if (ret) 147590defe5SGuenter Roeck break; 148590defe5SGuenter Roeck ret = pmbus_write_word_data(client, page, 149590defe5SGuenter Roeck MAX34446_MFR_POUT_AVG, 0); 150590defe5SGuenter Roeck break; 15198591dbeSGuenter Roeck case PMBUS_VIRT_RESET_VOUT_HISTORY: 15298591dbeSGuenter Roeck ret = pmbus_write_word_data(client, page, 15356aad5d1SGuenter Roeck MAX34440_MFR_VOUT_MIN, 0x7fff); 15456aad5d1SGuenter Roeck if (ret) 15556aad5d1SGuenter Roeck break; 15656aad5d1SGuenter Roeck ret = pmbus_write_word_data(client, page, 15798591dbeSGuenter Roeck MAX34440_MFR_VOUT_PEAK, 0); 15898591dbeSGuenter Roeck break; 15998591dbeSGuenter Roeck case PMBUS_VIRT_RESET_IOUT_HISTORY: 16098591dbeSGuenter Roeck ret = pmbus_write_word_data(client, page, 16198591dbeSGuenter Roeck MAX34440_MFR_IOUT_PEAK, 0); 1627a001dbaSKun Yi if (!ret && (data->id == max34446 || data->id == max34451)) 163590defe5SGuenter Roeck ret = pmbus_write_word_data(client, page, 164590defe5SGuenter Roeck MAX34446_MFR_IOUT_AVG, 0); 165590defe5SGuenter Roeck 16698591dbeSGuenter Roeck break; 16798591dbeSGuenter Roeck case PMBUS_VIRT_RESET_TEMP_HISTORY: 16898591dbeSGuenter Roeck ret = pmbus_write_word_data(client, page, 16998591dbeSGuenter Roeck MAX34440_MFR_TEMPERATURE_PEAK, 170dc91ad8eSGuenter Roeck 0x8000); 171590defe5SGuenter Roeck if (!ret && data->id == max34446) 172590defe5SGuenter Roeck ret = pmbus_write_word_data(client, page, 173590defe5SGuenter Roeck MAX34446_MFR_TEMPERATURE_AVG, 0); 17498591dbeSGuenter Roeck break; 17598591dbeSGuenter Roeck default: 17698591dbeSGuenter Roeck ret = -ENODATA; 17798591dbeSGuenter Roeck break; 17898591dbeSGuenter Roeck } 17998591dbeSGuenter Roeck return ret; 18098591dbeSGuenter Roeck } 18198591dbeSGuenter Roeck 1829d2ecfb7SGuenter Roeck static int max34440_read_byte_data(struct i2c_client *client, int page, int reg) 1839d2ecfb7SGuenter Roeck { 184da8e48abSGuenter Roeck int ret = 0; 1859d2ecfb7SGuenter Roeck int mfg_status; 1869d2ecfb7SGuenter Roeck 187da8e48abSGuenter Roeck if (page >= 0) { 18843f33b6eSGuenter Roeck ret = pmbus_set_page(client, page, 0xff); 1899d2ecfb7SGuenter Roeck if (ret < 0) 1909d2ecfb7SGuenter Roeck return ret; 191da8e48abSGuenter Roeck } 1929d2ecfb7SGuenter Roeck 1939d2ecfb7SGuenter Roeck switch (reg) { 1949d2ecfb7SGuenter Roeck case PMBUS_STATUS_IOUT: 19543f33b6eSGuenter Roeck mfg_status = pmbus_read_word_data(client, 0, 0xff, 1969d2ecfb7SGuenter Roeck PMBUS_STATUS_MFR_SPECIFIC); 1979d2ecfb7SGuenter Roeck if (mfg_status < 0) 1989d2ecfb7SGuenter Roeck return mfg_status; 1999d2ecfb7SGuenter Roeck if (mfg_status & MAX34440_STATUS_OC_WARN) 2009d2ecfb7SGuenter Roeck ret |= PB_IOUT_OC_WARNING; 2019d2ecfb7SGuenter Roeck if (mfg_status & MAX34440_STATUS_OC_FAULT) 2029d2ecfb7SGuenter Roeck ret |= PB_IOUT_OC_FAULT; 2039d2ecfb7SGuenter Roeck break; 2049d2ecfb7SGuenter Roeck case PMBUS_STATUS_TEMPERATURE: 20543f33b6eSGuenter Roeck mfg_status = pmbus_read_word_data(client, 0, 0xff, 2069d2ecfb7SGuenter Roeck PMBUS_STATUS_MFR_SPECIFIC); 2079d2ecfb7SGuenter Roeck if (mfg_status < 0) 2089d2ecfb7SGuenter Roeck return mfg_status; 2099d2ecfb7SGuenter Roeck if (mfg_status & MAX34440_STATUS_OT_WARN) 2109d2ecfb7SGuenter Roeck ret |= PB_TEMP_OT_WARNING; 2119d2ecfb7SGuenter Roeck if (mfg_status & MAX34440_STATUS_OT_FAULT) 2129d2ecfb7SGuenter Roeck ret |= PB_TEMP_OT_FAULT; 2139d2ecfb7SGuenter Roeck break; 2149d2ecfb7SGuenter Roeck default: 2159d2ecfb7SGuenter Roeck ret = -ENODATA; 2169d2ecfb7SGuenter Roeck break; 2179d2ecfb7SGuenter Roeck } 2189d2ecfb7SGuenter Roeck return ret; 2199d2ecfb7SGuenter Roeck } 2209d2ecfb7SGuenter Roeck 2217a001dbaSKun Yi static int max34451_set_supported_funcs(struct i2c_client *client, 2227a001dbaSKun Yi struct max34440_data *data) 2237a001dbaSKun Yi { 2247a001dbaSKun Yi /* 2257a001dbaSKun Yi * Each of the channel 0-15 can be configured to monitor the following 2267a001dbaSKun Yi * functions based on MFR_CHANNEL_CONFIG[5:0] 2277a001dbaSKun Yi * 0x10: Sequencing + voltage monitoring (only valid for PAGES 0–11) 2287a001dbaSKun Yi * 0x20: Voltage monitoring (no sequencing) 2297a001dbaSKun Yi * 0x21: Voltage read only 2307a001dbaSKun Yi * 0x22: Current monitoring 2317a001dbaSKun Yi * 0x23: Current read only 2327a001dbaSKun Yi * 0x30: General-purpose input active low 2337a001dbaSKun Yi * 0x34: General-purpose input active high 2347a001dbaSKun Yi * 0x00: Disabled 2357a001dbaSKun Yi */ 2367a001dbaSKun Yi 2377a001dbaSKun Yi int page, rv; 2387a001dbaSKun Yi 2397a001dbaSKun Yi for (page = 0; page < 16; page++) { 2407a001dbaSKun Yi rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); 2417a001dbaSKun Yi if (rv < 0) 2427a001dbaSKun Yi return rv; 2437a001dbaSKun Yi 2447a001dbaSKun Yi rv = i2c_smbus_read_word_data(client, 2457a001dbaSKun Yi MAX34451_MFR_CHANNEL_CONFIG); 2467a001dbaSKun Yi if (rv < 0) 2477a001dbaSKun Yi return rv; 2487a001dbaSKun Yi 2497a001dbaSKun Yi switch (rv & MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK) { 2507a001dbaSKun Yi case 0x10: 2517a001dbaSKun Yi case 0x20: 2527a001dbaSKun Yi data->info.func[page] = PMBUS_HAVE_VOUT | 2537a001dbaSKun Yi PMBUS_HAVE_STATUS_VOUT; 2547a001dbaSKun Yi break; 2557a001dbaSKun Yi case 0x21: 2567a001dbaSKun Yi data->info.func[page] = PMBUS_HAVE_VOUT; 2577a001dbaSKun Yi break; 2587a001dbaSKun Yi case 0x22: 2597a001dbaSKun Yi data->info.func[page] = PMBUS_HAVE_IOUT | 2607a001dbaSKun Yi PMBUS_HAVE_STATUS_IOUT; 2617a001dbaSKun Yi break; 2627a001dbaSKun Yi case 0x23: 2637a001dbaSKun Yi data->info.func[page] = PMBUS_HAVE_IOUT; 2647a001dbaSKun Yi break; 2657a001dbaSKun Yi default: 2667a001dbaSKun Yi break; 2677a001dbaSKun Yi } 2687a001dbaSKun Yi } 2697a001dbaSKun Yi 2707a001dbaSKun Yi return 0; 2717a001dbaSKun Yi } 2727a001dbaSKun Yi 2739d2ecfb7SGuenter Roeck static struct pmbus_driver_info max34440_info[] = { 2749d2ecfb7SGuenter Roeck [max34440] = { 2759d2ecfb7SGuenter Roeck .pages = 14, 2761061d851SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 2771061d851SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 2781061d851SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 2791061d851SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 2809d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_IN] = 1, 2819d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 2829d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_IN] = 3, /* R = 0 in datasheet reflects mV */ 2839d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 2849d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 2859d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, /* R = 0 in datasheet reflects mV */ 2869d2ecfb7SGuenter Roeck .m[PSC_CURRENT_OUT] = 1, 2879d2ecfb7SGuenter Roeck .b[PSC_CURRENT_OUT] = 0, 2889d2ecfb7SGuenter Roeck .R[PSC_CURRENT_OUT] = 3, /* R = 0 in datasheet reflects mA */ 2899d2ecfb7SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 2909d2ecfb7SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 2919d2ecfb7SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 2929d2ecfb7SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2939d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2949d2ecfb7SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2959d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2969d2ecfb7SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2979d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 2989d2ecfb7SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 2999d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 3009d2ecfb7SGuenter Roeck .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 3019d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 3029d2ecfb7SGuenter Roeck .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 3039d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 3049d2ecfb7SGuenter Roeck .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3059d2ecfb7SGuenter Roeck .func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3069d2ecfb7SGuenter Roeck .func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3079d2ecfb7SGuenter Roeck .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3089d2ecfb7SGuenter Roeck .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3099d2ecfb7SGuenter Roeck .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3109d2ecfb7SGuenter Roeck .func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3119d2ecfb7SGuenter Roeck .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3129d2ecfb7SGuenter Roeck .read_byte_data = max34440_read_byte_data, 31398591dbeSGuenter Roeck .read_word_data = max34440_read_word_data, 31498591dbeSGuenter Roeck .write_word_data = max34440_write_word_data, 3159d2ecfb7SGuenter Roeck }, 3169d2ecfb7SGuenter Roeck [max34441] = { 3179d2ecfb7SGuenter Roeck .pages = 12, 3181061d851SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 3191061d851SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 3201061d851SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 3211061d851SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 3221061d851SGuenter Roeck .format[PSC_FAN] = direct, 3239d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_IN] = 1, 3249d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 3259d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_IN] = 3, 3269d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 3279d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 3289d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, 3299d2ecfb7SGuenter Roeck .m[PSC_CURRENT_OUT] = 1, 3309d2ecfb7SGuenter Roeck .b[PSC_CURRENT_OUT] = 0, 3319d2ecfb7SGuenter Roeck .R[PSC_CURRENT_OUT] = 3, 3329d2ecfb7SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 3339d2ecfb7SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 3349d2ecfb7SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 3359d2ecfb7SGuenter Roeck .m[PSC_FAN] = 1, 3369d2ecfb7SGuenter Roeck .b[PSC_FAN] = 0, 3379d2ecfb7SGuenter Roeck .R[PSC_FAN] = 0, 3389d2ecfb7SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 3399d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 3409d2ecfb7SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 3419d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 3429d2ecfb7SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 3439d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 3449d2ecfb7SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 3459d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 3469d2ecfb7SGuenter Roeck .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 3479d2ecfb7SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 3489d2ecfb7SGuenter Roeck .func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12, 3499d2ecfb7SGuenter Roeck .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3509d2ecfb7SGuenter Roeck .func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3519d2ecfb7SGuenter Roeck .func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3529d2ecfb7SGuenter Roeck .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3539d2ecfb7SGuenter Roeck .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3549d2ecfb7SGuenter Roeck .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 3559d2ecfb7SGuenter Roeck .read_byte_data = max34440_read_byte_data, 35698591dbeSGuenter Roeck .read_word_data = max34440_read_word_data, 35798591dbeSGuenter Roeck .write_word_data = max34440_write_word_data, 3589d2ecfb7SGuenter Roeck }, 359590defe5SGuenter Roeck [max34446] = { 360590defe5SGuenter Roeck .pages = 7, 361590defe5SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 362590defe5SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 363590defe5SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 364590defe5SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 365590defe5SGuenter Roeck .format[PSC_POWER] = direct, 366590defe5SGuenter Roeck .m[PSC_VOLTAGE_IN] = 1, 367590defe5SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 368590defe5SGuenter Roeck .R[PSC_VOLTAGE_IN] = 3, 369590defe5SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 370590defe5SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 371590defe5SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, 372590defe5SGuenter Roeck .m[PSC_CURRENT_OUT] = 1, 373590defe5SGuenter Roeck .b[PSC_CURRENT_OUT] = 0, 374590defe5SGuenter Roeck .R[PSC_CURRENT_OUT] = 3, 375590defe5SGuenter Roeck .m[PSC_POWER] = 1, 376590defe5SGuenter Roeck .b[PSC_POWER] = 0, 377590defe5SGuenter Roeck .R[PSC_POWER] = 3, 378590defe5SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 379590defe5SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 380590defe5SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 381590defe5SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 382590defe5SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 383590defe5SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 384590defe5SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 385590defe5SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 386590defe5SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 387590defe5SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 388590defe5SGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, 389590defe5SGuenter Roeck .func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 390590defe5SGuenter Roeck .func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 391590defe5SGuenter Roeck .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 392590defe5SGuenter Roeck .read_byte_data = max34440_read_byte_data, 393590defe5SGuenter Roeck .read_word_data = max34440_read_word_data, 394590defe5SGuenter Roeck .write_word_data = max34440_write_word_data, 395590defe5SGuenter Roeck }, 3967a001dbaSKun Yi [max34451] = { 3977a001dbaSKun Yi .pages = 21, 3987a001dbaSKun Yi .format[PSC_VOLTAGE_OUT] = direct, 3997a001dbaSKun Yi .format[PSC_TEMPERATURE] = direct, 4007a001dbaSKun Yi .format[PSC_CURRENT_OUT] = direct, 4017a001dbaSKun Yi .m[PSC_VOLTAGE_OUT] = 1, 4027a001dbaSKun Yi .b[PSC_VOLTAGE_OUT] = 0, 4037a001dbaSKun Yi .R[PSC_VOLTAGE_OUT] = 3, 4047a001dbaSKun Yi .m[PSC_CURRENT_OUT] = 1, 4057a001dbaSKun Yi .b[PSC_CURRENT_OUT] = 0, 4067a001dbaSKun Yi .R[PSC_CURRENT_OUT] = 2, 4077a001dbaSKun Yi .m[PSC_TEMPERATURE] = 1, 4087a001dbaSKun Yi .b[PSC_TEMPERATURE] = 0, 4097a001dbaSKun Yi .R[PSC_TEMPERATURE] = 2, 4107a001dbaSKun Yi /* func 0-15 is set dynamically before probing */ 4117a001dbaSKun Yi .func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 4127a001dbaSKun Yi .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 4137a001dbaSKun Yi .func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 4147a001dbaSKun Yi .func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 4157a001dbaSKun Yi .func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 4167a001dbaSKun Yi .read_word_data = max34440_read_word_data, 4177a001dbaSKun Yi .write_word_data = max34440_write_word_data, 4187a001dbaSKun Yi }, 41950115ac9SGuenter Roeck [max34460] = { 42050115ac9SGuenter Roeck .pages = 18, 42150115ac9SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 42250115ac9SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 42350115ac9SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 42450115ac9SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 42550115ac9SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, 42650115ac9SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 42750115ac9SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 42850115ac9SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 42950115ac9SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43050115ac9SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43150115ac9SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43250115ac9SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43350115ac9SGuenter Roeck .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43450115ac9SGuenter Roeck .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43550115ac9SGuenter Roeck .func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43650115ac9SGuenter Roeck .func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43750115ac9SGuenter Roeck .func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43850115ac9SGuenter Roeck .func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 43950115ac9SGuenter Roeck .func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 44050115ac9SGuenter Roeck .func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 44150115ac9SGuenter Roeck .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 44250115ac9SGuenter Roeck .func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 44350115ac9SGuenter Roeck .func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 44450115ac9SGuenter Roeck .func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 44550115ac9SGuenter Roeck .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 44650115ac9SGuenter Roeck .read_word_data = max34440_read_word_data, 44750115ac9SGuenter Roeck .write_word_data = max34440_write_word_data, 44850115ac9SGuenter Roeck }, 44950115ac9SGuenter Roeck [max34461] = { 45050115ac9SGuenter Roeck .pages = 23, 45150115ac9SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 45250115ac9SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 45350115ac9SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 1, 45450115ac9SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 45550115ac9SGuenter Roeck .R[PSC_VOLTAGE_OUT] = 3, 45650115ac9SGuenter Roeck .m[PSC_TEMPERATURE] = 1, 45750115ac9SGuenter Roeck .b[PSC_TEMPERATURE] = 0, 45850115ac9SGuenter Roeck .R[PSC_TEMPERATURE] = 2, 45950115ac9SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46050115ac9SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46150115ac9SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46250115ac9SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46350115ac9SGuenter Roeck .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46450115ac9SGuenter Roeck .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46550115ac9SGuenter Roeck .func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46650115ac9SGuenter Roeck .func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46750115ac9SGuenter Roeck .func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46850115ac9SGuenter Roeck .func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 46950115ac9SGuenter Roeck .func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 47050115ac9SGuenter Roeck .func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 47150115ac9SGuenter Roeck .func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 47250115ac9SGuenter Roeck .func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 47350115ac9SGuenter Roeck .func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 47450115ac9SGuenter Roeck .func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 47550115ac9SGuenter Roeck /* page 16 is reserved */ 47650115ac9SGuenter Roeck .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 47750115ac9SGuenter Roeck .func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 47850115ac9SGuenter Roeck .func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 47950115ac9SGuenter Roeck .func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 48050115ac9SGuenter Roeck .func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 48150115ac9SGuenter Roeck .read_word_data = max34440_read_word_data, 48250115ac9SGuenter Roeck .write_word_data = max34440_write_word_data, 48350115ac9SGuenter Roeck }, 4849d2ecfb7SGuenter Roeck }; 4859d2ecfb7SGuenter Roeck 486dd431939SStephen Kitt static int max34440_probe(struct i2c_client *client) 4879d2ecfb7SGuenter Roeck { 488590defe5SGuenter Roeck struct max34440_data *data; 4897a001dbaSKun Yi int rv; 490590defe5SGuenter Roeck 491590defe5SGuenter Roeck data = devm_kzalloc(&client->dev, sizeof(struct max34440_data), 492590defe5SGuenter Roeck GFP_KERNEL); 493590defe5SGuenter Roeck if (!data) 494590defe5SGuenter Roeck return -ENOMEM; 495dd431939SStephen Kitt data->id = i2c_match_id(max34440_id, client)->driver_data; 496dd431939SStephen Kitt data->info = max34440_info[data->id]; 497590defe5SGuenter Roeck 4987a001dbaSKun Yi if (data->id == max34451) { 4997a001dbaSKun Yi rv = max34451_set_supported_funcs(client, data); 5007a001dbaSKun Yi if (rv) 5017a001dbaSKun Yi return rv; 5027a001dbaSKun Yi } 5037a001dbaSKun Yi 504dd431939SStephen Kitt return pmbus_do_probe(client, &data->info); 5059d2ecfb7SGuenter Roeck } 5069d2ecfb7SGuenter Roeck 5079d2ecfb7SGuenter Roeck static const struct i2c_device_id max34440_id[] = { 5089d2ecfb7SGuenter Roeck {"max34440", max34440}, 5099d2ecfb7SGuenter Roeck {"max34441", max34441}, 510590defe5SGuenter Roeck {"max34446", max34446}, 5117a001dbaSKun Yi {"max34451", max34451}, 51250115ac9SGuenter Roeck {"max34460", max34460}, 51350115ac9SGuenter Roeck {"max34461", max34461}, 5149d2ecfb7SGuenter Roeck {} 5159d2ecfb7SGuenter Roeck }; 5169d2ecfb7SGuenter Roeck MODULE_DEVICE_TABLE(i2c, max34440_id); 5179d2ecfb7SGuenter Roeck 5189d2ecfb7SGuenter Roeck /* This is the driver that will be inserted */ 5199d2ecfb7SGuenter Roeck static struct i2c_driver max34440_driver = { 5209d2ecfb7SGuenter Roeck .driver = { 5219d2ecfb7SGuenter Roeck .name = "max34440", 5229d2ecfb7SGuenter Roeck }, 523*1975d167SUwe Kleine-König .probe = max34440_probe, 5249d2ecfb7SGuenter Roeck .id_table = max34440_id, 5259d2ecfb7SGuenter Roeck }; 5269d2ecfb7SGuenter Roeck 527f0967eeaSAxel Lin module_i2c_driver(max34440_driver); 5289d2ecfb7SGuenter Roeck 5299d2ecfb7SGuenter Roeck MODULE_AUTHOR("Guenter Roeck"); 5309d2ecfb7SGuenter Roeck MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441"); 5319d2ecfb7SGuenter Roeck MODULE_LICENSE("GPL"); 532b94ca77eSGuenter Roeck MODULE_IMPORT_NS(PMBUS); 533