summaryrefslogtreecommitdiff
path: root/zephyr/shim/include/usbc/ppc.h
blob: 98e9c3f72833674dbf655f3ecb75e73c0fa75832 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* Copyright 2021 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef ZEPHYR_CHROME_USBC_PPC_H
#define ZEPHYR_CHROME_USBC_PPC_H

#include "usbc/ppc_aoz1380.h"
#include "usbc/ppc_nx20p348x.h"
#include "usbc/ppc_rt1739.h"
#include "usbc/ppc_sn5s330.h"
#include "usbc/ppc_syv682x.h"
#include "usbc/utils.h"
#include "usbc_ppc.h"

#include <zephyr/device.h>
#include <zephyr/devicetree.h>

/**
 * @brief Create a unique name based on a PPC altnernate node.
 *
 *	ppc_syv682x_alt: syv682x@43 {
 *		compatible = "silergy,syv682x";
 *		status = "okay";
 *		reg = <0x43>;
 *		frs_en_gpio = <&ioex_usb_c0_frs_en>;
 *		is-alt;
 *	};
 *
 * Usage:
 *	PPC_ALT_NAME_GET(DT_NODELABEL(ppc_syv682x_alt))
 *
 * expands to "ppc_alt_DT_N_S_i2c_100_S_syv682x_43"
 */
#define PPC_ALT_NAME_GET(node_id) DT_CAT(ppc_alt_, node_id)

/**
 * @brief Get the PPC alternate entry based on a nodelabel.
 *
 * Usage:
 *	PPC_ALT_FROM_NODELABEL(ppc_syv682x_alt))
 *
 * expands to "ppc_alt_DT_N_S_i2c_100_S_syv682x_43"
 */
#define PPC_ALT_FROM_NODELABEL(lbl) (PPC_ALT_NAME_GET(DT_NODELABEL(lbl)))

/**
 * @brief - Forward declare a global struct ppc_config_t entry based on
 * a single PPC altnerate from the devicetree.
 */
#define PPC_ALT_DECLARATION(node_id) \
	extern const struct ppc_config_t PPC_ALT_NAME_GET(node_id)

#define PPC_ALT_DECLARE(node_id)                    \
	COND_CODE_1(DT_PROP_OR(node_id, is_alt, 0), \
		    (PPC_ALT_DECLARATION(node_id);), ())

/*
 * Forward declare a struct ppc_config_t for every PPC node in the tree with the
 * "is-alt" property set.
 */
DT_FOREACH_STATUS_OKAY(AOZ1380_COMPAT, PPC_ALT_DECLARE)
DT_FOREACH_STATUS_OKAY(NX20P348X_COMPAT, PPC_ALT_DECLARE)
DT_FOREACH_STATUS_OKAY(RT1739_PPC_COMPAT, PPC_ALT_DECLARE)
DT_FOREACH_STATUS_OKAY(SN5S330_COMPAT, PPC_ALT_DECLARE)
DT_FOREACH_STATUS_OKAY(SN5S330_EMUL_COMPAT, PPC_ALT_DECLARE)
DT_FOREACH_STATUS_OKAY(SYV682X_COMPAT, PPC_ALT_DECLARE)
DT_FOREACH_STATUS_OKAY(SYV682X_EMUL_COMPAT, PPC_ALT_DECLARE)

extern struct ppc_config_t ppc_chips_alt[];

#define ALT_PPC_CHIP_CHK(usbc_id, usb_port_num)                              \
	COND_CODE_1(DT_REG_HAS_IDX(usbc_id, usb_port_num),                   \
		    (COND_CODE_1(DT_NODE_HAS_PROP(usbc_id, ppc_alt), (|| 1), \
				 (|| 0))),                                   \
		    (|| 0))

#define PPC_ENABLE_ALTERNATE(usb_port_num)                                            \
	do {                                                                          \
		BUILD_ASSERT(                                                         \
			(0 DT_FOREACH_STATUS_OKAY_VARGS(named_usbc_port,              \
							ALT_PPC_CHIP_CHK,             \
							usb_port_num)),               \
			"Selected USB node does not exist or does not specify a PPC " \
			"alternate chip");                                            \
		memcpy(&ppc_chips[usb_port_num], &ppc_chips_alt[usb_port_num],        \
		       sizeof(struct ppc_config_t));                                  \
	} while (0)

#define PPC_ENABLE_ALTERNATE_BY_NODELABEL(usb_port_num, nodelabel)           \
	memcpy(&ppc_chips[usb_port_num], &PPC_ALT_FROM_NODELABEL(nodelabel), \
	       sizeof(struct ppc_config_t))

#endif /* ZEPHYR_CHROME_USBC_PPC_H */