1 /*
2  * Copyright 2024 Google LLC
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <zephyr/device.h>
7 #include <zephyr/logging/log.h>
8 #include <zephyr/drivers/gpio.h>
9 #include <zephyr/drivers/i2c.h>
10 #include <zephyr/drivers/usb_c/tcpci_priv.h>
11 #include <zephyr/usb_c/usbc.h>
12 #include <zephyr/usb_c/tcpci.h>
13 #include <zephyr/shell/shell.h>
14 #include "ps8xxx_priv.h"
15 
16 #define DT_DRV_COMPAT parade_ps8xxx
17 LOG_MODULE_REGISTER(ps8xxx, CONFIG_USBC_LOG_LEVEL);
18 
19 /** Data structure for device instances */
20 struct ps8xxx_data {
21 	/** Device structure used to retrieve it in k_work functions */
22 	const struct device *const dev;
23 	/** Delayable work item for chip initialization */
24 	struct k_work_delayable init_dwork;
25 	/** Initialization retries counter */
26 	int init_retries;
27 	/** Boolean value if chip was successfully initialized */
28 	bool initialized;
29 
30 	/** Callback for alert GPIO */
31 	struct gpio_callback alert_cb;
32 	/** Work item for alert handling out of interrupt context */
33 	struct k_work alert_work;
34 	/** Boolean value if there is a message pending */
35 	bool msg_pending;
36 
37 	/** Alert handler set by USB-C stack */
38 	tcpc_alert_handler_cb_t alert_handler;
39 	/** Alert handler data set by USB-C stack */
40 	void *alert_handler_data;
41 
42 	/** VCONN discharge callback set by USB-C stack */
43 	tcpc_vconn_discharge_cb_t vconn_discharge_cb;
44 	/** VCONN discharge callback data set by USB-C stack */
45 	tcpc_vconn_control_cb_t vconn_cb;
46 	/** Polarity of CC lines for PD and VCONN */
47 	enum tc_cc_polarity cc_polarity;
48 
49 	/** Boolean value if there was a change on the CC lines since last check */
50 	bool cc_changed;
51 	/** State of CC1 line */
52 	enum tc_cc_voltage_state cc1;
53 	/** State of CC2 line */
54 	enum tc_cc_voltage_state cc2;
55 };
56 
57 /** Configuration structure for device instances */
58 struct ps8xxx_cfg {
59 	/** I2C bus and address used for communication */
60 	const struct i2c_dt_spec bus;
61 	/** GPIO specification for alert pin */
62 	const struct gpio_dt_spec alert_gpio;
63 	/** Maximum number of packet retransmissions done by TCPC */
64 	const uint8_t transmit_retries;
65 };
66 
tcpci_init_alert_mask(const struct device * dev)67 static int tcpci_init_alert_mask(const struct device *dev)
68 {
69 	const struct ps8xxx_cfg *cfg = dev->config;
70 	int ret;
71 
72 	uint16_t mask = TCPC_REG_ALERT_TX_COMPLETE | TCPC_REG_ALERT_RX_STATUS |
73 			TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS |
74 			TCPC_REG_ALERT_FAULT | TCPC_REG_ALERT_POWER_STATUS;
75 
76 	ret = tcpci_write_reg16(&cfg->bus, TCPC_REG_ALERT_MASK, mask);
77 	if (ret != 0) {
78 		return ret;
79 	}
80 
81 	return 0;
82 }
83 
ps8xxx_tcpc_init(const struct device * dev)84 static int ps8xxx_tcpc_init(const struct device *dev)
85 {
86 	struct ps8xxx_data *data = dev->data;
87 
88 	if (!data->initialized) {
89 		if (data->init_retries > CONFIG_USBC_TCPC_PS8XXX_INIT_RETRIES) {
90 			LOG_ERR("TCPC was not initialized correctly");
91 			return -EIO;
92 		}
93 
94 		return -EAGAIN;
95 	}
96 
97 	LOG_INF("PS8xxx TCPC initialized");
98 	return 0;
99 }
100 
ps8xxx_tcpc_get_cc(const struct device * dev,enum tc_cc_voltage_state * cc1,enum tc_cc_voltage_state * cc2)101 int ps8xxx_tcpc_get_cc(const struct device *dev, enum tc_cc_voltage_state *cc1,
102 		       enum tc_cc_voltage_state *cc2)
103 {
104 	const struct ps8xxx_cfg *cfg = dev->config;
105 	struct ps8xxx_data *data = dev->data;
106 	int ret;
107 
108 	if (!data->initialized) {
109 		return -EIO;
110 	}
111 
112 	if (IS_ENABLED(CONFIG_USBC_CSM_SINK_ONLY) && !data->cc_changed) {
113 		*cc1 = data->cc1;
114 		*cc2 = data->cc2;
115 
116 		return 0;
117 	}
118 
119 	data->cc_changed = false;
120 
121 	ret = tcpci_tcpm_get_cc(&cfg->bus, cc1, cc2);
122 
123 	if (IS_ENABLED(CONFIG_USBC_CSM_SINK_ONLY) || *cc1 != data->cc1 || *cc2 != data->cc2) {
124 		LOG_DBG("CC changed values: %d->%d, %d->%d", data->cc1, *cc1, data->cc2, *cc2);
125 		data->cc1 = *cc1;
126 		data->cc2 = *cc2;
127 	}
128 
129 	return ret;
130 }
131 
ps8xxx_tcpc_select_rp_value(const struct device * dev,enum tc_rp_value rp)132 int ps8xxx_tcpc_select_rp_value(const struct device *dev, enum tc_rp_value rp)
133 {
134 	const struct ps8xxx_cfg *cfg = dev->config;
135 	struct ps8xxx_data *data = dev->data;
136 
137 	data->cc_changed = true;
138 
139 	return tcpci_update_reg8(&cfg->bus, TCPC_REG_ROLE_CTRL, TCPC_REG_ROLE_CTRL_RP_MASK,
140 				 TCPC_REG_ROLE_CTRL_SET(0, rp, 0, 0));
141 }
142 
ps8xxx_tcpc_get_rp_value(const struct device * dev,enum tc_rp_value * rp)143 int ps8xxx_tcpc_get_rp_value(const struct device *dev, enum tc_rp_value *rp)
144 {
145 	const struct ps8xxx_cfg *cfg = dev->config;
146 	uint8_t reg_value = 0;
147 	int ret;
148 
149 	ret = tcpci_read_reg8(&cfg->bus, TCPC_REG_ROLE_CTRL, &reg_value);
150 	*rp = TCPC_REG_ROLE_CTRL_RP(reg_value);
151 
152 	return ret;
153 }
154 
ps8xxx_tcpc_set_cc(const struct device * dev,enum tc_cc_pull pull)155 int ps8xxx_tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull)
156 {
157 	const struct ps8xxx_cfg *cfg = dev->config;
158 	struct ps8xxx_data *data = dev->data;
159 
160 	if (!data->initialized) {
161 		return -EIO;
162 	}
163 
164 	data->cc_changed = true;
165 
166 	return tcpci_update_reg8(&cfg->bus, TCPC_REG_ROLE_CTRL,
167 				 TCPC_REG_ROLE_CTRL_CC1_MASK | TCPC_REG_ROLE_CTRL_CC2_MASK,
168 				 TCPC_REG_ROLE_CTRL_SET(0, 0, pull, pull));
169 }
170 
ps8xxx_tcpc_set_vconn_discharge_cb(const struct device * dev,tcpc_vconn_discharge_cb_t cb)171 void ps8xxx_tcpc_set_vconn_discharge_cb(const struct device *dev, tcpc_vconn_discharge_cb_t cb)
172 {
173 	struct ps8xxx_data *data = dev->data;
174 
175 	data->vconn_discharge_cb = cb;
176 }
177 
ps8xxx_tcpc_set_vconn_cb(const struct device * dev,tcpc_vconn_control_cb_t vconn_cb)178 void ps8xxx_tcpc_set_vconn_cb(const struct device *dev, tcpc_vconn_control_cb_t vconn_cb)
179 {
180 	struct ps8xxx_data *data = dev->data;
181 
182 	data->vconn_cb = vconn_cb;
183 }
184 
ps8xxx_tcpc_vconn_discharge(const struct device * dev,bool enable)185 int ps8xxx_tcpc_vconn_discharge(const struct device *dev, bool enable)
186 {
187 	const struct ps8xxx_cfg *cfg = dev->config;
188 
189 	return tcpci_update_reg8(&cfg->bus, TCPC_REG_POWER_CTRL,
190 				 TCPC_REG_POWER_CTRL_AUTO_DISCHARGE_DISCONNECT,
191 				 (enable) ? TCPC_REG_POWER_CTRL_AUTO_DISCHARGE_DISCONNECT : 0);
192 }
193 
ps8xxx_tcpc_set_vconn(const struct device * dev,bool enable)194 int ps8xxx_tcpc_set_vconn(const struct device *dev, bool enable)
195 {
196 	const struct ps8xxx_cfg *cfg = dev->config;
197 	struct ps8xxx_data *data = dev->data;
198 	int ret;
199 
200 	if (!data->initialized) {
201 		return -EIO;
202 	}
203 
204 	data->cc_changed = true;
205 	ret = tcpci_update_reg8(&cfg->bus, TCPC_REG_POWER_CTRL, TCPC_REG_POWER_CTRL_VCONN_EN,
206 				enable ? TCPC_REG_POWER_CTRL_VCONN_EN : 0);
207 
208 	if (ret != 0) {
209 		return ret;
210 	}
211 
212 	if (data->vconn_cb != NULL) {
213 		ret = data->vconn_cb(dev, data->cc_polarity, enable);
214 	}
215 
216 	return ret;
217 }
218 
ps8xxx_tcpc_set_roles(const struct device * dev,enum tc_power_role power_role,enum tc_data_role data_role)219 int ps8xxx_tcpc_set_roles(const struct device *dev, enum tc_power_role power_role,
220 			  enum tc_data_role data_role)
221 {
222 	const struct ps8xxx_cfg *cfg = dev->config;
223 
224 	return tcpci_update_reg8(&cfg->bus, TCPC_REG_MSG_HDR_INFO, TCPC_REG_MSG_HDR_INFO_ROLES_MASK,
225 				 TCPC_REG_MSG_HDR_INFO_SET(PD_REV30, data_role, power_role));
226 }
227 
ps8xxx_tcpc_get_rx_pending_msg(const struct device * dev,struct pd_msg * msg)228 int ps8xxx_tcpc_get_rx_pending_msg(const struct device *dev, struct pd_msg *msg)
229 {
230 	const struct ps8xxx_cfg *cfg = dev->config;
231 	struct ps8xxx_data *data = dev->data;
232 	struct i2c_msg buf[5];
233 	uint8_t msg_len = 0;
234 	uint8_t unused;
235 	int buf_count;
236 	int reg = TCPC_REG_RX_BUFFER;
237 	int ret;
238 
239 	if (!data->msg_pending) {
240 		return -ENODATA;
241 	}
242 
243 	if (msg == NULL) {
244 		return 0;
245 	}
246 
247 	data->msg_pending = false;
248 
249 	buf[0].buf = (uint8_t *)&reg;
250 	buf[0].len = 1;
251 	buf[0].flags = I2C_MSG_WRITE;
252 
253 	buf[1].buf = &msg_len;
254 	buf[1].len = 1;
255 	buf[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP;
256 	ret = i2c_transfer(cfg->bus.bus, buf, 2, cfg->bus.addr);
257 
258 	if (msg_len <= 1) {
259 		return 0;
260 	}
261 
262 	buf[1].buf = &unused;
263 	buf[1].len = 1;
264 	buf[1].flags = I2C_MSG_RESTART | I2C_MSG_READ;
265 
266 	buf[2].buf = (uint8_t *)&msg->type;
267 	buf[2].len = 1;
268 	buf[2].flags = I2C_MSG_RESTART | I2C_MSG_READ;
269 
270 	msg->header.raw_value = 0;
271 	buf[3].buf = (uint8_t *)&msg->header.raw_value;
272 	buf[3].len = 2;
273 	buf[3].flags = I2C_MSG_RESTART | I2C_MSG_READ;
274 
275 	if (msg_len > 3) {
276 		buf[4].buf = msg->data;
277 		buf[4].len = msg_len - 3;
278 		buf[4].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP;
279 		buf_count = 5;
280 	} else if (msg_len == 3) {
281 		buf[3].flags |= I2C_MSG_STOP;
282 		buf_count = 4;
283 	} else {
284 		buf[2].flags |= I2C_MSG_STOP;
285 		buf_count = 3;
286 	}
287 
288 	ret = i2c_transfer(cfg->bus.bus, buf, buf_count, cfg->bus.addr);
289 	if (ret != 0) {
290 		LOG_ERR("I2C transfer error: %d", ret);
291 	} else {
292 		msg->len = (msg_len > 3) ? msg_len - 3 : 0;
293 		ret = sizeof(msg->header.raw_value) + msg->len;
294 	}
295 
296 	tcpci_write_reg16(&cfg->bus, TCPC_REG_ALERT, TCPC_REG_ALERT_RX_STATUS);
297 	return ret;
298 }
299 
ps8xxx_tcpc_set_rx_enable(const struct device * dev,bool enable)300 int ps8xxx_tcpc_set_rx_enable(const struct device *dev, bool enable)
301 {
302 	const struct ps8xxx_cfg *cfg = dev->config;
303 	int detect_sop_en = enable ? TCPC_REG_RX_DETECT_SOP_HRST_MASK : 0;
304 
305 	return tcpci_write_reg8(&cfg->bus, TCPC_REG_RX_DETECT, detect_sop_en);
306 }
307 
ps8xxx_tcpc_set_cc_polarity(const struct device * dev,enum tc_cc_polarity polarity)308 int ps8xxx_tcpc_set_cc_polarity(const struct device *dev, enum tc_cc_polarity polarity)
309 {
310 	const struct ps8xxx_cfg *cfg = dev->config;
311 	struct ps8xxx_data *data = dev->data;
312 	int ret;
313 
314 	if (!data->initialized) {
315 		return -EIO;
316 	}
317 
318 	ret = tcpci_update_reg8(
319 		&cfg->bus, TCPC_REG_TCPC_CTRL, TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION,
320 		(polarity == TC_POLARITY_CC1) ? 0 : TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION);
321 
322 	if (ret != 0) {
323 		return ret;
324 	}
325 
326 	data->cc_changed = true;
327 	data->cc_polarity = polarity;
328 	return 0;
329 }
330 
ps8xxx_tcpc_transmit_data(const struct device * dev,struct pd_msg * msg)331 int ps8xxx_tcpc_transmit_data(const struct device *dev, struct pd_msg *msg)
332 {
333 	const struct ps8xxx_cfg *cfg = dev->config;
334 
335 	int reg = TCPC_REG_TX_BUFFER;
336 	int rv;
337 	int cnt = 4 * msg->header.number_of_data_objects;
338 
339 	/* If not SOP* transmission, just write to the transmit register */
340 	if (msg->header.message_type >= NUM_SOP_STAR_TYPES) {
341 		/*
342 		 * Per TCPCI spec, do not specify retry (although the TCPC
343 		 * should ignore retry field for these 3 types).
344 		 */
345 		return tcpci_write_reg8(
346 			&cfg->bus, TCPC_REG_TRANSMIT,
347 			TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(msg->header.message_type));
348 	}
349 
350 	if (cnt > 0) {
351 		reg = TCPC_REG_TX_BUFFER;
352 		/* TX_BYTE_CNT includes extra bytes for message header */
353 		cnt += sizeof(msg->header.raw_value);
354 
355 		struct i2c_msg buf[3];
356 
357 		uint8_t tmp[2] = {TCPC_REG_TX_BUFFER, cnt};
358 
359 		buf[0].buf = tmp;
360 		buf[0].len = 2;
361 		buf[0].flags = I2C_MSG_WRITE;
362 
363 		buf[1].buf = (uint8_t *)&msg->header.raw_value;
364 		buf[1].len = sizeof(msg->header.raw_value);
365 		buf[1].flags = I2C_MSG_WRITE;
366 
367 		buf[2].buf = (uint8_t *)msg->data;
368 		buf[2].len = msg->len;
369 		buf[2].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
370 
371 		if (cnt > sizeof(msg->header.raw_value)) {
372 			rv = i2c_transfer(cfg->bus.bus, buf, 3, cfg->bus.addr);
373 		} else {
374 			buf[1].flags |= I2C_MSG_STOP;
375 			rv = i2c_transfer(cfg->bus.bus, buf, 2, cfg->bus.addr);
376 		}
377 
378 		/* If tcpc write fails, return error */
379 		if (rv) {
380 			return rv;
381 		}
382 	}
383 
384 	/*
385 	 * We always retry in TCPC hardware since the TCPM is too slow to
386 	 * respond within tRetry (~195 usec).
387 	 *
388 	 * The retry count used is dependent on the maximum PD revision
389 	 * supported at build time.
390 	 */
391 	rv = tcpci_write_reg8(&cfg->bus, TCPC_REG_TRANSMIT,
392 			      TCPC_REG_TRANSMIT_SET_WITH_RETRY(cfg->transmit_retries, msg->type));
393 
394 	return rv;
395 }
396 
ps8xxx_tcpc_dump_std_reg(const struct device * dev)397 int ps8xxx_tcpc_dump_std_reg(const struct device *dev)
398 {
399 	const struct ps8xxx_cfg *cfg = dev->config;
400 	uint16_t value;
401 
402 	LOG_INF("TCPC %s:%s registers:", cfg->bus.bus->name, dev->name);
403 	for (unsigned int a = 0; a < TCPCI_STD_REGS_SIZE; a++) {
404 		switch (tcpci_std_regs[a].size) {
405 		case 1:
406 			tcpci_read_reg8(&cfg->bus, tcpci_std_regs[a].addr, (uint8_t *)&value);
407 			LOG_INF("- %-30s(0x%02x) =   0x%02x", tcpci_std_regs[a].name,
408 				tcpci_std_regs[a].addr, (uint8_t)value);
409 			break;
410 		case 2:
411 			tcpci_read_reg16(&cfg->bus, tcpci_std_regs[a].addr, &value);
412 			LOG_INF("- %-30s(0x%02x) = 0x%04x", tcpci_std_regs[a].name,
413 				tcpci_std_regs[a].addr, value);
414 			break;
415 		}
416 	}
417 
418 	return 0;
419 }
420 
ps8xxx_tcpc_alert_handler_cb(const struct device * dev,void * data,enum tcpc_alert alert)421 void ps8xxx_tcpc_alert_handler_cb(const struct device *dev, void *data, enum tcpc_alert alert)
422 {
423 }
424 
ps8xxx_tcpc_get_status_register(const struct device * dev,enum tcpc_status_reg reg,uint32_t * status)425 int ps8xxx_tcpc_get_status_register(const struct device *dev, enum tcpc_status_reg reg,
426 				    uint32_t *status)
427 {
428 	return -ENOSYS;
429 }
430 
ps8xxx_tcpc_clear_status_register(const struct device * dev,enum tcpc_status_reg reg,uint32_t mask)431 int ps8xxx_tcpc_clear_status_register(const struct device *dev, enum tcpc_status_reg reg,
432 				      uint32_t mask)
433 {
434 	return -ENOSYS;
435 }
436 
ps8xxx_tcpc_mask_status_register(const struct device * dev,enum tcpc_status_reg reg,uint32_t mask)437 int ps8xxx_tcpc_mask_status_register(const struct device *dev, enum tcpc_status_reg reg,
438 				     uint32_t mask)
439 {
440 	return -ENOSYS;
441 }
442 
ps8xxx_tcpc_set_debug_accessory(const struct device * dev,bool enable)443 int ps8xxx_tcpc_set_debug_accessory(const struct device *dev, bool enable)
444 {
445 	return -ENOSYS;
446 }
447 
ps8xxx_tcpc_set_debug_detach(const struct device * dev)448 int ps8xxx_tcpc_set_debug_detach(const struct device *dev)
449 {
450 	return -ENOSYS;
451 }
452 
ps8xxx_tcpc_set_drp_toggle(const struct device * dev,bool enable)453 int ps8xxx_tcpc_set_drp_toggle(const struct device *dev, bool enable)
454 {
455 	return -ENOSYS;
456 }
457 
ps8xxx_tcpc_get_snk_ctrl(const struct device * dev)458 int ps8xxx_tcpc_get_snk_ctrl(const struct device *dev)
459 {
460 	return -ENOSYS;
461 }
462 
ps8xxx_tcpc_set_snk_ctrl(const struct device * dev,bool enable)463 int ps8xxx_tcpc_set_snk_ctrl(const struct device *dev, bool enable)
464 {
465 	const struct ps8xxx_cfg *cfg = dev->config;
466 	uint8_t cmd = (enable) ? TCPC_REG_COMMAND_SNK_CTRL_HIGH : TCPC_REG_COMMAND_SNK_CTRL_LOW;
467 
468 	return tcpci_write_reg8(&cfg->bus, TCPC_REG_COMMAND, cmd);
469 }
470 
ps8xxx_tcpc_get_src_ctrl(const struct device * dev)471 int ps8xxx_tcpc_get_src_ctrl(const struct device *dev)
472 {
473 	return -ENOSYS;
474 }
475 
ps8xxx_tcpc_set_src_ctrl(const struct device * dev,bool enable)476 int ps8xxx_tcpc_set_src_ctrl(const struct device *dev, bool enable)
477 {
478 	const struct ps8xxx_cfg *cfg = dev->config;
479 	uint8_t cmd = (enable) ? TCPC_REG_COMMAND_SRC_CTRL_DEF : TCPC_REG_COMMAND_SRC_CTRL_LOW;
480 
481 	return tcpci_write_reg8(&cfg->bus, TCPC_REG_COMMAND, cmd);
482 }
483 
ps8xxx_tcpc_get_chip_info(const struct device * dev,struct tcpc_chip_info * chip_info)484 int ps8xxx_tcpc_get_chip_info(const struct device *dev, struct tcpc_chip_info *chip_info)
485 {
486 	const struct ps8xxx_cfg *cfg = dev->config;
487 	int ret = 0;
488 
489 	if (chip_info == NULL) {
490 		return -EIO;
491 	}
492 
493 	ret |= tcpci_read_reg16(&cfg->bus, TCPC_REG_VENDOR_ID, &chip_info->vendor_id);
494 	ret |= tcpci_read_reg16(&cfg->bus, TCPC_REG_PRODUCT_ID, &chip_info->product_id);
495 	ret |= tcpci_read_reg16(&cfg->bus, TCPC_REG_BCD_DEV, &chip_info->device_id);
496 
497 	/* Vendor specific register for PS8815 model only */
498 	if (chip_info->product_id == PS8815_PRODUCT_ID) {
499 		uint8_t fw_ver;
500 
501 		ret |= tcpci_read_reg8(&cfg->bus, PS8815_REG_FW_VER, &fw_ver);
502 		chip_info->fw_version_number = fw_ver;
503 	} else {
504 		chip_info->fw_version_number = 0;
505 	}
506 
507 	chip_info->min_req_fw_version_number = 0;
508 
509 	return ret;
510 }
511 
ps8xxx_tcpc_set_low_power_mode(const struct device * dev,bool enable)512 int ps8xxx_tcpc_set_low_power_mode(const struct device *dev, bool enable)
513 {
514 	const struct ps8xxx_cfg *cfg = dev->config;
515 
516 	return tcpci_write_reg8(&cfg->bus, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE);
517 }
518 
ps8xxx_tcpc_sop_prime_enable(const struct device * dev,bool enable)519 int ps8xxx_tcpc_sop_prime_enable(const struct device *dev, bool enable)
520 {
521 	return -ENOSYS;
522 }
523 
ps8xxx_tcpc_set_bist_test_mode(const struct device * dev,bool enable)524 int ps8xxx_tcpc_set_bist_test_mode(const struct device *dev, bool enable)
525 {
526 	return -ENOSYS;
527 }
528 
ps8xxx_tcpc_set_alert_handler_cb(const struct device * dev,tcpc_alert_handler_cb_t handler,void * handler_data)529 int ps8xxx_tcpc_set_alert_handler_cb(const struct device *dev, tcpc_alert_handler_cb_t handler,
530 				     void *handler_data)
531 {
532 	struct ps8xxx_data *data = dev->data;
533 
534 	if (data->alert_handler == handler && data->alert_handler_data == handler_data) {
535 		return 0;
536 	}
537 
538 	data->alert_handler = handler;
539 	data->alert_handler_data = handler_data;
540 
541 	return 0;
542 }
543 
544 /* Functions not assigned to the driver API but used by device */
545 
546 static DEVICE_API(tcpc, ps8xxx_driver_api) = {
547 	.init = ps8xxx_tcpc_init,
548 	.get_cc = ps8xxx_tcpc_get_cc,
549 	.select_rp_value = ps8xxx_tcpc_select_rp_value,
550 	.get_rp_value = ps8xxx_tcpc_get_rp_value,
551 	.set_cc = ps8xxx_tcpc_set_cc,
552 	.set_vconn_discharge_cb = ps8xxx_tcpc_set_vconn_discharge_cb,
553 	.set_vconn_cb = ps8xxx_tcpc_set_vconn_cb,
554 	.vconn_discharge = ps8xxx_tcpc_vconn_discharge,
555 	.set_vconn = ps8xxx_tcpc_set_vconn,
556 	.set_roles = ps8xxx_tcpc_set_roles,
557 	.get_rx_pending_msg = ps8xxx_tcpc_get_rx_pending_msg,
558 	.set_rx_enable = ps8xxx_tcpc_set_rx_enable,
559 	.set_cc_polarity = ps8xxx_tcpc_set_cc_polarity,
560 	.transmit_data = ps8xxx_tcpc_transmit_data,
561 	.dump_std_reg = ps8xxx_tcpc_dump_std_reg,
562 	.alert_handler_cb = ps8xxx_tcpc_alert_handler_cb,
563 	.get_status_register = ps8xxx_tcpc_get_status_register,
564 	.clear_status_register = ps8xxx_tcpc_clear_status_register,
565 	.mask_status_register = ps8xxx_tcpc_mask_status_register,
566 	.set_debug_accessory = ps8xxx_tcpc_set_debug_accessory,
567 	.set_debug_detach = ps8xxx_tcpc_set_debug_detach,
568 	.set_drp_toggle = ps8xxx_tcpc_set_drp_toggle,
569 	.get_snk_ctrl = ps8xxx_tcpc_get_snk_ctrl,
570 	.set_snk_ctrl = ps8xxx_tcpc_set_snk_ctrl,
571 	.get_src_ctrl = ps8xxx_tcpc_get_src_ctrl,
572 	.set_src_ctrl = ps8xxx_tcpc_set_src_ctrl,
573 	.get_chip_info = ps8xxx_tcpc_get_chip_info,
574 	.set_low_power_mode = ps8xxx_tcpc_set_low_power_mode,
575 	.sop_prime_enable = ps8xxx_tcpc_sop_prime_enable,
576 	.set_bist_test_mode = ps8xxx_tcpc_set_bist_test_mode,
577 	.set_alert_handler_cb = ps8xxx_tcpc_set_alert_handler_cb,
578 };
579 
ps8xxx_alert_cb(const struct device * port,struct gpio_callback * cb,gpio_port_pins_t pins)580 void ps8xxx_alert_cb(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins)
581 {
582 	struct ps8xxx_data *data = CONTAINER_OF(cb, struct ps8xxx_data, alert_cb);
583 
584 	k_work_submit(&data->alert_work);
585 }
586 
ps8xxx_alert_work_cb(struct k_work * work)587 void ps8xxx_alert_work_cb(struct k_work *work)
588 {
589 	struct ps8xxx_data *data = CONTAINER_OF(work, struct ps8xxx_data, alert_work);
590 	const struct device *dev = data->dev;
591 	const struct ps8xxx_cfg *cfg = dev->config;
592 	uint16_t alert_reg = 0;
593 	uint16_t clear_flags = 0;
594 
595 	if (!data->initialized) {
596 		return;
597 	}
598 
599 	tcpci_read_reg16(&cfg->bus, TCPC_REG_ALERT, &alert_reg);
600 
601 	while (alert_reg != 0) {
602 		enum tcpc_alert alert_type = tcpci_alert_reg_to_enum(alert_reg);
603 
604 		if (alert_type == TCPC_ALERT_HARD_RESET_RECEIVED) {
605 			LOG_DBG("PS8xxx hard rst received");
606 			tcpci_init_alert_mask(dev);
607 			data->cc_changed = true;
608 		} else if (alert_type == TCPC_ALERT_FAULT_STATUS) {
609 			uint8_t fault;
610 
611 			tcpci_read_reg8(&cfg->bus, TCPC_REG_FAULT_STATUS, &fault);
612 			tcpci_write_reg8(&cfg->bus, TCPC_REG_FAULT_STATUS, fault);
613 
614 			LOG_DBG("PS8xxx fault: %02x", fault);
615 		} else if (alert_type == TCPC_ALERT_EXTENDED_STATUS) {
616 			uint8_t ext_status;
617 
618 			tcpci_read_reg8(&cfg->bus, TCPC_REG_EXT_STATUS, &ext_status);
619 			tcpci_write_reg8(&cfg->bus, TCPC_REG_EXT_STATUS, ext_status);
620 
621 			data->cc_changed = true;
622 			LOG_DBG("PS8xxx ext status: %02x", ext_status);
623 		} else if (alert_type == TCPC_ALERT_POWER_STATUS) {
624 			uint8_t pwr_status;
625 
626 			tcpci_read_reg8(&cfg->bus, TCPC_REG_POWER_STATUS, &pwr_status);
627 			tcpci_write_reg8(&cfg->bus, TCPC_REG_POWER_STATUS, pwr_status);
628 
629 			LOG_DBG("PS8xxx power status: %02x", pwr_status);
630 		} else if (alert_type == TCPC_ALERT_EXTENDED) {
631 			uint8_t alert_status;
632 
633 			tcpci_read_reg8(&cfg->bus, TCPC_REG_ALERT_EXT, &alert_status);
634 			tcpci_write_reg8(&cfg->bus, TCPC_REG_ALERT_EXT, alert_status);
635 
636 			LOG_DBG("PS8xxx ext alert: %02x", alert_status);
637 		} else if (alert_type == TCPC_ALERT_MSG_STATUS) {
638 			data->msg_pending = true;
639 		} else if (alert_type == TCPC_ALERT_CC_STATUS) {
640 			data->cc_changed = true;
641 		}
642 
643 		if (data->alert_handler != NULL) {
644 			data->alert_handler(data->dev, data->alert_handler_data, alert_type);
645 		}
646 
647 		clear_flags |= BIT(alert_type);
648 		alert_reg &= ~BIT(alert_type);
649 	}
650 
651 	tcpci_write_reg16(&cfg->bus, TCPC_REG_ALERT, clear_flags);
652 
653 	tcpci_read_reg16(&cfg->bus, TCPC_REG_ALERT, &alert_reg);
654 	if (alert_reg != 0) {
655 		k_work_submit(work);
656 	}
657 }
658 
ps8xxx_init_work_cb(struct k_work * work)659 void ps8xxx_init_work_cb(struct k_work *work)
660 {
661 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
662 	struct ps8xxx_data *data = CONTAINER_OF(dwork, struct ps8xxx_data, init_dwork);
663 
664 	const struct ps8xxx_cfg *cfg = data->dev->config;
665 	uint8_t power_reg = 0;
666 	uint16_t idVendor = 0;
667 	uint16_t idProduct = 0;
668 	uint16_t idDevice = 0;
669 	int res;
670 
671 	LOG_INF("Initializing PS8xxx chip: %s", data->dev->name);
672 	res = tcpci_read_reg8(&cfg->bus, TCPC_REG_POWER_STATUS, &power_reg);
673 	if (res != 0 || (power_reg & TCPC_REG_POWER_STATUS_UNINIT)) {
674 		data->init_retries++;
675 
676 		if (data->init_retries > CONFIG_USBC_TCPC_PS8XXX_INIT_RETRIES) {
677 			LOG_ERR("Chip didn't respond");
678 			return;
679 		}
680 
681 		LOG_DBG("Postpone chip initialization %d", data->init_retries);
682 		k_work_schedule_for_queue(&k_sys_work_q, &data->init_dwork,
683 					  K_MSEC(CONFIG_USBC_TCPC_PS8XXX_INIT_DELAY));
684 
685 		return;
686 	}
687 
688 	tcpci_read_reg16(&cfg->bus, TCPC_REG_VENDOR_ID, &idVendor);
689 	tcpci_read_reg16(&cfg->bus, TCPC_REG_PRODUCT_ID, &idProduct);
690 	tcpci_read_reg16(&cfg->bus, TCPC_REG_BCD_DEV, &idDevice);
691 	LOG_INF("Initialized chip is: %04x:%04x:%04x", idVendor, idProduct, idDevice);
692 
693 	/* Initialize alert interrupt */
694 	gpio_pin_configure_dt(&cfg->alert_gpio, GPIO_INPUT);
695 
696 	gpio_init_callback(&data->alert_cb, ps8xxx_alert_cb, BIT(cfg->alert_gpio.pin));
697 	gpio_add_callback(cfg->alert_gpio.port, &data->alert_cb);
698 	gpio_pin_interrupt_configure_dt(&cfg->alert_gpio, GPIO_INT_EDGE_TO_ACTIVE);
699 
700 	tcpci_init_alert_mask(data->dev);
701 	data->initialized = true;
702 
703 	/* Disable the vconn and open CC lines to reinitialize the communication with partner */
704 	ps8xxx_tcpc_set_vconn(data->dev, false);
705 	ps8xxx_tcpc_set_cc(data->dev, TC_CC_OPEN);
706 
707 	/* Check and clear any alert set after initialization */
708 	k_work_submit(&data->alert_work);
709 }
710 
ps8xxx_dev_init(const struct device * dev)711 static int ps8xxx_dev_init(const struct device *dev)
712 {
713 	const struct ps8xxx_cfg *cfg = dev->config;
714 	struct ps8xxx_data *data = dev->data;
715 
716 	if (!device_is_ready(cfg->bus.bus)) {
717 		return -EIO;
718 	}
719 
720 	k_work_init_delayable(&data->init_dwork, ps8xxx_init_work_cb);
721 	k_work_schedule_for_queue(&k_sys_work_q, &data->init_dwork,
722 				  K_MSEC(CONFIG_USBC_TCPC_PS8XXX_INIT_DELAY));
723 
724 	k_work_init(&data->alert_work, ps8xxx_alert_work_cb);
725 
726 	return 0;
727 }
728 
729 #define PS8XXX_DRIVER_DATA_INIT(node)                                                              \
730 	{                                                                                          \
731 		.dev = DEVICE_DT_GET(node),                                                        \
732 		.init_retries = 0,                                                                 \
733 		.cc_changed = true,                                                                \
734 	}
735 
736 #define PS8XXX_DRIVER_CFG_INIT(node)                                                               \
737 	{                                                                                          \
738 		.bus = I2C_DT_SPEC_GET(node),                                                      \
739 		.alert_gpio = GPIO_DT_SPEC_GET(node, irq_gpios),                                   \
740 		.transmit_retries = DT_PROP(node, transmit_retries),                               \
741 	}
742 
743 #define PS8XXX_DRIVER_INIT(inst)                                                                   \
744 	static struct ps8xxx_data drv_data_ps8xxx##inst =                                          \
745 		PS8XXX_DRIVER_DATA_INIT(DT_DRV_INST(inst));                                        \
746 	static struct ps8xxx_cfg drv_cfg_ps8xxx##inst = PS8XXX_DRIVER_CFG_INIT(DT_DRV_INST(inst)); \
747 	DEVICE_DT_INST_DEFINE(inst, &ps8xxx_dev_init, NULL, &drv_data_ps8xxx##inst,                \
748 			      &drv_cfg_ps8xxx##inst, POST_KERNEL, CONFIG_USBC_TCPC_INIT_PRIORITY,  \
749 			      &ps8xxx_driver_api);
750 
751 DT_INST_FOREACH_STATUS_OKAY(PS8XXX_DRIVER_INIT)
752