forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/hwmon/pmbus/tps53679.c
....@@ -1,26 +1,25 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Hardware monitoring driver for Texas Instruments TPS53679
34 *
45 * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
56 * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
167 */
178
9
+#include <linux/bits.h>
1810 #include <linux/err.h>
1911 #include <linux/i2c.h>
2012 #include <linux/init.h>
2113 #include <linux/kernel.h>
2214 #include <linux/module.h>
15
+#include <linux/of_device.h>
2316 #include "pmbus.h"
17
+
18
+enum chips {
19
+ tps53647, tps53667, tps53679, tps53681, tps53688
20
+};
21
+
22
+#define TPS53647_PAGE_NUM 1
2423
2524 #define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */
2625 #define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */
....@@ -29,76 +28,219 @@
2928 #define TPS53679_PROT_VR13_5MV 0x07 /* VR13.0 mode, 5-mV DAC */
3029 #define TPS53679_PAGE_NUM 2
3130
32
-static int tps53679_identify(struct i2c_client *client,
33
- struct pmbus_driver_info *info)
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)
3441 {
3542 u8 vout_params;
36
- int ret;
43
+ int i, ret;
3744
38
- /* Read the register with VOUT scaling value.*/
39
- ret = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
40
- if (ret < 0)
41
- return ret;
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;
4250
43
- vout_params = ret & GENMASK(4, 0);
51
+ vout_params = ret & GENMASK(4, 0);
4452
45
- switch (vout_params) {
46
- case TPS53679_PROT_VR13_10MV:
47
- case TPS53679_PROT_VR12_5_10MV:
48
- info->vrm_version = vr13;
49
- break;
50
- case TPS53679_PROT_VR13_5MV:
51
- case TPS53679_PROT_VR12_5MV:
52
- case TPS53679_PROT_IMVP8_5MV:
53
- info->vrm_version = vr12;
54
- break;
55
- default:
56
- return -EINVAL;
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
+ }
5766 }
5867
5968 return 0;
6069 }
6170
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
+
62164 static struct pmbus_driver_info tps53679_info = {
63
- .pages = TPS53679_PAGE_NUM,
64165 .format[PSC_VOLTAGE_IN] = linear,
65166 .format[PSC_VOLTAGE_OUT] = vid,
66167 .format[PSC_TEMPERATURE] = linear,
67168 .format[PSC_CURRENT_OUT] = linear,
68169 .format[PSC_POWER] = linear,
69
- .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
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 |
70173 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
71174 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
72175 PMBUS_HAVE_POUT,
73
- .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
176
+ .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
74177 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
75178 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
76179 PMBUS_HAVE_POUT,
77
- .identify = tps53679_identify,
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,
78186 };
79187
80
-static int tps53679_probe(struct i2c_client *client,
81
- const struct i2c_device_id *id)
188
+static int tps53679_probe(struct i2c_client *client)
82189 {
190
+ struct device *dev = &client->dev;
83191 struct pmbus_driver_info *info;
192
+ enum chips chip_id;
84193
85
- info = devm_kmemdup(&client->dev, &tps53679_info, sizeof(*info),
86
- GFP_KERNEL);
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);
87200 if (!info)
88201 return -ENOMEM;
89202
90
- return pmbus_do_probe(client, id, info);
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);
91225 }
92226
93227 static const struct i2c_device_id tps53679_id[] = {
94
- {"tps53679", 0},
228
+ {"tps53647", tps53647},
229
+ {"tps53667", tps53667},
230
+ {"tps53679", tps53679},
231
+ {"tps53681", tps53681},
232
+ {"tps53688", tps53688},
95233 {}
96234 };
97235
98236 MODULE_DEVICE_TABLE(i2c, tps53679_id);
99237
100
-static const struct of_device_id tps53679_of_match[] = {
101
- {.compatible = "ti,tps53679"},
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},
102244 {}
103245 };
104246 MODULE_DEVICE_TABLE(of, tps53679_of_match);
....@@ -108,7 +250,7 @@
108250 .name = "tps53679",
109251 .of_match_table = of_match_ptr(tps53679_of_match),
110252 },
111
- .probe = tps53679_probe,
253
+ .probe_new = tps53679_probe,
112254 .remove = pmbus_do_remove,
113255 .id_table = tps53679_id,
114256 };