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 */ 17d128a259SKuninori Morimoto #include <linux/dma-mapping.h> 182f98382dSKuninori Morimoto #include <linux/io.h> 192f98382dSKuninori Morimoto #include <linux/module.h> 202f98382dSKuninori Morimoto #include <linux/platform_device.h> 212f98382dSKuninori Morimoto #include <linux/usb/ch9.h> 222f98382dSKuninori Morimoto #include <linux/usb/gadget.h> 232f98382dSKuninori Morimoto #include "common.h" 242f98382dSKuninori Morimoto 252f98382dSKuninori Morimoto /* 262f98382dSKuninori Morimoto * struct 272f98382dSKuninori Morimoto */ 282f98382dSKuninori Morimoto struct usbhsg_request { 292f98382dSKuninori Morimoto struct usb_request req; 304bd04811SKuninori Morimoto struct usbhs_pkt pkt; 312f98382dSKuninori Morimoto }; 322f98382dSKuninori Morimoto 332f98382dSKuninori Morimoto #define EP_NAME_SIZE 8 342f98382dSKuninori Morimoto struct usbhsg_gpriv; 352f98382dSKuninori Morimoto struct usbhsg_uep { 362f98382dSKuninori Morimoto struct usb_ep ep; 372f98382dSKuninori Morimoto struct usbhs_pipe *pipe; 382f98382dSKuninori Morimoto 392f98382dSKuninori Morimoto char ep_name[EP_NAME_SIZE]; 402f98382dSKuninori Morimoto 412f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv; 422f98382dSKuninori Morimoto }; 432f98382dSKuninori Morimoto 442f98382dSKuninori Morimoto struct usbhsg_gpriv { 452f98382dSKuninori Morimoto struct usb_gadget gadget; 462f98382dSKuninori Morimoto struct usbhs_mod mod; 473b872188SKuninori Morimoto struct list_head link; 482f98382dSKuninori Morimoto 492f98382dSKuninori Morimoto struct usbhsg_uep *uep; 502f98382dSKuninori Morimoto int uep_size; 512f98382dSKuninori Morimoto 522f98382dSKuninori Morimoto struct usb_gadget_driver *driver; 532f98382dSKuninori Morimoto 542f98382dSKuninori Morimoto u32 status; 552f98382dSKuninori Morimoto #define USBHSG_STATUS_STARTED (1 << 0) 562f98382dSKuninori Morimoto #define USBHSG_STATUS_REGISTERD (1 << 1) 572f98382dSKuninori Morimoto #define USBHSG_STATUS_WEDGE (1 << 2) 582f98382dSKuninori Morimoto }; 592f98382dSKuninori Morimoto 602f98382dSKuninori Morimoto struct usbhsg_recip_handle { 612f98382dSKuninori Morimoto char *name; 622f98382dSKuninori Morimoto int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 632f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 642f98382dSKuninori Morimoto int (*interface)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 652f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 662f98382dSKuninori Morimoto int (*endpoint)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 672f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 682f98382dSKuninori Morimoto }; 692f98382dSKuninori Morimoto 702f98382dSKuninori Morimoto /* 712f98382dSKuninori Morimoto * macro 722f98382dSKuninori Morimoto */ 732f98382dSKuninori Morimoto #define usbhsg_priv_to_gpriv(priv) \ 742f98382dSKuninori Morimoto container_of( \ 752f98382dSKuninori Morimoto usbhs_mod_get(priv, USBHS_GADGET), \ 762f98382dSKuninori Morimoto struct usbhsg_gpriv, mod) 772f98382dSKuninori Morimoto 782f98382dSKuninori Morimoto #define __usbhsg_for_each_uep(start, pos, g, i) \ 79e94c587eSKuninori Morimoto for (i = start, pos = (g)->uep + i; \ 802f98382dSKuninori Morimoto i < (g)->uep_size; \ 812f98382dSKuninori Morimoto i++, pos = (g)->uep + i) 822f98382dSKuninori Morimoto 832f98382dSKuninori Morimoto #define usbhsg_for_each_uep(pos, gpriv, i) \ 842f98382dSKuninori Morimoto __usbhsg_for_each_uep(1, pos, gpriv, i) 852f98382dSKuninori Morimoto 862f98382dSKuninori Morimoto #define usbhsg_for_each_uep_with_dcp(pos, gpriv, i) \ 872f98382dSKuninori Morimoto __usbhsg_for_each_uep(0, pos, gpriv, i) 882f98382dSKuninori Morimoto 892f98382dSKuninori Morimoto #define usbhsg_gadget_to_gpriv(g)\ 902f98382dSKuninori Morimoto container_of(g, struct usbhsg_gpriv, gadget) 912f98382dSKuninori Morimoto 922f98382dSKuninori Morimoto #define usbhsg_req_to_ureq(r)\ 932f98382dSKuninori Morimoto container_of(r, struct usbhsg_request, req) 942f98382dSKuninori Morimoto 952f98382dSKuninori Morimoto #define usbhsg_ep_to_uep(e) container_of(e, struct usbhsg_uep, ep) 962f98382dSKuninori Morimoto #define usbhsg_gpriv_to_dev(gp) usbhs_priv_to_dev((gp)->mod.priv) 972f98382dSKuninori Morimoto #define usbhsg_gpriv_to_priv(gp) ((gp)->mod.priv) 982f98382dSKuninori Morimoto #define usbhsg_gpriv_to_dcp(gp) ((gp)->uep) 992f98382dSKuninori Morimoto #define usbhsg_gpriv_to_nth_uep(gp, i) ((gp)->uep + i) 1002f98382dSKuninori Morimoto #define usbhsg_uep_to_gpriv(u) ((u)->gpriv) 1012f98382dSKuninori Morimoto #define usbhsg_uep_to_pipe(u) ((u)->pipe) 1022f98382dSKuninori Morimoto #define usbhsg_pipe_to_uep(p) ((p)->mod_private) 1032f98382dSKuninori Morimoto #define usbhsg_is_dcp(u) ((u) == usbhsg_gpriv_to_dcp((u)->gpriv)) 1042f98382dSKuninori Morimoto 1054bd04811SKuninori Morimoto #define usbhsg_ureq_to_pkt(u) (&(u)->pkt) 1064bd04811SKuninori Morimoto #define usbhsg_pkt_to_ureq(i) \ 1074bd04811SKuninori Morimoto container_of(i, struct usbhsg_request, pkt) 1084bd04811SKuninori Morimoto 1092f98382dSKuninori Morimoto #define usbhsg_is_not_connected(gp) ((gp)->gadget.speed == USB_SPEED_UNKNOWN) 1102f98382dSKuninori Morimoto 1112f98382dSKuninori Morimoto /* status */ 1122f98382dSKuninori Morimoto #define usbhsg_status_init(gp) do {(gp)->status = 0; } while (0) 1132f98382dSKuninori Morimoto #define usbhsg_status_set(gp, b) (gp->status |= b) 1142f98382dSKuninori Morimoto #define usbhsg_status_clr(gp, b) (gp->status &= ~b) 1152f98382dSKuninori Morimoto #define usbhsg_status_has(gp, b) (gp->status & b) 1162f98382dSKuninori Morimoto 1173b872188SKuninori Morimoto /* controller */ 1183b872188SKuninori Morimoto LIST_HEAD(the_controller_link); 1193b872188SKuninori Morimoto 1203b872188SKuninori Morimoto #define usbhsg_for_each_controller(gpriv)\ 1213b872188SKuninori Morimoto list_for_each_entry(gpriv, &the_controller_link, link) 1223b872188SKuninori Morimoto #define usbhsg_controller_register(gpriv)\ 1233b872188SKuninori Morimoto list_add_tail(&(gpriv)->link, &the_controller_link) 1243b872188SKuninori Morimoto #define usbhsg_controller_unregister(gpriv)\ 1253b872188SKuninori Morimoto list_del_init(&(gpriv)->link) 1263b872188SKuninori Morimoto 1272f98382dSKuninori Morimoto /* 128233f519dSKuninori Morimoto * queue push/pop 1292f98382dSKuninori Morimoto */ 1302f98382dSKuninori Morimoto static void usbhsg_queue_pop(struct usbhsg_uep *uep, 1312f98382dSKuninori Morimoto struct usbhsg_request *ureq, 1322f98382dSKuninori Morimoto int status) 1332f98382dSKuninori Morimoto { 1342f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 1352f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 1362f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 1372f98382dSKuninori Morimoto 1382f98382dSKuninori Morimoto dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); 1392f98382dSKuninori Morimoto 1402f98382dSKuninori Morimoto ureq->req.status = status; 1412f98382dSKuninori Morimoto ureq->req.complete(&uep->ep, &ureq->req); 1422f98382dSKuninori Morimoto } 1432f98382dSKuninori Morimoto 1442cc97197SKuninori Morimoto static void usbhsg_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) 1452f98382dSKuninori Morimoto { 1464bd04811SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 1474bd04811SKuninori Morimoto struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); 1484bd04811SKuninori Morimoto struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); 1494bd04811SKuninori Morimoto 150659d4954SKuninori Morimoto ureq->req.actual = pkt->actual; 1512f98382dSKuninori Morimoto 1522f98382dSKuninori Morimoto usbhsg_queue_pop(uep, ureq, 0); 1532f98382dSKuninori Morimoto } 1544bd04811SKuninori Morimoto 155b331872bSKuninori Morimoto static void usbhsg_queue_push(struct usbhsg_uep *uep, 156b331872bSKuninori Morimoto struct usbhsg_request *ureq) 157b331872bSKuninori Morimoto { 158b331872bSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 159b331872bSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 160b331872bSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 161b331872bSKuninori Morimoto struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); 162b331872bSKuninori Morimoto struct usb_request *req = &ureq->req; 163b331872bSKuninori Morimoto 164b331872bSKuninori Morimoto req->actual = 0; 165b331872bSKuninori Morimoto req->status = -EINPROGRESS; 166b331872bSKuninori Morimoto usbhs_pkt_push(pipe, pkt, usbhsg_queue_done, 167b331872bSKuninori Morimoto req->buf, req->length, req->zero); 168654c35abSKuninori Morimoto usbhs_pkt_start(pipe); 169b331872bSKuninori Morimoto 170b331872bSKuninori Morimoto dev_dbg(dev, "pipe %d : queue push (%d)\n", 171b331872bSKuninori Morimoto usbhs_pipe_number(pipe), 172b331872bSKuninori Morimoto req->length); 173b331872bSKuninori Morimoto } 174b331872bSKuninori Morimoto 175233f519dSKuninori Morimoto /* 176233f519dSKuninori Morimoto * dma map/unmap 177233f519dSKuninori Morimoto */ 178e73a9891SKuninori Morimoto static int usbhsg_dma_map(struct device *dev, 179e73a9891SKuninori Morimoto struct usbhs_pkt *pkt, 180e73a9891SKuninori Morimoto enum dma_data_direction dir) 181e73a9891SKuninori Morimoto { 182e73a9891SKuninori Morimoto struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); 183e73a9891SKuninori Morimoto struct usb_request *req = &ureq->req; 184e73a9891SKuninori Morimoto 185e73a9891SKuninori Morimoto if (pkt->dma != DMA_ADDR_INVALID) { 186e73a9891SKuninori Morimoto dev_err(dev, "dma is already mapped\n"); 187e73a9891SKuninori Morimoto return -EIO; 188e73a9891SKuninori Morimoto } 189e73a9891SKuninori Morimoto 190e73a9891SKuninori Morimoto if (req->dma == DMA_ADDR_INVALID) { 191e73a9891SKuninori Morimoto pkt->dma = dma_map_single(dev, pkt->buf, pkt->length, dir); 192e73a9891SKuninori Morimoto } else { 193e73a9891SKuninori Morimoto dma_sync_single_for_device(dev, req->dma, req->length, dir); 194e73a9891SKuninori Morimoto pkt->dma = req->dma; 195e73a9891SKuninori Morimoto } 196e73a9891SKuninori Morimoto 197e73a9891SKuninori Morimoto if (dma_mapping_error(dev, pkt->dma)) { 198e73a9891SKuninori Morimoto dev_err(dev, "dma mapping error %x\n", pkt->dma); 199e73a9891SKuninori Morimoto return -EIO; 200e73a9891SKuninori Morimoto } 201e73a9891SKuninori Morimoto 202e73a9891SKuninori Morimoto return 0; 203e73a9891SKuninori Morimoto } 204e73a9891SKuninori Morimoto 205e73a9891SKuninori Morimoto static int usbhsg_dma_unmap(struct device *dev, 206e73a9891SKuninori Morimoto struct usbhs_pkt *pkt, 207e73a9891SKuninori Morimoto enum dma_data_direction dir) 208e73a9891SKuninori Morimoto { 209e73a9891SKuninori Morimoto struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); 210e73a9891SKuninori Morimoto struct usb_request *req = &ureq->req; 211e73a9891SKuninori Morimoto 212e73a9891SKuninori Morimoto if (pkt->dma == DMA_ADDR_INVALID) { 213e73a9891SKuninori Morimoto dev_err(dev, "dma is not mapped\n"); 214e73a9891SKuninori Morimoto return -EIO; 215e73a9891SKuninori Morimoto } 216e73a9891SKuninori Morimoto 217e73a9891SKuninori Morimoto if (req->dma == DMA_ADDR_INVALID) 218e73a9891SKuninori Morimoto dma_unmap_single(dev, pkt->dma, pkt->length, dir); 219e73a9891SKuninori Morimoto else 220e73a9891SKuninori Morimoto dma_sync_single_for_cpu(dev, req->dma, req->length, dir); 221e73a9891SKuninori Morimoto 222e73a9891SKuninori Morimoto pkt->dma = DMA_ADDR_INVALID; 223e73a9891SKuninori Morimoto 224e73a9891SKuninori Morimoto return 0; 225e73a9891SKuninori Morimoto } 226e73a9891SKuninori Morimoto 227e73a9891SKuninori Morimoto static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map) 228e73a9891SKuninori Morimoto { 229e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 230e73a9891SKuninori Morimoto struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); 231e73a9891SKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 232e73a9891SKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 233e73a9891SKuninori Morimoto enum dma_data_direction dir; 234e73a9891SKuninori Morimoto 235e73a9891SKuninori Morimoto dir = usbhs_pipe_is_dir_in(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 236e73a9891SKuninori Morimoto 237e73a9891SKuninori Morimoto if (map) 238e73a9891SKuninori Morimoto return usbhsg_dma_map(dev, pkt, dir); 239e73a9891SKuninori Morimoto else 240e73a9891SKuninori Morimoto return usbhsg_dma_unmap(dev, pkt, dir); 241e73a9891SKuninori Morimoto } 242e73a9891SKuninori Morimoto 2432f98382dSKuninori Morimoto /* 2442f98382dSKuninori Morimoto * USB_TYPE_STANDARD / clear feature functions 2452f98382dSKuninori Morimoto */ 2462f98382dSKuninori Morimoto static int usbhsg_recip_handler_std_control_done(struct usbhs_priv *priv, 2472f98382dSKuninori Morimoto struct usbhsg_uep *uep, 2482f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 2492f98382dSKuninori Morimoto { 2502f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 2512f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 2522f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); 2532f98382dSKuninori Morimoto 2542f98382dSKuninori Morimoto usbhs_dcp_control_transfer_done(pipe); 2552f98382dSKuninori Morimoto 2562f98382dSKuninori Morimoto return 0; 2572f98382dSKuninori Morimoto } 2582f98382dSKuninori Morimoto 2592f98382dSKuninori Morimoto static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, 2602f98382dSKuninori Morimoto struct usbhsg_uep *uep, 2612f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 2622f98382dSKuninori Morimoto { 2632f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 2642f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 2652f98382dSKuninori Morimoto 2662f98382dSKuninori Morimoto if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { 267e8d548d5SKuninori Morimoto usbhs_pipe_disable(pipe); 2686e6db82bSKuninori Morimoto usbhs_pipe_sequence_data0(pipe); 269e8d548d5SKuninori Morimoto usbhs_pipe_enable(pipe); 2702f98382dSKuninori Morimoto } 2712f98382dSKuninori Morimoto 2722f98382dSKuninori Morimoto usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 2732f98382dSKuninori Morimoto 2742f98382dSKuninori Morimoto return 0; 2752f98382dSKuninori Morimoto } 2762f98382dSKuninori Morimoto 2772f98382dSKuninori Morimoto struct usbhsg_recip_handle req_clear_feature = { 2782f98382dSKuninori Morimoto .name = "clear feature", 2792f98382dSKuninori Morimoto .device = usbhsg_recip_handler_std_control_done, 2802f98382dSKuninori Morimoto .interface = usbhsg_recip_handler_std_control_done, 2812f98382dSKuninori Morimoto .endpoint = usbhsg_recip_handler_std_clear_endpoint, 2822f98382dSKuninori Morimoto }; 2832f98382dSKuninori Morimoto 2842f98382dSKuninori Morimoto /* 2852f98382dSKuninori Morimoto * USB_TYPE handler 2862f98382dSKuninori Morimoto */ 2872f98382dSKuninori Morimoto static int usbhsg_recip_run_handle(struct usbhs_priv *priv, 2882f98382dSKuninori Morimoto struct usbhsg_recip_handle *handler, 2892f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl) 2902f98382dSKuninori Morimoto { 2912f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 2922f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 2932f98382dSKuninori Morimoto struct usbhsg_uep *uep; 2940432eed0SKuninori Morimoto struct usbhs_pipe *pipe; 2952f98382dSKuninori Morimoto int recip = ctrl->bRequestType & USB_RECIP_MASK; 2962f98382dSKuninori Morimoto int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; 2972f98382dSKuninori Morimoto int ret; 2982f98382dSKuninori Morimoto int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 2992f98382dSKuninori Morimoto struct usb_ctrlrequest *ctrl); 3002f98382dSKuninori Morimoto char *msg; 3012f98382dSKuninori Morimoto 3022f98382dSKuninori Morimoto uep = usbhsg_gpriv_to_nth_uep(gpriv, nth); 3030432eed0SKuninori Morimoto pipe = usbhsg_uep_to_pipe(uep); 3040432eed0SKuninori Morimoto if (!pipe) { 3059a28b7bdSKuninori Morimoto dev_err(dev, "wrong recip request\n"); 30697664a20SKuninori Morimoto ret = -EINVAL; 30797664a20SKuninori Morimoto goto usbhsg_recip_run_handle_end; 3089a28b7bdSKuninori Morimoto } 3092f98382dSKuninori Morimoto 3102f98382dSKuninori Morimoto switch (recip) { 3112f98382dSKuninori Morimoto case USB_RECIP_DEVICE: 3122f98382dSKuninori Morimoto msg = "DEVICE"; 3132f98382dSKuninori Morimoto func = handler->device; 3142f98382dSKuninori Morimoto break; 3152f98382dSKuninori Morimoto case USB_RECIP_INTERFACE: 3162f98382dSKuninori Morimoto msg = "INTERFACE"; 3172f98382dSKuninori Morimoto func = handler->interface; 3182f98382dSKuninori Morimoto break; 3192f98382dSKuninori Morimoto case USB_RECIP_ENDPOINT: 3202f98382dSKuninori Morimoto msg = "ENDPOINT"; 3212f98382dSKuninori Morimoto func = handler->endpoint; 3222f98382dSKuninori Morimoto break; 3232f98382dSKuninori Morimoto default: 3242f98382dSKuninori Morimoto dev_warn(dev, "unsupported RECIP(%d)\n", recip); 3252f98382dSKuninori Morimoto func = NULL; 3262f98382dSKuninori Morimoto ret = -EINVAL; 3272f98382dSKuninori Morimoto } 3282f98382dSKuninori Morimoto 3292f98382dSKuninori Morimoto if (func) { 33097664a20SKuninori Morimoto unsigned long flags; 33197664a20SKuninori Morimoto 3322f98382dSKuninori Morimoto dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); 33397664a20SKuninori Morimoto 33497664a20SKuninori Morimoto /******************** spin lock ********************/ 33597664a20SKuninori Morimoto usbhs_lock(priv, flags); 3362f98382dSKuninori Morimoto ret = func(priv, uep, ctrl); 33797664a20SKuninori Morimoto usbhs_unlock(priv, flags); 33897664a20SKuninori Morimoto /******************** spin unlock ******************/ 3392f98382dSKuninori Morimoto } 3402f98382dSKuninori Morimoto 34197664a20SKuninori Morimoto usbhsg_recip_run_handle_end: 3420432eed0SKuninori Morimoto usbhs_pkt_start(pipe); 34397664a20SKuninori Morimoto 3442f98382dSKuninori Morimoto return ret; 3452f98382dSKuninori Morimoto } 3462f98382dSKuninori Morimoto 3472f98382dSKuninori Morimoto /* 3482f98382dSKuninori Morimoto * irq functions 3492f98382dSKuninori Morimoto * 3502f98382dSKuninori Morimoto * it will be called from usbhs_interrupt 3512f98382dSKuninori Morimoto */ 3522f98382dSKuninori Morimoto static int usbhsg_irq_dev_state(struct usbhs_priv *priv, 3532f98382dSKuninori Morimoto struct usbhs_irq_state *irq_state) 3542f98382dSKuninori Morimoto { 3552f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 3562f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 3572f98382dSKuninori Morimoto 35875587f52SKuninori Morimoto gpriv->gadget.speed = usbhs_bus_get_speed(priv); 3592f98382dSKuninori Morimoto 3602f98382dSKuninori Morimoto dev_dbg(dev, "state = %x : speed : %d\n", 3612f98382dSKuninori Morimoto usbhs_status_get_device_state(irq_state), 3622f98382dSKuninori Morimoto gpriv->gadget.speed); 3632f98382dSKuninori Morimoto 3642f98382dSKuninori Morimoto return 0; 3652f98382dSKuninori Morimoto } 3662f98382dSKuninori Morimoto 3672f98382dSKuninori Morimoto static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, 3682f98382dSKuninori Morimoto struct usbhs_irq_state *irq_state) 3692f98382dSKuninori Morimoto { 3702f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 3712f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 3722f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); 3732f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 3742f98382dSKuninori Morimoto struct usb_ctrlrequest ctrl; 3752f98382dSKuninori Morimoto struct usbhsg_recip_handle *recip_handler = NULL; 3762f98382dSKuninori Morimoto int stage = usbhs_status_get_ctrl_stage(irq_state); 3772f98382dSKuninori Morimoto int ret = 0; 3782f98382dSKuninori Morimoto 3792f98382dSKuninori Morimoto dev_dbg(dev, "stage = %d\n", stage); 3802f98382dSKuninori Morimoto 3812f98382dSKuninori Morimoto /* 3822f98382dSKuninori Morimoto * see Manual 3832f98382dSKuninori Morimoto * 3842f98382dSKuninori Morimoto * "Operation" 3852f98382dSKuninori Morimoto * - "Interrupt Function" 3862f98382dSKuninori Morimoto * - "Control Transfer Stage Transition Interrupt" 3872f98382dSKuninori Morimoto * - Fig. "Control Transfer Stage Transitions" 3882f98382dSKuninori Morimoto */ 3892f98382dSKuninori Morimoto 3902f98382dSKuninori Morimoto switch (stage) { 3912f98382dSKuninori Morimoto case READ_DATA_STAGE: 3920c6ef985SKuninori Morimoto pipe->handler = &usbhs_fifo_pio_push_handler; 3932f98382dSKuninori Morimoto break; 3942f98382dSKuninori Morimoto case WRITE_DATA_STAGE: 3950c6ef985SKuninori Morimoto pipe->handler = &usbhs_fifo_pio_pop_handler; 3962f98382dSKuninori Morimoto break; 3972f98382dSKuninori Morimoto case NODATA_STATUS_STAGE: 3980c6ef985SKuninori Morimoto pipe->handler = &usbhs_ctrl_stage_end_handler; 3992f98382dSKuninori Morimoto break; 4002f98382dSKuninori Morimoto default: 4012f98382dSKuninori Morimoto return ret; 4022f98382dSKuninori Morimoto } 4032f98382dSKuninori Morimoto 4042f98382dSKuninori Morimoto /* 4052f98382dSKuninori Morimoto * get usb request 4062f98382dSKuninori Morimoto */ 4072f98382dSKuninori Morimoto usbhs_usbreq_get_val(priv, &ctrl); 4082f98382dSKuninori Morimoto 4092f98382dSKuninori Morimoto switch (ctrl.bRequestType & USB_TYPE_MASK) { 4102f98382dSKuninori Morimoto case USB_TYPE_STANDARD: 4112f98382dSKuninori Morimoto switch (ctrl.bRequest) { 4122f98382dSKuninori Morimoto case USB_REQ_CLEAR_FEATURE: 4132f98382dSKuninori Morimoto recip_handler = &req_clear_feature; 4142f98382dSKuninori Morimoto break; 4152f98382dSKuninori Morimoto } 4162f98382dSKuninori Morimoto } 4172f98382dSKuninori Morimoto 4182f98382dSKuninori Morimoto /* 4192f98382dSKuninori Morimoto * setup stage / run recip 4202f98382dSKuninori Morimoto */ 4212f98382dSKuninori Morimoto if (recip_handler) 4222f98382dSKuninori Morimoto ret = usbhsg_recip_run_handle(priv, recip_handler, &ctrl); 4232f98382dSKuninori Morimoto else 4242f98382dSKuninori Morimoto ret = gpriv->driver->setup(&gpriv->gadget, &ctrl); 4252f98382dSKuninori Morimoto 4262f98382dSKuninori Morimoto if (ret < 0) 427e8d548d5SKuninori Morimoto usbhs_pipe_stall(pipe); 4282f98382dSKuninori Morimoto 4292f98382dSKuninori Morimoto return ret; 4302f98382dSKuninori Morimoto } 4312f98382dSKuninori Morimoto 4322f98382dSKuninori Morimoto /* 4332f98382dSKuninori Morimoto * 4342f98382dSKuninori Morimoto * usb_dcp_ops 4352f98382dSKuninori Morimoto * 4362f98382dSKuninori Morimoto */ 4372f98382dSKuninori Morimoto static int usbhsg_pipe_disable(struct usbhsg_uep *uep) 4382f98382dSKuninori Morimoto { 4392f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 4408a2c225dSKuninori Morimoto struct usbhs_pkt *pkt; 4412f98382dSKuninori Morimoto 442e8d548d5SKuninori Morimoto usbhs_pipe_disable(pipe); 4432f98382dSKuninori Morimoto 4442f98382dSKuninori Morimoto while (1) { 44597664a20SKuninori Morimoto pkt = usbhs_pkt_pop(pipe, NULL); 4468a2c225dSKuninori Morimoto if (!pkt) 4472f98382dSKuninori Morimoto break; 4482f98382dSKuninori Morimoto } 4492f98382dSKuninori Morimoto 4502f98382dSKuninori Morimoto return 0; 4512f98382dSKuninori Morimoto } 4522f98382dSKuninori Morimoto 453409ba9e7SKuninori Morimoto static void usbhsg_uep_init(struct usbhsg_gpriv *gpriv) 454409ba9e7SKuninori Morimoto { 455409ba9e7SKuninori Morimoto int i; 456409ba9e7SKuninori Morimoto struct usbhsg_uep *uep; 457409ba9e7SKuninori Morimoto 458409ba9e7SKuninori Morimoto usbhsg_for_each_uep_with_dcp(uep, gpriv, i) 459409ba9e7SKuninori Morimoto uep->pipe = NULL; 460409ba9e7SKuninori Morimoto } 461409ba9e7SKuninori Morimoto 4622f98382dSKuninori Morimoto /* 4632f98382dSKuninori Morimoto * 4642f98382dSKuninori Morimoto * usb_ep_ops 4652f98382dSKuninori Morimoto * 4662f98382dSKuninori Morimoto */ 4672f98382dSKuninori Morimoto static int usbhsg_ep_enable(struct usb_ep *ep, 4682f98382dSKuninori Morimoto const struct usb_endpoint_descriptor *desc) 4692f98382dSKuninori Morimoto { 4702f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 4712f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 4722f98382dSKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 4732f98382dSKuninori Morimoto struct usbhs_pipe *pipe; 4742f98382dSKuninori Morimoto int ret = -EIO; 4752f98382dSKuninori Morimoto 476409ba9e7SKuninori Morimoto /* 477409ba9e7SKuninori Morimoto * if it already have pipe, 478409ba9e7SKuninori Morimoto * nothing to do 479409ba9e7SKuninori Morimoto */ 48008e6c611SKuninori Morimoto if (uep->pipe) { 48108e6c611SKuninori Morimoto usbhs_pipe_clear(uep->pipe); 4826e6db82bSKuninori Morimoto usbhs_pipe_sequence_data0(uep->pipe); 483409ba9e7SKuninori Morimoto return 0; 48408e6c611SKuninori Morimoto } 485409ba9e7SKuninori Morimoto 486f5aa889fSKuninori Morimoto pipe = usbhs_pipe_malloc(priv, 487f5aa889fSKuninori Morimoto usb_endpoint_type(desc), 488f5aa889fSKuninori Morimoto usb_endpoint_dir_in(desc)); 4892f98382dSKuninori Morimoto if (pipe) { 4902f98382dSKuninori Morimoto uep->pipe = pipe; 4912f98382dSKuninori Morimoto pipe->mod_private = uep; 4922f98382dSKuninori Morimoto 493f5aa889fSKuninori Morimoto /* set epnum / maxp */ 494bc6fbf59SKuninori Morimoto usbhs_pipe_config_update(pipe, 0, 495f5aa889fSKuninori Morimoto usb_endpoint_num(desc), 496f5aa889fSKuninori Morimoto usb_endpoint_maxp(desc)); 497f5aa889fSKuninori Morimoto 498233f519dSKuninori Morimoto /* 499233f519dSKuninori Morimoto * usbhs_fifo_dma_push/pop_handler try to 500233f519dSKuninori Morimoto * use dmaengine if possible. 501233f519dSKuninori Morimoto * It will use pio handler if impossible. 502233f519dSKuninori Morimoto */ 5032f98382dSKuninori Morimoto if (usb_endpoint_dir_in(desc)) 5040c6ef985SKuninori Morimoto pipe->handler = &usbhs_fifo_dma_push_handler; 5052f98382dSKuninori Morimoto else 5060c6ef985SKuninori Morimoto pipe->handler = &usbhs_fifo_dma_pop_handler; 5072f98382dSKuninori Morimoto 5082f98382dSKuninori Morimoto ret = 0; 5092f98382dSKuninori Morimoto } 510cb96632cSKuninori Morimoto 5112f98382dSKuninori Morimoto return ret; 5122f98382dSKuninori Morimoto } 5132f98382dSKuninori Morimoto 5142f98382dSKuninori Morimoto static int usbhsg_ep_disable(struct usb_ep *ep) 5152f98382dSKuninori Morimoto { 5162f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5172f98382dSKuninori Morimoto 51897664a20SKuninori Morimoto return usbhsg_pipe_disable(uep); 5192f98382dSKuninori Morimoto } 5202f98382dSKuninori Morimoto 5212f98382dSKuninori Morimoto static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, 5222f98382dSKuninori Morimoto gfp_t gfp_flags) 5232f98382dSKuninori Morimoto { 5242f98382dSKuninori Morimoto struct usbhsg_request *ureq; 5252f98382dSKuninori Morimoto 5262f98382dSKuninori Morimoto ureq = kzalloc(sizeof *ureq, gfp_flags); 5272f98382dSKuninori Morimoto if (!ureq) 5282f98382dSKuninori Morimoto return NULL; 5292f98382dSKuninori Morimoto 5306acb95d4SKuninori Morimoto usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); 5316acb95d4SKuninori Morimoto 532e73a9891SKuninori Morimoto ureq->req.dma = DMA_ADDR_INVALID; 533e73a9891SKuninori Morimoto 5342f98382dSKuninori Morimoto return &ureq->req; 5352f98382dSKuninori Morimoto } 5362f98382dSKuninori Morimoto 5372f98382dSKuninori Morimoto static void usbhsg_ep_free_request(struct usb_ep *ep, 5382f98382dSKuninori Morimoto struct usb_request *req) 5392f98382dSKuninori Morimoto { 5402f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 5412f98382dSKuninori Morimoto 5426acb95d4SKuninori Morimoto WARN_ON(!list_empty(&ureq->pkt.node)); 5432f98382dSKuninori Morimoto kfree(ureq); 5442f98382dSKuninori Morimoto } 5452f98382dSKuninori Morimoto 5462f98382dSKuninori Morimoto static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, 5472f98382dSKuninori Morimoto gfp_t gfp_flags) 5482f98382dSKuninori Morimoto { 5492f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5502f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 5512f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 5522f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 5532f98382dSKuninori Morimoto 5542f98382dSKuninori Morimoto /* param check */ 5552f98382dSKuninori Morimoto if (usbhsg_is_not_connected(gpriv) || 5562f98382dSKuninori Morimoto unlikely(!gpriv->driver) || 5572f98382dSKuninori Morimoto unlikely(!pipe)) 55897664a20SKuninori Morimoto return -ESHUTDOWN; 55997664a20SKuninori Morimoto 5602f98382dSKuninori Morimoto usbhsg_queue_push(uep, ureq); 5612f98382dSKuninori Morimoto 56297664a20SKuninori Morimoto return 0; 5632f98382dSKuninori Morimoto } 5642f98382dSKuninori Morimoto 5652f98382dSKuninori Morimoto static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) 5662f98382dSKuninori Morimoto { 5672f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5682f98382dSKuninori Morimoto struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 56997664a20SKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 5702f98382dSKuninori Morimoto 57197664a20SKuninori Morimoto usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); 5722f98382dSKuninori Morimoto usbhsg_queue_pop(uep, ureq, -ECONNRESET); 5732f98382dSKuninori Morimoto 5742f98382dSKuninori Morimoto return 0; 5752f98382dSKuninori Morimoto } 5762f98382dSKuninori Morimoto 5772f98382dSKuninori Morimoto static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) 5782f98382dSKuninori Morimoto { 5792f98382dSKuninori Morimoto struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 5802f98382dSKuninori Morimoto struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 5812f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 58297664a20SKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 5832f98382dSKuninori Morimoto struct device *dev = usbhsg_gpriv_to_dev(gpriv); 5842f98382dSKuninori Morimoto unsigned long flags; 5852f98382dSKuninori Morimoto 58697664a20SKuninori Morimoto usbhsg_pipe_disable(uep); 5872f98382dSKuninori Morimoto 5882f98382dSKuninori Morimoto dev_dbg(dev, "set halt %d (pipe %d)\n", 5892f98382dSKuninori Morimoto halt, usbhs_pipe_number(pipe)); 5902f98382dSKuninori Morimoto 59197664a20SKuninori Morimoto /******************** spin lock ********************/ 59297664a20SKuninori Morimoto usbhs_lock(priv, flags); 59397664a20SKuninori Morimoto 5942f98382dSKuninori Morimoto if (halt) 595e8d548d5SKuninori Morimoto usbhs_pipe_stall(pipe); 5962f98382dSKuninori Morimoto else 597e8d548d5SKuninori Morimoto usbhs_pipe_disable(pipe); 5982f98382dSKuninori Morimoto 5992f98382dSKuninori Morimoto if (halt && wedge) 6002f98382dSKuninori Morimoto usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); 6012f98382dSKuninori Morimoto else 6022f98382dSKuninori Morimoto usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); 6032f98382dSKuninori Morimoto 60497664a20SKuninori Morimoto usbhs_unlock(priv, flags); 6052f98382dSKuninori Morimoto /******************** spin unlock ******************/ 6062f98382dSKuninori Morimoto 60797664a20SKuninori Morimoto return 0; 6082f98382dSKuninori Morimoto } 6092f98382dSKuninori Morimoto 6102f98382dSKuninori Morimoto static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) 6112f98382dSKuninori Morimoto { 6122f98382dSKuninori Morimoto return __usbhsg_ep_set_halt_wedge(ep, value, 0); 6132f98382dSKuninori Morimoto } 6142f98382dSKuninori Morimoto 6152f98382dSKuninori Morimoto static int usbhsg_ep_set_wedge(struct usb_ep *ep) 6162f98382dSKuninori Morimoto { 6172f98382dSKuninori Morimoto return __usbhsg_ep_set_halt_wedge(ep, 1, 1); 6182f98382dSKuninori Morimoto } 6192f98382dSKuninori Morimoto 6202f98382dSKuninori Morimoto static struct usb_ep_ops usbhsg_ep_ops = { 6212f98382dSKuninori Morimoto .enable = usbhsg_ep_enable, 6222f98382dSKuninori Morimoto .disable = usbhsg_ep_disable, 6232f98382dSKuninori Morimoto 6242f98382dSKuninori Morimoto .alloc_request = usbhsg_ep_alloc_request, 6252f98382dSKuninori Morimoto .free_request = usbhsg_ep_free_request, 6262f98382dSKuninori Morimoto 6272f98382dSKuninori Morimoto .queue = usbhsg_ep_queue, 6282f98382dSKuninori Morimoto .dequeue = usbhsg_ep_dequeue, 6292f98382dSKuninori Morimoto 6302f98382dSKuninori Morimoto .set_halt = usbhsg_ep_set_halt, 6312f98382dSKuninori Morimoto .set_wedge = usbhsg_ep_set_wedge, 6322f98382dSKuninori Morimoto }; 6332f98382dSKuninori Morimoto 6342f98382dSKuninori Morimoto /* 6352f98382dSKuninori Morimoto * usb module start/end 6362f98382dSKuninori Morimoto */ 6372f98382dSKuninori Morimoto static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) 6382f98382dSKuninori Morimoto { 6392f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 6402f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 6412f98382dSKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 6422f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 6432f98382dSKuninori Morimoto unsigned long flags; 64497664a20SKuninori Morimoto int ret = 0; 6452f98382dSKuninori Morimoto 6462f98382dSKuninori Morimoto /******************** spin lock ********************/ 64797664a20SKuninori Morimoto usbhs_lock(priv, flags); 64897664a20SKuninori Morimoto 64997664a20SKuninori Morimoto usbhsg_status_set(gpriv, status); 65097664a20SKuninori Morimoto if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && 65197664a20SKuninori Morimoto usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) 65297664a20SKuninori Morimoto ret = -1; /* not ready */ 65397664a20SKuninori Morimoto 65497664a20SKuninori Morimoto usbhs_unlock(priv, flags); 65597664a20SKuninori Morimoto /******************** spin unlock ********************/ 65697664a20SKuninori Morimoto 65797664a20SKuninori Morimoto if (ret < 0) 65897664a20SKuninori Morimoto return 0; /* not ready is not error */ 6592f98382dSKuninori Morimoto 6602f98382dSKuninori Morimoto /* 6612f98382dSKuninori Morimoto * enable interrupt and systems if ready 6622f98382dSKuninori Morimoto */ 6632f98382dSKuninori Morimoto dev_dbg(dev, "start gadget\n"); 6642f98382dSKuninori Morimoto 6652f98382dSKuninori Morimoto /* 6662f98382dSKuninori Morimoto * pipe initialize and enable DCP 6672f98382dSKuninori Morimoto */ 6684bd04811SKuninori Morimoto usbhs_pipe_init(priv, 669e73a9891SKuninori Morimoto usbhsg_dma_map_ctrl); 670dad67397SKuninori Morimoto usbhs_fifo_init(priv); 671409ba9e7SKuninori Morimoto usbhsg_uep_init(gpriv); 67297664a20SKuninori Morimoto 67397664a20SKuninori Morimoto /* dcp init */ 67497664a20SKuninori Morimoto dcp->pipe = usbhs_dcp_malloc(priv); 67597664a20SKuninori Morimoto dcp->pipe->mod_private = dcp; 676bc6fbf59SKuninori Morimoto usbhs_pipe_config_update(dcp->pipe, 0, 0, 64); 6772f98382dSKuninori Morimoto 6782f98382dSKuninori Morimoto /* 6792f98382dSKuninori Morimoto * system config enble 6802f98382dSKuninori Morimoto * - HI speed 6812f98382dSKuninori Morimoto * - function 6822f98382dSKuninori Morimoto * - usb module 6832f98382dSKuninori Morimoto */ 6842f98382dSKuninori Morimoto usbhs_sys_hispeed_ctrl(priv, 1); 6852f98382dSKuninori Morimoto usbhs_sys_function_ctrl(priv, 1); 6862f98382dSKuninori Morimoto usbhs_sys_usb_ctrl(priv, 1); 6872f98382dSKuninori Morimoto 6882f98382dSKuninori Morimoto /* 6892f98382dSKuninori Morimoto * enable irq callback 6902f98382dSKuninori Morimoto */ 6912f98382dSKuninori Morimoto mod->irq_dev_state = usbhsg_irq_dev_state; 6922f98382dSKuninori Morimoto mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; 6932f98382dSKuninori Morimoto usbhs_irq_callback_update(priv, mod); 6942f98382dSKuninori Morimoto 6952f98382dSKuninori Morimoto return 0; 6962f98382dSKuninori Morimoto } 6972f98382dSKuninori Morimoto 6982f98382dSKuninori Morimoto static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) 6992f98382dSKuninori Morimoto { 7002f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 7012f98382dSKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 7022f98382dSKuninori Morimoto struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 7032f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 7042f98382dSKuninori Morimoto unsigned long flags; 70597664a20SKuninori Morimoto int ret = 0; 7062f98382dSKuninori Morimoto 7072f98382dSKuninori Morimoto /******************** spin lock ********************/ 70897664a20SKuninori Morimoto usbhs_lock(priv, flags); 70997664a20SKuninori Morimoto 71097664a20SKuninori Morimoto usbhsg_status_clr(gpriv, status); 71197664a20SKuninori Morimoto if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && 71297664a20SKuninori Morimoto !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) 71397664a20SKuninori Morimoto ret = -1; /* already done */ 71497664a20SKuninori Morimoto 71597664a20SKuninori Morimoto usbhs_unlock(priv, flags); 71697664a20SKuninori Morimoto /******************** spin unlock ********************/ 71797664a20SKuninori Morimoto 71897664a20SKuninori Morimoto if (ret < 0) 71997664a20SKuninori Morimoto return 0; /* already done is not error */ 7202f98382dSKuninori Morimoto 7212f98382dSKuninori Morimoto /* 7222f98382dSKuninori Morimoto * disable interrupt and systems if 1st try 7232f98382dSKuninori Morimoto */ 724dad67397SKuninori Morimoto usbhs_fifo_quit(priv); 725dad67397SKuninori Morimoto 7262f98382dSKuninori Morimoto /* disable all irq */ 7272f98382dSKuninori Morimoto mod->irq_dev_state = NULL; 7282f98382dSKuninori Morimoto mod->irq_ctrl_stage = NULL; 7292f98382dSKuninori Morimoto usbhs_irq_callback_update(priv, mod); 7302f98382dSKuninori Morimoto 7312f98382dSKuninori Morimoto gpriv->gadget.speed = USB_SPEED_UNKNOWN; 7322f98382dSKuninori Morimoto 7332f98382dSKuninori Morimoto /* disable sys */ 7342f98382dSKuninori Morimoto usbhs_sys_hispeed_ctrl(priv, 0); 7352f98382dSKuninori Morimoto usbhs_sys_function_ctrl(priv, 0); 7362f98382dSKuninori Morimoto usbhs_sys_usb_ctrl(priv, 0); 7372f98382dSKuninori Morimoto 73897664a20SKuninori Morimoto usbhsg_pipe_disable(dcp); 7392f98382dSKuninori Morimoto 7402f98382dSKuninori Morimoto dev_dbg(dev, "stop gadget\n"); 7412f98382dSKuninori Morimoto 7422f98382dSKuninori Morimoto return 0; 7432f98382dSKuninori Morimoto } 7442f98382dSKuninori Morimoto 7452f98382dSKuninori Morimoto /* 7462f98382dSKuninori Morimoto * 7472f98382dSKuninori Morimoto * linux usb function 7482f98382dSKuninori Morimoto * 7492f98382dSKuninori Morimoto */ 750af1d7056SFelipe Balbi static int usbhsg_gadget_start(struct usb_gadget *gadget, 751af1d7056SFelipe Balbi struct usb_gadget_driver *driver) 7522f98382dSKuninori Morimoto { 753af1d7056SFelipe Balbi struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 754*f8eff0a0SKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 7552f98382dSKuninori Morimoto 756af1d7056SFelipe Balbi if (!driver || 7572f98382dSKuninori Morimoto !driver->setup || 7582f98382dSKuninori Morimoto driver->speed != USB_SPEED_HIGH) 7592f98382dSKuninori Morimoto return -EINVAL; 7603b872188SKuninori Morimoto 7612f98382dSKuninori Morimoto /* first hook up the driver ... */ 7622f98382dSKuninori Morimoto gpriv->driver = driver; 7632f98382dSKuninori Morimoto gpriv->gadget.dev.driver = &driver->driver; 7642f98382dSKuninori Morimoto 7652f98382dSKuninori Morimoto return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); 7662f98382dSKuninori Morimoto } 7672f98382dSKuninori Morimoto 768af1d7056SFelipe Balbi static int usbhsg_gadget_stop(struct usb_gadget *gadget, 769af1d7056SFelipe Balbi struct usb_gadget_driver *driver) 7702f98382dSKuninori Morimoto { 771af1d7056SFelipe Balbi struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 772*f8eff0a0SKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 7732f98382dSKuninori Morimoto 7742f98382dSKuninori Morimoto if (!driver || 7753b872188SKuninori Morimoto !driver->unbind) 7762f98382dSKuninori Morimoto return -EINVAL; 7772f98382dSKuninori Morimoto 7782f98382dSKuninori Morimoto usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); 7792f98382dSKuninori Morimoto gpriv->driver = NULL; 7802f98382dSKuninori Morimoto 7812f98382dSKuninori Morimoto return 0; 7822f98382dSKuninori Morimoto } 7832f98382dSKuninori Morimoto 7842f98382dSKuninori Morimoto /* 7852f98382dSKuninori Morimoto * usb gadget ops 7862f98382dSKuninori Morimoto */ 7872f98382dSKuninori Morimoto static int usbhsg_get_frame(struct usb_gadget *gadget) 7882f98382dSKuninori Morimoto { 7892f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 7902f98382dSKuninori Morimoto struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 7912f98382dSKuninori Morimoto 7922f98382dSKuninori Morimoto return usbhs_frame_get_num(priv); 7932f98382dSKuninori Morimoto } 7942f98382dSKuninori Morimoto 7952f98382dSKuninori Morimoto static struct usb_gadget_ops usbhsg_gadget_ops = { 7962f98382dSKuninori Morimoto .get_frame = usbhsg_get_frame, 797af1d7056SFelipe Balbi .udc_start = usbhsg_gadget_start, 798af1d7056SFelipe Balbi .udc_stop = usbhsg_gadget_stop, 7992f98382dSKuninori Morimoto }; 8002f98382dSKuninori Morimoto 8012f98382dSKuninori Morimoto static int usbhsg_start(struct usbhs_priv *priv) 8022f98382dSKuninori Morimoto { 8032f98382dSKuninori Morimoto return usbhsg_try_start(priv, USBHSG_STATUS_STARTED); 8042f98382dSKuninori Morimoto } 8052f98382dSKuninori Morimoto 8062f98382dSKuninori Morimoto static int usbhsg_stop(struct usbhs_priv *priv) 8072f98382dSKuninori Morimoto { 8082f98382dSKuninori Morimoto return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); 8092f98382dSKuninori Morimoto } 8102f98382dSKuninori Morimoto 811b7a8d17dSKuninori Morimoto int usbhs_mod_gadget_probe(struct usbhs_priv *priv) 8122f98382dSKuninori Morimoto { 8132f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv; 8142f98382dSKuninori Morimoto struct usbhsg_uep *uep; 8152f98382dSKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 8162f98382dSKuninori Morimoto int pipe_size = usbhs_get_dparam(priv, pipe_size); 8172f98382dSKuninori Morimoto int i; 8180f91349bSSebastian Andrzej Siewior int ret; 8192f98382dSKuninori Morimoto 8202f98382dSKuninori Morimoto gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL); 8212f98382dSKuninori Morimoto if (!gpriv) { 8222f98382dSKuninori Morimoto dev_err(dev, "Could not allocate gadget priv\n"); 8232f98382dSKuninori Morimoto return -ENOMEM; 8242f98382dSKuninori Morimoto } 8252f98382dSKuninori Morimoto 8262f98382dSKuninori Morimoto uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL); 8272f98382dSKuninori Morimoto if (!uep) { 8282f98382dSKuninori Morimoto dev_err(dev, "Could not allocate ep\n"); 8290f91349bSSebastian Andrzej Siewior ret = -ENOMEM; 8302f98382dSKuninori Morimoto goto usbhs_mod_gadget_probe_err_gpriv; 8312f98382dSKuninori Morimoto } 8322f98382dSKuninori Morimoto 8332f98382dSKuninori Morimoto /* 8342f98382dSKuninori Morimoto * CAUTION 8352f98382dSKuninori Morimoto * 8362f98382dSKuninori Morimoto * There is no guarantee that it is possible to access usb module here. 8372f98382dSKuninori Morimoto * Don't accesses to it. 8382f98382dSKuninori Morimoto * The accesse will be enable after "usbhsg_start" 8392f98382dSKuninori Morimoto */ 8402f98382dSKuninori Morimoto 8412f98382dSKuninori Morimoto /* 8422f98382dSKuninori Morimoto * register itself 8432f98382dSKuninori Morimoto */ 8442f98382dSKuninori Morimoto usbhs_mod_register(priv, &gpriv->mod, USBHS_GADGET); 8452f98382dSKuninori Morimoto 8462f98382dSKuninori Morimoto /* init gpriv */ 8472f98382dSKuninori Morimoto gpriv->mod.name = "gadget"; 8482f98382dSKuninori Morimoto gpriv->mod.start = usbhsg_start; 8492f98382dSKuninori Morimoto gpriv->mod.stop = usbhsg_stop; 8502f98382dSKuninori Morimoto gpriv->uep = uep; 8512f98382dSKuninori Morimoto gpriv->uep_size = pipe_size; 8522f98382dSKuninori Morimoto usbhsg_status_init(gpriv); 8532f98382dSKuninori Morimoto 8542f98382dSKuninori Morimoto /* 8552f98382dSKuninori Morimoto * init gadget 8562f98382dSKuninori Morimoto */ 8572f98382dSKuninori Morimoto dev_set_name(&gpriv->gadget.dev, "gadget"); 8582f98382dSKuninori Morimoto gpriv->gadget.dev.parent = dev; 8592f98382dSKuninori Morimoto gpriv->gadget.name = "renesas_usbhs_udc"; 8602f98382dSKuninori Morimoto gpriv->gadget.ops = &usbhsg_gadget_ops; 8612f98382dSKuninori Morimoto gpriv->gadget.is_dualspeed = 1; 862*f8eff0a0SKuninori Morimoto ret = device_register(&gpriv->gadget.dev); 863*f8eff0a0SKuninori Morimoto if (ret < 0) 864*f8eff0a0SKuninori Morimoto goto err_add_udc; 8652f98382dSKuninori Morimoto 8662f98382dSKuninori Morimoto INIT_LIST_HEAD(&gpriv->gadget.ep_list); 8672f98382dSKuninori Morimoto 8682f98382dSKuninori Morimoto /* 8692f98382dSKuninori Morimoto * init usb_ep 8702f98382dSKuninori Morimoto */ 8712f98382dSKuninori Morimoto usbhsg_for_each_uep_with_dcp(uep, gpriv, i) { 8722f98382dSKuninori Morimoto uep->gpriv = gpriv; 8732f98382dSKuninori Morimoto snprintf(uep->ep_name, EP_NAME_SIZE, "ep%d", i); 8742f98382dSKuninori Morimoto 8752f98382dSKuninori Morimoto uep->ep.name = uep->ep_name; 8762f98382dSKuninori Morimoto uep->ep.ops = &usbhsg_ep_ops; 8772f98382dSKuninori Morimoto INIT_LIST_HEAD(&uep->ep.ep_list); 8782f98382dSKuninori Morimoto 8792f98382dSKuninori Morimoto /* init DCP */ 8802f98382dSKuninori Morimoto if (usbhsg_is_dcp(uep)) { 8812f98382dSKuninori Morimoto gpriv->gadget.ep0 = &uep->ep; 8822f98382dSKuninori Morimoto uep->ep.maxpacket = 64; 8832f98382dSKuninori Morimoto } 8842f98382dSKuninori Morimoto /* init normal pipe */ 8852f98382dSKuninori Morimoto else { 8862f98382dSKuninori Morimoto uep->ep.maxpacket = 512; 8872f98382dSKuninori Morimoto list_add_tail(&uep->ep.ep_list, &gpriv->gadget.ep_list); 8882f98382dSKuninori Morimoto } 8892f98382dSKuninori Morimoto } 8902f98382dSKuninori Morimoto 8913b872188SKuninori Morimoto usbhsg_controller_register(gpriv); 8922f98382dSKuninori Morimoto 8930f91349bSSebastian Andrzej Siewior ret = usb_add_gadget_udc(dev, &gpriv->gadget); 8940f91349bSSebastian Andrzej Siewior if (ret) 895*f8eff0a0SKuninori Morimoto goto err_register; 8960f91349bSSebastian Andrzej Siewior 8970f91349bSSebastian Andrzej Siewior 8982f98382dSKuninori Morimoto dev_info(dev, "gadget probed\n"); 8992f98382dSKuninori Morimoto 9002f98382dSKuninori Morimoto return 0; 901*f8eff0a0SKuninori Morimoto 902*f8eff0a0SKuninori Morimoto err_register: 903*f8eff0a0SKuninori Morimoto device_unregister(&gpriv->gadget.dev); 9040f91349bSSebastian Andrzej Siewior err_add_udc: 9050f91349bSSebastian Andrzej Siewior kfree(gpriv->uep); 9062f98382dSKuninori Morimoto 9072f98382dSKuninori Morimoto usbhs_mod_gadget_probe_err_gpriv: 9082f98382dSKuninori Morimoto kfree(gpriv); 9092f98382dSKuninori Morimoto 9100f91349bSSebastian Andrzej Siewior return ret; 9112f98382dSKuninori Morimoto } 9122f98382dSKuninori Morimoto 913b7a8d17dSKuninori Morimoto void usbhs_mod_gadget_remove(struct usbhs_priv *priv) 9142f98382dSKuninori Morimoto { 9152f98382dSKuninori Morimoto struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 9162f98382dSKuninori Morimoto 9170f91349bSSebastian Andrzej Siewior usb_del_gadget_udc(&gpriv->gadget); 9183b872188SKuninori Morimoto 919*f8eff0a0SKuninori Morimoto device_unregister(&gpriv->gadget.dev); 920*f8eff0a0SKuninori Morimoto 9213b872188SKuninori Morimoto usbhsg_controller_unregister(gpriv); 9223b872188SKuninori Morimoto 9233af51ac9SSebastian Andrzej Siewior kfree(gpriv->uep); 9242f98382dSKuninori Morimoto kfree(gpriv); 9252f98382dSKuninori Morimoto } 926