1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Hardware monitoring driver for Texas Instruments TPS53679
5 * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
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>
19 tps53647
, tps53667
, tps53676
, tps53679
, tps53681
, tps53688
22 #define TPS53647_PAGE_NUM 1
24 #define TPS53676_USER_DATA_03 0xb3
25 #define TPS53676_MAX_PHASES 7
27 #define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */
28 #define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */
29 #define TPS53679_PROT_VR13_10MV 0x04 /* VR13.0 mode, 10-mV DAC */
30 #define TPS53679_PROT_IMVP8_5MV 0x05 /* IMVP8 mode, 5-mV DAC */
31 #define TPS53679_PROT_VR13_5MV 0x07 /* VR13.0 mode, 5-mV DAC */
32 #define TPS53679_PAGE_NUM 2
34 #define TPS53681_DEVICE_ID 0x81
36 #define TPS53681_PMBUS_REVISION 0x33
38 #define TPS53681_MFR_SPECIFIC_20 0xe4 /* Number of phases, per page */
40 static const struct i2c_device_id tps53679_id
[];
42 static int tps53679_identify_mode(struct i2c_client
*client
,
43 struct pmbus_driver_info
*info
)
48 for (i
= 0; i
< info
->pages
; i
++) {
49 /* Read the register with VOUT scaling value.*/
50 ret
= pmbus_read_byte_data(client
, i
, PMBUS_VOUT_MODE
);
54 vout_params
= ret
& GENMASK(4, 0);
56 switch (vout_params
) {
57 case TPS53679_PROT_VR13_10MV
:
58 case TPS53679_PROT_VR12_5_10MV
:
59 info
->vrm_version
[i
] = vr13
;
61 case TPS53679_PROT_VR13_5MV
:
62 case TPS53679_PROT_VR12_5MV
:
63 case TPS53679_PROT_IMVP8_5MV
:
64 info
->vrm_version
[i
] = vr12
;
74 static int tps53679_identify_phases(struct i2c_client
*client
,
75 struct pmbus_driver_info
*info
)
79 /* On TPS53681, only channel A provides per-phase output current */
80 ret
= pmbus_read_byte_data(client
, 0, TPS53681_MFR_SPECIFIC_20
);
83 info
->phases
[0] = (ret
& 0x07) + 1;
88 static int tps53679_identify_chip(struct i2c_client
*client
,
91 u8 buf
[I2C_SMBUS_BLOCK_MAX
];
94 ret
= pmbus_read_byte_data(client
, 0, PMBUS_REVISION
);
97 if (ret
!= revision
) {
98 dev_err(&client
->dev
, "Unexpected PMBus revision 0x%x\n", ret
);
102 ret
= i2c_smbus_read_block_data(client
, PMBUS_IC_DEVICE_ID
, buf
);
105 if (ret
!= 1 || buf
[0] != id
) {
106 dev_err(&client
->dev
, "Unexpected device ID 0x%x\n", buf
[0]);
113 * Common identification function for chips with multi-phase support.
114 * Since those chips have special configuration registers, we want to have
115 * some level of reassurance that we are really talking with the chip
116 * being probed. Check PMBus revision and chip ID.
118 static int tps53679_identify_multiphase(struct i2c_client
*client
,
119 struct pmbus_driver_info
*info
,
120 int pmbus_rev
, int device_id
)
124 ret
= tps53679_identify_chip(client
, pmbus_rev
, device_id
);
128 ret
= tps53679_identify_mode(client
, info
);
132 return tps53679_identify_phases(client
, info
);
135 static int tps53679_identify(struct i2c_client
*client
,
136 struct pmbus_driver_info
*info
)
138 return tps53679_identify_mode(client
, info
);
141 static int tps53681_identify(struct i2c_client
*client
,
142 struct pmbus_driver_info
*info
)
144 return tps53679_identify_multiphase(client
, info
,
145 TPS53681_PMBUS_REVISION
,
149 static int tps53676_identify(struct i2c_client
*client
,
150 struct pmbus_driver_info
*info
)
152 u8 buf
[I2C_SMBUS_BLOCK_MAX
];
153 int phases_a
= 0, phases_b
= 0;
156 ret
= i2c_smbus_read_block_data(client
, PMBUS_IC_DEVICE_ID
, buf
);
159 if (strncmp("TI\x53\x67\x60", buf
, 5)) {
160 dev_err(&client
->dev
, "Unexpected device ID: %s\n", buf
);
164 ret
= i2c_smbus_read_block_data(client
, TPS53676_USER_DATA_03
, buf
);
169 for (i
= 0; i
< 2 * TPS53676_MAX_PHASES
; i
+= 2) {
170 if (buf
[i
+ 1] & 0x80) {
178 info
->format
[PSC_VOLTAGE_OUT
] = linear
;
180 info
->phases
[0] = phases_a
;
183 info
->phases
[1] = phases_b
;
188 static int tps53681_read_word_data(struct i2c_client
*client
, int page
,
192 * For reading the total output current (READ_IOUT) for all phases,
193 * the chip datasheet is a bit vague. It says "PHASE must be set to
194 * FFh to access all phases simultaneously. PHASE may also be set to
195 * 80h readack (!) the total phase current".
196 * Experiments show that the command does _not_ report the total
197 * current for all phases if the phase is set to 0xff. Instead, it
198 * appears to report the current of one of the phases. Override phase
199 * parameter with 0x80 when reading the total output current on page 0.
201 if (reg
== PMBUS_READ_IOUT
&& page
== 0 && phase
== 0xff)
202 return pmbus_read_word_data(client
, page
, 0x80, reg
);
206 static struct pmbus_driver_info tps53679_info
= {
207 .format
[PSC_VOLTAGE_IN
] = linear
,
208 .format
[PSC_VOLTAGE_OUT
] = vid
,
209 .format
[PSC_TEMPERATURE
] = linear
,
210 .format
[PSC_CURRENT_OUT
] = linear
,
211 .format
[PSC_POWER
] = linear
,
212 .func
[0] = PMBUS_HAVE_VIN
| PMBUS_HAVE_IIN
| PMBUS_HAVE_PIN
|
213 PMBUS_HAVE_STATUS_INPUT
|
214 PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
|
215 PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
|
216 PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
|
218 .func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
|
219 PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
|
220 PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
|
222 .pfunc
[0] = PMBUS_HAVE_IOUT
,
223 .pfunc
[1] = PMBUS_HAVE_IOUT
,
224 .pfunc
[2] = PMBUS_HAVE_IOUT
,
225 .pfunc
[3] = PMBUS_HAVE_IOUT
,
226 .pfunc
[4] = PMBUS_HAVE_IOUT
,
227 .pfunc
[5] = PMBUS_HAVE_IOUT
,
228 .pfunc
[6] = PMBUS_HAVE_IOUT
,
231 static int tps53679_probe(struct i2c_client
*client
)
233 struct device
*dev
= &client
->dev
;
234 struct pmbus_driver_info
*info
;
238 chip_id
= (uintptr_t)of_device_get_match_data(dev
);
240 chip_id
= i2c_match_id(tps53679_id
, client
)->driver_data
;
242 info
= devm_kmemdup(dev
, &tps53679_info
, sizeof(*info
), GFP_KERNEL
);
249 info
->pages
= TPS53647_PAGE_NUM
;
250 info
->identify
= tps53679_identify
;
253 info
->identify
= tps53676_identify
;
257 info
->pages
= TPS53679_PAGE_NUM
;
258 info
->identify
= tps53679_identify
;
261 info
->pages
= TPS53679_PAGE_NUM
;
263 info
->identify
= tps53681_identify
;
264 info
->read_word_data
= tps53681_read_word_data
;
270 return pmbus_do_probe(client
, info
);
273 static const struct i2c_device_id tps53679_id
[] = {
274 {"bmr474", tps53676
},
275 {"tps53647", tps53647
},
276 {"tps53667", tps53667
},
277 {"tps53676", tps53676
},
278 {"tps53679", tps53679
},
279 {"tps53681", tps53681
},
280 {"tps53688", tps53688
},
284 MODULE_DEVICE_TABLE(i2c
, tps53679_id
);
286 static const struct of_device_id __maybe_unused tps53679_of_match
[] = {
287 {.compatible
= "ti,tps53647", .data
= (void *)tps53647
},
288 {.compatible
= "ti,tps53667", .data
= (void *)tps53667
},
289 {.compatible
= "ti,tps53676", .data
= (void *)tps53676
},
290 {.compatible
= "ti,tps53679", .data
= (void *)tps53679
},
291 {.compatible
= "ti,tps53681", .data
= (void *)tps53681
},
292 {.compatible
= "ti,tps53688", .data
= (void *)tps53688
},
295 MODULE_DEVICE_TABLE(of
, tps53679_of_match
);
297 static struct i2c_driver tps53679_driver
= {
300 .of_match_table
= of_match_ptr(tps53679_of_match
),
302 .probe
= tps53679_probe
,
303 .id_table
= tps53679_id
,
306 module_i2c_driver(tps53679_driver
);
308 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
309 MODULE_DESCRIPTION("PMBus driver for Texas Instruments TPS53679");
310 MODULE_LICENSE("GPL");
311 MODULE_IMPORT_NS(PMBUS
);