^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for MAX20710, MAX20730, MAX20734, and MAX20743 Integrated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Step-Down Switching Regulators
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2019 Google LLC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2020 Maxim Integrated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pmbus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/util_macros.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "pmbus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) enum chips {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) max20710,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) max20730,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) max20734,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) max20743
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MAX20730_DEBUGFS_VOUT_MIN = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) MAX20730_DEBUGFS_FREQUENCY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MAX20730_DEBUGFS_PG_DELAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) MAX20730_DEBUGFS_INTERNAL_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) MAX20730_DEBUGFS_BOOT_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) MAX20730_DEBUGFS_OUT_V_RAMP_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MAX20730_DEBUGFS_OC_PROTECT_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MAX20730_DEBUGFS_SS_TIMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) MAX20730_DEBUGFS_IMAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) MAX20730_DEBUGFS_OPERATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) MAX20730_DEBUGFS_ON_OFF_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) MAX20730_DEBUGFS_SMBALERT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) MAX20730_DEBUGFS_VOUT_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) MAX20730_DEBUGFS_VOUT_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MAX20730_DEBUGFS_VOUT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) MAX20730_DEBUGFS_NUM_ENTRIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct max20730_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) enum chips id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct pmbus_driver_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct mutex lock; /* Used to protect against parallel writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u16 mfr_devset1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u16 mfr_devset2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u16 mfr_voutmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 vout_voltage_divider[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define to_max20730_data(x) container_of(x, struct max20730_data, info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define VOLT_FROM_REG(val) DIV_ROUND_CLOSEST((val), 1 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PMBUS_SMB_ALERT_MASK 0x1B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define MAX20730_MFR_VOUT_MIN 0xd1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MAX20730_MFR_DEVSET1 0xd2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define MAX20730_MFR_DEVSET2 0xd3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MAX20730_MFR_VOUT_MIN_MASK GENMASK(9, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define MAX20730_MFR_VOUT_MIN_BIT_POS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define MAX20730_MFR_DEVSET1_RGAIN_MASK (BIT(13) | BIT(14))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define MAX20730_MFR_DEVSET1_OTP_MASK (BIT(11) | BIT(12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define MAX20730_MFR_DEVSET1_VBOOT_MASK (BIT(8) | BIT(9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define MAX20730_MFR_DEVSET1_OCP_MASK (BIT(5) | BIT(6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define MAX20730_MFR_DEVSET1_FSW_MASK GENMASK(4, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define MAX20730_MFR_DEVSET1_TSTAT_MASK (BIT(0) | BIT(1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define MAX20730_MFR_DEVSET1_RGAIN_BIT_POS 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define MAX20730_MFR_DEVSET1_OTP_BIT_POS 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define MAX20730_MFR_DEVSET1_VBOOT_BIT_POS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define MAX20730_MFR_DEVSET1_OCP_BIT_POS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define MAX20730_MFR_DEVSET1_FSW_BIT_POS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define MAX20730_MFR_DEVSET1_TSTAT_BIT_POS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define MAX20730_MFR_DEVSET2_IMAX_MASK GENMASK(10, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define MAX20730_MFR_DEVSET2_VRATE (BIT(6) | BIT(7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define MAX20730_MFR_DEVSET2_OCPM_MASK BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define MAX20730_MFR_DEVSET2_SS_MASK (BIT(0) | BIT(1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define MAX20730_MFR_DEVSET2_IMAX_BIT_POS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define MAX20730_MFR_DEVSET2_VRATE_BIT_POS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define MAX20730_MFR_DEVSET2_OCPM_BIT_POS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define MAX20730_MFR_DEVSET2_SS_BIT_POS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define DEBUG_FS_DATA_MAX 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct max20730_debugfs_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int debugfs_entries[MAX20730_DEBUGFS_NUM_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define to_psu(x, y) container_of((x), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct max20730_debugfs_data, debugfs_entries[(y)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static ssize_t max20730_debugfs_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int ret, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int *idxp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int idx = *idxp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct max20730_debugfs_data *psu = to_psu(idxp, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) const struct pmbus_driver_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const struct max20730_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) char tbuf[DEBUG_FS_DATA_MAX] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) info = pmbus_get_driver_info(psu->client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) data = to_max20730_data(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) switch (idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case MAX20730_DEBUGFS_VOUT_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ret = VOLT_FROM_REG(data->mfr_voutmin * 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret / 10000, ret % 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) case MAX20730_DEBUGFS_FREQUENCY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_FSW_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) >> MAX20730_MFR_DEVSET1_FSW_BIT_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ret = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) else if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ret = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) else if (val == 2 || val == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = 600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) else if (val == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = 700;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) else if (val == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ret = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ret = 900;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case MAX20730_DEBUGFS_PG_DELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_TSTAT_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) >> MAX20730_MFR_DEVSET1_TSTAT_BIT_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) len = strlcpy(tbuf, "2000\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) len = strlcpy(tbuf, "125\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) else if (val == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) len = strlcpy(tbuf, "62.5\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) len = strlcpy(tbuf, "32\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case MAX20730_DEBUGFS_INTERNAL_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_RGAIN_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) >> MAX20730_MFR_DEVSET1_RGAIN_BIT_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (data->id == max20734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* AN6209 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) len = strlcpy(tbuf, "0.8\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) else if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) len = strlcpy(tbuf, "3.2\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) else if (val == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) len = strlcpy(tbuf, "1.6\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) len = strlcpy(tbuf, "6.4\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } else if (data->id == max20730 || data->id == max20710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* AN6042 or AN6140 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) len = strlcpy(tbuf, "0.9\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) else if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) len = strlcpy(tbuf, "3.6\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) else if (val == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) len = strlcpy(tbuf, "1.8\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) len = strlcpy(tbuf, "7.2\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) } else if (data->id == max20743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* AN6042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) len = strlcpy(tbuf, "0.45\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) else if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) len = strlcpy(tbuf, "1.8\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) else if (val == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) len = strlcpy(tbuf, "0.9\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) len = strlcpy(tbuf, "3.6\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) len = strlcpy(tbuf, "Not supported\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case MAX20730_DEBUGFS_BOOT_VOLTAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_VBOOT_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) >> MAX20730_MFR_DEVSET1_VBOOT_BIT_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) len = strlcpy(tbuf, "0.6484\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) else if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) len = strlcpy(tbuf, "0.8984\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) else if (val == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) len = strlcpy(tbuf, "1.0\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) len = strlcpy(tbuf, "Invalid\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case MAX20730_DEBUGFS_OUT_V_RAMP_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) val = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_VRATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) >> MAX20730_MFR_DEVSET2_VRATE_BIT_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) len = strlcpy(tbuf, "4\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) else if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) len = strlcpy(tbuf, "2\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) else if (val == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) len = strlcpy(tbuf, "1\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) len = strlcpy(tbuf, "Invalid\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case MAX20730_DEBUGFS_OC_PROTECT_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ret = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_OCPM_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) >> MAX20730_MFR_DEVSET2_OCPM_BIT_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case MAX20730_DEBUGFS_SS_TIMING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) val = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_SS_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) >> MAX20730_MFR_DEVSET2_SS_BIT_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) len = strlcpy(tbuf, "0.75\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) else if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) len = strlcpy(tbuf, "1.5\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) else if (val == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) len = strlcpy(tbuf, "3\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) len = strlcpy(tbuf, "6\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case MAX20730_DEBUGFS_IMAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ret = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_IMAX_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) >> MAX20730_MFR_DEVSET2_IMAX_BIT_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case MAX20730_DEBUGFS_OPERATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ret = i2c_smbus_read_byte_data(psu->client, PMBUS_OPERATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case MAX20730_DEBUGFS_ON_OFF_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ret = i2c_smbus_read_byte_data(psu->client, PMBUS_ON_OFF_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case MAX20730_DEBUGFS_SMBALERT_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = i2c_smbus_read_word_data(psu->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) PMBUS_SMB_ALERT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) case MAX20730_DEBUGFS_VOUT_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ret = i2c_smbus_read_byte_data(psu->client, PMBUS_VOUT_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case MAX20730_DEBUGFS_VOUT_COMMAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = i2c_smbus_read_word_data(psu->client, PMBUS_VOUT_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret = VOLT_FROM_REG(ret * 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) "%d.%d\n", ret / 10000, ret % 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case MAX20730_DEBUGFS_VOUT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = i2c_smbus_read_word_data(psu->client, PMBUS_VOUT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ret = VOLT_FROM_REG(ret * 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) len = scnprintf(tbuf, DEBUG_FS_DATA_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) "%d.%d\n", ret / 10000, ret % 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) len = strlcpy(tbuf, "Invalid\n", DEBUG_FS_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return simple_read_from_buffer(buf, count, ppos, tbuf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static const struct file_operations max20730_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .read = max20730_debugfs_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .write = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static int max20730_init_debugfs(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct max20730_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct dentry *debugfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct dentry *max20730_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct max20730_debugfs_data *psu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret = i2c_smbus_read_word_data(client, MAX20730_MFR_DEVSET2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) data->mfr_devset2 = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = i2c_smbus_read_word_data(client, MAX20730_MFR_VOUT_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) data->mfr_voutmin = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!psu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) psu->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) debugfs = pmbus_get_debugfs_dir(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!debugfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) max20730_dir = debugfs_create_dir(client->name, debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!max20730_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) for (i = 0; i < MAX20730_DEBUGFS_NUM_ENTRIES; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) psu->debugfs_entries[i] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) debugfs_create_file("vout_min", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MIN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) debugfs_create_file("frequency", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) &psu->debugfs_entries[MAX20730_DEBUGFS_FREQUENCY],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) debugfs_create_file("power_good_delay", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) &psu->debugfs_entries[MAX20730_DEBUGFS_PG_DELAY],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) debugfs_create_file("internal_gain", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) &psu->debugfs_entries[MAX20730_DEBUGFS_INTERNAL_GAIN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) debugfs_create_file("boot_voltage", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) &psu->debugfs_entries[MAX20730_DEBUGFS_BOOT_VOLTAGE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) debugfs_create_file("out_voltage_ramp_rate", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) &psu->debugfs_entries[MAX20730_DEBUGFS_OUT_V_RAMP_RATE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) debugfs_create_file("oc_protection_mode", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) &psu->debugfs_entries[MAX20730_DEBUGFS_OC_PROTECT_MODE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) debugfs_create_file("soft_start_timing", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) &psu->debugfs_entries[MAX20730_DEBUGFS_SS_TIMING],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) debugfs_create_file("imax", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) &psu->debugfs_entries[MAX20730_DEBUGFS_IMAX],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) debugfs_create_file("operation", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) &psu->debugfs_entries[MAX20730_DEBUGFS_OPERATION],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) debugfs_create_file("on_off_config", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) &psu->debugfs_entries[MAX20730_DEBUGFS_ON_OFF_CONFIG],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) debugfs_create_file("smbalert_mask", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) &psu->debugfs_entries[MAX20730_DEBUGFS_SMBALERT_MASK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) debugfs_create_file("vout_mode", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MODE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) debugfs_create_file("vout_command", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_COMMAND],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) debugfs_create_file("vout_max", 0444, max20730_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MAX],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) &max20730_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static int max20730_init_debugfs(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct max20730_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #endif /* CONFIG_DEBUG_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static const struct i2c_device_id max20730_id[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Convert discreet value to direct data format. Strictly speaking, all passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * values are constants, so we could do that calculation manually. On the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * downside, that would make the driver more difficult to maintain, so lets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * use this approach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static u16 val_to_direct(int v, enum pmbus_sensor_classes class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) const struct pmbus_driver_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int R = info->R[class] - 3; /* take milli-units into account */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int b = info->b[class] * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) long d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) d = v * info->m[class] + b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * R < 0 is true for all callers, so we don't need to bother
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * about the R > 0 case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) while (R < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) d = DIV_ROUND_CLOSEST(d, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) R++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return (u16)d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static long direct_to_val(u16 w, enum pmbus_sensor_classes class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) const struct pmbus_driver_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int R = info->R[class] - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int b = info->b[class] * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int m = info->m[class];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) long d = (s16)w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (m == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) while (R < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) d *= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) R++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) d = (d - b) / m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static u32 max_current[][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) [max20710] = { 6200, 8000, 9700, 11600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) [max20730] = { 13000, 16600, 20100, 23600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) [max20734] = { 21000, 27000, 32000, 38000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) [max20743] = { 18900, 24100, 29200, 34100 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int max20730_read_word_data(struct i2c_client *client, int page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int phase, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) const struct max20730_data *data = to_max20730_data(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) u32 max_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) case PMBUS_OT_FAULT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) switch ((data->mfr_devset1 >> 11) & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) case 0x0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ret = val_to_direct(150000, PSC_TEMPERATURE, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case 0x1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ret = val_to_direct(130000, PSC_TEMPERATURE, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) case PMBUS_IOUT_OC_FAULT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) max_c = max_current[data->id][(data->mfr_devset1 >> 5) & 0x3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ret = val_to_direct(max_c, PSC_CURRENT_OUT, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case PMBUS_READ_VOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ret = pmbus_read_word_data(client, page, phase, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (ret > 0 && data->vout_voltage_divider[0] && data->vout_voltage_divider[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u64 temp = DIV_ROUND_CLOSEST_ULL((u64)ret * data->vout_voltage_divider[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) data->vout_voltage_divider[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ret = clamp_val(temp, 0, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static int max20730_write_word_data(struct i2c_client *client, int page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int reg, u16 word)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct pmbus_driver_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct max20730_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u16 devset1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) info = (struct pmbus_driver_info *)pmbus_get_driver_info(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) data = to_max20730_data(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) devset1 = data->mfr_devset1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) case PMBUS_OT_FAULT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) devset1 &= ~(BIT(11) | BIT(12));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (direct_to_val(word, PSC_TEMPERATURE, info) < 140000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) devset1 |= BIT(11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) case PMBUS_IOUT_OC_FAULT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) devset1 &= ~(BIT(5) | BIT(6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) idx = find_closest(direct_to_val(word, PSC_CURRENT_OUT, info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) max_current[data->id], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) devset1 |= (idx << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (!ret && devset1 != data->mfr_devset1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ret = i2c_smbus_write_word_data(client, MAX20730_MFR_DEVSET1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) devset1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) data->mfr_devset1 = devset1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) pmbus_clear_cache(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static const struct pmbus_driver_info max20730_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) [max20710] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .pages = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .read_word_data = max20730_read_word_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .write_word_data = max20730_write_word_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* Source : Maxim AN6140 and AN6042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .format[PSC_TEMPERATURE] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .m[PSC_TEMPERATURE] = 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .b[PSC_TEMPERATURE] = 5887,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .R[PSC_TEMPERATURE] = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .format[PSC_VOLTAGE_IN] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .m[PSC_VOLTAGE_IN] = 3609,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .b[PSC_VOLTAGE_IN] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .R[PSC_VOLTAGE_IN] = -2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .format[PSC_CURRENT_OUT] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .m[PSC_CURRENT_OUT] = 153,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .b[PSC_CURRENT_OUT] = 4976,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .R[PSC_CURRENT_OUT] = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .format[PSC_VOLTAGE_OUT] = linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .func[0] = PMBUS_HAVE_VIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) PMBUS_HAVE_STATUS_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) [max20730] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .pages = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .read_word_data = max20730_read_word_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .write_word_data = max20730_write_word_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* Source : Maxim AN6042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .format[PSC_TEMPERATURE] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .m[PSC_TEMPERATURE] = 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .b[PSC_TEMPERATURE] = 5887,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .R[PSC_TEMPERATURE] = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .format[PSC_VOLTAGE_IN] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .m[PSC_VOLTAGE_IN] = 3609,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .b[PSC_VOLTAGE_IN] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .R[PSC_VOLTAGE_IN] = -2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * Values in the datasheet are adjusted for temperature and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * for the relationship between Vin and Vout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * Unfortunately, the data sheet suggests that Vout measurement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * may be scaled with a resistor array. This is indeed the case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * at least on the evaulation boards. As a result, any in-driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * adjustments would either be wrong or require elaborate means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * to configure the scaling. Instead of doing that, just report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * raw values and let userspace handle adjustments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) .format[PSC_CURRENT_OUT] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) .m[PSC_CURRENT_OUT] = 153,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) .b[PSC_CURRENT_OUT] = 4976,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .R[PSC_CURRENT_OUT] = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .format[PSC_VOLTAGE_OUT] = linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .func[0] = PMBUS_HAVE_VIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) PMBUS_HAVE_STATUS_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) [max20734] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .pages = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) .read_word_data = max20730_read_word_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .write_word_data = max20730_write_word_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /* Source : Maxim AN6209 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) .format[PSC_TEMPERATURE] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) .m[PSC_TEMPERATURE] = 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) .b[PSC_TEMPERATURE] = 5887,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .R[PSC_TEMPERATURE] = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) .format[PSC_VOLTAGE_IN] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) .m[PSC_VOLTAGE_IN] = 3592,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .b[PSC_VOLTAGE_IN] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .R[PSC_VOLTAGE_IN] = -2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .format[PSC_CURRENT_OUT] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .m[PSC_CURRENT_OUT] = 111,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .b[PSC_CURRENT_OUT] = 3461,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .R[PSC_CURRENT_OUT] = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .format[PSC_VOLTAGE_OUT] = linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .func[0] = PMBUS_HAVE_VIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) PMBUS_HAVE_STATUS_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) [max20743] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) .pages = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .read_word_data = max20730_read_word_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .write_word_data = max20730_write_word_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* Source : Maxim AN6042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .format[PSC_TEMPERATURE] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .m[PSC_TEMPERATURE] = 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .b[PSC_TEMPERATURE] = 5887,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .R[PSC_TEMPERATURE] = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .format[PSC_VOLTAGE_IN] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .m[PSC_VOLTAGE_IN] = 3597,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .b[PSC_VOLTAGE_IN] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .R[PSC_VOLTAGE_IN] = -2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .format[PSC_CURRENT_OUT] = direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .m[PSC_CURRENT_OUT] = 95,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) .b[PSC_CURRENT_OUT] = 5014,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) .R[PSC_CURRENT_OUT] = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) .format[PSC_VOLTAGE_OUT] = linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .func[0] = PMBUS_HAVE_VIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) PMBUS_HAVE_STATUS_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static int max20730_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct max20730_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) enum chips chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!i2c_check_functionality(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) I2C_FUNC_SMBUS_READ_BYTE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) I2C_FUNC_SMBUS_READ_WORD_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) I2C_FUNC_SMBUS_BLOCK_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dev_err(&client->dev, "Failed to read Manufacturer ID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ret != 5 || strncmp(buf, "MAXIM", 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) buf[ret] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) dev_err(dev, "Unsupported Manufacturer ID '%s'\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * The chips support reading PMBUS_MFR_MODEL. On both MAX20730
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * and MAX20734, reading it returns M20743. Presumably that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * the reason why the command is not documented. Unfortunately,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * that means that there is no reliable means to detect the chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * However, we can at least detect the chip series. Compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * the returned value against 'M20743' and bail out if there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * a mismatch. If that doesn't work for all chips, we may have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * to remove this check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dev_err(dev, "Failed to read Manufacturer Model\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (ret != 6 || strncmp(buf, "M20743", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) buf[ret] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) dev_err(dev, "Unsupported Manufacturer Model '%s'\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ret = i2c_smbus_read_block_data(client, PMBUS_MFR_REVISION, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) dev_err(dev, "Failed to read Manufacturer Revision\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (ret != 1 || buf[0] != 'F') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) buf[ret] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) dev_err(dev, "Unsupported Manufacturer Revision '%s'\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (client->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) chip_id = (enum chips)of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) chip_id = i2c_match_id(max20730_id, client)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) data->id = chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) memcpy(&data->info, &max20730_info[chip_id], sizeof(data->info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (of_property_read_u32_array(client->dev.of_node, "vout-voltage-divider",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) data->vout_voltage_divider,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ARRAY_SIZE(data->vout_voltage_divider)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) memset(data->vout_voltage_divider, 0, sizeof(data->vout_voltage_divider));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (data->vout_voltage_divider[1] < data->vout_voltage_divider[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) "The total resistance of voltage divider is less than output resistance\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ret = i2c_smbus_read_word_data(client, MAX20730_MFR_DEVSET1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) data->mfr_devset1 = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ret = pmbus_do_probe(client, &data->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ret = max20730_init_debugfs(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) dev_warn(dev, "Failed to register debugfs: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static const struct i2c_device_id max20730_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) { "max20710", max20710 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) { "max20730", max20730 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) { "max20734", max20734 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) { "max20743", max20743 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) MODULE_DEVICE_TABLE(i2c, max20730_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) static const struct of_device_id max20730_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) { .compatible = "maxim,max20710", .data = (void *)max20710 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) { .compatible = "maxim,max20730", .data = (void *)max20730 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) { .compatible = "maxim,max20734", .data = (void *)max20734 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) { .compatible = "maxim,max20743", .data = (void *)max20743 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) MODULE_DEVICE_TABLE(of, max20730_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static struct i2c_driver max20730_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) .name = "max20730",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) .of_match_table = max20730_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .probe_new = max20730_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) .remove = pmbus_do_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) .id_table = max20730_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) module_i2c_driver(max20730_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) MODULE_DESCRIPTION("PMBus driver for Maxim MAX20710 / MAX20730 / MAX20734 / MAX20743");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) MODULE_LICENSE("GPL");