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