xref: /linux/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c (revision 65538a8f02fe6e4f07228a816529b039b544f051)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2023, Linaro Ltd. All rights reserved.
4  */
5 
6 #include <linux/err.h>
7 #include <linux/interrupt.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/regmap.h>
12 #include <linux/regulator/consumer.h>
13 #include <linux/slab.h>
14 #include <linux/string_choices.h>
15 #include <linux/usb/pd.h>
16 #include <linux/usb/tcpm.h>
17 #include "qcom_pmic_typec.h"
18 #include "qcom_pmic_typec_pdphy.h"
19 
20 /* PD PHY register offsets and bit fields */
21 #define USB_PDPHY_MSG_CONFIG_REG	0x40
22 #define MSG_CONFIG_PORT_DATA_ROLE	BIT(3)
23 #define MSG_CONFIG_PORT_POWER_ROLE	BIT(2)
24 #define MSG_CONFIG_SPEC_REV_MASK	(BIT(1) | BIT(0))
25 
26 #define USB_PDPHY_EN_CONTROL_REG	0x46
27 #define CONTROL_ENABLE			BIT(0)
28 
29 #define USB_PDPHY_RX_STATUS_REG		0x4A
30 #define RX_FRAME_TYPE			(BIT(0) | BIT(1) | BIT(2))
31 
32 #define USB_PDPHY_FRAME_FILTER_REG	0x4C
33 #define FRAME_FILTER_EN_HARD_RESET	BIT(5)
34 #define FRAME_FILTER_EN_SOP		BIT(0)
35 
36 #define USB_PDPHY_TX_SIZE_REG		0x42
37 #define TX_SIZE_MASK			0xF
38 
39 #define USB_PDPHY_TX_CONTROL_REG	0x44
40 #define TX_CONTROL_RETRY_COUNT(n)	(((n) & 0x3) << 5)
41 #define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
42 #define TX_CONTROL_FRAME_TYPE_CABLE_RESET	(0x1 << 2)
43 #define TX_CONTROL_SEND_SIGNAL		BIT(1)
44 #define TX_CONTROL_SEND_MSG		BIT(0)
45 
46 #define USB_PDPHY_RX_SIZE_REG		0x48
47 
48 #define USB_PDPHY_RX_ACKNOWLEDGE_REG	0x4B
49 #define RX_BUFFER_TOKEN			BIT(0)
50 
51 #define USB_PDPHY_BIST_MODE_REG		0x4E
52 #define BIST_MODE_MASK			0xF
53 #define BIST_ENABLE			BIT(7)
54 #define PD_MSG_BIST			0x3
55 #define PD_BIST_TEST_DATA_MODE		0x8
56 
57 #define USB_PDPHY_TX_BUFFER_HDR_REG	0x60
58 #define USB_PDPHY_TX_BUFFER_DATA_REG	0x62
59 
60 #define USB_PDPHY_RX_BUFFER_REG		0x80
61 
62 /* VDD regulator */
63 #define VDD_PDPHY_VOL_MIN		2800000	/* uV */
64 #define VDD_PDPHY_VOL_MAX		3300000	/* uV */
65 #define VDD_PDPHY_HPM_LOAD		3000	/* uA */
66 
67 /* Message Spec Rev field */
68 #define PD_MSG_HDR_REV(hdr)		(((hdr) >> 6) & 3)
69 
70 /* timers */
71 #define RECEIVER_RESPONSE_TIME		15	/* tReceiverResponse */
72 #define HARD_RESET_COMPLETE_TIME	5	/* tHardResetComplete */
73 
74 /* Interrupt numbers */
75 #define PMIC_PDPHY_SIG_TX_IRQ		0x0
76 #define PMIC_PDPHY_SIG_RX_IRQ		0x1
77 #define PMIC_PDPHY_MSG_TX_IRQ		0x2
78 #define PMIC_PDPHY_MSG_RX_IRQ		0x3
79 #define PMIC_PDPHY_MSG_TX_FAIL_IRQ	0x4
80 #define PMIC_PDPHY_MSG_TX_DISCARD_IRQ	0x5
81 #define PMIC_PDPHY_MSG_RX_DISCARD_IRQ	0x6
82 #define PMIC_PDPHY_FR_SWAP_IRQ		0x7
83 
84 
85 struct pmic_typec_pdphy_irq_data {
86 	int				virq;
87 	int				irq;
88 	struct pmic_typec_pdphy		*pmic_typec_pdphy;
89 };
90 
91 struct pmic_typec_pdphy {
92 	struct device			*dev;
93 	struct tcpm_port		*tcpm_port;
94 	struct regmap			*regmap;
95 	u32				base;
96 
97 	unsigned int			nr_irqs;
98 	struct pmic_typec_pdphy_irq_data	*irq_data;
99 
100 	struct work_struct		reset_work;
101 	struct work_struct		receive_work;
102 	struct regulator		*vdd_pdphy;
103 	spinlock_t			lock;		/* Register atomicity */
104 };
105 
qcom_pmic_typec_pdphy_reset_on(struct pmic_typec_pdphy * pmic_typec_pdphy)106 static void qcom_pmic_typec_pdphy_reset_on(struct pmic_typec_pdphy *pmic_typec_pdphy)
107 {
108 	struct device *dev = pmic_typec_pdphy->dev;
109 	int ret;
110 
111 	/* Terminate TX */
112 	ret = regmap_write(pmic_typec_pdphy->regmap,
113 			   pmic_typec_pdphy->base + USB_PDPHY_TX_CONTROL_REG, 0);
114 	if (ret)
115 		goto err;
116 
117 	ret = regmap_write(pmic_typec_pdphy->regmap,
118 			   pmic_typec_pdphy->base + USB_PDPHY_FRAME_FILTER_REG, 0);
119 	if (ret)
120 		goto err;
121 
122 	return;
123 err:
124 	dev_err(dev, "pd_reset_on error\n");
125 }
126 
qcom_pmic_typec_pdphy_reset_off(struct pmic_typec_pdphy * pmic_typec_pdphy)127 static void qcom_pmic_typec_pdphy_reset_off(struct pmic_typec_pdphy *pmic_typec_pdphy)
128 {
129 	struct device *dev = pmic_typec_pdphy->dev;
130 	int ret;
131 
132 	ret = regmap_write(pmic_typec_pdphy->regmap,
133 			   pmic_typec_pdphy->base + USB_PDPHY_FRAME_FILTER_REG,
134 			   FRAME_FILTER_EN_SOP | FRAME_FILTER_EN_HARD_RESET);
135 	if (ret)
136 		dev_err(dev, "pd_reset_off error\n");
137 }
138 
qcom_pmic_typec_pdphy_sig_reset_work(struct work_struct * work)139 static void qcom_pmic_typec_pdphy_sig_reset_work(struct work_struct *work)
140 {
141 	struct pmic_typec_pdphy *pmic_typec_pdphy = container_of(work, struct pmic_typec_pdphy,
142 						     reset_work);
143 	unsigned long flags;
144 
145 	spin_lock_irqsave(&pmic_typec_pdphy->lock, flags);
146 
147 	qcom_pmic_typec_pdphy_reset_on(pmic_typec_pdphy);
148 	qcom_pmic_typec_pdphy_reset_off(pmic_typec_pdphy);
149 
150 	spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
151 
152 	tcpm_pd_hard_reset(pmic_typec_pdphy->tcpm_port);
153 }
154 
155 static int
qcom_pmic_typec_pdphy_clear_tx_control_reg(struct pmic_typec_pdphy * pmic_typec_pdphy)156 qcom_pmic_typec_pdphy_clear_tx_control_reg(struct pmic_typec_pdphy *pmic_typec_pdphy)
157 {
158 	struct device *dev = pmic_typec_pdphy->dev;
159 	unsigned int val;
160 	int ret;
161 
162 	/* Clear TX control register */
163 	ret = regmap_write(pmic_typec_pdphy->regmap,
164 			   pmic_typec_pdphy->base + USB_PDPHY_TX_CONTROL_REG, 0);
165 	if (ret)
166 		goto done;
167 
168 	/* Perform readback to ensure sufficient delay for command to latch */
169 	ret = regmap_read(pmic_typec_pdphy->regmap,
170 			  pmic_typec_pdphy->base + USB_PDPHY_TX_CONTROL_REG, &val);
171 
172 done:
173 	if (ret)
174 		dev_err(dev, "pd_clear_tx_control_reg: clear tx flag\n");
175 
176 	return ret;
177 }
178 
179 static int
qcom_pmic_typec_pdphy_pd_transmit_signal(struct pmic_typec_pdphy * pmic_typec_pdphy,enum tcpm_transmit_type type,unsigned int negotiated_rev)180 qcom_pmic_typec_pdphy_pd_transmit_signal(struct pmic_typec_pdphy *pmic_typec_pdphy,
181 					 enum tcpm_transmit_type type,
182 					 unsigned int negotiated_rev)
183 {
184 	struct device *dev = pmic_typec_pdphy->dev;
185 	unsigned int val;
186 	unsigned long flags;
187 	int ret;
188 
189 	spin_lock_irqsave(&pmic_typec_pdphy->lock, flags);
190 
191 	/* Clear TX control register */
192 	ret = qcom_pmic_typec_pdphy_clear_tx_control_reg(pmic_typec_pdphy);
193 	if (ret)
194 		goto done;
195 
196 	val = TX_CONTROL_SEND_SIGNAL;
197 	if (negotiated_rev == PD_REV30)
198 		val |= TX_CONTROL_RETRY_COUNT(2);
199 	else
200 		val |= TX_CONTROL_RETRY_COUNT(3);
201 
202 	if (type == TCPC_TX_CABLE_RESET || type == TCPC_TX_HARD_RESET)
203 		val |= TX_CONTROL_FRAME_TYPE(1);
204 
205 	ret = regmap_write(pmic_typec_pdphy->regmap,
206 			   pmic_typec_pdphy->base + USB_PDPHY_TX_CONTROL_REG, val);
207 
208 done:
209 	spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
210 
211 	dev_vdbg(dev, "pd_transmit_signal: type %d negotiate_rev %d send %d\n",
212 		 type, negotiated_rev, ret);
213 
214 	return ret;
215 }
216 
217 static int
qcom_pmic_typec_pdphy_pd_transmit_payload(struct pmic_typec_pdphy * pmic_typec_pdphy,enum tcpm_transmit_type type,const struct pd_message * msg,unsigned int negotiated_rev)218 qcom_pmic_typec_pdphy_pd_transmit_payload(struct pmic_typec_pdphy *pmic_typec_pdphy,
219 					  enum tcpm_transmit_type type,
220 					  const struct pd_message *msg,
221 					  unsigned int negotiated_rev)
222 {
223 	struct device *dev = pmic_typec_pdphy->dev;
224 	unsigned int val, hdr_len, txbuf_len, txsize_len;
225 	unsigned long flags;
226 	int ret;
227 
228 	spin_lock_irqsave(&pmic_typec_pdphy->lock, flags);
229 
230 	hdr_len = sizeof(msg->header);
231 	txbuf_len = pd_header_cnt_le(msg->header) * 4;
232 	txsize_len = hdr_len + txbuf_len - 1;
233 
234 	ret = regmap_read(pmic_typec_pdphy->regmap,
235 			  pmic_typec_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG,
236 			  &val);
237 	if (ret)
238 		goto done;
239 
240 	if (val) {
241 		dev_err(dev, "pd_transmit_payload: RX message pending\n");
242 		ret = -EBUSY;
243 		goto done;
244 	}
245 
246 	/* Clear TX control register */
247 	ret = qcom_pmic_typec_pdphy_clear_tx_control_reg(pmic_typec_pdphy);
248 	if (ret)
249 		goto done;
250 
251 	/* Write message header sizeof(u16) to USB_PDPHY_TX_BUFFER_HDR_REG */
252 	ret = regmap_bulk_write(pmic_typec_pdphy->regmap,
253 				pmic_typec_pdphy->base + USB_PDPHY_TX_BUFFER_HDR_REG,
254 				&msg->header, hdr_len);
255 	if (ret)
256 		goto done;
257 
258 	/* Write payload to USB_PDPHY_TX_BUFFER_DATA_REG for txbuf_len */
259 	if (txbuf_len) {
260 		ret = regmap_bulk_write(pmic_typec_pdphy->regmap,
261 					pmic_typec_pdphy->base + USB_PDPHY_TX_BUFFER_DATA_REG,
262 					&msg->payload, txbuf_len);
263 		if (ret)
264 			goto done;
265 	}
266 
267 	/* Write total length ((header + data) - 1) to USB_PDPHY_TX_SIZE_REG */
268 	ret = regmap_write(pmic_typec_pdphy->regmap,
269 			   pmic_typec_pdphy->base + USB_PDPHY_TX_SIZE_REG,
270 			   txsize_len);
271 	if (ret)
272 		goto done;
273 
274 	/* Clear TX control register */
275 	ret = qcom_pmic_typec_pdphy_clear_tx_control_reg(pmic_typec_pdphy);
276 	if (ret)
277 		goto done;
278 
279 	/* Initiate transmit with retry count as indicated by PD revision */
280 	val = TX_CONTROL_FRAME_TYPE(type) | TX_CONTROL_SEND_MSG;
281 	if (pd_header_rev(msg->header) == PD_REV30)
282 		val |= TX_CONTROL_RETRY_COUNT(2);
283 	else
284 		val |= TX_CONTROL_RETRY_COUNT(3);
285 
286 	ret = regmap_write(pmic_typec_pdphy->regmap,
287 			   pmic_typec_pdphy->base + USB_PDPHY_TX_CONTROL_REG, val);
288 
289 done:
290 	spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
291 
292 	if (ret) {
293 		dev_err(dev, "pd_transmit_payload: hdr %*ph data %*ph ret %d\n",
294 			hdr_len, &msg->header, txbuf_len, &msg->payload, ret);
295 	}
296 
297 	return ret;
298 }
299 
qcom_pmic_typec_pdphy_pd_transmit(struct tcpc_dev * tcpc,enum tcpm_transmit_type type,const struct pd_message * msg,unsigned int negotiated_rev)300 static int qcom_pmic_typec_pdphy_pd_transmit(struct tcpc_dev *tcpc,
301 					     enum tcpm_transmit_type type,
302 					     const struct pd_message *msg,
303 					     unsigned int negotiated_rev)
304 {
305 	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
306 	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
307 	struct device *dev = pmic_typec_pdphy->dev;
308 	int ret;
309 
310 	if (msg) {
311 		ret = qcom_pmic_typec_pdphy_pd_transmit_payload(pmic_typec_pdphy,
312 								type, msg,
313 								negotiated_rev);
314 	} else {
315 		ret = qcom_pmic_typec_pdphy_pd_transmit_signal(pmic_typec_pdphy,
316 							       type,
317 							       negotiated_rev);
318 	}
319 
320 	if (ret)
321 		dev_dbg(dev, "pd_transmit: type %x result %d\n", type, ret);
322 
323 	return ret;
324 }
325 
qcom_pmic_typec_pdphy_pd_receive(struct pmic_typec_pdphy * pmic_typec_pdphy)326 static void qcom_pmic_typec_pdphy_pd_receive(struct pmic_typec_pdphy *pmic_typec_pdphy)
327 {
328 	struct device *dev = pmic_typec_pdphy->dev;
329 	struct pd_message msg;
330 	unsigned int size, rx_status;
331 	unsigned long flags;
332 	int ret;
333 
334 	spin_lock_irqsave(&pmic_typec_pdphy->lock, flags);
335 
336 	ret = regmap_read(pmic_typec_pdphy->regmap,
337 			  pmic_typec_pdphy->base + USB_PDPHY_RX_SIZE_REG, &size);
338 	if (ret)
339 		goto done;
340 
341 	/* Hardware requires +1 of the real read value to be passed */
342 	if (size < 1 || size > sizeof(msg.payload) + 1) {
343 		dev_dbg(dev, "pd_receive: invalid size %d\n", size);
344 		goto done;
345 	}
346 
347 	size += 1;
348 	ret = regmap_read(pmic_typec_pdphy->regmap,
349 			  pmic_typec_pdphy->base + USB_PDPHY_RX_STATUS_REG,
350 			  &rx_status);
351 
352 	if (ret)
353 		goto done;
354 
355 	ret = regmap_bulk_read(pmic_typec_pdphy->regmap,
356 			       pmic_typec_pdphy->base + USB_PDPHY_RX_BUFFER_REG,
357 			       (u8 *)&msg, size);
358 	if (ret)
359 		goto done;
360 
361 	/* Return ownership of RX buffer to hardware */
362 	ret = regmap_write(pmic_typec_pdphy->regmap,
363 			   pmic_typec_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG, 0);
364 
365 done:
366 	spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
367 
368 	if (!ret) {
369 		dev_vdbg(dev, "pd_receive: handing %d bytes to tcpm\n", size);
370 		tcpm_pd_receive(pmic_typec_pdphy->tcpm_port, &msg, TCPC_TX_SOP);
371 	}
372 }
373 
qcom_pmic_typec_pdphy_isr(int irq,void * dev_id)374 static irqreturn_t qcom_pmic_typec_pdphy_isr(int irq, void *dev_id)
375 {
376 	struct pmic_typec_pdphy_irq_data *irq_data = dev_id;
377 	struct pmic_typec_pdphy *pmic_typec_pdphy = irq_data->pmic_typec_pdphy;
378 	struct device *dev = pmic_typec_pdphy->dev;
379 
380 	switch (irq_data->virq) {
381 	case PMIC_PDPHY_SIG_TX_IRQ:
382 		dev_err(dev, "isr: tx_sig\n");
383 		break;
384 	case PMIC_PDPHY_SIG_RX_IRQ:
385 		schedule_work(&pmic_typec_pdphy->reset_work);
386 		break;
387 	case PMIC_PDPHY_MSG_TX_IRQ:
388 		tcpm_pd_transmit_complete(pmic_typec_pdphy->tcpm_port,
389 					  TCPC_TX_SUCCESS);
390 		break;
391 	case PMIC_PDPHY_MSG_RX_IRQ:
392 		qcom_pmic_typec_pdphy_pd_receive(pmic_typec_pdphy);
393 		break;
394 	case PMIC_PDPHY_MSG_TX_FAIL_IRQ:
395 		tcpm_pd_transmit_complete(pmic_typec_pdphy->tcpm_port,
396 					  TCPC_TX_FAILED);
397 		break;
398 	case PMIC_PDPHY_MSG_TX_DISCARD_IRQ:
399 		tcpm_pd_transmit_complete(pmic_typec_pdphy->tcpm_port,
400 					  TCPC_TX_DISCARDED);
401 		break;
402 	}
403 
404 	return IRQ_HANDLED;
405 }
406 
qcom_pmic_typec_pdphy_set_pd_rx(struct tcpc_dev * tcpc,bool on)407 static int qcom_pmic_typec_pdphy_set_pd_rx(struct tcpc_dev *tcpc, bool on)
408 {
409 	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
410 	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
411 	unsigned long flags;
412 	int ret;
413 
414 	spin_lock_irqsave(&pmic_typec_pdphy->lock, flags);
415 
416 	ret = regmap_write(pmic_typec_pdphy->regmap,
417 			   pmic_typec_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG, !on);
418 
419 	spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
420 
421 	dev_dbg(pmic_typec_pdphy->dev, "set_pd_rx: %s\n", str_on_off(on));
422 
423 	return ret;
424 }
425 
qcom_pmic_typec_pdphy_set_roles(struct tcpc_dev * tcpc,bool attached,enum typec_role power_role,enum typec_data_role data_role)426 static int qcom_pmic_typec_pdphy_set_roles(struct tcpc_dev *tcpc, bool attached,
427 					   enum typec_role power_role,
428 					   enum typec_data_role data_role)
429 {
430 	struct pmic_typec *tcpm = tcpc_to_tcpm(tcpc);
431 	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
432 	struct device *dev = pmic_typec_pdphy->dev;
433 	unsigned long flags;
434 	int ret;
435 
436 	spin_lock_irqsave(&pmic_typec_pdphy->lock, flags);
437 
438 	ret = regmap_update_bits(pmic_typec_pdphy->regmap,
439 				 pmic_typec_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
440 				 MSG_CONFIG_PORT_DATA_ROLE |
441 				 MSG_CONFIG_PORT_POWER_ROLE,
442 				 (data_role == TYPEC_HOST ? MSG_CONFIG_PORT_DATA_ROLE : 0) |
443 				 (power_role == TYPEC_SOURCE ? MSG_CONFIG_PORT_POWER_ROLE : 0));
444 
445 	spin_unlock_irqrestore(&pmic_typec_pdphy->lock, flags);
446 
447 	dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
448 		data_role, power_role);
449 
450 	return ret;
451 }
452 
qcom_pmic_typec_pdphy_enable(struct pmic_typec_pdphy * pmic_typec_pdphy)453 static int qcom_pmic_typec_pdphy_enable(struct pmic_typec_pdphy *pmic_typec_pdphy)
454 {
455 	struct device *dev = pmic_typec_pdphy->dev;
456 	int ret;
457 
458 	/* PD 2.0, DR=TYPEC_DEVICE, PR=TYPEC_SINK */
459 	ret = regmap_update_bits(pmic_typec_pdphy->regmap,
460 				 pmic_typec_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
461 				 MSG_CONFIG_SPEC_REV_MASK, PD_REV20);
462 	if (ret)
463 		goto done;
464 
465 	ret = regmap_write(pmic_typec_pdphy->regmap,
466 			   pmic_typec_pdphy->base + USB_PDPHY_EN_CONTROL_REG, 0);
467 	if (ret)
468 		goto done;
469 
470 	ret = regmap_write(pmic_typec_pdphy->regmap,
471 			   pmic_typec_pdphy->base + USB_PDPHY_EN_CONTROL_REG,
472 			   CONTROL_ENABLE);
473 	if (ret)
474 		goto done;
475 
476 	qcom_pmic_typec_pdphy_reset_off(pmic_typec_pdphy);
477 done:
478 	if (ret)
479 		dev_err(dev, "pdphy_enable fail %d\n", ret);
480 
481 	return ret;
482 }
483 
qcom_pmic_typec_pdphy_disable(struct pmic_typec_pdphy * pmic_typec_pdphy)484 static int qcom_pmic_typec_pdphy_disable(struct pmic_typec_pdphy *pmic_typec_pdphy)
485 {
486 	int ret;
487 
488 	qcom_pmic_typec_pdphy_reset_on(pmic_typec_pdphy);
489 
490 	ret = regmap_write(pmic_typec_pdphy->regmap,
491 			   pmic_typec_pdphy->base + USB_PDPHY_EN_CONTROL_REG, 0);
492 
493 	return ret;
494 }
495 
pmic_typec_pdphy_reset(struct pmic_typec_pdphy * pmic_typec_pdphy)496 static int pmic_typec_pdphy_reset(struct pmic_typec_pdphy *pmic_typec_pdphy)
497 {
498 	int ret;
499 
500 	ret = qcom_pmic_typec_pdphy_disable(pmic_typec_pdphy);
501 	if (ret)
502 		goto done;
503 
504 	usleep_range(400, 500);
505 	ret = qcom_pmic_typec_pdphy_enable(pmic_typec_pdphy);
506 done:
507 	return ret;
508 }
509 
qcom_pmic_typec_pdphy_start(struct pmic_typec * tcpm,struct tcpm_port * tcpm_port)510 static int qcom_pmic_typec_pdphy_start(struct pmic_typec *tcpm,
511 				       struct tcpm_port *tcpm_port)
512 {
513 	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
514 	int i;
515 	int ret;
516 
517 	ret = regulator_enable(pmic_typec_pdphy->vdd_pdphy);
518 	if (ret)
519 		return ret;
520 
521 	pmic_typec_pdphy->tcpm_port = tcpm_port;
522 
523 	ret = pmic_typec_pdphy_reset(pmic_typec_pdphy);
524 	if (ret)
525 		goto err_disable_vdd_pdhy;
526 
527 	for (i = 0; i < pmic_typec_pdphy->nr_irqs; i++)
528 		enable_irq(pmic_typec_pdphy->irq_data[i].irq);
529 
530 	return 0;
531 
532 err_disable_vdd_pdhy:
533 	regulator_disable(pmic_typec_pdphy->vdd_pdphy);
534 
535 	return ret;
536 }
537 
qcom_pmic_typec_pdphy_stop(struct pmic_typec * tcpm)538 static void qcom_pmic_typec_pdphy_stop(struct pmic_typec *tcpm)
539 {
540 	struct pmic_typec_pdphy *pmic_typec_pdphy = tcpm->pmic_typec_pdphy;
541 	int i;
542 
543 	for (i = 0; i < pmic_typec_pdphy->nr_irqs; i++)
544 		disable_irq(pmic_typec_pdphy->irq_data[i].irq);
545 
546 	cancel_work_sync(&pmic_typec_pdphy->reset_work);
547 
548 	qcom_pmic_typec_pdphy_reset_on(pmic_typec_pdphy);
549 
550 	regulator_disable(pmic_typec_pdphy->vdd_pdphy);
551 }
552 
qcom_pmic_typec_pdphy_probe(struct platform_device * pdev,struct pmic_typec * tcpm,const struct pmic_typec_pdphy_resources * res,struct regmap * regmap,u32 base)553 int qcom_pmic_typec_pdphy_probe(struct platform_device *pdev,
554 				struct pmic_typec *tcpm,
555 				const struct pmic_typec_pdphy_resources *res,
556 				struct regmap *regmap,
557 				u32 base)
558 {
559 	struct pmic_typec_pdphy *pmic_typec_pdphy;
560 	struct device *dev = &pdev->dev;
561 	struct pmic_typec_pdphy_irq_data *irq_data;
562 	int i, ret, irq;
563 
564 	pmic_typec_pdphy = devm_kzalloc(dev, sizeof(*pmic_typec_pdphy), GFP_KERNEL);
565 	if (!pmic_typec_pdphy)
566 		return -ENOMEM;
567 
568 	if (!res->nr_irqs || res->nr_irqs > PMIC_PDPHY_MAX_IRQS)
569 		return -EINVAL;
570 
571 	irq_data = devm_kcalloc(dev, res->nr_irqs, sizeof(*irq_data),
572 				GFP_KERNEL);
573 	if (!irq_data)
574 		return -ENOMEM;
575 
576 	pmic_typec_pdphy->vdd_pdphy = devm_regulator_get(dev, "vdd-pdphy");
577 	if (IS_ERR(pmic_typec_pdphy->vdd_pdphy))
578 		return PTR_ERR(pmic_typec_pdphy->vdd_pdphy);
579 
580 	pmic_typec_pdphy->dev = dev;
581 	pmic_typec_pdphy->base = base;
582 	pmic_typec_pdphy->regmap = regmap;
583 	pmic_typec_pdphy->nr_irqs = res->nr_irqs;
584 	pmic_typec_pdphy->irq_data = irq_data;
585 	spin_lock_init(&pmic_typec_pdphy->lock);
586 	INIT_WORK(&pmic_typec_pdphy->reset_work, qcom_pmic_typec_pdphy_sig_reset_work);
587 
588 	for (i = 0; i < res->nr_irqs; i++, irq_data++) {
589 		irq = platform_get_irq_byname(pdev, res->irq_params[i].irq_name);
590 		if (irq < 0)
591 			return irq;
592 
593 		irq_data->pmic_typec_pdphy = pmic_typec_pdphy;
594 		irq_data->irq = irq;
595 		irq_data->virq = res->irq_params[i].virq;
596 
597 		ret = devm_request_threaded_irq(dev, irq, NULL,
598 						qcom_pmic_typec_pdphy_isr,
599 						IRQF_ONESHOT | IRQF_NO_AUTOEN,
600 						res->irq_params[i].irq_name,
601 						irq_data);
602 		if (ret)
603 			return ret;
604 	}
605 
606 	tcpm->pmic_typec_pdphy = pmic_typec_pdphy;
607 
608 	tcpm->tcpc.set_pd_rx = qcom_pmic_typec_pdphy_set_pd_rx;
609 	tcpm->tcpc.set_roles = qcom_pmic_typec_pdphy_set_roles;
610 	tcpm->tcpc.pd_transmit = qcom_pmic_typec_pdphy_pd_transmit;
611 
612 	tcpm->pdphy_start = qcom_pmic_typec_pdphy_start;
613 	tcpm->pdphy_stop = qcom_pmic_typec_pdphy_stop;
614 
615 	return 0;
616 }
617 
618 const struct pmic_typec_pdphy_resources pm8150b_pdphy_res = {
619 	.irq_params = {
620 		{
621 			.virq = PMIC_PDPHY_SIG_TX_IRQ,
622 			.irq_name = "sig-tx",
623 		},
624 		{
625 			.virq = PMIC_PDPHY_SIG_RX_IRQ,
626 			.irq_name = "sig-rx",
627 		},
628 		{
629 			.virq = PMIC_PDPHY_MSG_TX_IRQ,
630 			.irq_name = "msg-tx",
631 		},
632 		{
633 			.virq = PMIC_PDPHY_MSG_RX_IRQ,
634 			.irq_name = "msg-rx",
635 		},
636 		{
637 			.virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
638 			.irq_name = "msg-tx-failed",
639 		},
640 		{
641 			.virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
642 			.irq_name = "msg-tx-discarded",
643 		},
644 		{
645 			.virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
646 			.irq_name = "msg-rx-discarded",
647 		},
648 	},
649 	.nr_irqs = 7,
650 };
651