12f98382dSKuninori Morimoto /* 22f98382dSKuninori Morimoto * Renesas USB driver 32f98382dSKuninori Morimoto * 42f98382dSKuninori Morimoto * Copyright (C) 2011 Renesas Solutions Corp. 52f98382dSKuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 62f98382dSKuninori Morimoto * 72f98382dSKuninori Morimoto * This program is distributed in the hope that it will be useful, 82f98382dSKuninori Morimoto * but WITHOUT ANY WARRANTY; without even the implied warranty of 92f98382dSKuninori Morimoto * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 102f98382dSKuninori Morimoto * GNU General Public License for more details. 112f98382dSKuninori Morimoto * 122f98382dSKuninori Morimoto * You should have received a copy of the GNU General Public License 132f98382dSKuninori Morimoto * along with this program; if not, write to the Free Software 142f98382dSKuninori Morimoto * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 152f98382dSKuninori Morimoto * 162f98382dSKuninori Morimoto */ 17dfbb7f4fSKuninori Morimoto #include <linux/delay.h> 18d128a259SKuninori Morimoto #include <linux/dma-mapping.h> 192f98382dSKuninori Morimoto #include <linux/io.h> 202f98382dSKuninori Morimoto #include <linux/module.h> 212f98382dSKuninori Morimoto #include <linux/platform_device.h> 222f98382dSKuninori Morimoto #include <linux/usb/ch9.h> 232f98382dSKuninori Morimoto #include <linux/usb/gadget.h> 24b5a28756SPhil Edworthy #include <linux/usb/otg.h> 252f98382dSKuninori Morimoto #include "common.h" 262f98382dSKuninori Morimoto 272f98382dSKuninori Morimoto /* 282f98382dSKuninori Morimoto * struct 292f98382dSKuninori Morimoto */ 302f98382dSKuninori Morimoto struct usbhsg_request { 312f98382dSKuninori Morimoto struct usb_request req; 324bd04811SKuninori Morimoto struct usbhs_pkt pkt; 332f98382dSKuninori Morimoto }; 342f98382dSKuninori Morimoto 352f98382dSKuninori Morimoto #define EP_NAME_SIZE 8 362f98382dSKuninori Morimoto struct usbhsg_gpriv; 372f98382dSKuninori Morimoto struct usbhsg_uep { 382f98382dSKuninori Morimoto struct usb_ep ep; 392f98382dSKuninori Morimoto struct usbhs_pipe *pipe; 402f98382dSKuninori Morimoto 412f98382dSKuninori Morimoto char ep_name[EP_NAME_SIZE]; 422f98382dSKuninori Morimoto 432f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv; 442f98382dSKuninori Morimoto }; 452f98382dSKuninori Morimoto 462f98382dSKuninori Morimoto struct usbhsg_gpriv { 472f98382dSKuninori Morimoto struct usb_gadget gadget; 482f98382dSKuninori Morimoto struct usbhs_mod mod; 492f98382dSKuninori Morimoto 502f98382dSKuninori Morimoto struct usbhsg_uep *uep; 512f98382dSKuninori Morimoto int uep_size; 522f98382dSKuninori Morimoto 532f98382dSKuninori Morimoto struct usb_gadget_driver *driver; 54b5a28756SPhil Edworthy struct usb_phy *transceiver; 55b5a28756SPhil Edworthy bool vbus_active; 562f98382dSKuninori Morimoto 572f98382dSKuninori Morimoto u32 status; 582f98382dSKuninori Morimoto #define USBHSG_STATUS_STARTED (1 << 0) 592f98382dSKuninori Morimoto #define USBHSG_STATUS_REGISTERD (1 << 1) 602f98382dSKuninori Morimoto #define USBHSG_STATUS_WEDGE (1 << 2) 61cac402ddSShimoda, Yoshihiro #define USBHSG_STATUS_SELF_POWERED (1 << 3) 6204a5def3STakeshi Kihara #define USBHSG_STATUS_SOFT_CONNECT (1 << 4) 632f98382dSKuninori Morimoto }; 642f98382dSKuninori Morimoto 652f98382dSKuninori Morimoto struct usbhsg_recip_handle { 662f98382dSKuninori Morimoto char *name; 672f98382dSKuninori Morimoto int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 682f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 692f98382dSKuninori Morimoto int (*interface)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 702f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 712f98382dSKuninori Morimoto int (*endpoint)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 722f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 732f98382dSKuninori Morimoto }; 742f98382dSKuninori Morimoto 752f98382dSKuninori Morimoto /* 762f98382dSKuninori Morimoto * macro 772f98382dSKuninori Morimoto */ 782f98382dSKuninori Morimoto #define usbhsg_priv_to_gpriv(priv) \ 792f98382dSKuninori Morimoto container_of( \ 802f98382dSKuninori Morimoto usbhs_mod_get(priv, USBHS_GADGET), \ 812f98382dSKuninori Morimoto struct usbhsg_gpriv, mod) 822f98382dSKuninori Morimoto 832f98382dSKuninori Morimoto #define __usbhsg_for_each_uep(start, pos, g, i) \ 84925403f4SKuninori Morimoto for ((i) = start; \ 85925403f4SKuninori Morimoto ((i) < (g)->uep_size) && ((pos) = (g)->uep + (i)); \ 86925403f4SKuninori Morimoto (i)++) 872f98382dSKuninori Morimoto 882f98382dSKuninori Morimoto #define usbhsg_for_each_uep(pos, gpriv, i) \ 892f98382dSKuninori Morimoto __usbhsg_for_each_uep(1, pos, gpriv, i) 902f98382dSKuninori Morimoto 912f98382dSKuninori Morimoto #define usbhsg_for_each_uep_with_dcp(pos, gpriv, i) \ 922f98382dSKuninori Morimoto __usbhsg_for_each_uep(0, pos, gpriv, i) 932f98382dSKuninori Morimoto 942f98382dSKuninori Morimoto #define usbhsg_gadget_to_gpriv(g)\ 952f98382dSKuninori Morimoto container_of(g, struct usbhsg_gpriv, gadget) 962f98382dSKuninori Morimoto 972f98382dSKuninori Morimoto #define usbhsg_req_to_ureq(r)\ 982f98382dSKuninori Morimoto container_of(r, struct usbhsg_request, req) 992f98382dSKuninori Morimoto 1002f98382dSKuninori Morimoto #define usbhsg_ep_to_uep(e) container_of(e, struct usbhsg_uep, ep) 1012f98382dSKuninori Morimoto #define usbhsg_gpriv_to_dev(gp) usbhs_priv_to_dev((gp)->mod.priv) 1022f98382dSKuninori Morimoto #define usbhsg_gpriv_to_priv(gp) ((gp)->mod.priv) 1032f98382dSKuninori Morimoto #define usbhsg_gpriv_to_dcp(gp) ((gp)->uep) 1042f98382dSKuninori Morimoto #define usbhsg_gpriv_to_nth_uep(gp, i) ((gp)->uep + i) 1052f98382dSKuninori Morimoto #define usbhsg_uep_to_gpriv(u) ((u)->gpriv) 1062f98382dSKuninori Morimoto #define usbhsg_uep_to_pipe(u) ((u)->pipe) 1072f98382dSKuninori Morimoto #define usbhsg_pipe_to_uep(p) ((p)->mod_private) 1082f98382dSKuninori Morimoto #define usbhsg_is_dcp(u) ((u) == usbhsg_gpriv_to_dcp((u)->gpriv)) 1092f98382dSKuninori Morimoto 1104bd04811SKuninori Morimoto #define usbhsg_ureq_to_pkt(u) (&(u)->pkt) 1114bd04811SKuninori Morimoto #define usbhsg_pkt_to_ureq(i) \ 1124bd04811SKuninori Morimoto container_of(i, struct usbhsg_request, pkt) 1134bd04811SKuninori Morimoto 1142f98382dSKuninori Morimoto #define usbhsg_is_not_connected(gp) ((gp)->gadget.speed == USB_SPEED_UNKNOWN) 1152f98382dSKuninori Morimoto 1162f98382dSKuninori Morimoto /* status */ 1172f98382dSKuninori Morimoto #define usbhsg_status_init(gp) do {(gp)->status = 0; } while (0) 1182f98382dSKuninori Morimoto #define usbhsg_status_set(gp, b) (gp->status |= b) 1192f98382dSKuninori Morimoto #define usbhsg_status_clr(gp, b) (gp->status &= ~b) 1202f98382dSKuninori Morimoto #define usbhsg_status_has(gp, b) (gp->status & b) 1212f98382dSKuninori Morimoto 1222f98382dSKuninori Morimoto /* 123233f519dSKuninori Morimoto * queue push/pop 1242f98382dSKuninori Morimoto */ 12500f30d29SYoshihiro Shimoda static void __usbhsg_queue_pop(struct usbhsg_uep *uep, 1262f98382dSKuninori Morimoto struct usbhsg_request *ureq, 1272f98382dSKuninori Morimoto int status) 1282f98382dSKuninori Morimoto { 1292f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 1302f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 1312f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 13200f30d29SYoshihiro Shimoda struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 1332f98382dSKuninori Morimoto 134c9eb2950SYoshihiro Shimoda if (pipe) 1352f98382dSKuninori Morimoto dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); 1362f98382dSKuninori Morimoto 1372f98382dSKuninori Morimoto ureq->req.status = status; 13800f30d29SYoshihiro Shimoda spin_unlock(usbhs_priv_to_lock(priv)); 139304f7e5eSMichal Sojka usb_gadget_giveback_request(&uep->ep, &ureq->req); 14000f30d29SYoshihiro Shimoda spin_lock(usbhs_priv_to_lock(priv)); 14100f30d29SYoshihiro Shimoda } 14200f30d29SYoshihiro Shimoda 14300f30d29SYoshihiro Shimoda static void usbhsg_queue_pop(struct usbhsg_uep *uep, 14400f30d29SYoshihiro Shimoda struct usbhsg_request *ureq, 14500f30d29SYoshihiro Shimoda int status) 14600f30d29SYoshihiro Shimoda { 14700f30d29SYoshihiro Shimoda struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 14800f30d29SYoshihiro Shimoda struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 14900f30d29SYoshihiro Shimoda unsigned long flags; 15000f30d29SYoshihiro Shimoda 15100f30d29SYoshihiro Shimoda usbhs_lock(priv, flags); 15200f30d29SYoshihiro Shimoda __usbhsg_queue_pop(uep, ureq, status); 15300f30d29SYoshihiro Shimoda usbhs_unlock(priv, flags); 1542f98382dSKuninori Morimoto } 1552f98382dSKuninori Morimoto 1562cc97197SKuninori Morimoto static void usbhsg_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) 1572f98382dSKuninori Morimoto { 1584bd04811SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 1594bd04811SKuninori Morimoto struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); 1604bd04811SKuninori Morimoto struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); 1614bd04811SKuninori Morimoto 162659d4954SKuninori Morimoto ureq->req.actual = pkt->actual; 1632f98382dSKuninori Morimoto 1642f98382dSKuninori Morimoto usbhsg_queue_pop(uep, ureq, 0); 1652f98382dSKuninori Morimoto } 1664bd04811SKuninori Morimoto 167b331872bSKuninori Morimoto static void usbhsg_queue_push(struct usbhsg_uep *uep, 168b331872bSKuninori Morimoto struct usbhsg_request *ureq) 169b331872bSKuninori Morimoto { 170b331872bSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 171b331872bSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 172b331872bSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 173b331872bSKuninori Morimoto struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); 174b331872bSKuninori Morimoto struct usb_request *req = &ureq->req; 175b331872bSKuninori Morimoto 176b331872bSKuninori Morimoto req->actual = 0; 177b331872bSKuninori Morimoto req->status = -EINPROGRESS; 178b331872bSKuninori Morimoto usbhs_pkt_push(pipe, pkt, usbhsg_queue_done, 1793edeee38SKuninori Morimoto req->buf, req->length, req->zero, -1); 180654c35abSKuninori Morimoto usbhs_pkt_start(pipe); 181b331872bSKuninori Morimoto 182b331872bSKuninori Morimoto dev_dbg(dev, "pipe %d : queue push (%d)\n", 183b331872bSKuninori Morimoto usbhs_pipe_number(pipe), 184b331872bSKuninori Morimoto req->length); 185b331872bSKuninori Morimoto } 186b331872bSKuninori Morimoto 187233f519dSKuninori Morimoto /* 188233f519dSKuninori Morimoto * dma map/unmap 189233f519dSKuninori Morimoto */ 190e73a9891SKuninori Morimoto static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map) 191e73a9891SKuninori Morimoto { 192ade78f9fSFelipe Balbi struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); 193ade78f9fSFelipe Balbi struct usb_request *req = &ureq->req; 194e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 195e73a9891SKuninori Morimoto struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); 196e73a9891SKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 197e73a9891SKuninori Morimoto enum dma_data_direction dir; 198ade78f9fSFelipe Balbi int ret = 0; 199e73a9891SKuninori Morimoto 200ade78f9fSFelipe Balbi dir = usbhs_pipe_is_dir_host(pipe); 201e73a9891SKuninori Morimoto 202ade78f9fSFelipe Balbi if (map) { 203ade78f9fSFelipe Balbi /* it can not use scatter/gather */ 204ade78f9fSFelipe Balbi WARN_ON(req->num_sgs); 205ade78f9fSFelipe Balbi 206ade78f9fSFelipe Balbi ret = usb_gadget_map_request(&gpriv->gadget, req, dir); 207ade78f9fSFelipe Balbi if (ret < 0) 208ade78f9fSFelipe Balbi return ret; 209ade78f9fSFelipe Balbi 210ade78f9fSFelipe Balbi pkt->dma = req->dma; 211ade78f9fSFelipe Balbi } else { 212ade78f9fSFelipe Balbi usb_gadget_unmap_request(&gpriv->gadget, req, dir); 213ade78f9fSFelipe Balbi } 214ade78f9fSFelipe Balbi 215ade78f9fSFelipe Balbi return ret; 216e73a9891SKuninori Morimoto } 217e73a9891SKuninori Morimoto 2182f98382dSKuninori Morimoto /* 2192f98382dSKuninori Morimoto * USB_TYPE_STANDARD / clear feature functions 2202f98382dSKuninori Morimoto */ 2212f98382dSKuninori Morimoto static int usbhsg_recip_handler_std_control_done(struct usbhs_priv *priv, 2222f98382dSKuninori Morimoto struct usbhsg_uep *uep, 2232f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 2242f98382dSKuninori Morimoto { 2252f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 2262f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 2272f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); 2282f98382dSKuninori Morimoto 2292f98382dSKuninori Morimoto usbhs_dcp_control_transfer_done(pipe); 2302f98382dSKuninori Morimoto 2312f98382dSKuninori Morimoto return 0; 2322f98382dSKuninori Morimoto } 2332f98382dSKuninori Morimoto 2342f98382dSKuninori Morimoto static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, 2352f98382dSKuninori Morimoto struct usbhsg_uep *uep, 2362f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 2372f98382dSKuninori Morimoto { 2382f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 2392f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 2402f98382dSKuninori Morimoto 2412f98382dSKuninori Morimoto if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { 242e8d548d5SKuninori Morimoto usbhs_pipe_disable(pipe); 2436e6db82bSKuninori Morimoto usbhs_pipe_sequence_data0(pipe); 244e8d548d5SKuninori Morimoto usbhs_pipe_enable(pipe); 2452f98382dSKuninori Morimoto } 2462f98382dSKuninori Morimoto 2472f98382dSKuninori Morimoto usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 2482f98382dSKuninori Morimoto 24925fa7079SKuninori Morimoto usbhs_pkt_start(pipe); 25025fa7079SKuninori Morimoto 2512f98382dSKuninori Morimoto return 0; 2522f98382dSKuninori Morimoto } 2532f98382dSKuninori Morimoto 254225da3e3SKuninori Morimoto static struct usbhsg_recip_handle req_clear_feature = { 2552f98382dSKuninori Morimoto .name = "clear feature", 2562f98382dSKuninori Morimoto .device = usbhsg_recip_handler_std_control_done, 2572f98382dSKuninori Morimoto .interface = usbhsg_recip_handler_std_control_done, 2582f98382dSKuninori Morimoto .endpoint = usbhsg_recip_handler_std_clear_endpoint, 2592f98382dSKuninori Morimoto }; 2602f98382dSKuninori Morimoto 2612f98382dSKuninori Morimoto /* 262ced6e09eSKuninori Morimoto * USB_TYPE_STANDARD / set feature functions 263ced6e09eSKuninori Morimoto */ 264dfbb7f4fSKuninori Morimoto static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv, 265dfbb7f4fSKuninori Morimoto struct usbhsg_uep *uep, 266dfbb7f4fSKuninori Morimoto struct usb_ctrlrequest *ctrl) 267dfbb7f4fSKuninori Morimoto { 268dfbb7f4fSKuninori Morimoto switch (le16_to_cpu(ctrl->wValue)) { 269dfbb7f4fSKuninori Morimoto case USB_DEVICE_TEST_MODE: 270dfbb7f4fSKuninori Morimoto usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 271dfbb7f4fSKuninori Morimoto udelay(100); 272dfbb7f4fSKuninori Morimoto usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex >> 8)); 273dfbb7f4fSKuninori Morimoto break; 274dfbb7f4fSKuninori Morimoto default: 275dfbb7f4fSKuninori Morimoto usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 276dfbb7f4fSKuninori Morimoto break; 277dfbb7f4fSKuninori Morimoto } 278dfbb7f4fSKuninori Morimoto 279dfbb7f4fSKuninori Morimoto return 0; 280dfbb7f4fSKuninori Morimoto } 281dfbb7f4fSKuninori Morimoto 282ced6e09eSKuninori Morimoto static int usbhsg_recip_handler_std_set_endpoint(struct usbhs_priv *priv, 283ced6e09eSKuninori Morimoto struct usbhsg_uep *uep, 284ced6e09eSKuninori Morimoto struct usb_ctrlrequest *ctrl) 285ced6e09eSKuninori Morimoto { 286ced6e09eSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 287ced6e09eSKuninori Morimoto 288ced6e09eSKuninori Morimoto usbhs_pipe_stall(pipe); 289ced6e09eSKuninori Morimoto 290ced6e09eSKuninori Morimoto usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 291ced6e09eSKuninori Morimoto 292ced6e09eSKuninori Morimoto return 0; 293ced6e09eSKuninori Morimoto } 294ced6e09eSKuninori Morimoto 295225da3e3SKuninori Morimoto static struct usbhsg_recip_handle req_set_feature = { 296ced6e09eSKuninori Morimoto .name = "set feature", 297dfbb7f4fSKuninori Morimoto .device = usbhsg_recip_handler_std_set_device, 298ced6e09eSKuninori Morimoto .interface = usbhsg_recip_handler_std_control_done, 299ced6e09eSKuninori Morimoto .endpoint = usbhsg_recip_handler_std_set_endpoint, 300ced6e09eSKuninori Morimoto }; 301ced6e09eSKuninori Morimoto 302ced6e09eSKuninori Morimoto /* 30317f7f769SKuninori Morimoto * USB_TYPE_STANDARD / get status functions 30417f7f769SKuninori Morimoto */ 30517f7f769SKuninori Morimoto static void __usbhsg_recip_send_complete(struct usb_ep *ep, 30617f7f769SKuninori Morimoto struct usb_request *req) 30717f7f769SKuninori Morimoto { 30817f7f769SKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 30917f7f769SKuninori Morimoto 31017f7f769SKuninori Morimoto /* free allocated recip-buffer/usb_request */ 31117f7f769SKuninori Morimoto kfree(ureq->pkt.buf); 31217f7f769SKuninori Morimoto usb_ep_free_request(ep, req); 31317f7f769SKuninori Morimoto } 31417f7f769SKuninori Morimoto 31517f7f769SKuninori Morimoto static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, 31617f7f769SKuninori Morimoto unsigned short status) 31717f7f769SKuninori Morimoto { 31817f7f769SKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 31917f7f769SKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); 32017f7f769SKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 32117f7f769SKuninori Morimoto struct usb_request *req; 32217f7f769SKuninori Morimoto unsigned short *buf; 32317f7f769SKuninori Morimoto 32417f7f769SKuninori Morimoto /* alloc new usb_request for recip */ 32517f7f769SKuninori Morimoto req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC); 32617f7f769SKuninori Morimoto if (!req) { 32717f7f769SKuninori Morimoto dev_err(dev, "recip request allocation fail\n"); 32817f7f769SKuninori Morimoto return; 32917f7f769SKuninori Morimoto } 33017f7f769SKuninori Morimoto 33117f7f769SKuninori Morimoto /* alloc recip data buffer */ 33217f7f769SKuninori Morimoto buf = kmalloc(sizeof(*buf), GFP_ATOMIC); 33317f7f769SKuninori Morimoto if (!buf) { 33417f7f769SKuninori Morimoto usb_ep_free_request(&dcp->ep, req); 33517f7f769SKuninori Morimoto dev_err(dev, "recip data allocation fail\n"); 33617f7f769SKuninori Morimoto return; 33717f7f769SKuninori Morimoto } 33817f7f769SKuninori Morimoto 33917f7f769SKuninori Morimoto /* recip data is status */ 34017f7f769SKuninori Morimoto *buf = cpu_to_le16(status); 34117f7f769SKuninori Morimoto 34217f7f769SKuninori Morimoto /* allocated usb_request/buffer will be freed */ 34317f7f769SKuninori Morimoto req->complete = __usbhsg_recip_send_complete; 34417f7f769SKuninori Morimoto req->buf = buf; 34517f7f769SKuninori Morimoto req->length = sizeof(*buf); 34617f7f769SKuninori Morimoto req->zero = 0; 34717f7f769SKuninori Morimoto 34817f7f769SKuninori Morimoto /* push packet */ 34917f7f769SKuninori Morimoto pipe->handler = &usbhs_fifo_pio_push_handler; 35017f7f769SKuninori Morimoto usbhsg_queue_push(dcp, usbhsg_req_to_ureq(req)); 35117f7f769SKuninori Morimoto } 35217f7f769SKuninori Morimoto 35317f7f769SKuninori Morimoto static int usbhsg_recip_handler_std_get_device(struct usbhs_priv *priv, 35417f7f769SKuninori Morimoto struct usbhsg_uep *uep, 35517f7f769SKuninori Morimoto struct usb_ctrlrequest *ctrl) 35617f7f769SKuninori Morimoto { 35717f7f769SKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 358cac402ddSShimoda, Yoshihiro unsigned short status = 0; 359cac402ddSShimoda, Yoshihiro 360cac402ddSShimoda, Yoshihiro if (usbhsg_status_has(gpriv, USBHSG_STATUS_SELF_POWERED)) 361cac402ddSShimoda, Yoshihiro status = 1 << USB_DEVICE_SELF_POWERED; 36217f7f769SKuninori Morimoto 36317f7f769SKuninori Morimoto __usbhsg_recip_send_status(gpriv, status); 36417f7f769SKuninori Morimoto 36517f7f769SKuninori Morimoto return 0; 36617f7f769SKuninori Morimoto } 36717f7f769SKuninori Morimoto 36817f7f769SKuninori Morimoto static int usbhsg_recip_handler_std_get_interface(struct usbhs_priv *priv, 36917f7f769SKuninori Morimoto struct usbhsg_uep *uep, 37017f7f769SKuninori Morimoto struct usb_ctrlrequest *ctrl) 37117f7f769SKuninori Morimoto { 37217f7f769SKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 37317f7f769SKuninori Morimoto unsigned short status = 0; 37417f7f769SKuninori Morimoto 37517f7f769SKuninori Morimoto __usbhsg_recip_send_status(gpriv, status); 37617f7f769SKuninori Morimoto 37717f7f769SKuninori Morimoto return 0; 37817f7f769SKuninori Morimoto } 37917f7f769SKuninori Morimoto 38017f7f769SKuninori Morimoto static int usbhsg_recip_handler_std_get_endpoint(struct usbhs_priv *priv, 38117f7f769SKuninori Morimoto struct usbhsg_uep *uep, 38217f7f769SKuninori Morimoto struct usb_ctrlrequest *ctrl) 38317f7f769SKuninori Morimoto { 38417f7f769SKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 38517f7f769SKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 38617f7f769SKuninori Morimoto unsigned short status = 0; 38717f7f769SKuninori Morimoto 38817f7f769SKuninori Morimoto if (usbhs_pipe_is_stall(pipe)) 38917f7f769SKuninori Morimoto status = 1 << USB_ENDPOINT_HALT; 39017f7f769SKuninori Morimoto 39117f7f769SKuninori Morimoto __usbhsg_recip_send_status(gpriv, status); 39217f7f769SKuninori Morimoto 39317f7f769SKuninori Morimoto return 0; 39417f7f769SKuninori Morimoto } 39517f7f769SKuninori Morimoto 396225da3e3SKuninori Morimoto static struct usbhsg_recip_handle req_get_status = { 39717f7f769SKuninori Morimoto .name = "get status", 39817f7f769SKuninori Morimoto .device = usbhsg_recip_handler_std_get_device, 39917f7f769SKuninori Morimoto .interface = usbhsg_recip_handler_std_get_interface, 40017f7f769SKuninori Morimoto .endpoint = usbhsg_recip_handler_std_get_endpoint, 40117f7f769SKuninori Morimoto }; 40217f7f769SKuninori Morimoto 40317f7f769SKuninori Morimoto /* 4042f98382dSKuninori Morimoto * USB_TYPE handler 4052f98382dSKuninori Morimoto */ 4062f98382dSKuninori Morimoto static int usbhsg_recip_run_handle(struct usbhs_priv *priv, 4072f98382dSKuninori Morimoto struct usbhsg_recip_handle *handler, 4082f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 4092f98382dSKuninori Morimoto { 4102f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 4112f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 4122f98382dSKuninori Morimoto struct usbhsg_uep *uep; 4130432eed0SKuninori Morimoto struct usbhs_pipe *pipe; 4142f98382dSKuninori Morimoto int recip = ctrl->bRequestType & USB_RECIP_MASK; 4152f98382dSKuninori Morimoto int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; 4167983bc74SJesper Juhl int ret = 0; 4172f98382dSKuninori Morimoto int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 4182f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 4192f98382dSKuninori Morimoto char *msg; 4202f98382dSKuninori Morimoto 4212f98382dSKuninori Morimoto uep = usbhsg_gpriv_to_nth_uep(gpriv, nth); 4220432eed0SKuninori Morimoto pipe = usbhsg_uep_to_pipe(uep); 4230432eed0SKuninori Morimoto if (!pipe) { 4249a28b7bdSKuninori Morimoto dev_err(dev, "wrong recip request\n"); 42525fa7079SKuninori Morimoto return -EINVAL; 4269a28b7bdSKuninori Morimoto } 4272f98382dSKuninori Morimoto 4282f98382dSKuninori Morimoto switch (recip) { 4292f98382dSKuninori Morimoto case USB_RECIP_DEVICE: 4302f98382dSKuninori Morimoto msg = "DEVICE"; 4312f98382dSKuninori Morimoto func = handler->device; 4322f98382dSKuninori Morimoto break; 4332f98382dSKuninori Morimoto case USB_RECIP_INTERFACE: 4342f98382dSKuninori Morimoto msg = "INTERFACE"; 4352f98382dSKuninori Morimoto func = handler->interface; 4362f98382dSKuninori Morimoto break; 4372f98382dSKuninori Morimoto case USB_RECIP_ENDPOINT: 4382f98382dSKuninori Morimoto msg = "ENDPOINT"; 4392f98382dSKuninori Morimoto func = handler->endpoint; 4402f98382dSKuninori Morimoto break; 4412f98382dSKuninori Morimoto default: 4422f98382dSKuninori Morimoto dev_warn(dev, "unsupported RECIP(%d)\n", recip); 4432f98382dSKuninori Morimoto func = NULL; 4442f98382dSKuninori Morimoto ret = -EINVAL; 4452f98382dSKuninori Morimoto } 4462f98382dSKuninori Morimoto 4472f98382dSKuninori Morimoto if (func) { 4482f98382dSKuninori Morimoto dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); 4492f98382dSKuninori Morimoto ret = func(priv, uep, ctrl); 4502f98382dSKuninori Morimoto } 4512f98382dSKuninori Morimoto 4522f98382dSKuninori Morimoto return ret; 4532f98382dSKuninori Morimoto } 4542f98382dSKuninori Morimoto 4552f98382dSKuninori Morimoto /* 4562f98382dSKuninori Morimoto * irq functions 4572f98382dSKuninori Morimoto * 4582f98382dSKuninori Morimoto * it will be called from usbhs_interrupt 4592f98382dSKuninori Morimoto */ 4602f98382dSKuninori Morimoto static int usbhsg_irq_dev_state(struct usbhs_priv *priv, 4612f98382dSKuninori Morimoto struct usbhs_irq_state *irq_state) 4622f98382dSKuninori Morimoto { 4632f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 4642f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 4652f98382dSKuninori Morimoto 46675587f52SKuninori Morimoto gpriv->gadget.speed = usbhs_bus_get_speed(priv); 4672f98382dSKuninori Morimoto 4682f98382dSKuninori Morimoto dev_dbg(dev, "state = %x : speed : %d\n", 4692f98382dSKuninori Morimoto usbhs_status_get_device_state(irq_state), 4702f98382dSKuninori Morimoto gpriv->gadget.speed); 4712f98382dSKuninori Morimoto 4722f98382dSKuninori Morimoto return 0; 4732f98382dSKuninori Morimoto } 4742f98382dSKuninori Morimoto 4752f98382dSKuninori Morimoto static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, 4762f98382dSKuninori Morimoto struct usbhs_irq_state *irq_state) 4772f98382dSKuninori Morimoto { 4782f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 4792f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 4802f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); 4812f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 4822f98382dSKuninori Morimoto struct usb_ctrlrequest ctrl; 4832f98382dSKuninori Morimoto struct usbhsg_recip_handle *recip_handler = NULL; 4842f98382dSKuninori Morimoto int stage = usbhs_status_get_ctrl_stage(irq_state); 4852f98382dSKuninori Morimoto int ret = 0; 4862f98382dSKuninori Morimoto 4872f98382dSKuninori Morimoto dev_dbg(dev, "stage = %d\n", stage); 4882f98382dSKuninori Morimoto 4892f98382dSKuninori Morimoto /* 4902f98382dSKuninori Morimoto * see Manual 4912f98382dSKuninori Morimoto * 4922f98382dSKuninori Morimoto * "Operation" 4932f98382dSKuninori Morimoto * - "Interrupt Function" 4942f98382dSKuninori Morimoto * - "Control Transfer Stage Transition Interrupt" 4952f98382dSKuninori Morimoto * - Fig. "Control Transfer Stage Transitions" 4962f98382dSKuninori Morimoto */ 4972f98382dSKuninori Morimoto 4982f98382dSKuninori Morimoto switch (stage) { 4992f98382dSKuninori Morimoto case READ_DATA_STAGE: 5000c6ef985SKuninori Morimoto pipe->handler = &usbhs_fifo_pio_push_handler; 5012f98382dSKuninori Morimoto break; 5022f98382dSKuninori Morimoto case WRITE_DATA_STAGE: 5030c6ef985SKuninori Morimoto pipe->handler = &usbhs_fifo_pio_pop_handler; 5042f98382dSKuninori Morimoto break; 5052f98382dSKuninori Morimoto case NODATA_STATUS_STAGE: 5060c6ef985SKuninori Morimoto pipe->handler = &usbhs_ctrl_stage_end_handler; 5072f98382dSKuninori Morimoto break; 5084ef35b10SYoshihiro Shimoda case READ_STATUS_STAGE: 5094ef35b10SYoshihiro Shimoda case WRITE_STATUS_STAGE: 5104ef35b10SYoshihiro Shimoda usbhs_dcp_control_transfer_done(pipe); 5112f98382dSKuninori Morimoto default: 5122f98382dSKuninori Morimoto return ret; 5132f98382dSKuninori Morimoto } 5142f98382dSKuninori Morimoto 5152f98382dSKuninori Morimoto /* 5162f98382dSKuninori Morimoto * get usb request 5172f98382dSKuninori Morimoto */ 5182f98382dSKuninori Morimoto usbhs_usbreq_get_val(priv, &ctrl); 5192f98382dSKuninori Morimoto 5202f98382dSKuninori Morimoto switch (ctrl.bRequestType & USB_TYPE_MASK) { 5212f98382dSKuninori Morimoto case USB_TYPE_STANDARD: 5222f98382dSKuninori Morimoto switch (ctrl.bRequest) { 5232f98382dSKuninori Morimoto case USB_REQ_CLEAR_FEATURE: 5242f98382dSKuninori Morimoto recip_handler = &req_clear_feature; 5252f98382dSKuninori Morimoto break; 526ced6e09eSKuninori Morimoto case USB_REQ_SET_FEATURE: 527ced6e09eSKuninori Morimoto recip_handler = &req_set_feature; 528ced6e09eSKuninori Morimoto break; 52917f7f769SKuninori Morimoto case USB_REQ_GET_STATUS: 53017f7f769SKuninori Morimoto recip_handler = &req_get_status; 53117f7f769SKuninori Morimoto break; 5322f98382dSKuninori Morimoto } 5332f98382dSKuninori Morimoto } 5342f98382dSKuninori Morimoto 5352f98382dSKuninori Morimoto /* 5362f98382dSKuninori Morimoto * setup stage / run recip 5372f98382dSKuninori Morimoto */ 5382f98382dSKuninori Morimoto if (recip_handler) 5392f98382dSKuninori Morimoto ret = usbhsg_recip_run_handle(priv, recip_handler, &ctrl); 5402f98382dSKuninori Morimoto else 5412f98382dSKuninori Morimoto ret = gpriv->driver->setup(&gpriv->gadget, &ctrl); 5422f98382dSKuninori Morimoto 5432f98382dSKuninori Morimoto if (ret < 0) 544e8d548d5SKuninori Morimoto usbhs_pipe_stall(pipe); 5452f98382dSKuninori Morimoto 5462f98382dSKuninori Morimoto return ret; 5472f98382dSKuninori Morimoto } 5482f98382dSKuninori Morimoto 5492f98382dSKuninori Morimoto /* 5502f98382dSKuninori Morimoto * 5512f98382dSKuninori Morimoto * usb_dcp_ops 5522f98382dSKuninori Morimoto * 5532f98382dSKuninori Morimoto */ 5542f98382dSKuninori Morimoto static int usbhsg_pipe_disable(struct usbhsg_uep *uep) 5552f98382dSKuninori Morimoto { 5562f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 5578a2c225dSKuninori Morimoto struct usbhs_pkt *pkt; 5582f98382dSKuninori Morimoto 5592f98382dSKuninori Morimoto while (1) { 56097664a20SKuninori Morimoto pkt = usbhs_pkt_pop(pipe, NULL); 5618a2c225dSKuninori Morimoto if (!pkt) 5622f98382dSKuninori Morimoto break; 56391b158f4SKuninori Morimoto 56491b158f4SKuninori Morimoto usbhsg_queue_pop(uep, usbhsg_pkt_to_ureq(pkt), -ECONNRESET); 5652f98382dSKuninori Morimoto } 5662f98382dSKuninori Morimoto 56791b158f4SKuninori Morimoto usbhs_pipe_disable(pipe); 56891b158f4SKuninori Morimoto 5692f98382dSKuninori Morimoto return 0; 5702f98382dSKuninori Morimoto } 5712f98382dSKuninori Morimoto 5722f98382dSKuninori Morimoto /* 5732f98382dSKuninori Morimoto * 5742f98382dSKuninori Morimoto * usb_ep_ops 5752f98382dSKuninori Morimoto * 5762f98382dSKuninori Morimoto */ 5772f98382dSKuninori Morimoto static int usbhsg_ep_enable(struct usb_ep *ep, 5782f98382dSKuninori Morimoto const struct usb_endpoint_descriptor *desc) 5792f98382dSKuninori Morimoto { 5802f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5812f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 5822f98382dSKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 5832f98382dSKuninori Morimoto struct usbhs_pipe *pipe; 5842f98382dSKuninori Morimoto int ret = -EIO; 5852f98382dSKuninori Morimoto 586409ba9e7SKuninori Morimoto /* 587409ba9e7SKuninori Morimoto * if it already have pipe, 588409ba9e7SKuninori Morimoto * nothing to do 589409ba9e7SKuninori Morimoto */ 59008e6c611SKuninori Morimoto if (uep->pipe) { 59108e6c611SKuninori Morimoto usbhs_pipe_clear(uep->pipe); 5926e6db82bSKuninori Morimoto usbhs_pipe_sequence_data0(uep->pipe); 593409ba9e7SKuninori Morimoto return 0; 59408e6c611SKuninori Morimoto } 595409ba9e7SKuninori Morimoto 596f5aa889fSKuninori Morimoto pipe = usbhs_pipe_malloc(priv, 597f5aa889fSKuninori Morimoto usb_endpoint_type(desc), 598f5aa889fSKuninori Morimoto usb_endpoint_dir_in(desc)); 5992f98382dSKuninori Morimoto if (pipe) { 6002f98382dSKuninori Morimoto uep->pipe = pipe; 6012f98382dSKuninori Morimoto pipe->mod_private = uep; 6022f98382dSKuninori Morimoto 603f5aa889fSKuninori Morimoto /* set epnum / maxp */ 604bc6fbf59SKuninori Morimoto usbhs_pipe_config_update(pipe, 0, 605f5aa889fSKuninori Morimoto usb_endpoint_num(desc), 606f5aa889fSKuninori Morimoto usb_endpoint_maxp(desc)); 607f5aa889fSKuninori Morimoto 608233f519dSKuninori Morimoto /* 609233f519dSKuninori Morimoto * usbhs_fifo_dma_push/pop_handler try to 610233f519dSKuninori Morimoto * use dmaengine if possible. 611233f519dSKuninori Morimoto * It will use pio handler if impossible. 612233f519dSKuninori Morimoto */ 6132f98382dSKuninori Morimoto if (usb_endpoint_dir_in(desc)) 6140c6ef985SKuninori Morimoto pipe->handler = &usbhs_fifo_dma_push_handler; 6152f98382dSKuninori Morimoto else 6160c6ef985SKuninori Morimoto pipe->handler = &usbhs_fifo_dma_pop_handler; 6172f98382dSKuninori Morimoto 6182f98382dSKuninori Morimoto ret = 0; 6192f98382dSKuninori Morimoto } 620cb96632cSKuninori Morimoto 6212f98382dSKuninori Morimoto return ret; 6222f98382dSKuninori Morimoto } 6232f98382dSKuninori Morimoto 6242f98382dSKuninori Morimoto static int usbhsg_ep_disable(struct usb_ep *ep) 6252f98382dSKuninori Morimoto { 6262f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 627dfb87b8bSYoshihiro Shimoda struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 6282f98382dSKuninori Morimoto 62911432050SKazuya Mizuguchi if (!pipe) 63011432050SKazuya Mizuguchi return -EINVAL; 63111432050SKazuya Mizuguchi 632d9fa298fSKuninori Morimoto usbhsg_pipe_disable(uep); 633dfb87b8bSYoshihiro Shimoda usbhs_pipe_free(pipe); 634d9fa298fSKuninori Morimoto 635d9fa298fSKuninori Morimoto uep->pipe->mod_private = NULL; 636d9fa298fSKuninori Morimoto uep->pipe = NULL; 637d9fa298fSKuninori Morimoto 638d9fa298fSKuninori Morimoto return 0; 6392f98382dSKuninori Morimoto } 6402f98382dSKuninori Morimoto 6412f98382dSKuninori Morimoto static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, 6422f98382dSKuninori Morimoto gfp_t gfp_flags) 6432f98382dSKuninori Morimoto { 6442f98382dSKuninori Morimoto struct usbhsg_request *ureq; 6452f98382dSKuninori Morimoto 6462f98382dSKuninori Morimoto ureq = kzalloc(sizeof *ureq, gfp_flags); 6472f98382dSKuninori Morimoto if (!ureq) 6482f98382dSKuninori Morimoto return NULL; 6492f98382dSKuninori Morimoto 6506acb95d4SKuninori Morimoto usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); 6516acb95d4SKuninori Morimoto 6522f98382dSKuninori Morimoto return &ureq->req; 6532f98382dSKuninori Morimoto } 6542f98382dSKuninori Morimoto 6552f98382dSKuninori Morimoto static void usbhsg_ep_free_request(struct usb_ep *ep, 6562f98382dSKuninori Morimoto struct usb_request *req) 6572f98382dSKuninori Morimoto { 6582f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 6592f98382dSKuninori Morimoto 6606acb95d4SKuninori Morimoto WARN_ON(!list_empty(&ureq->pkt.node)); 6612f98382dSKuninori Morimoto kfree(ureq); 6622f98382dSKuninori Morimoto } 6632f98382dSKuninori Morimoto 6642f98382dSKuninori Morimoto static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, 6652f98382dSKuninori Morimoto gfp_t gfp_flags) 6662f98382dSKuninori Morimoto { 6672f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 6682f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 6692f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 6702f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 6712f98382dSKuninori Morimoto 6722f98382dSKuninori Morimoto /* param check */ 6732f98382dSKuninori Morimoto if (usbhsg_is_not_connected(gpriv) || 6742f98382dSKuninori Morimoto unlikely(!gpriv->driver) || 6752f98382dSKuninori Morimoto unlikely(!pipe)) 67697664a20SKuninori Morimoto return -ESHUTDOWN; 67797664a20SKuninori Morimoto 6782f98382dSKuninori Morimoto usbhsg_queue_push(uep, ureq); 6792f98382dSKuninori Morimoto 68097664a20SKuninori Morimoto return 0; 6812f98382dSKuninori Morimoto } 6822f98382dSKuninori Morimoto 6832f98382dSKuninori Morimoto static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) 6842f98382dSKuninori Morimoto { 6852f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 6862f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 68797664a20SKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 6882f98382dSKuninori Morimoto 689c9eb2950SYoshihiro Shimoda if (pipe) 69097664a20SKuninori Morimoto usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); 691c9eb2950SYoshihiro Shimoda 692c9eb2950SYoshihiro Shimoda /* 693c9eb2950SYoshihiro Shimoda * To dequeue a request, this driver should call the usbhsg_queue_pop() 694c9eb2950SYoshihiro Shimoda * even if the pipe is NULL. 695c9eb2950SYoshihiro Shimoda */ 6962f98382dSKuninori Morimoto usbhsg_queue_pop(uep, ureq, -ECONNRESET); 6972f98382dSKuninori Morimoto 6982f98382dSKuninori Morimoto return 0; 6992f98382dSKuninori Morimoto } 7002f98382dSKuninori Morimoto 7012f98382dSKuninori Morimoto static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) 7022f98382dSKuninori Morimoto { 7032f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 7042f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 7052f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 70697664a20SKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 7072f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 7082f98382dSKuninori Morimoto unsigned long flags; 7092f98382dSKuninori Morimoto 71097664a20SKuninori Morimoto usbhsg_pipe_disable(uep); 7112f98382dSKuninori Morimoto 7122f98382dSKuninori Morimoto dev_dbg(dev, "set halt %d (pipe %d)\n", 7132f98382dSKuninori Morimoto halt, usbhs_pipe_number(pipe)); 7142f98382dSKuninori Morimoto 71597664a20SKuninori Morimoto /******************** spin lock ********************/ 71697664a20SKuninori Morimoto usbhs_lock(priv, flags); 71797664a20SKuninori Morimoto 7182f98382dSKuninori Morimoto if (halt) 719e8d548d5SKuninori Morimoto usbhs_pipe_stall(pipe); 7202f98382dSKuninori Morimoto else 721e8d548d5SKuninori Morimoto usbhs_pipe_disable(pipe); 7222f98382dSKuninori Morimoto 7232f98382dSKuninori Morimoto if (halt && wedge) 7242f98382dSKuninori Morimoto usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); 7252f98382dSKuninori Morimoto else 7262f98382dSKuninori Morimoto usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); 7272f98382dSKuninori Morimoto 72897664a20SKuninori Morimoto usbhs_unlock(priv, flags); 7292f98382dSKuninori Morimoto /******************** spin unlock ******************/ 7302f98382dSKuninori Morimoto 73197664a20SKuninori Morimoto return 0; 7322f98382dSKuninori Morimoto } 7332f98382dSKuninori Morimoto 7342f98382dSKuninori Morimoto static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) 7352f98382dSKuninori Morimoto { 7362f98382dSKuninori Morimoto return __usbhsg_ep_set_halt_wedge(ep, value, 0); 7372f98382dSKuninori Morimoto } 7382f98382dSKuninori Morimoto 7392f98382dSKuninori Morimoto static int usbhsg_ep_set_wedge(struct usb_ep *ep) 7402f98382dSKuninori Morimoto { 7412f98382dSKuninori Morimoto return __usbhsg_ep_set_halt_wedge(ep, 1, 1); 7422f98382dSKuninori Morimoto } 7432f98382dSKuninori Morimoto 7442f98382dSKuninori Morimoto static struct usb_ep_ops usbhsg_ep_ops = { 7452f98382dSKuninori Morimoto .enable = usbhsg_ep_enable, 7462f98382dSKuninori Morimoto .disable = usbhsg_ep_disable, 7472f98382dSKuninori Morimoto 7482f98382dSKuninori Morimoto .alloc_request = usbhsg_ep_alloc_request, 7492f98382dSKuninori Morimoto .free_request = usbhsg_ep_free_request, 7502f98382dSKuninori Morimoto 7512f98382dSKuninori Morimoto .queue = usbhsg_ep_queue, 7522f98382dSKuninori Morimoto .dequeue = usbhsg_ep_dequeue, 7532f98382dSKuninori Morimoto 7542f98382dSKuninori Morimoto .set_halt = usbhsg_ep_set_halt, 7552f98382dSKuninori Morimoto .set_wedge = usbhsg_ep_set_wedge, 7562f98382dSKuninori Morimoto }; 7572f98382dSKuninori Morimoto 7582f98382dSKuninori Morimoto /* 75904a5def3STakeshi Kihara * pullup control 76004a5def3STakeshi Kihara */ 76104a5def3STakeshi Kihara static int usbhsg_can_pullup(struct usbhs_priv *priv) 76204a5def3STakeshi Kihara { 76304a5def3STakeshi Kihara struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 76404a5def3STakeshi Kihara 76504a5def3STakeshi Kihara return gpriv->driver && 76604a5def3STakeshi Kihara usbhsg_status_has(gpriv, USBHSG_STATUS_SOFT_CONNECT); 76704a5def3STakeshi Kihara } 76804a5def3STakeshi Kihara 76904a5def3STakeshi Kihara static void usbhsg_update_pullup(struct usbhs_priv *priv) 77004a5def3STakeshi Kihara { 77104a5def3STakeshi Kihara if (usbhsg_can_pullup(priv)) 77204a5def3STakeshi Kihara usbhs_sys_function_pullup(priv, 1); 77304a5def3STakeshi Kihara else 77404a5def3STakeshi Kihara usbhs_sys_function_pullup(priv, 0); 77504a5def3STakeshi Kihara } 77604a5def3STakeshi Kihara 77704a5def3STakeshi Kihara /* 7782f98382dSKuninori Morimoto * usb module start/end 7792f98382dSKuninori Morimoto */ 7802f98382dSKuninori Morimoto static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) 7812f98382dSKuninori Morimoto { 7822f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 7832f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 7842f98382dSKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 7852f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 7862f98382dSKuninori Morimoto unsigned long flags; 78797664a20SKuninori Morimoto int ret = 0; 7882f98382dSKuninori Morimoto 7892f98382dSKuninori Morimoto /******************** spin lock ********************/ 79097664a20SKuninori Morimoto usbhs_lock(priv, flags); 79197664a20SKuninori Morimoto 79297664a20SKuninori Morimoto usbhsg_status_set(gpriv, status); 79397664a20SKuninori Morimoto if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && 79497664a20SKuninori Morimoto usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) 79597664a20SKuninori Morimoto ret = -1; /* not ready */ 79697664a20SKuninori Morimoto 79797664a20SKuninori Morimoto usbhs_unlock(priv, flags); 79897664a20SKuninori Morimoto /******************** spin unlock ********************/ 79997664a20SKuninori Morimoto 80097664a20SKuninori Morimoto if (ret < 0) 80197664a20SKuninori Morimoto return 0; /* not ready is not error */ 8022f98382dSKuninori Morimoto 8032f98382dSKuninori Morimoto /* 8042f98382dSKuninori Morimoto * enable interrupt and systems if ready 8052f98382dSKuninori Morimoto */ 8062f98382dSKuninori Morimoto dev_dbg(dev, "start gadget\n"); 8072f98382dSKuninori Morimoto 8082f98382dSKuninori Morimoto /* 8092f98382dSKuninori Morimoto * pipe initialize and enable DCP 8102f98382dSKuninori Morimoto */ 811cdeb7943SYoshihiro Shimoda usbhs_fifo_init(priv); 8124bd04811SKuninori Morimoto usbhs_pipe_init(priv, 813e73a9891SKuninori Morimoto usbhsg_dma_map_ctrl); 81497664a20SKuninori Morimoto 815d9fa298fSKuninori Morimoto /* dcp init instead of usbhsg_ep_enable() */ 81697664a20SKuninori Morimoto dcp->pipe = usbhs_dcp_malloc(priv); 81797664a20SKuninori Morimoto dcp->pipe->mod_private = dcp; 818bc6fbf59SKuninori Morimoto usbhs_pipe_config_update(dcp->pipe, 0, 0, 64); 8192f98382dSKuninori Morimoto 8202f98382dSKuninori Morimoto /* 8212f98382dSKuninori Morimoto * system config enble 8222f98382dSKuninori Morimoto * - HI speed 8232f98382dSKuninori Morimoto * - function 8242f98382dSKuninori Morimoto * - usb module 8252f98382dSKuninori Morimoto */ 8262f98382dSKuninori Morimoto usbhs_sys_function_ctrl(priv, 1); 82704a5def3STakeshi Kihara usbhsg_update_pullup(priv); 8282f98382dSKuninori Morimoto 8292f98382dSKuninori Morimoto /* 8302f98382dSKuninori Morimoto * enable irq callback 8312f98382dSKuninori Morimoto */ 8322f98382dSKuninori Morimoto mod->irq_dev_state = usbhsg_irq_dev_state; 8332f98382dSKuninori Morimoto mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; 8342f98382dSKuninori Morimoto usbhs_irq_callback_update(priv, mod); 8352f98382dSKuninori Morimoto 8362f98382dSKuninori Morimoto return 0; 8372f98382dSKuninori Morimoto } 8382f98382dSKuninori Morimoto 8392f98382dSKuninori Morimoto static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) 8402f98382dSKuninori Morimoto { 8412f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 8422f98382dSKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 8432f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 8442f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 8452f98382dSKuninori Morimoto unsigned long flags; 84697664a20SKuninori Morimoto int ret = 0; 8472f98382dSKuninori Morimoto 8482f98382dSKuninori Morimoto /******************** spin lock ********************/ 84997664a20SKuninori Morimoto usbhs_lock(priv, flags); 85097664a20SKuninori Morimoto 85197664a20SKuninori Morimoto usbhsg_status_clr(gpriv, status); 85297664a20SKuninori Morimoto if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && 85397664a20SKuninori Morimoto !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) 85497664a20SKuninori Morimoto ret = -1; /* already done */ 85597664a20SKuninori Morimoto 85697664a20SKuninori Morimoto usbhs_unlock(priv, flags); 85797664a20SKuninori Morimoto /******************** spin unlock ********************/ 85897664a20SKuninori Morimoto 85997664a20SKuninori Morimoto if (ret < 0) 86097664a20SKuninori Morimoto return 0; /* already done is not error */ 8612f98382dSKuninori Morimoto 8622f98382dSKuninori Morimoto /* 8632f98382dSKuninori Morimoto * disable interrupt and systems if 1st try 8642f98382dSKuninori Morimoto */ 865dad67397SKuninori Morimoto usbhs_fifo_quit(priv); 866dad67397SKuninori Morimoto 8672f98382dSKuninori Morimoto /* disable all irq */ 8682f98382dSKuninori Morimoto mod->irq_dev_state = NULL; 8692f98382dSKuninori Morimoto mod->irq_ctrl_stage = NULL; 8702f98382dSKuninori Morimoto usbhs_irq_callback_update(priv, mod); 8712f98382dSKuninori Morimoto 8722f98382dSKuninori Morimoto gpriv->gadget.speed = USB_SPEED_UNKNOWN; 8732f98382dSKuninori Morimoto 8742f98382dSKuninori Morimoto /* disable sys */ 875dfbb7f4fSKuninori Morimoto usbhs_sys_set_test_mode(priv, 0); 8762f98382dSKuninori Morimoto usbhs_sys_function_ctrl(priv, 0); 8772f98382dSKuninori Morimoto 878d9fa298fSKuninori Morimoto usbhsg_ep_disable(&dcp->ep); 8792f98382dSKuninori Morimoto 8802f98382dSKuninori Morimoto dev_dbg(dev, "stop gadget\n"); 8812f98382dSKuninori Morimoto 8822f98382dSKuninori Morimoto return 0; 8832f98382dSKuninori Morimoto } 8842f98382dSKuninori Morimoto 8852f98382dSKuninori Morimoto /* 886b5a28756SPhil Edworthy * VBUS provided by the PHY 887b5a28756SPhil Edworthy */ 888b5a28756SPhil Edworthy static int usbhsm_phy_get_vbus(struct platform_device *pdev) 889b5a28756SPhil Edworthy { 890b5a28756SPhil Edworthy struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); 891b5a28756SPhil Edworthy struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 892b5a28756SPhil Edworthy 893b5a28756SPhil Edworthy return gpriv->vbus_active; 894b5a28756SPhil Edworthy } 895b5a28756SPhil Edworthy 896b5a28756SPhil Edworthy static void usbhs_mod_phy_mode(struct usbhs_priv *priv) 897b5a28756SPhil Edworthy { 898b5a28756SPhil Edworthy struct usbhs_mod_info *info = &priv->mod_info; 899b5a28756SPhil Edworthy 900b5a28756SPhil Edworthy info->irq_vbus = NULL; 901b5a28756SPhil Edworthy priv->pfunc.get_vbus = usbhsm_phy_get_vbus; 902b5a28756SPhil Edworthy 903b5a28756SPhil Edworthy usbhs_irq_callback_update(priv, NULL); 904b5a28756SPhil Edworthy } 905b5a28756SPhil Edworthy 906b5a28756SPhil Edworthy /* 9072f98382dSKuninori Morimoto * 9082f98382dSKuninori Morimoto * linux usb function 9092f98382dSKuninori Morimoto * 9102f98382dSKuninori Morimoto */ 911af1d7056SFelipe Balbi static int usbhsg_gadget_start(struct usb_gadget *gadget, 912af1d7056SFelipe Balbi struct usb_gadget_driver *driver) 9132f98382dSKuninori Morimoto { 914af1d7056SFelipe Balbi struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 915f8eff0a0SKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 916b5a28756SPhil Edworthy struct device *dev = usbhs_priv_to_dev(priv); 917b5a28756SPhil Edworthy int ret; 9182f98382dSKuninori Morimoto 919af1d7056SFelipe Balbi if (!driver || 9202f98382dSKuninori Morimoto !driver->setup || 9217177aed4SMichal Nazarewicz driver->max_speed < USB_SPEED_FULL) 9222f98382dSKuninori Morimoto return -EINVAL; 9233b872188SKuninori Morimoto 924b5a28756SPhil Edworthy /* connect to bus through transceiver */ 925b5a28756SPhil Edworthy if (!IS_ERR_OR_NULL(gpriv->transceiver)) { 926b5a28756SPhil Edworthy ret = otg_set_peripheral(gpriv->transceiver->otg, 927b5a28756SPhil Edworthy &gpriv->gadget); 928b5a28756SPhil Edworthy if (ret) { 929b5a28756SPhil Edworthy dev_err(dev, "%s: can't bind to transceiver\n", 930b5a28756SPhil Edworthy gpriv->gadget.name); 931b5a28756SPhil Edworthy return ret; 932b5a28756SPhil Edworthy } 933b5a28756SPhil Edworthy 934b5a28756SPhil Edworthy /* get vbus using phy versions */ 935b5a28756SPhil Edworthy usbhs_mod_phy_mode(priv); 936b5a28756SPhil Edworthy } 937b5a28756SPhil Edworthy 9382f98382dSKuninori Morimoto /* first hook up the driver ... */ 9392f98382dSKuninori Morimoto gpriv->driver = driver; 9402f98382dSKuninori Morimoto 9412f98382dSKuninori Morimoto return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); 9422f98382dSKuninori Morimoto } 9432f98382dSKuninori Morimoto 94422835b80SFelipe Balbi static int usbhsg_gadget_stop(struct usb_gadget *gadget) 9452f98382dSKuninori Morimoto { 946af1d7056SFelipe Balbi struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 947f8eff0a0SKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 9482f98382dSKuninori Morimoto 9492f98382dSKuninori Morimoto usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); 950b5a28756SPhil Edworthy 951b5a28756SPhil Edworthy if (!IS_ERR_OR_NULL(gpriv->transceiver)) 952b5a28756SPhil Edworthy otg_set_peripheral(gpriv->transceiver->otg, NULL); 953b5a28756SPhil Edworthy 9542f98382dSKuninori Morimoto gpriv->driver = NULL; 9552f98382dSKuninori Morimoto 9562f98382dSKuninori Morimoto return 0; 9572f98382dSKuninori Morimoto } 9582f98382dSKuninori Morimoto 9592f98382dSKuninori Morimoto /* 9602f98382dSKuninori Morimoto * usb gadget ops 9612f98382dSKuninori Morimoto */ 9622f98382dSKuninori Morimoto static int usbhsg_get_frame(struct usb_gadget *gadget) 9632f98382dSKuninori Morimoto { 9642f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 9652f98382dSKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 9662f98382dSKuninori Morimoto 9672f98382dSKuninori Morimoto return usbhs_frame_get_num(priv); 9682f98382dSKuninori Morimoto } 9692f98382dSKuninori Morimoto 9704cd2f599Skuninori.morimoto.gx@renesas.com static int usbhsg_pullup(struct usb_gadget *gadget, int is_on) 9714cd2f599Skuninori.morimoto.gx@renesas.com { 9724cd2f599Skuninori.morimoto.gx@renesas.com struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 9734cd2f599Skuninori.morimoto.gx@renesas.com struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 97404a5def3STakeshi Kihara unsigned long flags; 9754cd2f599Skuninori.morimoto.gx@renesas.com 97604a5def3STakeshi Kihara usbhs_lock(priv, flags); 97704a5def3STakeshi Kihara if (is_on) 97804a5def3STakeshi Kihara usbhsg_status_set(gpriv, USBHSG_STATUS_SOFT_CONNECT); 97904a5def3STakeshi Kihara else 98004a5def3STakeshi Kihara usbhsg_status_clr(gpriv, USBHSG_STATUS_SOFT_CONNECT); 98104a5def3STakeshi Kihara usbhsg_update_pullup(priv); 98204a5def3STakeshi Kihara usbhs_unlock(priv, flags); 9834cd2f599Skuninori.morimoto.gx@renesas.com 9844cd2f599Skuninori.morimoto.gx@renesas.com return 0; 9854cd2f599Skuninori.morimoto.gx@renesas.com } 9864cd2f599Skuninori.morimoto.gx@renesas.com 987cac402ddSShimoda, Yoshihiro static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self) 988cac402ddSShimoda, Yoshihiro { 989cac402ddSShimoda, Yoshihiro struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 990cac402ddSShimoda, Yoshihiro 991cac402ddSShimoda, Yoshihiro if (is_self) 992cac402ddSShimoda, Yoshihiro usbhsg_status_set(gpriv, USBHSG_STATUS_SELF_POWERED); 993cac402ddSShimoda, Yoshihiro else 994cac402ddSShimoda, Yoshihiro usbhsg_status_clr(gpriv, USBHSG_STATUS_SELF_POWERED); 995cac402ddSShimoda, Yoshihiro 996a17fd412SPeter Chen gadget->is_selfpowered = (is_self != 0); 997a17fd412SPeter Chen 998cac402ddSShimoda, Yoshihiro return 0; 999cac402ddSShimoda, Yoshihiro } 1000cac402ddSShimoda, Yoshihiro 1001b5a28756SPhil Edworthy static int usbhsg_vbus_session(struct usb_gadget *gadget, int is_active) 1002b5a28756SPhil Edworthy { 1003b5a28756SPhil Edworthy struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 1004b5a28756SPhil Edworthy struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 1005b5a28756SPhil Edworthy struct platform_device *pdev = usbhs_priv_to_pdev(priv); 1006b5a28756SPhil Edworthy 1007b5a28756SPhil Edworthy gpriv->vbus_active = !!is_active; 1008b5a28756SPhil Edworthy 1009b5a28756SPhil Edworthy renesas_usbhs_call_notify_hotplug(pdev); 1010b5a28756SPhil Edworthy 1011b5a28756SPhil Edworthy return 0; 1012b5a28756SPhil Edworthy } 1013b5a28756SPhil Edworthy 1014eeef4587SFelipe Balbi static const struct usb_gadget_ops usbhsg_gadget_ops = { 10152f98382dSKuninori Morimoto .get_frame = usbhsg_get_frame, 1016cac402ddSShimoda, Yoshihiro .set_selfpowered = usbhsg_set_selfpowered, 1017af1d7056SFelipe Balbi .udc_start = usbhsg_gadget_start, 1018af1d7056SFelipe Balbi .udc_stop = usbhsg_gadget_stop, 10194cd2f599Skuninori.morimoto.gx@renesas.com .pullup = usbhsg_pullup, 1020b5a28756SPhil Edworthy .vbus_session = usbhsg_vbus_session, 10212f98382dSKuninori Morimoto }; 10222f98382dSKuninori Morimoto 10232f98382dSKuninori Morimoto static int usbhsg_start(struct usbhs_priv *priv) 10242f98382dSKuninori Morimoto { 10252f98382dSKuninori Morimoto return usbhsg_try_start(priv, USBHSG_STATUS_STARTED); 10262f98382dSKuninori Morimoto } 10272f98382dSKuninori Morimoto 10282f98382dSKuninori Morimoto static int usbhsg_stop(struct usbhs_priv *priv) 10292f98382dSKuninori Morimoto { 10308885a897SKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 10318885a897SKuninori Morimoto 10328885a897SKuninori Morimoto /* cable disconnect */ 10338885a897SKuninori Morimoto if (gpriv->driver && 10348885a897SKuninori Morimoto gpriv->driver->disconnect) 10358885a897SKuninori Morimoto gpriv->driver->disconnect(&gpriv->gadget); 10368885a897SKuninori Morimoto 10372f98382dSKuninori Morimoto return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); 10382f98382dSKuninori Morimoto } 10392f98382dSKuninori Morimoto 1040b7a8d17dSKuninori Morimoto int usbhs_mod_gadget_probe(struct usbhs_priv *priv) 10412f98382dSKuninori Morimoto { 10422f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv; 10432f98382dSKuninori Morimoto struct usbhsg_uep *uep; 10442f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 1045*64c5f48bSYoshihiro Shimoda struct renesas_usbhs_driver_pipe_config *pipe_configs = 1046*64c5f48bSYoshihiro Shimoda usbhs_get_dparam(priv, pipe_configs); 10472f98382dSKuninori Morimoto int pipe_size = usbhs_get_dparam(priv, pipe_size); 10482f98382dSKuninori Morimoto int i; 10490f91349bSSebastian Andrzej Siewior int ret; 10502f98382dSKuninori Morimoto 10512f98382dSKuninori Morimoto gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL); 10522f98382dSKuninori Morimoto if (!gpriv) { 10532f98382dSKuninori Morimoto dev_err(dev, "Could not allocate gadget priv\n"); 10542f98382dSKuninori Morimoto return -ENOMEM; 10552f98382dSKuninori Morimoto } 10562f98382dSKuninori Morimoto 10572f98382dSKuninori Morimoto uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL); 10582f98382dSKuninori Morimoto if (!uep) { 10592f98382dSKuninori Morimoto dev_err(dev, "Could not allocate ep\n"); 10600f91349bSSebastian Andrzej Siewior ret = -ENOMEM; 10612f98382dSKuninori Morimoto goto usbhs_mod_gadget_probe_err_gpriv; 10622f98382dSKuninori Morimoto } 10632f98382dSKuninori Morimoto 1064b5a28756SPhil Edworthy gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED); 1065b5a28756SPhil Edworthy dev_info(dev, "%stransceiver found\n", 1066b5a28756SPhil Edworthy gpriv->transceiver ? "" : "no "); 1067b5a28756SPhil Edworthy 10682f98382dSKuninori Morimoto /* 10692f98382dSKuninori Morimoto * CAUTION 10702f98382dSKuninori Morimoto * 10712f98382dSKuninori Morimoto * There is no guarantee that it is possible to access usb module here. 10722f98382dSKuninori Morimoto * Don't accesses to it. 10732f98382dSKuninori Morimoto * The accesse will be enable after "usbhsg_start" 10742f98382dSKuninori Morimoto */ 10752f98382dSKuninori Morimoto 10762f98382dSKuninori Morimoto /* 10772f98382dSKuninori Morimoto * register itself 10782f98382dSKuninori Morimoto */ 10792f98382dSKuninori Morimoto usbhs_mod_register(priv, &gpriv->mod, USBHS_GADGET); 10802f98382dSKuninori Morimoto 10812f98382dSKuninori Morimoto /* init gpriv */ 10822f98382dSKuninori Morimoto gpriv->mod.name = "gadget"; 10832f98382dSKuninori Morimoto gpriv->mod.start = usbhsg_start; 10842f98382dSKuninori Morimoto gpriv->mod.stop = usbhsg_stop; 10852f98382dSKuninori Morimoto gpriv->uep = uep; 10862f98382dSKuninori Morimoto gpriv->uep_size = pipe_size; 10872f98382dSKuninori Morimoto usbhsg_status_init(gpriv); 10882f98382dSKuninori Morimoto 10892f98382dSKuninori Morimoto /* 10902f98382dSKuninori Morimoto * init gadget 10912f98382dSKuninori Morimoto */ 10922f98382dSKuninori Morimoto gpriv->gadget.dev.parent = dev; 10932f98382dSKuninori Morimoto gpriv->gadget.name = "renesas_usbhs_udc"; 10942f98382dSKuninori Morimoto gpriv->gadget.ops = &usbhsg_gadget_ops; 1095d327ab5bSMichal Nazarewicz gpriv->gadget.max_speed = USB_SPEED_HIGH; 10962f98382dSKuninori Morimoto 10972f98382dSKuninori Morimoto INIT_LIST_HEAD(&gpriv->gadget.ep_list); 10982f98382dSKuninori Morimoto 10992f98382dSKuninori Morimoto /* 11002f98382dSKuninori Morimoto * init usb_ep 11012f98382dSKuninori Morimoto */ 11022f98382dSKuninori Morimoto usbhsg_for_each_uep_with_dcp(uep, gpriv, i) { 11032f98382dSKuninori Morimoto uep->gpriv = gpriv; 110458482945SKuninori Morimoto uep->pipe = NULL; 11052f98382dSKuninori Morimoto snprintf(uep->ep_name, EP_NAME_SIZE, "ep%d", i); 11062f98382dSKuninori Morimoto 11072f98382dSKuninori Morimoto uep->ep.name = uep->ep_name; 11082f98382dSKuninori Morimoto uep->ep.ops = &usbhsg_ep_ops; 11092f98382dSKuninori Morimoto INIT_LIST_HEAD(&uep->ep.ep_list); 11102f98382dSKuninori Morimoto 11112f98382dSKuninori Morimoto /* init DCP */ 11122f98382dSKuninori Morimoto if (usbhsg_is_dcp(uep)) { 11132f98382dSKuninori Morimoto gpriv->gadget.ep0 = &uep->ep; 1114e117e742SRobert Baldyga usb_ep_set_maxpacket_limit(&uep->ep, 64); 1115916f7ac5SRobert Baldyga uep->ep.caps.type_control = true; 1116*64c5f48bSYoshihiro Shimoda } else { 11172f98382dSKuninori Morimoto /* init normal pipe */ 1118*64c5f48bSYoshihiro Shimoda if (pipe_configs[i].type == USB_ENDPOINT_XFER_ISOC) 1119916f7ac5SRobert Baldyga uep->ep.caps.type_iso = true; 1120*64c5f48bSYoshihiro Shimoda if (pipe_configs[i].type == USB_ENDPOINT_XFER_BULK) 1121916f7ac5SRobert Baldyga uep->ep.caps.type_bulk = true; 1122*64c5f48bSYoshihiro Shimoda if (pipe_configs[i].type == USB_ENDPOINT_XFER_INT) 1123916f7ac5SRobert Baldyga uep->ep.caps.type_int = true; 1124*64c5f48bSYoshihiro Shimoda usb_ep_set_maxpacket_limit(&uep->ep, 1125*64c5f48bSYoshihiro Shimoda pipe_configs[i].bufsize); 11262f98382dSKuninori Morimoto list_add_tail(&uep->ep.ep_list, &gpriv->gadget.ep_list); 11272f98382dSKuninori Morimoto } 1128916f7ac5SRobert Baldyga uep->ep.caps.dir_in = true; 1129916f7ac5SRobert Baldyga uep->ep.caps.dir_out = true; 11302f98382dSKuninori Morimoto } 11312f98382dSKuninori Morimoto 11320f91349bSSebastian Andrzej Siewior ret = usb_add_gadget_udc(dev, &gpriv->gadget); 11330f91349bSSebastian Andrzej Siewior if (ret) 11340972ef71SFelipe Balbi goto err_add_udc; 11350f91349bSSebastian Andrzej Siewior 11360f91349bSSebastian Andrzej Siewior 11372f98382dSKuninori Morimoto dev_info(dev, "gadget probed\n"); 11382f98382dSKuninori Morimoto 11392f98382dSKuninori Morimoto return 0; 1140f8eff0a0SKuninori Morimoto 11410f91349bSSebastian Andrzej Siewior err_add_udc: 11420f91349bSSebastian Andrzej Siewior kfree(gpriv->uep); 11432f98382dSKuninori Morimoto 11442f98382dSKuninori Morimoto usbhs_mod_gadget_probe_err_gpriv: 11452f98382dSKuninori Morimoto kfree(gpriv); 11462f98382dSKuninori Morimoto 11470f91349bSSebastian Andrzej Siewior return ret; 11482f98382dSKuninori Morimoto } 11492f98382dSKuninori Morimoto 1150b7a8d17dSKuninori Morimoto void usbhs_mod_gadget_remove(struct usbhs_priv *priv) 11512f98382dSKuninori Morimoto { 11522f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 11532f98382dSKuninori Morimoto 11540f91349bSSebastian Andrzej Siewior usb_del_gadget_udc(&gpriv->gadget); 11553b872188SKuninori Morimoto 11563af51ac9SSebastian Andrzej Siewior kfree(gpriv->uep); 11572f98382dSKuninori Morimoto kfree(gpriv); 11582f98382dSKuninori Morimoto } 1159