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/of_device.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15 #include <linux/regulator/consumer.h>
16 #include <linux/slab.h>
17 #include <linux/usb/tcpm.h>
18 #include <linux/usb/typec_mux.h>
19 #include <linux/workqueue.h>
20 #include "qcom_pmic_typec_port.h"
21 
22 struct pmic_typec_port_irq_data {
23 	int				virq;
24 	int				irq;
25 	struct pmic_typec_port		*pmic_typec_port;
26 };
27 
28 struct pmic_typec_port {
29 	struct device			*dev;
30 	struct tcpm_port		*tcpm_port;
31 	struct regmap			*regmap;
32 	u32				base;
33 	unsigned int			nr_irqs;
34 	struct pmic_typec_port_irq_data	*irq_data;
35 
36 	struct regulator		*vdd_vbus;
37 
38 	int				cc;
39 	bool				debouncing_cc;
40 	struct delayed_work		cc_debounce_dwork;
41 
42 	spinlock_t			lock;	/* Register atomicity */
43 };
44 
45 static const char * const typec_cc_status_name[] = {
46 	[TYPEC_CC_OPEN]		= "Open",
47 	[TYPEC_CC_RA]		= "Ra",
48 	[TYPEC_CC_RD]		= "Rd",
49 	[TYPEC_CC_RP_DEF]	= "Rp-def",
50 	[TYPEC_CC_RP_1_5]	= "Rp-1.5",
51 	[TYPEC_CC_RP_3_0]	= "Rp-3.0",
52 };
53 
54 static const char *rp_unknown = "unknown";
55 
56 static const char *cc_to_name(enum typec_cc_status cc)
57 {
58 	if (cc > TYPEC_CC_RP_3_0)
59 		return rp_unknown;
60 
61 	return typec_cc_status_name[cc];
62 }
63 
64 static const char * const rp_sel_name[] = {
65 	[TYPEC_SRC_RP_SEL_80UA]		= "Rp-def-80uA",
66 	[TYPEC_SRC_RP_SEL_180UA]	= "Rp-1.5-180uA",
67 	[TYPEC_SRC_RP_SEL_330UA]	= "Rp-3.0-330uA",
68 };
69 
70 static const char *rp_sel_to_name(int rp_sel)
71 {
72 	if (rp_sel > TYPEC_SRC_RP_SEL_330UA)
73 		return rp_unknown;
74 
75 	return rp_sel_name[rp_sel];
76 }
77 
78 #define misc_to_cc(msic) !!(misc & CC_ORIENTATION) ? "cc1" : "cc2"
79 #define misc_to_vconn(msic) !!(misc & CC_ORIENTATION) ? "cc2" : "cc1"
80 
81 static void qcom_pmic_typec_port_cc_debounce(struct work_struct *work)
82 {
83 	struct pmic_typec_port *pmic_typec_port =
84 		container_of(work, struct pmic_typec_port, cc_debounce_dwork.work);
85 	unsigned long flags;
86 
87 	spin_lock_irqsave(&pmic_typec_port->lock, flags);
88 	pmic_typec_port->debouncing_cc = false;
89 	spin_unlock_irqrestore(&pmic_typec_port->lock, flags);
90 
91 	dev_dbg(pmic_typec_port->dev, "Debounce cc complete\n");
92 }
93 
94 static irqreturn_t pmic_typec_port_isr(int irq, void *dev_id)
95 {
96 	struct pmic_typec_port_irq_data *irq_data = dev_id;
97 	struct pmic_typec_port *pmic_typec_port = irq_data->pmic_typec_port;
98 	u32 misc_stat;
99 	bool vbus_change = false;
100 	bool cc_change = false;
101 	unsigned long flags;
102 	int ret;
103 
104 	spin_lock_irqsave(&pmic_typec_port->lock, flags);
105 
106 	ret = regmap_read(pmic_typec_port->regmap,
107 			  pmic_typec_port->base + TYPEC_MISC_STATUS_REG,
108 			  &misc_stat);
109 	if (ret)
110 		goto done;
111 
112 	switch (irq_data->virq) {
113 	case PMIC_TYPEC_VBUS_IRQ:
114 		vbus_change = true;
115 		break;
116 	case PMIC_TYPEC_CC_STATE_IRQ:
117 	case PMIC_TYPEC_ATTACH_DETACH_IRQ:
118 		if (!pmic_typec_port->debouncing_cc)
119 			cc_change = true;
120 		break;
121 	}
122 
123 done:
124 	spin_unlock_irqrestore(&pmic_typec_port->lock, flags);
125 
126 	if (vbus_change)
127 		tcpm_vbus_change(pmic_typec_port->tcpm_port);
128 
129 	if (cc_change)
130 		tcpm_cc_change(pmic_typec_port->tcpm_port);
131 
132 	return IRQ_HANDLED;
133 }
134 
135 int qcom_pmic_typec_port_get_vbus(struct pmic_typec_port *pmic_typec_port)
136 {
137 	struct device *dev = pmic_typec_port->dev;
138 	unsigned int misc;
139 	int ret;
140 
141 	ret = regmap_read(pmic_typec_port->regmap,
142 			  pmic_typec_port->base + TYPEC_MISC_STATUS_REG,
143 			  &misc);
144 	if (ret)
145 		misc = 0;
146 
147 	dev_dbg(dev, "get_vbus: 0x%08x detect %d\n", misc, !!(misc & TYPEC_VBUS_DETECT));
148 
149 	return !!(misc & TYPEC_VBUS_DETECT);
150 }
151 
152 int qcom_pmic_typec_port_set_vbus(struct pmic_typec_port *pmic_typec_port, bool on)
153 {
154 	u32 sm_stat;
155 	u32 val;
156 	int ret;
157 
158 	if (on) {
159 		ret = regulator_enable(pmic_typec_port->vdd_vbus);
160 		if (ret)
161 			return ret;
162 
163 		val = TYPEC_SM_VBUS_VSAFE5V;
164 	} else {
165 		ret = regulator_disable(pmic_typec_port->vdd_vbus);
166 		if (ret)
167 			return ret;
168 
169 		val = TYPEC_SM_VBUS_VSAFE0V;
170 	}
171 
172 	/* Poll waiting for transition to required vSafe5V or vSafe0V */
173 	ret = regmap_read_poll_timeout(pmic_typec_port->regmap,
174 				       pmic_typec_port->base + TYPEC_SM_STATUS_REG,
175 				       sm_stat, sm_stat & val,
176 				       100, 250000);
177 	if (ret)
178 		dev_warn(pmic_typec_port->dev, "vbus vsafe%dv fail\n", on ? 5 : 0);
179 
180 	return 0;
181 }
182 
183 int qcom_pmic_typec_port_get_cc(struct pmic_typec_port *pmic_typec_port,
184 				enum typec_cc_status *cc1,
185 				enum typec_cc_status *cc2)
186 {
187 	struct device *dev = pmic_typec_port->dev;
188 	unsigned int misc, val;
189 	bool attached;
190 	int ret = 0;
191 
192 	ret = regmap_read(pmic_typec_port->regmap,
193 			  pmic_typec_port->base + TYPEC_MISC_STATUS_REG, &misc);
194 	if (ret)
195 		goto done;
196 
197 	attached = !!(misc & CC_ATTACHED);
198 
199 	if (pmic_typec_port->debouncing_cc) {
200 		ret = -EBUSY;
201 		goto done;
202 	}
203 
204 	*cc1 = TYPEC_CC_OPEN;
205 	*cc2 = TYPEC_CC_OPEN;
206 
207 	if (!attached)
208 		goto done;
209 
210 	if (misc & SNK_SRC_MODE) {
211 		ret = regmap_read(pmic_typec_port->regmap,
212 				  pmic_typec_port->base + TYPEC_SRC_STATUS_REG,
213 				  &val);
214 		if (ret)
215 			goto done;
216 		switch (val & DETECTED_SRC_TYPE_MASK) {
217 		case SRC_RD_OPEN:
218 			val = TYPEC_CC_RD;
219 			break;
220 		case SRC_RD_RA_VCONN:
221 			val = TYPEC_CC_RD;
222 			*cc1 = TYPEC_CC_RA;
223 			*cc2 = TYPEC_CC_RA;
224 			break;
225 		default:
226 			dev_warn(dev, "unexpected src status %.2x\n", val);
227 			val = TYPEC_CC_RD;
228 			break;
229 		}
230 	} else {
231 		ret = regmap_read(pmic_typec_port->regmap,
232 				  pmic_typec_port->base + TYPEC_SNK_STATUS_REG,
233 				  &val);
234 		if (ret)
235 			goto done;
236 		switch (val & DETECTED_SNK_TYPE_MASK) {
237 		case SNK_RP_STD:
238 			val = TYPEC_CC_RP_DEF;
239 			break;
240 		case SNK_RP_1P5:
241 			val = TYPEC_CC_RP_1_5;
242 			break;
243 		case SNK_RP_3P0:
244 			val = TYPEC_CC_RP_3_0;
245 			break;
246 		default:
247 			dev_warn(dev, "unexpected snk status %.2x\n", val);
248 			val = TYPEC_CC_RP_DEF;
249 			break;
250 		}
251 		val = TYPEC_CC_RP_DEF;
252 	}
253 
254 	if (misc & CC_ORIENTATION)
255 		*cc2 = val;
256 	else
257 		*cc1 = val;
258 
259 done:
260 	dev_dbg(dev, "get_cc: misc 0x%08x cc1 0x%08x %s cc2 0x%08x %s attached %d cc=%s\n",
261 		misc, *cc1, cc_to_name(*cc1), *cc2, cc_to_name(*cc2), attached,
262 		misc_to_cc(misc));
263 
264 	return ret;
265 }
266 
267 static void qcom_pmic_set_cc_debounce(struct pmic_typec_port *pmic_typec_port)
268 {
269 	pmic_typec_port->debouncing_cc = true;
270 	schedule_delayed_work(&pmic_typec_port->cc_debounce_dwork,
271 			      msecs_to_jiffies(2));
272 }
273 
274 int qcom_pmic_typec_port_set_cc(struct pmic_typec_port *pmic_typec_port,
275 				enum typec_cc_status cc)
276 {
277 	struct device *dev = pmic_typec_port->dev;
278 	unsigned int mode, currsrc;
279 	unsigned int misc;
280 	unsigned long flags;
281 	int ret;
282 
283 	spin_lock_irqsave(&pmic_typec_port->lock, flags);
284 
285 	ret = regmap_read(pmic_typec_port->regmap,
286 			  pmic_typec_port->base + TYPEC_MISC_STATUS_REG,
287 			  &misc);
288 	if (ret)
289 		goto done;
290 
291 	mode = EN_SRC_ONLY;
292 
293 	switch (cc) {
294 	case TYPEC_CC_OPEN:
295 		currsrc = TYPEC_SRC_RP_SEL_80UA;
296 		break;
297 	case TYPEC_CC_RP_DEF:
298 		currsrc = TYPEC_SRC_RP_SEL_80UA;
299 		break;
300 	case TYPEC_CC_RP_1_5:
301 		currsrc = TYPEC_SRC_RP_SEL_180UA;
302 		break;
303 	case TYPEC_CC_RP_3_0:
304 		currsrc = TYPEC_SRC_RP_SEL_330UA;
305 		break;
306 	case TYPEC_CC_RD:
307 		currsrc = TYPEC_SRC_RP_SEL_80UA;
308 		mode = EN_SNK_ONLY;
309 		break;
310 	default:
311 		dev_warn(dev, "unexpected set_cc %d\n", cc);
312 		ret = -EINVAL;
313 		goto done;
314 	}
315 
316 	if (mode == EN_SRC_ONLY) {
317 		ret = regmap_write(pmic_typec_port->regmap,
318 				   pmic_typec_port->base + TYPEC_CURRSRC_CFG_REG,
319 				   currsrc);
320 		if (ret)
321 			goto done;
322 	}
323 
324 	pmic_typec_port->cc = cc;
325 	qcom_pmic_set_cc_debounce(pmic_typec_port);
326 	ret = 0;
327 
328 done:
329 	spin_unlock_irqrestore(&pmic_typec_port->lock, flags);
330 
331 	dev_dbg(dev, "set_cc: currsrc=%x %s mode %s debounce %d attached %d cc=%s\n",
332 		currsrc, rp_sel_to_name(currsrc),
333 		mode == EN_SRC_ONLY ? "EN_SRC_ONLY" : "EN_SNK_ONLY",
334 		pmic_typec_port->debouncing_cc, !!(misc & CC_ATTACHED),
335 		misc_to_cc(misc));
336 
337 	return ret;
338 }
339 
340 int qcom_pmic_typec_port_set_vconn(struct pmic_typec_port *pmic_typec_port, bool on)
341 {
342 	struct device *dev = pmic_typec_port->dev;
343 	unsigned int orientation, misc, mask, value;
344 	unsigned long flags;
345 	int ret;
346 
347 	spin_lock_irqsave(&pmic_typec_port->lock, flags);
348 
349 	ret = regmap_read(pmic_typec_port->regmap,
350 			  pmic_typec_port->base + TYPEC_MISC_STATUS_REG, &misc);
351 	if (ret)
352 		goto done;
353 
354 	/* Set VCONN on the inversion of the active CC channel */
355 	orientation = (misc & CC_ORIENTATION) ? 0 : VCONN_EN_ORIENTATION;
356 	if (on) {
357 		mask = VCONN_EN_ORIENTATION | VCONN_EN_VALUE;
358 		value = orientation | VCONN_EN_VALUE | VCONN_EN_SRC;
359 	} else {
360 		mask = VCONN_EN_VALUE;
361 		value = 0;
362 	}
363 
364 	ret = regmap_update_bits(pmic_typec_port->regmap,
365 				 pmic_typec_port->base + TYPEC_VCONN_CONTROL_REG,
366 				 mask, value);
367 done:
368 	spin_unlock_irqrestore(&pmic_typec_port->lock, flags);
369 
370 	dev_dbg(dev, "set_vconn: orientation %d control 0x%08x state %s cc %s vconn %s\n",
371 		orientation, value, on ? "on" : "off", misc_to_vconn(misc), misc_to_cc(misc));
372 
373 	return ret;
374 }
375 
376 int qcom_pmic_typec_port_start_toggling(struct pmic_typec_port *pmic_typec_port,
377 					enum typec_port_type port_type,
378 					enum typec_cc_status cc)
379 {
380 	struct device *dev = pmic_typec_port->dev;
381 	unsigned int misc;
382 	u8 mode = 0;
383 	unsigned long flags;
384 	int ret;
385 
386 	switch (port_type) {
387 	case TYPEC_PORT_SRC:
388 		mode = EN_SRC_ONLY;
389 		break;
390 	case TYPEC_PORT_SNK:
391 		mode = EN_SNK_ONLY;
392 		break;
393 	case TYPEC_PORT_DRP:
394 		mode = EN_TRY_SNK;
395 		break;
396 	}
397 
398 	spin_lock_irqsave(&pmic_typec_port->lock, flags);
399 
400 	ret = regmap_read(pmic_typec_port->regmap,
401 			  pmic_typec_port->base + TYPEC_MISC_STATUS_REG, &misc);
402 	if (ret)
403 		goto done;
404 
405 	dev_dbg(dev, "start_toggling: misc 0x%08x attached %d port_type %d current cc %d new %d\n",
406 		misc, !!(misc & CC_ATTACHED), port_type, pmic_typec_port->cc, cc);
407 
408 	qcom_pmic_set_cc_debounce(pmic_typec_port);
409 
410 	/* force it to toggle at least once */
411 	ret = regmap_write(pmic_typec_port->regmap,
412 			   pmic_typec_port->base + TYPEC_MODE_CFG_REG,
413 			   TYPEC_DISABLE_CMD);
414 	if (ret)
415 		goto done;
416 
417 	ret = regmap_write(pmic_typec_port->regmap,
418 			   pmic_typec_port->base + TYPEC_MODE_CFG_REG,
419 			   mode);
420 done:
421 	spin_unlock_irqrestore(&pmic_typec_port->lock, flags);
422 
423 	return ret;
424 }
425 
426 #define TYPEC_INTR_EN_CFG_1_MASK		  \
427 	(TYPEC_LEGACY_CABLE_INT_EN		| \
428 	 TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN	| \
429 	 TYPEC_TRYSOURCE_DETECT_INT_EN		| \
430 	 TYPEC_TRYSINK_DETECT_INT_EN		| \
431 	 TYPEC_CCOUT_DETACH_INT_EN		| \
432 	 TYPEC_CCOUT_ATTACH_INT_EN		| \
433 	 TYPEC_VBUS_DEASSERT_INT_EN		| \
434 	 TYPEC_VBUS_ASSERT_INT_EN)
435 
436 #define TYPEC_INTR_EN_CFG_2_MASK \
437 	(TYPEC_STATE_MACHINE_CHANGE_INT_EN | TYPEC_VBUS_ERROR_INT_EN | \
438 	 TYPEC_DEBOUNCE_DONE_INT_EN)
439 
440 int qcom_pmic_typec_port_start(struct pmic_typec_port *pmic_typec_port,
441 			       struct tcpm_port *tcpm_port)
442 {
443 	int i;
444 	int mask;
445 	int ret;
446 
447 	/* Configure interrupt sources */
448 	ret = regmap_write(pmic_typec_port->regmap,
449 			   pmic_typec_port->base + TYPEC_INTERRUPT_EN_CFG_1_REG,
450 			   TYPEC_INTR_EN_CFG_1_MASK);
451 	if (ret)
452 		goto done;
453 
454 	ret = regmap_write(pmic_typec_port->regmap,
455 			   pmic_typec_port->base + TYPEC_INTERRUPT_EN_CFG_2_REG,
456 			   TYPEC_INTR_EN_CFG_2_MASK);
457 	if (ret)
458 		goto done;
459 
460 	/* start in TRY_SNK mode */
461 	ret = regmap_write(pmic_typec_port->regmap,
462 			   pmic_typec_port->base + TYPEC_MODE_CFG_REG, EN_TRY_SNK);
463 	if (ret)
464 		goto done;
465 
466 	/* Configure VCONN for software control */
467 	ret = regmap_update_bits(pmic_typec_port->regmap,
468 				 pmic_typec_port->base + TYPEC_VCONN_CONTROL_REG,
469 				 VCONN_EN_SRC | VCONN_EN_VALUE, VCONN_EN_SRC);
470 	if (ret)
471 		goto done;
472 
473 	/* Set CC threshold to 1.6 Volts | tPDdebounce = 10-20ms */
474 	mask = SEL_SRC_UPPER_REF | USE_TPD_FOR_EXITING_ATTACHSRC;
475 	ret = regmap_update_bits(pmic_typec_port->regmap,
476 				 pmic_typec_port->base + TYPEC_EXIT_STATE_CFG_REG,
477 				 mask, mask);
478 	if (ret)
479 		goto done;
480 
481 	pmic_typec_port->tcpm_port = tcpm_port;
482 
483 	for (i = 0; i < pmic_typec_port->nr_irqs; i++)
484 		enable_irq(pmic_typec_port->irq_data[i].irq);
485 
486 done:
487 	return ret;
488 }
489 
490 void qcom_pmic_typec_port_stop(struct pmic_typec_port *pmic_typec_port)
491 {
492 	int i;
493 
494 	for (i = 0; i < pmic_typec_port->nr_irqs; i++)
495 		disable_irq(pmic_typec_port->irq_data[i].irq);
496 }
497 
498 struct pmic_typec_port *qcom_pmic_typec_port_alloc(struct device *dev)
499 {
500 	return devm_kzalloc(dev, sizeof(struct pmic_typec_port), GFP_KERNEL);
501 }
502 
503 int qcom_pmic_typec_port_probe(struct platform_device *pdev,
504 			       struct pmic_typec_port *pmic_typec_port,
505 			       struct pmic_typec_port_resources *res,
506 			       struct regmap *regmap,
507 			       u32 base)
508 {
509 	struct device *dev = &pdev->dev;
510 	struct pmic_typec_port_irq_data *irq_data;
511 	int i, ret, irq;
512 
513 	if (!res->nr_irqs || res->nr_irqs > PMIC_TYPEC_MAX_IRQS)
514 		return -EINVAL;
515 
516 	irq_data = devm_kzalloc(dev, sizeof(*irq_data) * res->nr_irqs,
517 				GFP_KERNEL);
518 	if (!irq_data)
519 		return -ENOMEM;
520 
521 	pmic_typec_port->vdd_vbus = devm_regulator_get(dev, "vdd-vbus");
522 	if (IS_ERR(pmic_typec_port->vdd_vbus))
523 		return PTR_ERR(pmic_typec_port->vdd_vbus);
524 
525 	pmic_typec_port->dev = dev;
526 	pmic_typec_port->base = base;
527 	pmic_typec_port->regmap = regmap;
528 	pmic_typec_port->nr_irqs = res->nr_irqs;
529 	pmic_typec_port->irq_data = irq_data;
530 	spin_lock_init(&pmic_typec_port->lock);
531 	INIT_DELAYED_WORK(&pmic_typec_port->cc_debounce_dwork,
532 			  qcom_pmic_typec_port_cc_debounce);
533 
534 	irq = platform_get_irq(pdev, 0);
535 	if (irq < 0)
536 		return irq;
537 
538 	for (i = 0; i < res->nr_irqs; i++, irq_data++) {
539 		irq = platform_get_irq_byname(pdev,
540 					      res->irq_params[i].irq_name);
541 		if (irq < 0)
542 			return irq;
543 
544 		irq_data->pmic_typec_port = pmic_typec_port;
545 		irq_data->irq = irq;
546 		irq_data->virq = res->irq_params[i].virq;
547 		ret = devm_request_threaded_irq(dev, irq, NULL, pmic_typec_port_isr,
548 						IRQF_ONESHOT | IRQF_NO_AUTOEN,
549 						res->irq_params[i].irq_name,
550 						irq_data);
551 		if (ret)
552 			return ret;
553 	}
554 
555 	return 0;
556 }
557