1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * MUSB OTG driver peripheral defines
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright 2005 Mentor Graphics Corporation
6*4882a593Smuzhiyun * Copyright (C) 2005-2006 by Texas Instruments
7*4882a593Smuzhiyun * Copyright (C) 2006-2007 Nokia Corporation
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #ifndef __MUSB_GADGET_H
11*4882a593Smuzhiyun #define __MUSB_GADGET_H
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <linux/list.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_USB_MUSB_GADGET) || IS_ENABLED(CONFIG_USB_MUSB_DUAL_ROLE)
16*4882a593Smuzhiyun extern irqreturn_t musb_g_ep0_irq(struct musb *);
17*4882a593Smuzhiyun extern void musb_g_tx(struct musb *, u8);
18*4882a593Smuzhiyun extern void musb_g_rx(struct musb *, u8);
19*4882a593Smuzhiyun extern void musb_g_reset(struct musb *);
20*4882a593Smuzhiyun extern void musb_g_suspend(struct musb *);
21*4882a593Smuzhiyun extern void musb_g_resume(struct musb *);
22*4882a593Smuzhiyun extern void musb_g_wakeup(struct musb *);
23*4882a593Smuzhiyun extern void musb_g_disconnect(struct musb *);
24*4882a593Smuzhiyun extern void musb_gadget_cleanup(struct musb *);
25*4882a593Smuzhiyun extern int musb_gadget_setup(struct musb *);
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #else
musb_g_ep0_irq(struct musb * musb)28*4882a593Smuzhiyun static inline irqreturn_t musb_g_ep0_irq(struct musb *musb)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun return 0;
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun
musb_g_tx(struct musb * musb,u8 epnum)33*4882a593Smuzhiyun static inline void musb_g_tx(struct musb *musb, u8 epnum) {}
musb_g_rx(struct musb * musb,u8 epnum)34*4882a593Smuzhiyun static inline void musb_g_rx(struct musb *musb, u8 epnum) {}
musb_g_reset(struct musb * musb)35*4882a593Smuzhiyun static inline void musb_g_reset(struct musb *musb) {}
musb_g_suspend(struct musb * musb)36*4882a593Smuzhiyun static inline void musb_g_suspend(struct musb *musb) {}
musb_g_resume(struct musb * musb)37*4882a593Smuzhiyun static inline void musb_g_resume(struct musb *musb) {}
musb_g_wakeup(struct musb * musb)38*4882a593Smuzhiyun static inline void musb_g_wakeup(struct musb *musb) {}
musb_g_disconnect(struct musb * musb)39*4882a593Smuzhiyun static inline void musb_g_disconnect(struct musb *musb) {}
musb_gadget_cleanup(struct musb * musb)40*4882a593Smuzhiyun static inline void musb_gadget_cleanup(struct musb *musb) {}
musb_gadget_setup(struct musb * musb)41*4882a593Smuzhiyun static inline int musb_gadget_setup(struct musb *musb)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun return 0;
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun #endif
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun enum buffer_map_state {
48*4882a593Smuzhiyun UN_MAPPED = 0,
49*4882a593Smuzhiyun PRE_MAPPED,
50*4882a593Smuzhiyun MUSB_MAPPED
51*4882a593Smuzhiyun };
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun struct musb_request {
54*4882a593Smuzhiyun struct usb_request request;
55*4882a593Smuzhiyun struct list_head list;
56*4882a593Smuzhiyun struct musb_ep *ep;
57*4882a593Smuzhiyun struct musb *musb;
58*4882a593Smuzhiyun u8 tx; /* endpoint direction */
59*4882a593Smuzhiyun u8 epnum;
60*4882a593Smuzhiyun enum buffer_map_state map_state;
61*4882a593Smuzhiyun };
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #define to_musb_request(r) container_of((r), struct musb_request, request)
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun extern struct usb_request *
66*4882a593Smuzhiyun musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
67*4882a593Smuzhiyun extern void musb_free_request(struct usb_ep *ep, struct usb_request *req);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /*
71*4882a593Smuzhiyun * struct musb_ep - peripheral side view of endpoint rx or tx side
72*4882a593Smuzhiyun */
73*4882a593Smuzhiyun struct musb_ep {
74*4882a593Smuzhiyun /* stuff towards the head is basically write-once. */
75*4882a593Smuzhiyun struct usb_ep end_point;
76*4882a593Smuzhiyun char name[12];
77*4882a593Smuzhiyun struct musb_hw_ep *hw_ep;
78*4882a593Smuzhiyun struct musb *musb;
79*4882a593Smuzhiyun u8 current_epnum;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /* ... when enabled/disabled ... */
82*4882a593Smuzhiyun u8 type;
83*4882a593Smuzhiyun u8 is_in;
84*4882a593Smuzhiyun u16 packet_sz;
85*4882a593Smuzhiyun const struct usb_endpoint_descriptor *desc;
86*4882a593Smuzhiyun struct dma_channel *dma;
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun /* later things are modified based on usage */
89*4882a593Smuzhiyun struct list_head req_list;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun u8 wedged;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /* true if lock must be dropped but req_list may not be advanced */
94*4882a593Smuzhiyun u8 busy;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun u8 hb_mult;
97*4882a593Smuzhiyun };
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun #define to_musb_ep(ep) container_of((ep), struct musb_ep, end_point)
100*4882a593Smuzhiyun
next_request(struct musb_ep * ep)101*4882a593Smuzhiyun static inline struct musb_request *next_request(struct musb_ep *ep)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun struct list_head *queue = &ep->req_list;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun if (list_empty(queue))
106*4882a593Smuzhiyun return NULL;
107*4882a593Smuzhiyun return container_of(queue->next, struct musb_request, list);
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun extern const struct usb_ep_ops musb_g_ep0_ops;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun extern void musb_ep_restart(struct musb *, struct musb_request *);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun #endif /* __MUSB_GADGET_H */
117