1 | /* SPDX-License-Identifier: GPL-1.0+ */ |
2 | /* |
3 | * Renesas USB driver |
4 | * |
5 | * Copyright (C) 2011 Renesas Solutions Corp. |
6 | * Copyright (C) 2019 Renesas Electronics Corporation |
7 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
8 | */ |
9 | #ifndef RENESAS_USB_MOD_H |
10 | #define RENESAS_USB_MOD_H |
11 | |
12 | #include <linux/spinlock.h> |
13 | #include <linux/usb/renesas_usbhs.h> |
14 | #include "common.h" |
15 | |
16 | /* |
17 | * struct |
18 | */ |
19 | struct usbhs_irq_state { |
20 | u16 intsts0; |
21 | u16 intsts1; |
22 | u16 brdysts; |
23 | u16 nrdysts; |
24 | u16 bempsts; |
25 | }; |
26 | |
27 | struct usbhs_mod { |
28 | char *name; |
29 | |
30 | /* |
31 | * entry point from common.c |
32 | */ |
33 | int (*start)(struct usbhs_priv *priv); |
34 | int (*stop)(struct usbhs_priv *priv); |
35 | |
36 | /* |
37 | * INTSTS0 |
38 | */ |
39 | |
40 | /* DVST (DVSQ) */ |
41 | int (*irq_dev_state)(struct usbhs_priv *priv, |
42 | struct usbhs_irq_state *irq_state); |
43 | |
44 | /* CTRT (CTSQ) */ |
45 | int (*irq_ctrl_stage)(struct usbhs_priv *priv, |
46 | struct usbhs_irq_state *irq_state); |
47 | |
48 | /* BEMP / BEMPSTS */ |
49 | int (*irq_empty)(struct usbhs_priv *priv, |
50 | struct usbhs_irq_state *irq_state); |
51 | u16 irq_bempsts; |
52 | |
53 | /* BRDY / BRDYSTS */ |
54 | int (*irq_ready)(struct usbhs_priv *priv, |
55 | struct usbhs_irq_state *irq_state); |
56 | u16 irq_brdysts; |
57 | |
58 | /* |
59 | * INTSTS1 |
60 | */ |
61 | |
62 | /* ATTCHE */ |
63 | int (*irq_attch)(struct usbhs_priv *priv, |
64 | struct usbhs_irq_state *irq_state); |
65 | |
66 | /* DTCHE */ |
67 | int (*irq_dtch)(struct usbhs_priv *priv, |
68 | struct usbhs_irq_state *irq_state); |
69 | |
70 | /* SIGN */ |
71 | int (*irq_sign)(struct usbhs_priv *priv, |
72 | struct usbhs_irq_state *irq_state); |
73 | |
74 | /* SACK */ |
75 | int (*irq_sack)(struct usbhs_priv *priv, |
76 | struct usbhs_irq_state *irq_state); |
77 | |
78 | struct usbhs_priv *priv; |
79 | }; |
80 | |
81 | struct usbhs_mod_info { |
82 | struct usbhs_mod *mod[USBHS_MAX]; |
83 | struct usbhs_mod *curt; /* current mod */ |
84 | |
85 | /* |
86 | * INTSTS0 :: VBINT |
87 | * |
88 | * This function will be used as autonomy mode (runtime_pwctrl == 0) |
89 | * when the platform doesn't have own get_vbus function. |
90 | * |
91 | * This callback cannot be member of "struct usbhs_mod" because it |
92 | * will be used even though host/gadget has not been selected. |
93 | */ |
94 | int (*irq_vbus)(struct usbhs_priv *priv, |
95 | struct usbhs_irq_state *irq_state); |
96 | |
97 | /* |
98 | * This function will be used on any gadget mode. To simplify the code, |
99 | * this member is in here. |
100 | */ |
101 | int (*get_vbus)(struct platform_device *pdev); |
102 | }; |
103 | |
104 | /* |
105 | * for host/gadget module |
106 | */ |
107 | struct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id); |
108 | struct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv); |
109 | void usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *usb, int id); |
110 | int usbhs_mod_is_host(struct usbhs_priv *priv); |
111 | int usbhs_mod_change(struct usbhs_priv *priv, int id); |
112 | int usbhs_mod_probe(struct usbhs_priv *priv); |
113 | void usbhs_mod_remove(struct usbhs_priv *priv); |
114 | |
115 | void usbhs_mod_autonomy_mode(struct usbhs_priv *priv); |
116 | void usbhs_mod_non_autonomy_mode(struct usbhs_priv *priv); |
117 | |
118 | /* |
119 | * status functions |
120 | */ |
121 | int usbhs_status_get_device_state(struct usbhs_irq_state *irq_state); |
122 | int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state); |
123 | |
124 | /* |
125 | * callback functions |
126 | */ |
127 | void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); |
128 | |
129 | |
130 | #define usbhs_mod_call(priv, func, param...) \ |
131 | ({ \ |
132 | struct usbhs_mod *mod; \ |
133 | mod = usbhs_mod_get_current(priv); \ |
134 | !mod ? -ENODEV : \ |
135 | !mod->func ? 0 : \ |
136 | mod->func(param); \ |
137 | }) |
138 | |
139 | #define usbhs_priv_to_modinfo(priv) (&priv->mod_info) |
140 | #define usbhs_mod_info_call(priv, func, param...) \ |
141 | ({ \ |
142 | struct usbhs_mod_info *info; \ |
143 | info = usbhs_priv_to_modinfo(priv); \ |
144 | !info->func ? 0 : \ |
145 | info->func(param); \ |
146 | }) |
147 | |
148 | /* |
149 | * host / gadget control |
150 | */ |
151 | #if defined(CONFIG_USB_RENESAS_USBHS_HCD) || \ |
152 | defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE) |
153 | extern int usbhs_mod_host_probe(struct usbhs_priv *priv); |
154 | extern int usbhs_mod_host_remove(struct usbhs_priv *priv); |
155 | #else |
156 | static inline int usbhs_mod_host_probe(struct usbhs_priv *priv) |
157 | { |
158 | return 0; |
159 | } |
160 | static inline void usbhs_mod_host_remove(struct usbhs_priv *priv) |
161 | { |
162 | } |
163 | #endif |
164 | |
165 | #if defined(CONFIG_USB_RENESAS_USBHS_UDC) || \ |
166 | defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE) |
167 | extern int usbhs_mod_gadget_probe(struct usbhs_priv *priv); |
168 | extern void usbhs_mod_gadget_remove(struct usbhs_priv *priv); |
169 | #else |
170 | static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv) |
171 | { |
172 | return 0; |
173 | } |
174 | static inline void usbhs_mod_gadget_remove(struct usbhs_priv *priv) |
175 | { |
176 | } |
177 | #endif |
178 | |
179 | #endif /* RENESAS_USB_MOD_H */ |
180 | |