1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Hardware monitoring driver for Texas Instruments TPS53679 4 * 5 * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 6 * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com> 7 */ 8 9 #include <linux/bits.h> 10 #include <linux/err.h> 11 #include <linux/i2c.h> 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/of_device.h> 16 #include "pmbus.h" 17 18 enum chips { 19 tps53647, tps53667, tps53679, tps53681, tps53688 20 }; 21 22 #define TPS53647_PAGE_NUM 1 23 24 #define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */ 25 #define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */ 26 #define TPS53679_PROT_VR13_10MV 0x04 /* VR13.0 mode, 10-mV DAC */ 27 #define TPS53679_PROT_IMVP8_5MV 0x05 /* IMVP8 mode, 5-mV DAC */ 28 #define TPS53679_PROT_VR13_5MV 0x07 /* VR13.0 mode, 5-mV DAC */ 29 #define TPS53679_PAGE_NUM 2 30 31 #define TPS53681_DEVICE_ID 0x81 32 33 #define TPS53681_PMBUS_REVISION 0x33 34 35 #define TPS53681_MFR_SPECIFIC_20 0xe4 /* Number of phases, per page */ 36 37 static const struct i2c_device_id tps53679_id[]; 38 39 static int tps53679_identify_mode(struct i2c_client *client, 40 struct pmbus_driver_info *info) 41 { 42 u8 vout_params; 43 int i, ret; 44 45 for (i = 0; i < info->pages; i++) { 46 /* Read the register with VOUT scaling value.*/ 47 ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); 48 if (ret < 0) 49 return ret; 50 51 vout_params = ret & GENMASK(4, 0); 52 53 switch (vout_params) { 54 case TPS53679_PROT_VR13_10MV: 55 case TPS53679_PROT_VR12_5_10MV: 56 info->vrm_version[i] = vr13; 57 break; 58 case TPS53679_PROT_VR13_5MV: 59 case TPS53679_PROT_VR12_5MV: 60 case TPS53679_PROT_IMVP8_5MV: 61 info->vrm_version[i] = vr12; 62 break; 63 default: 64 return -EINVAL; 65 } 66 } 67 68 return 0; 69 } 70 71 static int tps53679_identify_phases(struct i2c_client *client, 72 struct pmbus_driver_info *info) 73 { 74 int ret; 75 76 /* On TPS53681, only channel A provides per-phase output current */ 77 ret = pmbus_read_byte_data(client, 0, TPS53681_MFR_SPECIFIC_20); 78 if (ret < 0) 79 return ret; 80 info->phases[0] = (ret & 0x07) + 1; 81 82 return 0; 83 } 84 85 static int tps53679_identify_chip(struct i2c_client *client, 86 u8 revision, u16 id) 87 { 88 u8 buf[I2C_SMBUS_BLOCK_MAX]; 89 int ret; 90 91 ret = pmbus_read_byte_data(client, 0, PMBUS_REVISION); 92 if (ret < 0) 93 return ret; 94 if (ret != revision) { 95 dev_err(&client->dev, "Unexpected PMBus revision 0x%x\n", ret); 96 return -ENODEV; 97 } 98 99 ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf); 100 if (ret < 0) 101 return ret; 102 if (ret != 1 || buf[0] != id) { 103 dev_err(&client->dev, "Unexpected device ID 0x%x\n", buf[0]); 104 return -ENODEV; 105 } 106 return 0; 107 } 108 109 /* 110 * Common identification function for chips with multi-phase support. 111 * Since those chips have special configuration registers, we want to have 112 * some level of reassurance that we are really talking with the chip 113 * being probed. Check PMBus revision and chip ID. 114 */ 115 static int tps53679_identify_multiphase(struct i2c_client *client, 116 struct pmbus_driver_info *info, 117 int pmbus_rev, int device_id) 118 { 119 int ret; 120 121 ret = tps53679_identify_chip(client, pmbus_rev, device_id); 122 if (ret < 0) 123 return ret; 124 125 ret = tps53679_identify_mode(client, info); 126 if (ret < 0) 127 return ret; 128 129 return tps53679_identify_phases(client, info); 130 } 131 132 static int tps53679_identify(struct i2c_client *client, 133 struct pmbus_driver_info *info) 134 { 135 return tps53679_identify_mode(client, info); 136 } 137 138 static int tps53681_identify(struct i2c_client *client, 139 struct pmbus_driver_info *info) 140 { 141 return tps53679_identify_multiphase(client, info, 142 TPS53681_PMBUS_REVISION, 143 TPS53681_DEVICE_ID); 144 } 145 146 static int tps53681_read_word_data(struct i2c_client *client, int page, 147 int phase, int reg) 148 { 149 /* 150 * For reading the total output current (READ_IOUT) for all phases, 151 * the chip datasheet is a bit vague. It says "PHASE must be set to 152 * FFh to access all phases simultaneously. PHASE may also be set to 153 * 80h readack (!) the total phase current". 154 * Experiments show that the command does _not_ report the total 155 * current for all phases if the phase is set to 0xff. Instead, it 156 * appears to report the current of one of the phases. Override phase 157 * parameter with 0x80 when reading the total output current on page 0. 158 */ 159 if (reg == PMBUS_READ_IOUT && page == 0 && phase == 0xff) 160 return pmbus_read_word_data(client, page, 0x80, reg); 161 return -ENODATA; 162 } 163 164 static struct pmbus_driver_info tps53679_info = { 165 .format[PSC_VOLTAGE_IN] = linear, 166 .format[PSC_VOLTAGE_OUT] = vid, 167 .format[PSC_TEMPERATURE] = linear, 168 .format[PSC_CURRENT_OUT] = linear, 169 .format[PSC_POWER] = linear, 170 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | 171 PMBUS_HAVE_STATUS_INPUT | 172 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 173 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 174 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 175 PMBUS_HAVE_POUT, 176 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 177 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 178 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 179 PMBUS_HAVE_POUT, 180 .pfunc[0] = PMBUS_HAVE_IOUT, 181 .pfunc[1] = PMBUS_HAVE_IOUT, 182 .pfunc[2] = PMBUS_HAVE_IOUT, 183 .pfunc[3] = PMBUS_HAVE_IOUT, 184 .pfunc[4] = PMBUS_HAVE_IOUT, 185 .pfunc[5] = PMBUS_HAVE_IOUT, 186 }; 187 188 static int tps53679_probe(struct i2c_client *client) 189 { 190 struct device *dev = &client->dev; 191 struct pmbus_driver_info *info; 192 enum chips chip_id; 193 194 if (dev->of_node) 195 chip_id = (enum chips)of_device_get_match_data(dev); 196 else 197 chip_id = i2c_match_id(tps53679_id, client)->driver_data; 198 199 info = devm_kmemdup(dev, &tps53679_info, sizeof(*info), GFP_KERNEL); 200 if (!info) 201 return -ENOMEM; 202 203 switch (chip_id) { 204 case tps53647: 205 case tps53667: 206 info->pages = TPS53647_PAGE_NUM; 207 info->identify = tps53679_identify; 208 break; 209 case tps53679: 210 case tps53688: 211 info->pages = TPS53679_PAGE_NUM; 212 info->identify = tps53679_identify; 213 break; 214 case tps53681: 215 info->pages = TPS53679_PAGE_NUM; 216 info->phases[0] = 6; 217 info->identify = tps53681_identify; 218 info->read_word_data = tps53681_read_word_data; 219 break; 220 default: 221 return -ENODEV; 222 } 223 224 return pmbus_do_probe(client, info); 225 } 226 227 static const struct i2c_device_id tps53679_id[] = { 228 {"tps53647", tps53647}, 229 {"tps53667", tps53667}, 230 {"tps53679", tps53679}, 231 {"tps53681", tps53681}, 232 {"tps53688", tps53688}, 233 {} 234 }; 235 236 MODULE_DEVICE_TABLE(i2c, tps53679_id); 237 238 static const struct of_device_id __maybe_unused tps53679_of_match[] = { 239 {.compatible = "ti,tps53647", .data = (void *)tps53647}, 240 {.compatible = "ti,tps53667", .data = (void *)tps53667}, 241 {.compatible = "ti,tps53679", .data = (void *)tps53679}, 242 {.compatible = "ti,tps53681", .data = (void *)tps53681}, 243 {.compatible = "ti,tps53688", .data = (void *)tps53688}, 244 {} 245 }; 246 MODULE_DEVICE_TABLE(of, tps53679_of_match); 247 248 static struct i2c_driver tps53679_driver = { 249 .driver = { 250 .name = "tps53679", 251 .of_match_table = of_match_ptr(tps53679_of_match), 252 }, 253 .probe_new = tps53679_probe, 254 .remove = pmbus_do_remove, 255 .id_table = tps53679_id, 256 }; 257 258 module_i2c_driver(tps53679_driver); 259 260 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>"); 261 MODULE_DESCRIPTION("PMBus driver for Texas Instruments TPS53679"); 262 MODULE_LICENSE("GPL"); 263