1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2023, Linaro Ltd. All rights reserved.
4 */
5
6#include <linux/delay.h>
7#include <linux/err.h>
8#include <linux/interrupt.h>
9#include <linux/kernel.h>
10#include <linux/mod_devicetable.h>
11#include <linux/module.h>
12#include <linux/platform_device.h>
13#include <linux/regmap.h>
14#include <linux/regulator/consumer.h>
15#include <linux/slab.h>
16#include <linux/usb/tcpm.h>
17#include <linux/usb/typec_mux.h>
18#include <linux/workqueue.h>
19
20#include "qcom_pmic_typec.h"
21#include "qcom_pmic_typec_port.h"
22
23#define TYPEC_SNK_STATUS_REG 0x06
24#define DETECTED_SNK_TYPE_MASK GENMASK(6, 0)
25#define SNK_DAM_MASK GENMASK(6, 4)
26#define SNK_DAM_500MA BIT(6)
27#define SNK_DAM_1500MA BIT(5)
28#define SNK_DAM_3000MA BIT(4)
29#define SNK_RP_STD BIT(3)
30#define SNK_RP_1P5 BIT(2)
31#define SNK_RP_3P0 BIT(1)
32#define SNK_RP_SHORT BIT(0)
33
34#define TYPEC_SRC_STATUS_REG 0x08
35#define DETECTED_SRC_TYPE_MASK GENMASK(4, 0)
36#define SRC_HIGH_BATT BIT(5)
37#define SRC_DEBUG_ACCESS BIT(4)
38#define SRC_RD_OPEN BIT(3)
39#define SRC_RD_RA_VCONN BIT(2)
40#define SRC_RA_OPEN BIT(1)
41#define AUDIO_ACCESS_RA_RA BIT(0)
42
43#define TYPEC_STATE_MACHINE_STATUS_REG 0x09
44#define TYPEC_ATTACH_DETACH_STATE BIT(5)
45
46#define TYPEC_SM_STATUS_REG 0x0A
47#define TYPEC_SM_VBUS_VSAFE5V BIT(5)
48#define TYPEC_SM_VBUS_VSAFE0V BIT(6)
49#define TYPEC_SM_USBIN_LT_LV BIT(7)
50
51#define TYPEC_MISC_STATUS_REG 0x0B
52#define TYPEC_WATER_DETECTION_STATUS BIT(7)
53#define SNK_SRC_MODE BIT(6)
54#define TYPEC_VBUS_DETECT BIT(5)
55#define TYPEC_VBUS_ERROR_STATUS BIT(4)
56#define TYPEC_DEBOUNCE_DONE BIT(3)
57#define CC_ORIENTATION BIT(1)
58#define CC_ATTACHED BIT(0)
59
60#define LEGACY_CABLE_STATUS_REG 0x0D
61#define TYPEC_LEGACY_CABLE_STATUS BIT(1)
62#define TYPEC_NONCOMP_LEGACY_CABLE_STATUS BIT(0)
63
64#define TYPEC_U_USB_STATUS_REG 0x0F
65#define U_USB_GROUND_NOVBUS BIT(6)
66#define U_USB_GROUND BIT(4)
67#define U_USB_FMB1 BIT(3)
68#define U_USB_FLOAT1 BIT(2)
69#define U_USB_FMB2 BIT(1)
70#define U_USB_FLOAT2 BIT(0)
71
72#define TYPEC_MODE_CFG_REG 0x44
73#define TYPEC_TRY_MODE_MASK GENMASK(4, 3)
74#define EN_TRY_SNK BIT(4)
75#define EN_TRY_SRC BIT(3)
76#define TYPEC_POWER_ROLE_CMD_MASK GENMASK(2, 0)
77#define EN_SRC_ONLY BIT(2)
78#define EN_SNK_ONLY BIT(1)
79#define TYPEC_DISABLE_CMD BIT(0)
80
81#define TYPEC_VCONN_CONTROL_REG 0x46
82#define VCONN_EN_ORIENTATION BIT(2)
83#define VCONN_EN_VALUE BIT(1)
84#define VCONN_EN_SRC BIT(0)
85
86#define TYPEC_CCOUT_CONTROL_REG 0x48
87#define TYPEC_CCOUT_BUFFER_EN BIT(2)
88#define TYPEC_CCOUT_VALUE BIT(1)
89#define TYPEC_CCOUT_SRC BIT(0)
90
91#define DEBUG_ACCESS_SRC_CFG_REG 0x4C
92#define EN_UNORIENTED_DEBUG_ACCESS_SRC BIT(0)
93
94#define TYPE_C_CRUDE_SENSOR_CFG_REG 0x4e
95#define EN_SRC_CRUDE_SENSOR BIT(1)
96#define EN_SNK_CRUDE_SENSOR BIT(0)
97
98#define TYPEC_EXIT_STATE_CFG_REG 0x50
99#define BYPASS_VSAFE0V_DURING_ROLE_SWAP BIT(3)
100#define SEL_SRC_UPPER_REF BIT(2)
101#define USE_TPD_FOR_EXITING_ATTACHSRC BIT(1)
102#define EXIT_SNK_BASED_ON_CC BIT(0)
103
104#define TYPEC_CURRSRC_CFG_REG 0x52
105#define TYPEC_SRC_RP_SEL_330UA BIT(1)
106#define TYPEC_SRC_RP_SEL_180UA BIT(0)
107#define TYPEC_SRC_RP_SEL_80UA 0
108#define TYPEC_SRC_RP_SEL_MASK GENMASK(1, 0)
109
110#define TYPEC_INTERRUPT_EN_CFG_1_REG 0x5E
111#define TYPEC_LEGACY_CABLE_INT_EN BIT(7)
112#define TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN BIT(6)
113#define TYPEC_TRYSOURCE_DETECT_INT_EN BIT(5)
114#define TYPEC_TRYSINK_DETECT_INT_EN BIT(4)
115#define TYPEC_CCOUT_DETACH_INT_EN BIT(3)
116#define TYPEC_CCOUT_ATTACH_INT_EN BIT(2)
117#define TYPEC_VBUS_DEASSERT_INT_EN BIT(1)
118#define TYPEC_VBUS_ASSERT_INT_EN BIT(0)
119
120#define TYPEC_INTERRUPT_EN_CFG_2_REG 0x60
121#define TYPEC_SRC_BATT_HPWR_INT_EN BIT(6)
122#define MICRO_USB_STATE_CHANGE_INT_EN BIT(5)
123#define TYPEC_STATE_MACHINE_CHANGE_INT_EN BIT(4)
124#define TYPEC_DEBUG_ACCESS_DETECT_INT_EN BIT(3)
125#define TYPEC_WATER_DETECTION_INT_EN BIT(2)
126#define TYPEC_VBUS_ERROR_INT_EN BIT(1)
127#define TYPEC_DEBOUNCE_DONE_INT_EN BIT(0)
128
129#define TYPEC_DEBOUNCE_OPTION_REG 0x62
130#define REDUCE_TCCDEBOUNCE_TO_2MS BIT(2)
131
132#define TYPE_C_SBU_CFG_REG 0x6A
133#define SEL_SBU1_ISRC_VAL 0x04
134#define SEL_SBU2_ISRC_VAL 0x01
135
136#define TYPEC_U_USB_CFG_REG 0x70
137#define EN_MICRO_USB_FACTORY_MODE BIT(1)
138#define EN_MICRO_USB_MODE BIT(0)
139
140#define TYPEC_PMI632_U_USB_WATER_PROTECTION_CFG_REG 0x72
141
142#define TYPEC_U_USB_WATER_PROTECTION_CFG_REG 0x73
143#define EN_MICRO_USB_WATER_PROTECTION BIT(4)
144#define MICRO_USB_DETECTION_ON_TIME_CFG_MASK GENMASK(3, 2)
145#define MICRO_USB_DETECTION_PERIOD_CFG_MASK GENMASK(1, 0)
146
147#define TYPEC_PMI632_MICRO_USB_MODE_REG 0x73
148#define MICRO_USB_MODE_ONLY BIT(0)
149
150/* Interrupt numbers */
151#define PMIC_TYPEC_OR_RID_IRQ 0x0
152#define PMIC_TYPEC_VPD_IRQ 0x1
153#define PMIC_TYPEC_CC_STATE_IRQ 0x2
154#define PMIC_TYPEC_VCONN_OC_IRQ 0x3
155#define PMIC_TYPEC_VBUS_IRQ 0x4
156#define PMIC_TYPEC_ATTACH_DETACH_IRQ 0x5
157#define PMIC_TYPEC_LEGACY_CABLE_IRQ 0x6
158#define PMIC_TYPEC_TRY_SNK_SRC_IRQ 0x7
159
160struct pmic_typec_port_irq_data {
161 int virq;
162 int irq;
163 struct pmic_typec_port *pmic_typec_port;
164};
165
166struct pmic_typec_port {
167 struct device *dev;
168 struct tcpm_port *tcpm_port;
169 struct regmap *regmap;
170 u32 base;
171 unsigned int nr_irqs;
172 struct pmic_typec_port_irq_data *irq_data;
173
174 struct regulator *vdd_vbus;
175 bool vbus_enabled;
176 struct mutex vbus_lock; /* VBUS state serialization */
177
178 int cc;
179 bool debouncing_cc;
180 struct delayed_work cc_debounce_dwork;
181
182 spinlock_t lock; /* Register atomicity */
183};
184
185static const char * const typec_cc_status_name[] = {
186 [TYPEC_CC_OPEN] = "Open",
187 [TYPEC_CC_RA] = "Ra",
188 [TYPEC_CC_RD] = "Rd",
189 [TYPEC_CC_RP_DEF] = "Rp-def",
190 [TYPEC_CC_RP_1_5] = "Rp-1.5",
191 [TYPEC_CC_RP_3_0] = "Rp-3.0",
192};
193
194static const char *rp_unknown = "unknown";
195
196static const char *cc_to_name(enum typec_cc_status cc)
197{
198 if (cc > TYPEC_CC_RP_3_0)
199 return rp_unknown;
200
201 return typec_cc_status_name[cc];
202}
203
204static const char * const rp_sel_name[] = {
205 [TYPEC_SRC_RP_SEL_80UA] = "Rp-def-80uA",
206 [TYPEC_SRC_RP_SEL_180UA] = "Rp-1.5-180uA",
207 [TYPEC_SRC_RP_SEL_330UA] = "Rp-3.0-330uA",
208};
209
210static const char *rp_sel_to_name(int rp_sel)
211{
212 if (rp_sel > TYPEC_SRC_RP_SEL_330UA)
213 return rp_unknown;
214
215 return rp_sel_name[rp_sel];
216}
217
218#define misc_to_cc(msic) !!(misc & CC_ORIENTATION) ? "cc1" : "cc2"
219#define misc_to_vconn(msic) !!(misc & CC_ORIENTATION) ? "cc2" : "cc1"
220
221static void qcom_pmic_typec_port_cc_debounce(struct work_struct *work)
222{
223 struct pmic_typec_port *pmic_typec_port =
224 container_of(work, struct pmic_typec_port, cc_debounce_dwork.work);
225 unsigned long flags;
226
227 spin_lock_irqsave(&pmic_typec_port->lock, flags);
228 pmic_typec_port->debouncing_cc = false;
229 spin_unlock_irqrestore(lock: &pmic_typec_port->lock, flags);
230
231 dev_dbg(pmic_typec_port->dev, "Debounce cc complete\n");
232}
233
234static irqreturn_t pmic_typec_port_isr(int irq, void *dev_id)
235{
236 struct pmic_typec_port_irq_data *irq_data = dev_id;
237 struct pmic_typec_port *pmic_typec_port = irq_data->pmic_typec_port;
238 u32 misc_stat;
239 bool vbus_change = false;
240 bool cc_change = false;
241 unsigned long flags;
242 int ret;
243
244 spin_lock_irqsave(&pmic_typec_port->lock, flags);
245
246 ret = regmap_read(map: pmic_typec_port->regmap,
247 reg: pmic_typec_port->base + TYPEC_MISC_STATUS_REG,
248 val: &misc_stat);
249 if (ret)
250 goto done;
251
252 switch (irq_data->virq) {
253 case PMIC_TYPEC_VBUS_IRQ:
254 vbus_change = true;
255 break;
256 case PMIC_TYPEC_CC_STATE_IRQ:
257 case PMIC_TYPEC_ATTACH_DETACH_IRQ:
258 if (!pmic_typec_port->debouncing_cc)
259 cc_change = true;
260 break;
261 }
262
263done:
264 spin_unlock_irqrestore(lock: &pmic_typec_port->lock, flags);
265
266 if (vbus_change)
267 tcpm_vbus_change(port: pmic_typec_port->tcpm_port);
268
269 if (cc_change)
270 tcpm_cc_change(port: pmic_typec_port->tcpm_port);
271
272 return IRQ_HANDLED;
273}
274
275static int qcom_pmic_typec_port_vbus_detect(struct pmic_typec_port *pmic_typec_port)
276{
277 struct device *dev = pmic_typec_port->dev;
278 unsigned int misc;
279 int ret;
280
281 ret = regmap_read(map: pmic_typec_port->regmap,
282 reg: pmic_typec_port->base + TYPEC_MISC_STATUS_REG,
283 val: &misc);
284 if (ret)
285 misc = 0;
286
287 dev_dbg(dev, "get_vbus: 0x%08x detect %d\n", misc, !!(misc & TYPEC_VBUS_DETECT));
288
289 return !!(misc & TYPEC_VBUS_DETECT);
290}
291
292static int qcom_pmic_typec_port_vbus_toggle(struct pmic_typec_port *pmic_typec_port, bool on)
293{
294 u32 sm_stat;
295 u32 val;
296 int ret;
297
298 if (on) {
299 ret = regulator_enable(regulator: pmic_typec_port->vdd_vbus);
300 if (ret)
301 return ret;
302
303 val = TYPEC_SM_VBUS_VSAFE5V;
304 } else {
305 ret = regulator_disable(regulator: pmic_typec_port->vdd_vbus);
306 if (ret)
307 return ret;
308
309 val = TYPEC_SM_VBUS_VSAFE0V;
310 }
311
312 /* Poll waiting for transition to required vSafe5V or vSafe0V */
313 ret = regmap_read_poll_timeout(pmic_typec_port->regmap,
314 pmic_typec_port->base + TYPEC_SM_STATUS_REG,
315 sm_stat, sm_stat & val,
316 100, 250000);
317 if (ret)
318 dev_warn(pmic_typec_port->dev, "vbus vsafe%dv fail\n", on ? 5 : 0);
319
320 return 0;
321}
322
323static int qcom_pmic_typec_port_get_vbus(struct tcpc_dev *tcpc)
324{
325 struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
326 struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
327 int ret;
328
329 mutex_lock(&pmic_typec_port->vbus_lock);
330 ret = pmic_typec_port->vbus_enabled || qcom_pmic_typec_port_vbus_detect(pmic_typec_port);
331 mutex_unlock(lock: &pmic_typec_port->vbus_lock);
332
333 return ret;
334}
335
336static int qcom_pmic_typec_port_set_vbus(struct tcpc_dev *tcpc, bool on, bool sink)
337{
338 struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
339 struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
340 int ret = 0;
341
342 mutex_lock(&pmic_typec_port->vbus_lock);
343 if (pmic_typec_port->vbus_enabled == on)
344 goto done;
345
346 ret = qcom_pmic_typec_port_vbus_toggle(pmic_typec_port, on);
347 if (ret)
348 goto done;
349
350 pmic_typec_port->vbus_enabled = on;
351 tcpm_vbus_change(port: tcpm->tcpm_port);
352
353done:
354 dev_dbg(tcpm->dev, "set_vbus set: %d result %d\n", on, ret);
355 mutex_unlock(lock: &pmic_typec_port->vbus_lock);
356
357 return ret;
358}
359
360static int qcom_pmic_typec_port_get_cc(struct tcpc_dev *tcpc,
361 enum typec_cc_status *cc1,
362 enum typec_cc_status *cc2)
363{
364 struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
365 struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
366 struct device *dev = pmic_typec_port->dev;
367 unsigned int misc, val;
368 bool attached;
369 int ret = 0;
370
371 ret = regmap_read(map: pmic_typec_port->regmap,
372 reg: pmic_typec_port->base + TYPEC_MISC_STATUS_REG, val: &misc);
373 if (ret)
374 goto done;
375
376 attached = !!(misc & CC_ATTACHED);
377
378 if (pmic_typec_port->debouncing_cc) {
379 ret = -EBUSY;
380 goto done;
381 }
382
383 *cc1 = TYPEC_CC_OPEN;
384 *cc2 = TYPEC_CC_OPEN;
385
386 if (!attached)
387 goto done;
388
389 if (misc & SNK_SRC_MODE) {
390 ret = regmap_read(map: pmic_typec_port->regmap,
391 reg: pmic_typec_port->base + TYPEC_SRC_STATUS_REG,
392 val: &val);
393 if (ret)
394 goto done;
395 switch (val & DETECTED_SRC_TYPE_MASK) {
396 case AUDIO_ACCESS_RA_RA:
397 val = TYPEC_CC_RA;
398 *cc1 = TYPEC_CC_RA;
399 *cc2 = TYPEC_CC_RA;
400 break;
401 case SRC_RD_OPEN:
402 val = TYPEC_CC_RD;
403 break;
404 case SRC_RD_RA_VCONN:
405 val = TYPEC_CC_RD;
406 *cc1 = TYPEC_CC_RA;
407 *cc2 = TYPEC_CC_RA;
408 break;
409 default:
410 dev_warn(dev, "unexpected src status %.2x\n", val);
411 val = TYPEC_CC_RD;
412 break;
413 }
414 } else {
415 ret = regmap_read(map: pmic_typec_port->regmap,
416 reg: pmic_typec_port->base + TYPEC_SNK_STATUS_REG,
417 val: &val);
418 if (ret)
419 goto done;
420 switch (val & DETECTED_SNK_TYPE_MASK) {
421 case SNK_RP_STD:
422 val = TYPEC_CC_RP_DEF;
423 break;
424 case SNK_RP_1P5:
425 val = TYPEC_CC_RP_1_5;
426 break;
427 case SNK_RP_3P0:
428 val = TYPEC_CC_RP_3_0;
429 break;
430 default:
431 dev_warn(dev, "unexpected snk status %.2x\n", val);
432 val = TYPEC_CC_RP_DEF;
433 break;
434 }
435 val = TYPEC_CC_RP_DEF;
436 }
437
438 if (misc & CC_ORIENTATION)
439 *cc2 = val;
440 else
441 *cc1 = val;
442
443done:
444 dev_dbg(dev, "get_cc: misc 0x%08x cc1 0x%08x %s cc2 0x%08x %s attached %d cc=%s\n",
445 misc, *cc1, cc_to_name(*cc1), *cc2, cc_to_name(*cc2), attached,
446 misc_to_cc(misc));
447
448 return ret;
449}
450
451static void qcom_pmic_set_cc_debounce(struct pmic_typec_port *pmic_typec_port)
452{
453 pmic_typec_port->debouncing_cc = true;
454 schedule_delayed_work(dwork: &pmic_typec_port->cc_debounce_dwork,
455 delay: msecs_to_jiffies(m: 2));
456}
457
458static int qcom_pmic_typec_port_set_cc(struct tcpc_dev *tcpc,
459 enum typec_cc_status cc)
460{
461 struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
462 struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
463 struct device *dev = pmic_typec_port->dev;
464 unsigned int mode, currsrc;
465 unsigned int misc;
466 unsigned long flags;
467 int ret;
468
469 spin_lock_irqsave(&pmic_typec_port->lock, flags);
470
471 ret = regmap_read(map: pmic_typec_port->regmap,
472 reg: pmic_typec_port->base + TYPEC_MISC_STATUS_REG,
473 val: &misc);
474 if (ret)
475 goto done;
476
477 mode = EN_SRC_ONLY;
478
479 switch (cc) {
480 case TYPEC_CC_OPEN:
481 currsrc = TYPEC_SRC_RP_SEL_80UA;
482 break;
483 case TYPEC_CC_RP_DEF:
484 currsrc = TYPEC_SRC_RP_SEL_80UA;
485 break;
486 case TYPEC_CC_RP_1_5:
487 currsrc = TYPEC_SRC_RP_SEL_180UA;
488 break;
489 case TYPEC_CC_RP_3_0:
490 currsrc = TYPEC_SRC_RP_SEL_330UA;
491 break;
492 case TYPEC_CC_RD:
493 currsrc = TYPEC_SRC_RP_SEL_80UA;
494 mode = EN_SNK_ONLY;
495 break;
496 default:
497 dev_warn(dev, "unexpected set_cc %d\n", cc);
498 ret = -EINVAL;
499 goto done;
500 }
501
502 if (mode == EN_SRC_ONLY) {
503 ret = regmap_write(map: pmic_typec_port->regmap,
504 reg: pmic_typec_port->base + TYPEC_CURRSRC_CFG_REG,
505 val: currsrc);
506 if (ret)
507 goto done;
508 }
509
510 pmic_typec_port->cc = cc;
511 qcom_pmic_set_cc_debounce(pmic_typec_port);
512 ret = 0;
513
514done:
515 spin_unlock_irqrestore(lock: &pmic_typec_port->lock, flags);
516
517 dev_dbg(dev, "set_cc: currsrc=%x %s mode %s debounce %d attached %d cc=%s\n",
518 currsrc, rp_sel_to_name(currsrc),
519 mode == EN_SRC_ONLY ? "EN_SRC_ONLY" : "EN_SNK_ONLY",
520 pmic_typec_port->debouncing_cc, !!(misc & CC_ATTACHED),
521 misc_to_cc(misc));
522
523 return ret;
524}
525
526static int qcom_pmic_typec_port_set_polarity(struct tcpc_dev *tcpc,
527 enum typec_cc_polarity pol)
528{
529 /* Polarity is set separately by phy-qcom-qmp.c */
530 return 0;
531}
532
533static int qcom_pmic_typec_port_set_vconn(struct tcpc_dev *tcpc, bool on)
534{
535 struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
536 struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
537 struct device *dev = pmic_typec_port->dev;
538 unsigned int orientation, misc, mask, value;
539 unsigned long flags;
540 int ret;
541
542 spin_lock_irqsave(&pmic_typec_port->lock, flags);
543
544 ret = regmap_read(map: pmic_typec_port->regmap,
545 reg: pmic_typec_port->base + TYPEC_MISC_STATUS_REG, val: &misc);
546 if (ret)
547 goto done;
548
549 /* Set VCONN on the inversion of the active CC channel */
550 orientation = (misc & CC_ORIENTATION) ? 0 : VCONN_EN_ORIENTATION;
551 if (on) {
552 mask = VCONN_EN_ORIENTATION | VCONN_EN_VALUE;
553 value = orientation | VCONN_EN_VALUE | VCONN_EN_SRC;
554 } else {
555 mask = VCONN_EN_VALUE;
556 value = 0;
557 }
558
559 ret = regmap_update_bits(map: pmic_typec_port->regmap,
560 reg: pmic_typec_port->base + TYPEC_VCONN_CONTROL_REG,
561 mask, val: value);
562done:
563 spin_unlock_irqrestore(lock: &pmic_typec_port->lock, flags);
564
565 dev_dbg(dev, "set_vconn: orientation %d control 0x%08x state %s cc %s vconn %s\n",
566 orientation, value, on ? "on" : "off", misc_to_vconn(misc), misc_to_cc(misc));
567
568 return ret;
569}
570
571static int qcom_pmic_typec_port_start_toggling(struct tcpc_dev *tcpc,
572 enum typec_port_type port_type,
573 enum typec_cc_status cc)
574{
575 struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
576 struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
577 struct device *dev = pmic_typec_port->dev;
578 unsigned int misc;
579 u8 mode = 0;
580 unsigned long flags;
581 int ret;
582
583 switch (port_type) {
584 case TYPEC_PORT_SRC:
585 mode = EN_SRC_ONLY;
586 break;
587 case TYPEC_PORT_SNK:
588 mode = EN_SNK_ONLY;
589 break;
590 case TYPEC_PORT_DRP:
591 mode = EN_TRY_SNK;
592 break;
593 }
594
595 spin_lock_irqsave(&pmic_typec_port->lock, flags);
596
597 ret = regmap_read(map: pmic_typec_port->regmap,
598 reg: pmic_typec_port->base + TYPEC_MISC_STATUS_REG, val: &misc);
599 if (ret)
600 goto done;
601
602 dev_dbg(dev, "start_toggling: misc 0x%08x attached %d port_type %d current cc %d new %d\n",
603 misc, !!(misc & CC_ATTACHED), port_type, pmic_typec_port->cc, cc);
604
605 qcom_pmic_set_cc_debounce(pmic_typec_port);
606
607 /* force it to toggle at least once */
608 ret = regmap_write(map: pmic_typec_port->regmap,
609 reg: pmic_typec_port->base + TYPEC_MODE_CFG_REG,
610 TYPEC_DISABLE_CMD);
611 if (ret)
612 goto done;
613
614 ret = regmap_write(map: pmic_typec_port->regmap,
615 reg: pmic_typec_port->base + TYPEC_MODE_CFG_REG,
616 val: mode);
617done:
618 spin_unlock_irqrestore(lock: &pmic_typec_port->lock, flags);
619
620 return ret;
621}
622
623#define TYPEC_INTR_EN_CFG_1_MASK \
624 (TYPEC_LEGACY_CABLE_INT_EN | \
625 TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN | \
626 TYPEC_TRYSOURCE_DETECT_INT_EN | \
627 TYPEC_TRYSINK_DETECT_INT_EN | \
628 TYPEC_CCOUT_DETACH_INT_EN | \
629 TYPEC_CCOUT_ATTACH_INT_EN | \
630 TYPEC_VBUS_DEASSERT_INT_EN | \
631 TYPEC_VBUS_ASSERT_INT_EN)
632
633#define TYPEC_INTR_EN_CFG_2_MASK \
634 (TYPEC_STATE_MACHINE_CHANGE_INT_EN | TYPEC_VBUS_ERROR_INT_EN | \
635 TYPEC_DEBOUNCE_DONE_INT_EN)
636
637static int qcom_pmic_typec_port_start(struct pmic_typec *tcpm,
638 struct tcpm_port *tcpm_port)
639{
640 struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
641 int i;
642 int mask;
643 int ret;
644
645 /* Configure interrupt sources */
646 ret = regmap_write(map: pmic_typec_port->regmap,
647 reg: pmic_typec_port->base + TYPEC_INTERRUPT_EN_CFG_1_REG,
648 TYPEC_INTR_EN_CFG_1_MASK);
649 if (ret)
650 goto done;
651
652 ret = regmap_write(map: pmic_typec_port->regmap,
653 reg: pmic_typec_port->base + TYPEC_INTERRUPT_EN_CFG_2_REG,
654 TYPEC_INTR_EN_CFG_2_MASK);
655 if (ret)
656 goto done;
657
658 /* start in TRY_SNK mode */
659 ret = regmap_write(map: pmic_typec_port->regmap,
660 reg: pmic_typec_port->base + TYPEC_MODE_CFG_REG, EN_TRY_SNK);
661 if (ret)
662 goto done;
663
664 /* Configure VCONN for software control */
665 ret = regmap_update_bits(map: pmic_typec_port->regmap,
666 reg: pmic_typec_port->base + TYPEC_VCONN_CONTROL_REG,
667 VCONN_EN_SRC | VCONN_EN_VALUE, VCONN_EN_SRC);
668 if (ret)
669 goto done;
670
671 /* Set CC threshold to 1.6 Volts | tPDdebounce = 10-20ms */
672 mask = SEL_SRC_UPPER_REF | USE_TPD_FOR_EXITING_ATTACHSRC;
673 ret = regmap_update_bits(map: pmic_typec_port->regmap,
674 reg: pmic_typec_port->base + TYPEC_EXIT_STATE_CFG_REG,
675 mask, val: mask);
676 if (ret)
677 goto done;
678
679 pmic_typec_port->tcpm_port = tcpm_port;
680
681 for (i = 0; i < pmic_typec_port->nr_irqs; i++)
682 enable_irq(irq: pmic_typec_port->irq_data[i].irq);
683
684done:
685 return ret;
686}
687
688static void qcom_pmic_typec_port_stop(struct pmic_typec *tcpm)
689{
690 struct pmic_typec_port *pmic_typec_port = tcpm->pmic_typec_port;
691 int i;
692
693 for (i = 0; i < pmic_typec_port->nr_irqs; i++)
694 disable_irq(irq: pmic_typec_port->irq_data[i].irq);
695}
696
697int qcom_pmic_typec_port_probe(struct platform_device *pdev,
698 struct pmic_typec *tcpm,
699 const struct pmic_typec_port_resources *res,
700 struct regmap *regmap,
701 u32 base)
702{
703 struct device *dev = &pdev->dev;
704 struct pmic_typec_port_irq_data *irq_data;
705 struct pmic_typec_port *pmic_typec_port;
706 int i, ret, irq;
707
708 pmic_typec_port = devm_kzalloc(dev, size: sizeof(*pmic_typec_port), GFP_KERNEL);
709 if (!pmic_typec_port)
710 return -ENOMEM;
711
712 if (!res->nr_irqs || res->nr_irqs > PMIC_TYPEC_MAX_IRQS)
713 return -EINVAL;
714
715 irq_data = devm_kzalloc(dev, size: sizeof(*irq_data) * res->nr_irqs,
716 GFP_KERNEL);
717 if (!irq_data)
718 return -ENOMEM;
719
720 mutex_init(&pmic_typec_port->vbus_lock);
721
722 pmic_typec_port->vdd_vbus = devm_regulator_get(dev, id: "vdd-vbus");
723 if (IS_ERR(ptr: pmic_typec_port->vdd_vbus))
724 return PTR_ERR(ptr: pmic_typec_port->vdd_vbus);
725
726 pmic_typec_port->dev = dev;
727 pmic_typec_port->base = base;
728 pmic_typec_port->regmap = regmap;
729 pmic_typec_port->nr_irqs = res->nr_irqs;
730 pmic_typec_port->irq_data = irq_data;
731 spin_lock_init(&pmic_typec_port->lock);
732 INIT_DELAYED_WORK(&pmic_typec_port->cc_debounce_dwork,
733 qcom_pmic_typec_port_cc_debounce);
734
735 irq = platform_get_irq(pdev, 0);
736 if (irq < 0)
737 return irq;
738
739 for (i = 0; i < res->nr_irqs; i++, irq_data++) {
740 irq = platform_get_irq_byname(pdev,
741 res->irq_params[i].irq_name);
742 if (irq < 0)
743 return irq;
744
745 irq_data->pmic_typec_port = pmic_typec_port;
746 irq_data->irq = irq;
747 irq_data->virq = res->irq_params[i].virq;
748 ret = devm_request_threaded_irq(dev, irq, NULL, thread_fn: pmic_typec_port_isr,
749 IRQF_ONESHOT | IRQF_NO_AUTOEN,
750 devname: res->irq_params[i].irq_name,
751 dev_id: irq_data);
752 if (ret)
753 return ret;
754 }
755
756 tcpm->pmic_typec_port = pmic_typec_port;
757
758 tcpm->tcpc.get_vbus = qcom_pmic_typec_port_get_vbus;
759 tcpm->tcpc.set_vbus = qcom_pmic_typec_port_set_vbus;
760 tcpm->tcpc.set_cc = qcom_pmic_typec_port_set_cc;
761 tcpm->tcpc.get_cc = qcom_pmic_typec_port_get_cc;
762 tcpm->tcpc.set_polarity = qcom_pmic_typec_port_set_polarity;
763 tcpm->tcpc.set_vconn = qcom_pmic_typec_port_set_vconn;
764 tcpm->tcpc.start_toggling = qcom_pmic_typec_port_start_toggling;
765
766 tcpm->port_start = qcom_pmic_typec_port_start;
767 tcpm->port_stop = qcom_pmic_typec_port_stop;
768
769 return 0;
770}
771
772const struct pmic_typec_port_resources pm8150b_port_res = {
773 .irq_params = {
774 {
775 .irq_name = "vpd-detect",
776 .virq = PMIC_TYPEC_VPD_IRQ,
777 },
778
779 {
780 .irq_name = "cc-state-change",
781 .virq = PMIC_TYPEC_CC_STATE_IRQ,
782 },
783 {
784 .irq_name = "vconn-oc",
785 .virq = PMIC_TYPEC_VCONN_OC_IRQ,
786 },
787
788 {
789 .irq_name = "vbus-change",
790 .virq = PMIC_TYPEC_VBUS_IRQ,
791 },
792
793 {
794 .irq_name = "attach-detach",
795 .virq = PMIC_TYPEC_ATTACH_DETACH_IRQ,
796 },
797 {
798 .irq_name = "legacy-cable-detect",
799 .virq = PMIC_TYPEC_LEGACY_CABLE_IRQ,
800 },
801
802 {
803 .irq_name = "try-snk-src-detect",
804 .virq = PMIC_TYPEC_TRY_SNK_SRC_IRQ,
805 },
806 },
807 .nr_irqs = 7,
808};
809

source code of linux/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c