1cce20958SGuenter Roeck // SPDX-License-Identifier: GPL-2.0-or-later 2cce20958SGuenter Roeck /* 35c9353f5SUgur Usug * Driver for MAX20710, MAX20730, MAX20734, and MAX20743 Integrated, 45c9353f5SUgur Usug * Step-Down Switching Regulators 5cce20958SGuenter Roeck * 6cce20958SGuenter Roeck * Copyright 2019 Google LLC. 75c9353f5SUgur Usug * Copyright 2020 Maxim Integrated 8cce20958SGuenter Roeck */ 9cce20958SGuenter Roeck 10cce20958SGuenter Roeck #include <linux/bits.h> 118910c0bdSUgur Usug #include <linux/debugfs.h> 12cce20958SGuenter Roeck #include <linux/err.h> 13cce20958SGuenter Roeck #include <linux/i2c.h> 14cce20958SGuenter Roeck #include <linux/init.h> 15cce20958SGuenter Roeck #include <linux/kernel.h> 16cce20958SGuenter Roeck #include <linux/module.h> 17cce20958SGuenter Roeck #include <linux/mutex.h> 18cce20958SGuenter Roeck #include <linux/of_device.h> 19cce20958SGuenter Roeck #include <linux/pmbus.h> 20cce20958SGuenter Roeck #include <linux/util_macros.h> 21cce20958SGuenter Roeck #include "pmbus.h" 22cce20958SGuenter Roeck 23cce20958SGuenter Roeck enum chips { 245c9353f5SUgur Usug max20710, 25cce20958SGuenter Roeck max20730, 26cce20958SGuenter Roeck max20734, 27cce20958SGuenter Roeck max20743 28cce20958SGuenter Roeck }; 29cce20958SGuenter Roeck 308910c0bdSUgur Usug enum { 318910c0bdSUgur Usug MAX20730_DEBUGFS_VOUT_MIN = 0, 328910c0bdSUgur Usug MAX20730_DEBUGFS_FREQUENCY, 338910c0bdSUgur Usug MAX20730_DEBUGFS_PG_DELAY, 348910c0bdSUgur Usug MAX20730_DEBUGFS_INTERNAL_GAIN, 358910c0bdSUgur Usug MAX20730_DEBUGFS_BOOT_VOLTAGE, 368910c0bdSUgur Usug MAX20730_DEBUGFS_OUT_V_RAMP_RATE, 378910c0bdSUgur Usug MAX20730_DEBUGFS_OC_PROTECT_MODE, 388910c0bdSUgur Usug MAX20730_DEBUGFS_SS_TIMING, 398910c0bdSUgur Usug MAX20730_DEBUGFS_IMAX, 408910c0bdSUgur Usug MAX20730_DEBUGFS_OPERATION, 418910c0bdSUgur Usug MAX20730_DEBUGFS_ON_OFF_CONFIG, 428910c0bdSUgur Usug MAX20730_DEBUGFS_SMBALERT_MASK, 438910c0bdSUgur Usug MAX20730_DEBUGFS_VOUT_MODE, 448910c0bdSUgur Usug MAX20730_DEBUGFS_VOUT_COMMAND, 458910c0bdSUgur Usug MAX20730_DEBUGFS_VOUT_MAX, 468910c0bdSUgur Usug MAX20730_DEBUGFS_NUM_ENTRIES 478910c0bdSUgur Usug }; 488910c0bdSUgur Usug 49cce20958SGuenter Roeck struct max20730_data { 50cce20958SGuenter Roeck enum chips id; 51cce20958SGuenter Roeck struct pmbus_driver_info info; 52cce20958SGuenter Roeck struct mutex lock; /* Used to protect against parallel writes */ 53cce20958SGuenter Roeck u16 mfr_devset1; 548910c0bdSUgur Usug u16 mfr_devset2; 558910c0bdSUgur Usug u16 mfr_voutmin; 56*9b20aec2SChu Lin u32 vout_voltage_divider[2]; 57cce20958SGuenter Roeck }; 58cce20958SGuenter Roeck 59cce20958SGuenter Roeck #define to_max20730_data(x) container_of(x, struct max20730_data, info) 60cce20958SGuenter Roeck 618910c0bdSUgur Usug #define VOLT_FROM_REG(val) DIV_ROUND_CLOSEST((val), 1 << 9) 628910c0bdSUgur Usug 638910c0bdSUgur Usug #define PMBUS_SMB_ALERT_MASK 0x1B 648910c0bdSUgur Usug 658910c0bdSUgur Usug #define MAX20730_MFR_VOUT_MIN 0xd1 66cce20958SGuenter Roeck #define MAX20730_MFR_DEVSET1 0xd2 678910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2 0xd3 688910c0bdSUgur Usug 698910c0bdSUgur Usug #define MAX20730_MFR_VOUT_MIN_MASK GENMASK(9, 0) 708910c0bdSUgur Usug #define MAX20730_MFR_VOUT_MIN_BIT_POS 0 718910c0bdSUgur Usug 728910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_RGAIN_MASK (BIT(13) | BIT(14)) 738910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_OTP_MASK (BIT(11) | BIT(12)) 748910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_VBOOT_MASK (BIT(8) | BIT(9)) 758910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_OCP_MASK (BIT(5) | BIT(6)) 768910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_FSW_MASK GENMASK(4, 2) 778910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_TSTAT_MASK (BIT(0) | BIT(1)) 788910c0bdSUgur Usug 798910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_RGAIN_BIT_POS 13 808910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_OTP_BIT_POS 11 818910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_VBOOT_BIT_POS 8 828910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_OCP_BIT_POS 5 838910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_FSW_BIT_POS 2 848910c0bdSUgur Usug #define MAX20730_MFR_DEVSET1_TSTAT_BIT_POS 0 858910c0bdSUgur Usug 868910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2_IMAX_MASK GENMASK(10, 8) 878910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2_VRATE (BIT(6) | BIT(7)) 888910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2_OCPM_MASK BIT(5) 898910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2_SS_MASK (BIT(0) | BIT(1)) 908910c0bdSUgur Usug 918910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2_IMAX_BIT_POS 8 928910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2_VRATE_BIT_POS 6 938910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2_OCPM_BIT_POS 5 948910c0bdSUgur Usug #define MAX20730_MFR_DEVSET2_SS_BIT_POS 0 958910c0bdSUgur Usug 968910c0bdSUgur Usug #define DEBUG_FS_DATA_MAX 16 978910c0bdSUgur Usug 988910c0bdSUgur Usug struct max20730_debugfs_data { 998910c0bdSUgur Usug struct i2c_client *client; 1008910c0bdSUgur Usug int debugfs_entries[MAX20730_DEBUGFS_NUM_ENTRIES]; 1018910c0bdSUgur Usug }; 1028910c0bdSUgur Usug 1038910c0bdSUgur Usug #define to_psu(x, y) container_of((x), \ 1048910c0bdSUgur Usug struct max20730_debugfs_data, debugfs_entries[(y)]) 1058910c0bdSUgur Usug 1068910c0bdSUgur Usug #ifdef CONFIG_DEBUG_FS 1078910c0bdSUgur Usug static ssize_t max20730_debugfs_read(struct file *file, char __user *buf, 1088910c0bdSUgur Usug size_t count, loff_t *ppos) 1098910c0bdSUgur Usug { 1108910c0bdSUgur Usug int ret, len; 1118910c0bdSUgur Usug int *idxp = file->private_data; 1128910c0bdSUgur Usug int idx = *idxp; 1138910c0bdSUgur Usug struct max20730_debugfs_data *psu = to_psu(idxp, idx); 1148910c0bdSUgur Usug const struct pmbus_driver_info *info; 1158910c0bdSUgur Usug const struct max20730_data *data; 1168910c0bdSUgur Usug char tbuf[DEBUG_FS_DATA_MAX] = { 0 }; 1178910c0bdSUgur Usug u16 val; 1188910c0bdSUgur Usug 1198910c0bdSUgur Usug info = pmbus_get_driver_info(psu->client); 1208910c0bdSUgur Usug data = to_max20730_data(info); 1218910c0bdSUgur Usug 1228910c0bdSUgur Usug switch (idx) { 1238910c0bdSUgur Usug case MAX20730_DEBUGFS_VOUT_MIN: 1248910c0bdSUgur Usug ret = VOLT_FROM_REG(data->mfr_voutmin * 10000); 1258910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, "%d.%d\n", 1268910c0bdSUgur Usug ret / 10000, ret % 10000); 1278910c0bdSUgur Usug break; 1288910c0bdSUgur Usug case MAX20730_DEBUGFS_FREQUENCY: 1298910c0bdSUgur Usug val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_FSW_MASK) 1308910c0bdSUgur Usug >> MAX20730_MFR_DEVSET1_FSW_BIT_POS; 1318910c0bdSUgur Usug 1328910c0bdSUgur Usug if (val == 0) 1338910c0bdSUgur Usug ret = 400; 1348910c0bdSUgur Usug else if (val == 1) 1358910c0bdSUgur Usug ret = 500; 1368910c0bdSUgur Usug else if (val == 2 || val == 3) 1378910c0bdSUgur Usug ret = 600; 1388910c0bdSUgur Usug else if (val == 4) 1398910c0bdSUgur Usug ret = 700; 1408910c0bdSUgur Usug else if (val == 5) 1418910c0bdSUgur Usug ret = 800; 1428910c0bdSUgur Usug else 1438910c0bdSUgur Usug ret = 900; 1448910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret); 1458910c0bdSUgur Usug break; 1468910c0bdSUgur Usug case MAX20730_DEBUGFS_PG_DELAY: 1478910c0bdSUgur Usug val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_TSTAT_MASK) 1488910c0bdSUgur Usug >> MAX20730_MFR_DEVSET1_TSTAT_BIT_POS; 1498910c0bdSUgur Usug 1508910c0bdSUgur Usug if (val == 0) 1518910c0bdSUgur Usug len = strlcpy(tbuf, "2000\n", DEBUG_FS_DATA_MAX); 1528910c0bdSUgur Usug else if (val == 1) 1538910c0bdSUgur Usug len = strlcpy(tbuf, "125\n", DEBUG_FS_DATA_MAX); 1548910c0bdSUgur Usug else if (val == 2) 1558910c0bdSUgur Usug len = strlcpy(tbuf, "62.5\n", DEBUG_FS_DATA_MAX); 1568910c0bdSUgur Usug else 1578910c0bdSUgur Usug len = strlcpy(tbuf, "32\n", DEBUG_FS_DATA_MAX); 1588910c0bdSUgur Usug break; 1598910c0bdSUgur Usug case MAX20730_DEBUGFS_INTERNAL_GAIN: 1608910c0bdSUgur Usug val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_RGAIN_MASK) 1618910c0bdSUgur Usug >> MAX20730_MFR_DEVSET1_RGAIN_BIT_POS; 1628910c0bdSUgur Usug 1638910c0bdSUgur Usug if (data->id == max20734) { 1648910c0bdSUgur Usug /* AN6209 */ 1658910c0bdSUgur Usug if (val == 0) 1668910c0bdSUgur Usug len = strlcpy(tbuf, "0.8\n", DEBUG_FS_DATA_MAX); 1678910c0bdSUgur Usug else if (val == 1) 1688910c0bdSUgur Usug len = strlcpy(tbuf, "3.2\n", DEBUG_FS_DATA_MAX); 1698910c0bdSUgur Usug else if (val == 2) 1708910c0bdSUgur Usug len = strlcpy(tbuf, "1.6\n", DEBUG_FS_DATA_MAX); 1718910c0bdSUgur Usug else 1728910c0bdSUgur Usug len = strlcpy(tbuf, "6.4\n", DEBUG_FS_DATA_MAX); 1738910c0bdSUgur Usug } else if (data->id == max20730 || data->id == max20710) { 1748910c0bdSUgur Usug /* AN6042 or AN6140 */ 1758910c0bdSUgur Usug if (val == 0) 1768910c0bdSUgur Usug len = strlcpy(tbuf, "0.9\n", DEBUG_FS_DATA_MAX); 1778910c0bdSUgur Usug else if (val == 1) 1788910c0bdSUgur Usug len = strlcpy(tbuf, "3.6\n", DEBUG_FS_DATA_MAX); 1798910c0bdSUgur Usug else if (val == 2) 1808910c0bdSUgur Usug len = strlcpy(tbuf, "1.8\n", DEBUG_FS_DATA_MAX); 1818910c0bdSUgur Usug else 1828910c0bdSUgur Usug len = strlcpy(tbuf, "7.2\n", DEBUG_FS_DATA_MAX); 1838910c0bdSUgur Usug } else if (data->id == max20743) { 1848910c0bdSUgur Usug /* AN6042 */ 1858910c0bdSUgur Usug if (val == 0) 1868910c0bdSUgur Usug len = strlcpy(tbuf, "0.45\n", DEBUG_FS_DATA_MAX); 1878910c0bdSUgur Usug else if (val == 1) 1888910c0bdSUgur Usug len = strlcpy(tbuf, "1.8\n", DEBUG_FS_DATA_MAX); 1898910c0bdSUgur Usug else if (val == 2) 1908910c0bdSUgur Usug len = strlcpy(tbuf, "0.9\n", DEBUG_FS_DATA_MAX); 1918910c0bdSUgur Usug else 1928910c0bdSUgur Usug len = strlcpy(tbuf, "3.6\n", DEBUG_FS_DATA_MAX); 1938910c0bdSUgur Usug } else { 1948910c0bdSUgur Usug len = strlcpy(tbuf, "Not supported\n", DEBUG_FS_DATA_MAX); 1958910c0bdSUgur Usug } 1968910c0bdSUgur Usug break; 1978910c0bdSUgur Usug case MAX20730_DEBUGFS_BOOT_VOLTAGE: 1988910c0bdSUgur Usug val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_VBOOT_MASK) 1998910c0bdSUgur Usug >> MAX20730_MFR_DEVSET1_VBOOT_BIT_POS; 2008910c0bdSUgur Usug 2018910c0bdSUgur Usug if (val == 0) 2028910c0bdSUgur Usug len = strlcpy(tbuf, "0.6484\n", DEBUG_FS_DATA_MAX); 2038910c0bdSUgur Usug else if (val == 1) 2048910c0bdSUgur Usug len = strlcpy(tbuf, "0.8984\n", DEBUG_FS_DATA_MAX); 2058910c0bdSUgur Usug else if (val == 2) 2068910c0bdSUgur Usug len = strlcpy(tbuf, "1.0\n", DEBUG_FS_DATA_MAX); 2078910c0bdSUgur Usug else 2088910c0bdSUgur Usug len = strlcpy(tbuf, "Invalid\n", DEBUG_FS_DATA_MAX); 2098910c0bdSUgur Usug break; 2108910c0bdSUgur Usug case MAX20730_DEBUGFS_OUT_V_RAMP_RATE: 2118910c0bdSUgur Usug val = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_VRATE) 2128910c0bdSUgur Usug >> MAX20730_MFR_DEVSET2_VRATE_BIT_POS; 2138910c0bdSUgur Usug 2148910c0bdSUgur Usug if (val == 0) 2158910c0bdSUgur Usug len = strlcpy(tbuf, "4\n", DEBUG_FS_DATA_MAX); 2168910c0bdSUgur Usug else if (val == 1) 2178910c0bdSUgur Usug len = strlcpy(tbuf, "2\n", DEBUG_FS_DATA_MAX); 2188910c0bdSUgur Usug else if (val == 2) 2198910c0bdSUgur Usug len = strlcpy(tbuf, "1\n", DEBUG_FS_DATA_MAX); 2208910c0bdSUgur Usug else 2218910c0bdSUgur Usug len = strlcpy(tbuf, "Invalid\n", DEBUG_FS_DATA_MAX); 2228910c0bdSUgur Usug break; 2238910c0bdSUgur Usug case MAX20730_DEBUGFS_OC_PROTECT_MODE: 2248910c0bdSUgur Usug ret = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_OCPM_MASK) 2258910c0bdSUgur Usug >> MAX20730_MFR_DEVSET2_OCPM_BIT_POS; 2268910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret); 2278910c0bdSUgur Usug break; 2288910c0bdSUgur Usug case MAX20730_DEBUGFS_SS_TIMING: 2298910c0bdSUgur Usug val = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_SS_MASK) 2308910c0bdSUgur Usug >> MAX20730_MFR_DEVSET2_SS_BIT_POS; 2318910c0bdSUgur Usug 2328910c0bdSUgur Usug if (val == 0) 2338910c0bdSUgur Usug len = strlcpy(tbuf, "0.75\n", DEBUG_FS_DATA_MAX); 2348910c0bdSUgur Usug else if (val == 1) 2358910c0bdSUgur Usug len = strlcpy(tbuf, "1.5\n", DEBUG_FS_DATA_MAX); 2368910c0bdSUgur Usug else if (val == 2) 2378910c0bdSUgur Usug len = strlcpy(tbuf, "3\n", DEBUG_FS_DATA_MAX); 2388910c0bdSUgur Usug else 2398910c0bdSUgur Usug len = strlcpy(tbuf, "6\n", DEBUG_FS_DATA_MAX); 2408910c0bdSUgur Usug break; 2418910c0bdSUgur Usug case MAX20730_DEBUGFS_IMAX: 2428910c0bdSUgur Usug ret = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_IMAX_MASK) 2438910c0bdSUgur Usug >> MAX20730_MFR_DEVSET2_IMAX_BIT_POS; 2448910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret); 2458910c0bdSUgur Usug break; 2468910c0bdSUgur Usug case MAX20730_DEBUGFS_OPERATION: 2478910c0bdSUgur Usug ret = i2c_smbus_read_byte_data(psu->client, PMBUS_OPERATION); 2488910c0bdSUgur Usug if (ret < 0) 2498910c0bdSUgur Usug return ret; 2508910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret); 2518910c0bdSUgur Usug break; 2528910c0bdSUgur Usug case MAX20730_DEBUGFS_ON_OFF_CONFIG: 2538910c0bdSUgur Usug ret = i2c_smbus_read_byte_data(psu->client, PMBUS_ON_OFF_CONFIG); 2548910c0bdSUgur Usug if (ret < 0) 2558910c0bdSUgur Usug return ret; 2568910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret); 2578910c0bdSUgur Usug break; 2588910c0bdSUgur Usug case MAX20730_DEBUGFS_SMBALERT_MASK: 2598910c0bdSUgur Usug ret = i2c_smbus_read_word_data(psu->client, 2608910c0bdSUgur Usug PMBUS_SMB_ALERT_MASK); 2618910c0bdSUgur Usug if (ret < 0) 2628910c0bdSUgur Usug return ret; 2638910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret); 2648910c0bdSUgur Usug break; 2658910c0bdSUgur Usug case MAX20730_DEBUGFS_VOUT_MODE: 2668910c0bdSUgur Usug ret = i2c_smbus_read_byte_data(psu->client, PMBUS_VOUT_MODE); 2678910c0bdSUgur Usug if (ret < 0) 2688910c0bdSUgur Usug return ret; 2698910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret); 2708910c0bdSUgur Usug break; 2718910c0bdSUgur Usug case MAX20730_DEBUGFS_VOUT_COMMAND: 2728910c0bdSUgur Usug ret = i2c_smbus_read_word_data(psu->client, PMBUS_VOUT_COMMAND); 2738910c0bdSUgur Usug if (ret < 0) 2748910c0bdSUgur Usug return ret; 2758910c0bdSUgur Usug 2768910c0bdSUgur Usug ret = VOLT_FROM_REG(ret * 10000); 2778910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, 2788910c0bdSUgur Usug "%d.%d\n", ret / 10000, ret % 10000); 2798910c0bdSUgur Usug break; 2808910c0bdSUgur Usug case MAX20730_DEBUGFS_VOUT_MAX: 2818910c0bdSUgur Usug ret = i2c_smbus_read_word_data(psu->client, PMBUS_VOUT_MAX); 2828910c0bdSUgur Usug if (ret < 0) 2838910c0bdSUgur Usug return ret; 2848910c0bdSUgur Usug 2858910c0bdSUgur Usug ret = VOLT_FROM_REG(ret * 10000); 2868910c0bdSUgur Usug len = snprintf(tbuf, DEBUG_FS_DATA_MAX, 2878910c0bdSUgur Usug "%d.%d\n", ret / 10000, ret % 10000); 2888910c0bdSUgur Usug break; 2898910c0bdSUgur Usug default: 2908910c0bdSUgur Usug len = strlcpy(tbuf, "Invalid\n", DEBUG_FS_DATA_MAX); 2918910c0bdSUgur Usug } 2928910c0bdSUgur Usug 2938910c0bdSUgur Usug return simple_read_from_buffer(buf, count, ppos, tbuf, len); 2948910c0bdSUgur Usug } 2958910c0bdSUgur Usug 2968910c0bdSUgur Usug static const struct file_operations max20730_fops = { 2978910c0bdSUgur Usug .llseek = noop_llseek, 2988910c0bdSUgur Usug .read = max20730_debugfs_read, 2998910c0bdSUgur Usug .write = NULL, 3008910c0bdSUgur Usug .open = simple_open, 3018910c0bdSUgur Usug }; 3028910c0bdSUgur Usug 3038910c0bdSUgur Usug static int max20730_init_debugfs(struct i2c_client *client, 3048910c0bdSUgur Usug struct max20730_data *data) 3058910c0bdSUgur Usug { 3068910c0bdSUgur Usug int ret, i; 3078910c0bdSUgur Usug struct dentry *debugfs; 3088910c0bdSUgur Usug struct dentry *max20730_dir; 3098910c0bdSUgur Usug struct max20730_debugfs_data *psu; 3108910c0bdSUgur Usug 3118910c0bdSUgur Usug ret = i2c_smbus_read_word_data(client, MAX20730_MFR_DEVSET2); 3128910c0bdSUgur Usug if (ret < 0) 3138910c0bdSUgur Usug return ret; 3148910c0bdSUgur Usug data->mfr_devset2 = ret; 3158910c0bdSUgur Usug 3168910c0bdSUgur Usug ret = i2c_smbus_read_word_data(client, MAX20730_MFR_VOUT_MIN); 3178910c0bdSUgur Usug if (ret < 0) 3188910c0bdSUgur Usug return ret; 3198910c0bdSUgur Usug data->mfr_voutmin = ret; 3208910c0bdSUgur Usug 3218910c0bdSUgur Usug psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL); 3228910c0bdSUgur Usug if (!psu) 3238910c0bdSUgur Usug return -ENOMEM; 3248910c0bdSUgur Usug psu->client = client; 3258910c0bdSUgur Usug 3268910c0bdSUgur Usug debugfs = pmbus_get_debugfs_dir(client); 3278910c0bdSUgur Usug if (!debugfs) 3288910c0bdSUgur Usug return -ENOENT; 3298910c0bdSUgur Usug 3308910c0bdSUgur Usug max20730_dir = debugfs_create_dir(client->name, debugfs); 3318910c0bdSUgur Usug if (!max20730_dir) 3328910c0bdSUgur Usug return -ENOENT; 3338910c0bdSUgur Usug 3348910c0bdSUgur Usug for (i = 0; i < MAX20730_DEBUGFS_NUM_ENTRIES; ++i) 3358910c0bdSUgur Usug psu->debugfs_entries[i] = i; 3368910c0bdSUgur Usug 3378910c0bdSUgur Usug debugfs_create_file("vout_min", 0444, max20730_dir, 3388910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MIN], 3398910c0bdSUgur Usug &max20730_fops); 3408910c0bdSUgur Usug debugfs_create_file("frequency", 0444, max20730_dir, 3418910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_FREQUENCY], 3428910c0bdSUgur Usug &max20730_fops); 3438910c0bdSUgur Usug debugfs_create_file("power_good_delay", 0444, max20730_dir, 3448910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_PG_DELAY], 3458910c0bdSUgur Usug &max20730_fops); 3468910c0bdSUgur Usug debugfs_create_file("internal_gain", 0444, max20730_dir, 3478910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_INTERNAL_GAIN], 3488910c0bdSUgur Usug &max20730_fops); 3498910c0bdSUgur Usug debugfs_create_file("boot_voltage", 0444, max20730_dir, 3508910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_BOOT_VOLTAGE], 3518910c0bdSUgur Usug &max20730_fops); 3528910c0bdSUgur Usug debugfs_create_file("out_voltage_ramp_rate", 0444, max20730_dir, 3538910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_OUT_V_RAMP_RATE], 3548910c0bdSUgur Usug &max20730_fops); 3558910c0bdSUgur Usug debugfs_create_file("oc_protection_mode", 0444, max20730_dir, 3568910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_OC_PROTECT_MODE], 3578910c0bdSUgur Usug &max20730_fops); 3588910c0bdSUgur Usug debugfs_create_file("soft_start_timing", 0444, max20730_dir, 3598910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_SS_TIMING], 3608910c0bdSUgur Usug &max20730_fops); 3618910c0bdSUgur Usug debugfs_create_file("imax", 0444, max20730_dir, 3628910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_IMAX], 3638910c0bdSUgur Usug &max20730_fops); 3648910c0bdSUgur Usug debugfs_create_file("operation", 0444, max20730_dir, 3658910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_OPERATION], 3668910c0bdSUgur Usug &max20730_fops); 3678910c0bdSUgur Usug debugfs_create_file("on_off_config", 0444, max20730_dir, 3688910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_ON_OFF_CONFIG], 3698910c0bdSUgur Usug &max20730_fops); 3708910c0bdSUgur Usug debugfs_create_file("smbalert_mask", 0444, max20730_dir, 3718910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_SMBALERT_MASK], 3728910c0bdSUgur Usug &max20730_fops); 3738910c0bdSUgur Usug debugfs_create_file("vout_mode", 0444, max20730_dir, 3748910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MODE], 3758910c0bdSUgur Usug &max20730_fops); 3768910c0bdSUgur Usug debugfs_create_file("vout_command", 0444, max20730_dir, 3778910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_COMMAND], 3788910c0bdSUgur Usug &max20730_fops); 3798910c0bdSUgur Usug debugfs_create_file("vout_max", 0444, max20730_dir, 3808910c0bdSUgur Usug &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MAX], 3818910c0bdSUgur Usug &max20730_fops); 3828910c0bdSUgur Usug 3838910c0bdSUgur Usug return 0; 3848910c0bdSUgur Usug } 3858910c0bdSUgur Usug #else 3868910c0bdSUgur Usug static int max20730_init_debugfs(struct i2c_client *client, 3878910c0bdSUgur Usug struct max20730_data *data) 3888910c0bdSUgur Usug { 3898910c0bdSUgur Usug return 0; 3908910c0bdSUgur Usug } 3918910c0bdSUgur Usug #endif /* CONFIG_DEBUG_FS */ 392cce20958SGuenter Roeck 393dd431939SStephen Kitt static const struct i2c_device_id max20730_id[]; 394dd431939SStephen Kitt 395cce20958SGuenter Roeck /* 396cce20958SGuenter Roeck * Convert discreet value to direct data format. Strictly speaking, all passed 397cce20958SGuenter Roeck * values are constants, so we could do that calculation manually. On the 398cce20958SGuenter Roeck * downside, that would make the driver more difficult to maintain, so lets 399cce20958SGuenter Roeck * use this approach. 400cce20958SGuenter Roeck */ 401cce20958SGuenter Roeck static u16 val_to_direct(int v, enum pmbus_sensor_classes class, 402cce20958SGuenter Roeck const struct pmbus_driver_info *info) 403cce20958SGuenter Roeck { 404cce20958SGuenter Roeck int R = info->R[class] - 3; /* take milli-units into account */ 405cce20958SGuenter Roeck int b = info->b[class] * 1000; 406cce20958SGuenter Roeck long d; 407cce20958SGuenter Roeck 408cce20958SGuenter Roeck d = v * info->m[class] + b; 409cce20958SGuenter Roeck /* 410cce20958SGuenter Roeck * R < 0 is true for all callers, so we don't need to bother 411cce20958SGuenter Roeck * about the R > 0 case. 412cce20958SGuenter Roeck */ 413cce20958SGuenter Roeck while (R < 0) { 414cce20958SGuenter Roeck d = DIV_ROUND_CLOSEST(d, 10); 415cce20958SGuenter Roeck R++; 416cce20958SGuenter Roeck } 417cce20958SGuenter Roeck return (u16)d; 418cce20958SGuenter Roeck } 419cce20958SGuenter Roeck 420cce20958SGuenter Roeck static long direct_to_val(u16 w, enum pmbus_sensor_classes class, 421cce20958SGuenter Roeck const struct pmbus_driver_info *info) 422cce20958SGuenter Roeck { 423cce20958SGuenter Roeck int R = info->R[class] - 3; 424cce20958SGuenter Roeck int b = info->b[class] * 1000; 425cce20958SGuenter Roeck int m = info->m[class]; 426cce20958SGuenter Roeck long d = (s16)w; 427cce20958SGuenter Roeck 428cce20958SGuenter Roeck if (m == 0) 429cce20958SGuenter Roeck return 0; 430cce20958SGuenter Roeck 431cce20958SGuenter Roeck while (R < 0) { 432cce20958SGuenter Roeck d *= 10; 433cce20958SGuenter Roeck R++; 434cce20958SGuenter Roeck } 435cce20958SGuenter Roeck d = (d - b) / m; 436cce20958SGuenter Roeck return d; 437cce20958SGuenter Roeck } 438cce20958SGuenter Roeck 439cce20958SGuenter Roeck static u32 max_current[][5] = { 4405c9353f5SUgur Usug [max20710] = { 6200, 8000, 9700, 11600 }, 441cce20958SGuenter Roeck [max20730] = { 13000, 16600, 20100, 23600 }, 442cce20958SGuenter Roeck [max20734] = { 21000, 27000, 32000, 38000 }, 443cce20958SGuenter Roeck [max20743] = { 18900, 24100, 29200, 34100 }, 444cce20958SGuenter Roeck }; 445cce20958SGuenter Roeck 44643f33b6eSGuenter Roeck static int max20730_read_word_data(struct i2c_client *client, int page, 44743f33b6eSGuenter Roeck int phase, int reg) 448cce20958SGuenter Roeck { 449cce20958SGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 450cce20958SGuenter Roeck const struct max20730_data *data = to_max20730_data(info); 451cce20958SGuenter Roeck int ret = 0; 452cce20958SGuenter Roeck u32 max_c; 453cce20958SGuenter Roeck 454cce20958SGuenter Roeck switch (reg) { 455cce20958SGuenter Roeck case PMBUS_OT_FAULT_LIMIT: 456cce20958SGuenter Roeck switch ((data->mfr_devset1 >> 11) & 0x3) { 457cce20958SGuenter Roeck case 0x0: 458cce20958SGuenter Roeck ret = val_to_direct(150000, PSC_TEMPERATURE, info); 459cce20958SGuenter Roeck break; 460cce20958SGuenter Roeck case 0x1: 461cce20958SGuenter Roeck ret = val_to_direct(130000, PSC_TEMPERATURE, info); 462cce20958SGuenter Roeck break; 463cce20958SGuenter Roeck default: 464cce20958SGuenter Roeck ret = -ENODATA; 465cce20958SGuenter Roeck break; 466cce20958SGuenter Roeck } 467cce20958SGuenter Roeck break; 468cce20958SGuenter Roeck case PMBUS_IOUT_OC_FAULT_LIMIT: 469cce20958SGuenter Roeck max_c = max_current[data->id][(data->mfr_devset1 >> 5) & 0x3]; 470cce20958SGuenter Roeck ret = val_to_direct(max_c, PSC_CURRENT_OUT, info); 471cce20958SGuenter Roeck break; 472*9b20aec2SChu Lin case PMBUS_READ_VOUT: 473*9b20aec2SChu Lin ret = pmbus_read_word_data(client, page, phase, reg); 474*9b20aec2SChu Lin if (ret > 0 && data->vout_voltage_divider[0] && data->vout_voltage_divider[1]) { 475*9b20aec2SChu Lin u64 temp = DIV_ROUND_CLOSEST_ULL((u64)ret * data->vout_voltage_divider[1], 476*9b20aec2SChu Lin data->vout_voltage_divider[0]); 477*9b20aec2SChu Lin ret = clamp_val(temp, 0, 0xffff); 478*9b20aec2SChu Lin } 479*9b20aec2SChu Lin break; 480cce20958SGuenter Roeck default: 481cce20958SGuenter Roeck ret = -ENODATA; 482cce20958SGuenter Roeck break; 483cce20958SGuenter Roeck } 484cce20958SGuenter Roeck return ret; 485cce20958SGuenter Roeck } 486cce20958SGuenter Roeck 487cce20958SGuenter Roeck static int max20730_write_word_data(struct i2c_client *client, int page, 488cce20958SGuenter Roeck int reg, u16 word) 489cce20958SGuenter Roeck { 490cce20958SGuenter Roeck struct pmbus_driver_info *info; 491cce20958SGuenter Roeck struct max20730_data *data; 492cce20958SGuenter Roeck u16 devset1; 493cce20958SGuenter Roeck int ret = 0; 494cce20958SGuenter Roeck int idx; 495cce20958SGuenter Roeck 496cce20958SGuenter Roeck info = (struct pmbus_driver_info *)pmbus_get_driver_info(client); 497cce20958SGuenter Roeck data = to_max20730_data(info); 498cce20958SGuenter Roeck 499cce20958SGuenter Roeck mutex_lock(&data->lock); 500cce20958SGuenter Roeck devset1 = data->mfr_devset1; 501cce20958SGuenter Roeck 502cce20958SGuenter Roeck switch (reg) { 503cce20958SGuenter Roeck case PMBUS_OT_FAULT_LIMIT: 504cce20958SGuenter Roeck devset1 &= ~(BIT(11) | BIT(12)); 505cce20958SGuenter Roeck if (direct_to_val(word, PSC_TEMPERATURE, info) < 140000) 506cce20958SGuenter Roeck devset1 |= BIT(11); 507cce20958SGuenter Roeck break; 508cce20958SGuenter Roeck case PMBUS_IOUT_OC_FAULT_LIMIT: 509cce20958SGuenter Roeck devset1 &= ~(BIT(5) | BIT(6)); 510cce20958SGuenter Roeck 511cce20958SGuenter Roeck idx = find_closest(direct_to_val(word, PSC_CURRENT_OUT, info), 512cce20958SGuenter Roeck max_current[data->id], 4); 513cce20958SGuenter Roeck devset1 |= (idx << 5); 514cce20958SGuenter Roeck break; 515cce20958SGuenter Roeck default: 516cce20958SGuenter Roeck ret = -ENODATA; 517cce20958SGuenter Roeck break; 518cce20958SGuenter Roeck } 519cce20958SGuenter Roeck 520cce20958SGuenter Roeck if (!ret && devset1 != data->mfr_devset1) { 521cce20958SGuenter Roeck ret = i2c_smbus_write_word_data(client, MAX20730_MFR_DEVSET1, 522cce20958SGuenter Roeck devset1); 523cce20958SGuenter Roeck if (!ret) { 524cce20958SGuenter Roeck data->mfr_devset1 = devset1; 525cce20958SGuenter Roeck pmbus_clear_cache(client); 526cce20958SGuenter Roeck } 527cce20958SGuenter Roeck } 528cce20958SGuenter Roeck mutex_unlock(&data->lock); 529cce20958SGuenter Roeck return ret; 530cce20958SGuenter Roeck } 531cce20958SGuenter Roeck 532cce20958SGuenter Roeck static const struct pmbus_driver_info max20730_info[] = { 5335c9353f5SUgur Usug [max20710] = { 5345c9353f5SUgur Usug .pages = 1, 5355c9353f5SUgur Usug .read_word_data = max20730_read_word_data, 5365c9353f5SUgur Usug .write_word_data = max20730_write_word_data, 5375c9353f5SUgur Usug 5385c9353f5SUgur Usug /* Source : Maxim AN6140 and AN6042 */ 5395c9353f5SUgur Usug .format[PSC_TEMPERATURE] = direct, 5405c9353f5SUgur Usug .m[PSC_TEMPERATURE] = 21, 5415c9353f5SUgur Usug .b[PSC_TEMPERATURE] = 5887, 5425c9353f5SUgur Usug .R[PSC_TEMPERATURE] = -1, 5435c9353f5SUgur Usug 5445c9353f5SUgur Usug .format[PSC_VOLTAGE_IN] = direct, 5455c9353f5SUgur Usug .m[PSC_VOLTAGE_IN] = 3609, 5465c9353f5SUgur Usug .b[PSC_VOLTAGE_IN] = 0, 5475c9353f5SUgur Usug .R[PSC_VOLTAGE_IN] = -2, 5485c9353f5SUgur Usug 5495c9353f5SUgur Usug .format[PSC_CURRENT_OUT] = direct, 5505c9353f5SUgur Usug .m[PSC_CURRENT_OUT] = 153, 5515c9353f5SUgur Usug .b[PSC_CURRENT_OUT] = 4976, 5525c9353f5SUgur Usug .R[PSC_CURRENT_OUT] = -1, 5535c9353f5SUgur Usug 5545c9353f5SUgur Usug .format[PSC_VOLTAGE_OUT] = linear, 5555c9353f5SUgur Usug 5565c9353f5SUgur Usug .func[0] = PMBUS_HAVE_VIN | 5575c9353f5SUgur Usug PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 5585c9353f5SUgur Usug PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 5595c9353f5SUgur Usug PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 5605c9353f5SUgur Usug PMBUS_HAVE_STATUS_INPUT, 5615c9353f5SUgur Usug }, 562cce20958SGuenter Roeck [max20730] = { 563cce20958SGuenter Roeck .pages = 1, 564cce20958SGuenter Roeck .read_word_data = max20730_read_word_data, 565cce20958SGuenter Roeck .write_word_data = max20730_write_word_data, 566cce20958SGuenter Roeck 567cce20958SGuenter Roeck /* Source : Maxim AN6042 */ 568cce20958SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 569cce20958SGuenter Roeck .m[PSC_TEMPERATURE] = 21, 570cce20958SGuenter Roeck .b[PSC_TEMPERATURE] = 5887, 571cce20958SGuenter Roeck .R[PSC_TEMPERATURE] = -1, 572cce20958SGuenter Roeck 573cce20958SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 574cce20958SGuenter Roeck .m[PSC_VOLTAGE_IN] = 3609, 575cce20958SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 576cce20958SGuenter Roeck .R[PSC_VOLTAGE_IN] = -2, 577cce20958SGuenter Roeck 578cce20958SGuenter Roeck /* 579cce20958SGuenter Roeck * Values in the datasheet are adjusted for temperature and 580cce20958SGuenter Roeck * for the relationship between Vin and Vout. 581cce20958SGuenter Roeck * Unfortunately, the data sheet suggests that Vout measurement 582cce20958SGuenter Roeck * may be scaled with a resistor array. This is indeed the case 583cce20958SGuenter Roeck * at least on the evaulation boards. As a result, any in-driver 584cce20958SGuenter Roeck * adjustments would either be wrong or require elaborate means 585cce20958SGuenter Roeck * to configure the scaling. Instead of doing that, just report 586cce20958SGuenter Roeck * raw values and let userspace handle adjustments. 587cce20958SGuenter Roeck */ 588cce20958SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 589cce20958SGuenter Roeck .m[PSC_CURRENT_OUT] = 153, 590cce20958SGuenter Roeck .b[PSC_CURRENT_OUT] = 4976, 591cce20958SGuenter Roeck .R[PSC_CURRENT_OUT] = -1, 592cce20958SGuenter Roeck 593cce20958SGuenter Roeck .format[PSC_VOLTAGE_OUT] = linear, 594cce20958SGuenter Roeck 595cce20958SGuenter Roeck .func[0] = PMBUS_HAVE_VIN | 596cce20958SGuenter Roeck PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 597cce20958SGuenter Roeck PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 5985c9353f5SUgur Usug PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 5995c9353f5SUgur Usug PMBUS_HAVE_STATUS_INPUT, 600cce20958SGuenter Roeck }, 601cce20958SGuenter Roeck [max20734] = { 602cce20958SGuenter Roeck .pages = 1, 603cce20958SGuenter Roeck .read_word_data = max20730_read_word_data, 604cce20958SGuenter Roeck .write_word_data = max20730_write_word_data, 605cce20958SGuenter Roeck 606cce20958SGuenter Roeck /* Source : Maxim AN6209 */ 607cce20958SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 608cce20958SGuenter Roeck .m[PSC_TEMPERATURE] = 21, 609cce20958SGuenter Roeck .b[PSC_TEMPERATURE] = 5887, 610cce20958SGuenter Roeck .R[PSC_TEMPERATURE] = -1, 611cce20958SGuenter Roeck 612cce20958SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 613cce20958SGuenter Roeck .m[PSC_VOLTAGE_IN] = 3592, 614cce20958SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 615cce20958SGuenter Roeck .R[PSC_VOLTAGE_IN] = -2, 616cce20958SGuenter Roeck 617cce20958SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 618cce20958SGuenter Roeck .m[PSC_CURRENT_OUT] = 111, 619cce20958SGuenter Roeck .b[PSC_CURRENT_OUT] = 3461, 620cce20958SGuenter Roeck .R[PSC_CURRENT_OUT] = -1, 621cce20958SGuenter Roeck 622cce20958SGuenter Roeck .format[PSC_VOLTAGE_OUT] = linear, 623cce20958SGuenter Roeck 624cce20958SGuenter Roeck .func[0] = PMBUS_HAVE_VIN | 625cce20958SGuenter Roeck PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 626cce20958SGuenter Roeck PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 6275c9353f5SUgur Usug PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 6285c9353f5SUgur Usug PMBUS_HAVE_STATUS_INPUT, 629cce20958SGuenter Roeck }, 630cce20958SGuenter Roeck [max20743] = { 631cce20958SGuenter Roeck .pages = 1, 632cce20958SGuenter Roeck .read_word_data = max20730_read_word_data, 633cce20958SGuenter Roeck .write_word_data = max20730_write_word_data, 634cce20958SGuenter Roeck 635cce20958SGuenter Roeck /* Source : Maxim AN6042 */ 636cce20958SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 637cce20958SGuenter Roeck .m[PSC_TEMPERATURE] = 21, 638cce20958SGuenter Roeck .b[PSC_TEMPERATURE] = 5887, 639cce20958SGuenter Roeck .R[PSC_TEMPERATURE] = -1, 640cce20958SGuenter Roeck 641cce20958SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 642cce20958SGuenter Roeck .m[PSC_VOLTAGE_IN] = 3597, 643cce20958SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 644cce20958SGuenter Roeck .R[PSC_VOLTAGE_IN] = -2, 645cce20958SGuenter Roeck 646cce20958SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 647cce20958SGuenter Roeck .m[PSC_CURRENT_OUT] = 95, 648cce20958SGuenter Roeck .b[PSC_CURRENT_OUT] = 5014, 649cce20958SGuenter Roeck .R[PSC_CURRENT_OUT] = -1, 650cce20958SGuenter Roeck 651cce20958SGuenter Roeck .format[PSC_VOLTAGE_OUT] = linear, 652cce20958SGuenter Roeck 653cce20958SGuenter Roeck .func[0] = PMBUS_HAVE_VIN | 654cce20958SGuenter Roeck PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 655cce20958SGuenter Roeck PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 6565c9353f5SUgur Usug PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 6575c9353f5SUgur Usug PMBUS_HAVE_STATUS_INPUT, 658cce20958SGuenter Roeck }, 659cce20958SGuenter Roeck }; 660cce20958SGuenter Roeck 661dd431939SStephen Kitt static int max20730_probe(struct i2c_client *client) 662cce20958SGuenter Roeck { 663cce20958SGuenter Roeck struct device *dev = &client->dev; 664cce20958SGuenter Roeck u8 buf[I2C_SMBUS_BLOCK_MAX + 1]; 665cce20958SGuenter Roeck struct max20730_data *data; 666cce20958SGuenter Roeck enum chips chip_id; 667cce20958SGuenter Roeck int ret; 668cce20958SGuenter Roeck 669cce20958SGuenter Roeck if (!i2c_check_functionality(client->adapter, 670cce20958SGuenter Roeck I2C_FUNC_SMBUS_READ_BYTE_DATA | 671cce20958SGuenter Roeck I2C_FUNC_SMBUS_READ_WORD_DATA | 672cce20958SGuenter Roeck I2C_FUNC_SMBUS_BLOCK_DATA)) 673cce20958SGuenter Roeck return -ENODEV; 674cce20958SGuenter Roeck 675cce20958SGuenter Roeck ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf); 676cce20958SGuenter Roeck if (ret < 0) { 677cce20958SGuenter Roeck dev_err(&client->dev, "Failed to read Manufacturer ID\n"); 678cce20958SGuenter Roeck return ret; 679cce20958SGuenter Roeck } 680cce20958SGuenter Roeck if (ret != 5 || strncmp(buf, "MAXIM", 5)) { 681cce20958SGuenter Roeck buf[ret] = '\0'; 682cce20958SGuenter Roeck dev_err(dev, "Unsupported Manufacturer ID '%s'\n", buf); 683cce20958SGuenter Roeck return -ENODEV; 684cce20958SGuenter Roeck } 685cce20958SGuenter Roeck 686cce20958SGuenter Roeck /* 687cce20958SGuenter Roeck * The chips support reading PMBUS_MFR_MODEL. On both MAX20730 688cce20958SGuenter Roeck * and MAX20734, reading it returns M20743. Presumably that is 689cce20958SGuenter Roeck * the reason why the command is not documented. Unfortunately, 690cce20958SGuenter Roeck * that means that there is no reliable means to detect the chip. 691cce20958SGuenter Roeck * However, we can at least detect the chip series. Compare 692cce20958SGuenter Roeck * the returned value against 'M20743' and bail out if there is 693cce20958SGuenter Roeck * a mismatch. If that doesn't work for all chips, we may have 694cce20958SGuenter Roeck * to remove this check. 695cce20958SGuenter Roeck */ 696cce20958SGuenter Roeck ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf); 697cce20958SGuenter Roeck if (ret < 0) { 698cce20958SGuenter Roeck dev_err(dev, "Failed to read Manufacturer Model\n"); 699cce20958SGuenter Roeck return ret; 700cce20958SGuenter Roeck } 701cce20958SGuenter Roeck if (ret != 6 || strncmp(buf, "M20743", 6)) { 702cce20958SGuenter Roeck buf[ret] = '\0'; 703cce20958SGuenter Roeck dev_err(dev, "Unsupported Manufacturer Model '%s'\n", buf); 704cce20958SGuenter Roeck return -ENODEV; 705cce20958SGuenter Roeck } 706cce20958SGuenter Roeck 707cce20958SGuenter Roeck ret = i2c_smbus_read_block_data(client, PMBUS_MFR_REVISION, buf); 708cce20958SGuenter Roeck if (ret < 0) { 709cce20958SGuenter Roeck dev_err(dev, "Failed to read Manufacturer Revision\n"); 710cce20958SGuenter Roeck return ret; 711cce20958SGuenter Roeck } 712cce20958SGuenter Roeck if (ret != 1 || buf[0] != 'F') { 713cce20958SGuenter Roeck buf[ret] = '\0'; 714cce20958SGuenter Roeck dev_err(dev, "Unsupported Manufacturer Revision '%s'\n", buf); 715cce20958SGuenter Roeck return -ENODEV; 716cce20958SGuenter Roeck } 717cce20958SGuenter Roeck 718cce20958SGuenter Roeck if (client->dev.of_node) 719cce20958SGuenter Roeck chip_id = (enum chips)of_device_get_match_data(dev); 720cce20958SGuenter Roeck else 721dd431939SStephen Kitt chip_id = i2c_match_id(max20730_id, client)->driver_data; 722cce20958SGuenter Roeck 723cce20958SGuenter Roeck data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 724cce20958SGuenter Roeck if (!data) 725cce20958SGuenter Roeck return -ENOMEM; 726cce20958SGuenter Roeck data->id = chip_id; 727cce20958SGuenter Roeck mutex_init(&data->lock); 728cce20958SGuenter Roeck memcpy(&data->info, &max20730_info[chip_id], sizeof(data->info)); 729*9b20aec2SChu Lin if (of_property_read_u32_array(client->dev.of_node, "vout-voltage-divider", 730*9b20aec2SChu Lin data->vout_voltage_divider, 731*9b20aec2SChu Lin ARRAY_SIZE(data->vout_voltage_divider)) != 0) 732*9b20aec2SChu Lin memset(data->vout_voltage_divider, 0, sizeof(data->vout_voltage_divider)); 733*9b20aec2SChu Lin if (data->vout_voltage_divider[1] < data->vout_voltage_divider[0]) { 734*9b20aec2SChu Lin dev_err(dev, 735*9b20aec2SChu Lin "The total resistance of voltage divider is less than output resistance\n"); 736*9b20aec2SChu Lin return -EINVAL; 737*9b20aec2SChu Lin } 738cce20958SGuenter Roeck 739cce20958SGuenter Roeck ret = i2c_smbus_read_word_data(client, MAX20730_MFR_DEVSET1); 740cce20958SGuenter Roeck if (ret < 0) 741cce20958SGuenter Roeck return ret; 742cce20958SGuenter Roeck data->mfr_devset1 = ret; 743cce20958SGuenter Roeck 7448910c0bdSUgur Usug ret = pmbus_do_probe(client, &data->info); 7458910c0bdSUgur Usug if (ret < 0) 7468910c0bdSUgur Usug return ret; 7478910c0bdSUgur Usug 7488910c0bdSUgur Usug ret = max20730_init_debugfs(client, data); 7498910c0bdSUgur Usug if (ret) 7508910c0bdSUgur Usug dev_warn(dev, "Failed to register debugfs: %d\n", 7518910c0bdSUgur Usug ret); 7528910c0bdSUgur Usug 7538910c0bdSUgur Usug return 0; 754cce20958SGuenter Roeck } 755cce20958SGuenter Roeck 756cce20958SGuenter Roeck static const struct i2c_device_id max20730_id[] = { 7575c9353f5SUgur Usug { "max20710", max20710 }, 758cce20958SGuenter Roeck { "max20730", max20730 }, 759cce20958SGuenter Roeck { "max20734", max20734 }, 760cce20958SGuenter Roeck { "max20743", max20743 }, 761cce20958SGuenter Roeck { }, 762cce20958SGuenter Roeck }; 763cce20958SGuenter Roeck 764cce20958SGuenter Roeck MODULE_DEVICE_TABLE(i2c, max20730_id); 765cce20958SGuenter Roeck 766cce20958SGuenter Roeck static const struct of_device_id max20730_of_match[] = { 7675c9353f5SUgur Usug { .compatible = "maxim,max20710", .data = (void *)max20710 }, 768cce20958SGuenter Roeck { .compatible = "maxim,max20730", .data = (void *)max20730 }, 769cce20958SGuenter Roeck { .compatible = "maxim,max20734", .data = (void *)max20734 }, 770cce20958SGuenter Roeck { .compatible = "maxim,max20743", .data = (void *)max20743 }, 771cce20958SGuenter Roeck { }, 772cce20958SGuenter Roeck }; 773cce20958SGuenter Roeck 774cce20958SGuenter Roeck MODULE_DEVICE_TABLE(of, max20730_of_match); 775cce20958SGuenter Roeck 776cce20958SGuenter Roeck static struct i2c_driver max20730_driver = { 777cce20958SGuenter Roeck .driver = { 778cce20958SGuenter Roeck .name = "max20730", 779cce20958SGuenter Roeck .of_match_table = max20730_of_match, 780cce20958SGuenter Roeck }, 781dd431939SStephen Kitt .probe_new = max20730_probe, 782cce20958SGuenter Roeck .remove = pmbus_do_remove, 783cce20958SGuenter Roeck .id_table = max20730_id, 784cce20958SGuenter Roeck }; 785cce20958SGuenter Roeck 786cce20958SGuenter Roeck module_i2c_driver(max20730_driver); 787cce20958SGuenter Roeck 788cce20958SGuenter Roeck MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); 7895c9353f5SUgur Usug MODULE_DESCRIPTION("PMBus driver for Maxim MAX20710 / MAX20730 / MAX20734 / MAX20743"); 790cce20958SGuenter Roeck MODULE_LICENSE("GPL"); 791