1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright 2022 Google, Inc
4 *
5 * USB-C module to reduce wakeups due to contaminants.
6 */
7
8 #include <linux/bitfield.h>
9 #include <linux/device.h>
10 #include <linux/irqreturn.h>
11 #include <linux/module.h>
12 #include <linux/regmap.h>
13 #include <linux/usb/tcpci.h>
14 #include <linux/usb/tcpm.h>
15 #include <linux/usb/typec.h>
16
17 #include "tcpci_maxim.h"
18
19 enum fladc_select {
20 CC1_SCALE1 = 1,
21 CC1_SCALE2,
22 CC2_SCALE1,
23 CC2_SCALE2,
24 SBU1,
25 SBU2,
26 };
27
28 #define FLADC_1uA_LSB_MV 25
29 /* High range CC */
30 #define FLADC_CC_HIGH_RANGE_LSB_MV 208
31 /* Low range CC */
32 #define FLADC_CC_LOW_RANGE_LSB_MV 126
33
34 /* 1uA current source */
35 #define FLADC_CC_SCALE1 1
36 /* 5 uA current source */
37 #define FLADC_CC_SCALE2 5
38
39 #define FLADC_1uA_CC_OFFSET_MV 300
40 #define FLADC_CC_HIGH_RANGE_OFFSET_MV 624
41 #define FLADC_CC_LOW_RANGE_OFFSET_MV 378
42
43 #define CONTAMINANT_THRESHOLD_SBU_K 1000
44 #define CONTAMINANT_THRESHOLD_CC_K 1000
45
46 #define READ1_SLEEP_MS 10
47 #define READ2_SLEEP_MS 5
48
49 #define IS_CC_OPEN(cc_status) \
50 (FIELD_GET(TCPC_CC_STATUS_CC1, cc_status) == TCPC_CC_STATE_SRC_OPEN \
51 && FIELD_GET(TCPC_CC_STATUS_CC2, cc_status) == TCPC_CC_STATE_SRC_OPEN)
52
max_contaminant_adc_to_mv(struct max_tcpci_chip * chip,enum fladc_select channel,bool ua_src,u8 fladc)53 static int max_contaminant_adc_to_mv(struct max_tcpci_chip *chip, enum fladc_select channel,
54 bool ua_src, u8 fladc)
55 {
56 /* SBU channels only have 1 scale with 1uA. */
57 if ((ua_src && (channel == CC1_SCALE2 || channel == CC2_SCALE2 || channel == SBU1 ||
58 channel == SBU2)))
59 /* Mean of range */
60 return FLADC_1uA_CC_OFFSET_MV + (fladc * FLADC_1uA_LSB_MV);
61 else if (!ua_src && (channel == CC1_SCALE1 || channel == CC2_SCALE1))
62 return FLADC_CC_HIGH_RANGE_OFFSET_MV + (fladc * FLADC_CC_HIGH_RANGE_LSB_MV);
63 else if (!ua_src && (channel == CC1_SCALE2 || channel == CC2_SCALE2))
64 return FLADC_CC_LOW_RANGE_OFFSET_MV + (fladc * FLADC_CC_LOW_RANGE_LSB_MV);
65
66 dev_err_once(chip->dev, "ADC ERROR: SCALE UNKNOWN");
67
68 return -EINVAL;
69 }
70
max_contaminant_read_adc_mv(struct max_tcpci_chip * chip,enum fladc_select channel,int sleep_msec,bool raw,bool ua_src)71 static int max_contaminant_read_adc_mv(struct max_tcpci_chip *chip, enum fladc_select channel,
72 int sleep_msec, bool raw, bool ua_src)
73 {
74 struct regmap *regmap = chip->data.regmap;
75 u8 fladc;
76 int ret;
77
78 /* Channel & scale select */
79 ret = regmap_update_bits(regmap, TCPC_VENDOR_ADC_CTRL1, ADCINSEL,
80 FIELD_PREP(ADCINSEL, channel));
81 if (ret < 0)
82 return ret;
83
84 /* Enable ADC */
85 ret = regmap_update_bits(regmap, TCPC_VENDOR_ADC_CTRL1, ADCEN, ADCEN);
86 if (ret < 0)
87 return ret;
88
89 usleep_range(sleep_msec * 1000, (sleep_msec + 1) * 1000);
90 ret = max_tcpci_read8(chip, TCPC_VENDOR_FLADC_STATUS, &fladc);
91 if (ret < 0)
92 return ret;
93
94 /* Disable ADC */
95 ret = regmap_update_bits(regmap, TCPC_VENDOR_ADC_CTRL1, ADCEN, 0);
96 if (ret < 0)
97 return ret;
98
99 ret = regmap_update_bits(regmap, TCPC_VENDOR_ADC_CTRL1, ADCINSEL,
100 FIELD_PREP(ADCINSEL, 0));
101 if (ret < 0)
102 return ret;
103
104 if (!raw)
105 return max_contaminant_adc_to_mv(chip, channel, ua_src, fladc);
106 else
107 return fladc;
108 }
109
max_contaminant_read_resistance_kohm(struct max_tcpci_chip * chip,enum fladc_select channel,int sleep_msec,bool raw)110 static int max_contaminant_read_resistance_kohm(struct max_tcpci_chip *chip,
111 enum fladc_select channel, int sleep_msec, bool raw)
112 {
113 struct regmap *regmap = chip->data.regmap;
114 int mv;
115 int ret;
116
117 if (channel == CC1_SCALE1 || channel == CC2_SCALE1 || channel == CC1_SCALE2 ||
118 channel == CC2_SCALE2) {
119 /* Enable 1uA current source */
120 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
121 FIELD_PREP(CCLPMODESEL, ULTRA_LOW_POWER_MODE));
122 if (ret < 0)
123 return ret;
124
125 /* Enable 1uA current source */
126 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCRPCTRL,
127 FIELD_PREP(CCRPCTRL, UA_1_SRC));
128 if (ret < 0)
129 return ret;
130
131 /* OVP disable */
132 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCOVPDIS, CCOVPDIS);
133 if (ret < 0)
134 return ret;
135
136 mv = max_contaminant_read_adc_mv(chip, channel, sleep_msec, raw, true);
137 if (mv < 0)
138 return mv;
139
140 /* OVP enable */
141 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCOVPDIS, 0);
142 if (ret < 0)
143 return ret;
144 /* returns KOhm as 1uA source is used. */
145 return mv;
146 }
147
148 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, SBUOVPDIS, SBUOVPDIS);
149 if (ret < 0)
150 return ret;
151
152 /* SBU switches auto configure when channel is selected. */
153 /* Enable 1ua current source */
154 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, SBURPCTRL, SBURPCTRL);
155 if (ret < 0)
156 return ret;
157
158 mv = max_contaminant_read_adc_mv(chip, channel, sleep_msec, raw, true);
159 if (mv < 0)
160 return mv;
161 /* Disable current source */
162 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, SBURPCTRL, 0);
163 if (ret < 0)
164 return ret;
165
166 /* OVP disable */
167 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, SBUOVPDIS, 0);
168 if (ret < 0)
169 return ret;
170
171 return mv;
172 }
173
max_contaminant_read_comparators(struct max_tcpci_chip * chip,u8 * vendor_cc_status2_cc1,u8 * vendor_cc_status2_cc2)174 static int max_contaminant_read_comparators(struct max_tcpci_chip *chip, u8 *vendor_cc_status2_cc1,
175 u8 *vendor_cc_status2_cc2)
176 {
177 struct regmap *regmap = chip->data.regmap;
178 int ret;
179
180 /* Enable 80uA source */
181 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCRPCTRL,
182 FIELD_PREP(CCRPCTRL, UA_80_SRC));
183 if (ret < 0)
184 return ret;
185
186 /* Enable comparators */
187 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCOMPEN, CCCOMPEN);
188 if (ret < 0)
189 return ret;
190
191 /* Disable low power mode */
192 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
193 FIELD_PREP(CCLPMODESEL,
194 LOW_POWER_MODE_DISABLE));
195
196 /* Sleep to allow comparators settle */
197 usleep_range(5000, 6000);
198 ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_ORIENTATION, PLUG_ORNT_CC1);
199 if (ret < 0)
200 return ret;
201
202 usleep_range(5000, 6000);
203 ret = max_tcpci_read8(chip, VENDOR_CC_STATUS2, vendor_cc_status2_cc1);
204 if (ret < 0)
205 return ret;
206
207 ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_ORIENTATION, PLUG_ORNT_CC2);
208 if (ret < 0)
209 return ret;
210
211 usleep_range(5000, 6000);
212 ret = max_tcpci_read8(chip, VENDOR_CC_STATUS2, vendor_cc_status2_cc2);
213 if (ret < 0)
214 return ret;
215
216 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCOMPEN, 0);
217 if (ret < 0)
218 return ret;
219
220 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCRPCTRL,
221 FIELD_PREP(CCRPCTRL, 0));
222 if (ret < 0)
223 return ret;
224
225 return 0;
226 }
227
max_contaminant_detect_contaminant(struct max_tcpci_chip * chip)228 static int max_contaminant_detect_contaminant(struct max_tcpci_chip *chip)
229 {
230 int cc1_k, cc2_k, sbu1_k, sbu2_k, ret;
231 u8 vendor_cc_status2_cc1 = 0xff, vendor_cc_status2_cc2 = 0xff;
232 u8 role_ctrl = 0, role_ctrl_backup = 0;
233 int inferred_state = NOT_DETECTED;
234
235 ret = max_tcpci_read8(chip, TCPC_ROLE_CTRL, &role_ctrl);
236 if (ret < 0)
237 return NOT_DETECTED;
238
239 role_ctrl_backup = role_ctrl;
240 role_ctrl = 0x0F;
241 ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, role_ctrl);
242 if (ret < 0)
243 return NOT_DETECTED;
244
245 cc1_k = max_contaminant_read_resistance_kohm(chip, CC1_SCALE2, READ1_SLEEP_MS, false);
246 if (cc1_k < 0)
247 goto exit;
248
249 cc2_k = max_contaminant_read_resistance_kohm(chip, CC2_SCALE2, READ2_SLEEP_MS, false);
250 if (cc2_k < 0)
251 goto exit;
252
253 sbu1_k = max_contaminant_read_resistance_kohm(chip, SBU1, READ1_SLEEP_MS, false);
254 if (sbu1_k < 0)
255 goto exit;
256
257 sbu2_k = max_contaminant_read_resistance_kohm(chip, SBU2, READ2_SLEEP_MS, false);
258 if (sbu2_k < 0)
259 goto exit;
260
261 ret = max_contaminant_read_comparators(chip, &vendor_cc_status2_cc1,
262 &vendor_cc_status2_cc2);
263
264 if (ret < 0)
265 goto exit;
266
267 if ((!(CC1_VUFP_RD0P5 & vendor_cc_status2_cc1) ||
268 !(CC2_VUFP_RD0P5 & vendor_cc_status2_cc2)) &&
269 !(CC1_VUFP_RD0P5 & vendor_cc_status2_cc1 && CC2_VUFP_RD0P5 & vendor_cc_status2_cc2))
270 inferred_state = SINK;
271 else if ((cc1_k < CONTAMINANT_THRESHOLD_CC_K || cc2_k < CONTAMINANT_THRESHOLD_CC_K) &&
272 (sbu1_k < CONTAMINANT_THRESHOLD_SBU_K || sbu2_k < CONTAMINANT_THRESHOLD_SBU_K))
273 inferred_state = DETECTED;
274
275 if (inferred_state == NOT_DETECTED)
276 max_tcpci_write8(chip, TCPC_ROLE_CTRL, role_ctrl_backup);
277 else
278 max_tcpci_write8(chip, TCPC_ROLE_CTRL, (TCPC_ROLE_CTRL_DRP | 0xA));
279
280 return inferred_state;
281 exit:
282 max_tcpci_write8(chip, TCPC_ROLE_CTRL, role_ctrl_backup);
283 return NOT_DETECTED;
284 }
285
max_contaminant_enable_dry_detection(struct max_tcpci_chip * chip)286 static int max_contaminant_enable_dry_detection(struct max_tcpci_chip *chip)
287 {
288 struct regmap *regmap = chip->data.regmap;
289 u8 temp;
290 int ret;
291
292 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL3,
293 CCWTRDEB | CCWTRSEL | WTRCYCLE,
294 FIELD_PREP(CCWTRDEB, CCWTRDEB_1MS)
295 | FIELD_PREP(CCWTRSEL, CCWTRSEL_1V)
296 | FIELD_PREP(WTRCYCLE, WTRCYCLE_4_8_S));
297 if (ret < 0)
298 return ret;
299
300 ret = regmap_update_bits(regmap, TCPC_ROLE_CTRL, TCPC_ROLE_CTRL_DRP, TCPC_ROLE_CTRL_DRP);
301 if (ret < 0)
302 return ret;
303
304 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCONNDRY, CCCONNDRY);
305 if (ret < 0)
306 return ret;
307 ret = max_tcpci_read8(chip, TCPC_VENDOR_CC_CTRL1, &temp);
308 if (ret < 0)
309 return ret;
310
311 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
312 FIELD_PREP(CCLPMODESEL,
313 ULTRA_LOW_POWER_MODE));
314 if (ret < 0)
315 return ret;
316 ret = max_tcpci_read8(chip, TCPC_VENDOR_CC_CTRL2, &temp);
317 if (ret < 0)
318 return ret;
319
320 /* Enable Look4Connection before sending the command */
321 ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_EN_LK4CONN_ALRT,
322 TCPC_TCPC_CTRL_EN_LK4CONN_ALRT);
323 if (ret < 0)
324 return ret;
325
326 ret = max_tcpci_write8(chip, TCPC_COMMAND, TCPC_CMD_LOOK4CONNECTION);
327 if (ret < 0)
328 return ret;
329 return 0;
330 }
331
max_contaminant_enable_toggling(struct max_tcpci_chip * chip)332 static int max_contaminant_enable_toggling(struct max_tcpci_chip *chip)
333 {
334 struct regmap *regmap = chip->data.regmap;
335 int ret;
336
337 /* Disable dry detection if enabled. */
338 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
339 FIELD_PREP(CCLPMODESEL,
340 LOW_POWER_MODE_DISABLE));
341 if (ret)
342 return ret;
343
344 ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCONNDRY, 0);
345 if (ret)
346 return ret;
347
348 ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, TCPC_ROLE_CTRL_DRP |
349 FIELD_PREP(TCPC_ROLE_CTRL_CC1,
350 TCPC_ROLE_CTRL_CC_RD) |
351 FIELD_PREP(TCPC_ROLE_CTRL_CC2,
352 TCPC_ROLE_CTRL_CC_RD));
353 if (ret)
354 return ret;
355
356 ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL,
357 TCPC_TCPC_CTRL_EN_LK4CONN_ALRT,
358 TCPC_TCPC_CTRL_EN_LK4CONN_ALRT);
359 if (ret)
360 return ret;
361
362 return max_tcpci_write8(chip, TCPC_COMMAND, TCPC_CMD_LOOK4CONNECTION);
363 }
364
max_contaminant_is_contaminant(struct max_tcpci_chip * chip,bool disconnect_while_debounce,bool * cc_handled)365 bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect_while_debounce,
366 bool *cc_handled)
367 {
368 u8 cc_status, pwr_cntl;
369 int ret;
370
371 *cc_handled = true;
372
373 ret = max_tcpci_read8(chip, TCPC_CC_STATUS, &cc_status);
374 if (ret < 0)
375 return false;
376
377 ret = max_tcpci_read8(chip, TCPC_POWER_CTRL, &pwr_cntl);
378 if (ret < 0)
379 return false;
380
381 if (cc_status & TCPC_CC_STATUS_TOGGLING) {
382 if (chip->contaminant_state == DETECTED)
383 return true;
384 return false;
385 }
386
387 if (chip->contaminant_state == NOT_DETECTED || chip->contaminant_state == SINK) {
388 if (!disconnect_while_debounce)
389 msleep(100);
390
391 ret = max_tcpci_read8(chip, TCPC_CC_STATUS, &cc_status);
392 if (ret < 0)
393 return false;
394
395 if (IS_CC_OPEN(cc_status)) {
396 u8 role_ctrl, role_ctrl_backup;
397
398 ret = max_tcpci_read8(chip, TCPC_ROLE_CTRL, &role_ctrl);
399 if (ret < 0)
400 return false;
401
402 role_ctrl_backup = role_ctrl;
403 role_ctrl |= 0x0F;
404 role_ctrl &= ~(TCPC_ROLE_CTRL_DRP);
405 ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, role_ctrl);
406 if (ret < 0)
407 return false;
408
409 chip->contaminant_state = max_contaminant_detect_contaminant(chip);
410
411 ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, role_ctrl_backup);
412 if (ret < 0)
413 return false;
414
415 if (chip->contaminant_state == DETECTED) {
416 max_contaminant_enable_dry_detection(chip);
417 return true;
418 }
419
420 ret = max_contaminant_enable_toggling(chip);
421 if (ret)
422 dev_err(chip->dev,
423 "Failed to enable toggling, ret=%d",
424 ret);
425 }
426 } else if (chip->contaminant_state == DETECTED) {
427 if (!(cc_status & TCPC_CC_STATUS_TOGGLING)) {
428 chip->contaminant_state = max_contaminant_detect_contaminant(chip);
429 if (chip->contaminant_state == DETECTED) {
430 max_contaminant_enable_dry_detection(chip);
431 return true;
432 } else {
433 ret = max_contaminant_enable_toggling(chip);
434 if (ret) {
435 dev_err(chip->dev,
436 "Failed to enable toggling, ret=%d",
437 ret);
438 return true;
439 }
440 }
441 }
442 }
443
444 *cc_handled = false;
445 return false;
446 }
447
448 MODULE_DESCRIPTION("MAXIM TCPC CONTAMINANT Module");
449 MODULE_AUTHOR("Badhri Jagan Sridharan <badhri@google.com>");
450 MODULE_LICENSE("GPL");
451