Lines Matching refs:hsudc

181 static inline void set_index(struct s3c_hsudc *hsudc, int ep_addr)  in set_index()  argument
184 writel(ep_addr, hsudc->regs + S3C_IR); in set_index()
249 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_complete_request() local
255 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_complete_request()
260 spin_unlock(&hsudc->lock); in s3c_hsudc_complete_request()
262 spin_lock(&hsudc->lock); in s3c_hsudc_complete_request()
289 static void s3c_hsudc_stop_activity(struct s3c_hsudc *hsudc) in s3c_hsudc_stop_activity() argument
294 hsudc->gadget.speed = USB_SPEED_UNKNOWN; in s3c_hsudc_stop_activity()
296 for (epnum = 0; epnum < hsudc->pd->epnum; epnum++) { in s3c_hsudc_stop_activity()
297 hsep = &hsudc->ep[epnum]; in s3c_hsudc_stop_activity()
312 static void s3c_hsudc_read_setup_pkt(struct s3c_hsudc *hsudc, u16 *buf) in s3c_hsudc_read_setup_pkt() argument
316 count = readl(hsudc->regs + S3C_BRCR); in s3c_hsudc_read_setup_pkt()
318 *buf++ = (u16)readl(hsudc->regs + S3C_BR(0)); in s3c_hsudc_read_setup_pkt()
320 writel(S3C_EP0SR_RX_SUCCESS, hsudc->regs + S3C_EP0SR); in s3c_hsudc_read_setup_pkt()
380 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_read_fifo() local
388 csr = readl(hsudc->regs + offset); in s3c_hsudc_read_fifo()
396 rcnt = readl(hsudc->regs + S3C_BRCR); in s3c_hsudc_read_fifo()
412 writel(S3C_ESR_RX_SUCCESS, hsudc->regs + offset); in s3c_hsudc_read_fifo()
430 static void s3c_hsudc_epin_intr(struct s3c_hsudc *hsudc, u32 ep_idx) in s3c_hsudc_epin_intr() argument
432 struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx]; in s3c_hsudc_epin_intr()
436 csr = readl(hsudc->regs + S3C_ESR); in s3c_hsudc_epin_intr()
438 writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); in s3c_hsudc_epin_intr()
443 writel(S3C_ESR_TX_SUCCESS, hsudc->regs + S3C_ESR); in s3c_hsudc_epin_intr()
463 static void s3c_hsudc_epout_intr(struct s3c_hsudc *hsudc, u32 ep_idx) in s3c_hsudc_epout_intr() argument
465 struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx]; in s3c_hsudc_epout_intr()
469 csr = readl(hsudc->regs + S3C_ESR); in s3c_hsudc_epout_intr()
471 writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); in s3c_hsudc_epout_intr()
476 __orr32(hsudc->regs + S3C_ECR, S3C_ECR_FLUSH); in s3c_hsudc_epout_intr()
503 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_set_halt() local
512 spin_lock_irqsave(&hsudc->lock, irqflags); in s3c_hsudc_set_halt()
513 set_index(hsudc, ep_index(hsep)); in s3c_hsudc_set_halt()
515 ecr = readl(hsudc->regs + offset); in s3c_hsudc_set_halt()
526 writel(ecr, hsudc->regs + offset); in s3c_hsudc_set_halt()
535 spin_unlock_irqrestore(&hsudc->lock, irqflags); in s3c_hsudc_set_halt()
561 static int s3c_hsudc_handle_reqfeat(struct s3c_hsudc *hsudc, in s3c_hsudc_handle_reqfeat() argument
569 hsep = &hsudc->ep[ep_num]; in s3c_hsudc_handle_reqfeat()
588 static void s3c_hsudc_process_req_status(struct s3c_hsudc *hsudc, in s3c_hsudc_process_req_status() argument
591 struct s3c_hsudc_ep *hsep0 = &hsudc->ep[0]; in s3c_hsudc_process_req_status()
608 hsep = &hsudc->ep[epnum]; in s3c_hsudc_process_req_status()
628 static void s3c_hsudc_process_setup(struct s3c_hsudc *hsudc) in s3c_hsudc_process_setup() argument
630 struct s3c_hsudc_ep *hsep = &hsudc->ep[0]; in s3c_hsudc_process_setup()
635 s3c_hsudc_read_setup_pkt(hsudc, (u16 *)&ctrl); in s3c_hsudc_process_setup()
639 hsudc->ep0state = DATA_STATE_XMIT; in s3c_hsudc_process_setup()
642 hsudc->ep0state = DATA_STATE_RECV; in s3c_hsudc_process_setup()
649 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_process_setup()
655 s3c_hsudc_process_req_status(hsudc, &ctrl); in s3c_hsudc_process_setup()
662 s3c_hsudc_handle_reqfeat(hsudc, &ctrl); in s3c_hsudc_process_setup()
663 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_process_setup()
667 if (hsudc->driver) { in s3c_hsudc_process_setup()
668 spin_unlock(&hsudc->lock); in s3c_hsudc_process_setup()
669 ret = hsudc->driver->setup(&hsudc->gadget, &ctrl); in s3c_hsudc_process_setup()
670 spin_lock(&hsudc->lock); in s3c_hsudc_process_setup()
674 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_process_setup()
678 dev_err(hsudc->dev, "setup failed, returned %d\n", in s3c_hsudc_process_setup()
681 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_process_setup()
694 static void s3c_hsudc_handle_ep0_intr(struct s3c_hsudc *hsudc) in s3c_hsudc_handle_ep0_intr() argument
696 struct s3c_hsudc_ep *hsep = &hsudc->ep[0]; in s3c_hsudc_handle_ep0_intr()
698 u32 csr = readl(hsudc->regs + S3C_EP0SR); in s3c_hsudc_handle_ep0_intr()
702 ecr = readl(hsudc->regs + S3C_EP0CR); in s3c_hsudc_handle_ep0_intr()
704 writel(ecr, hsudc->regs + S3C_EP0CR); in s3c_hsudc_handle_ep0_intr()
706 writel(S3C_EP0SR_STALL, hsudc->regs + S3C_EP0SR); in s3c_hsudc_handle_ep0_intr()
710 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_handle_ep0_intr()
716 writel(S3C_EP0SR_TX_SUCCESS, hsudc->regs + S3C_EP0SR); in s3c_hsudc_handle_ep0_intr()
728 if (hsudc->ep0state == WAIT_FOR_SETUP) in s3c_hsudc_handle_ep0_intr()
729 s3c_hsudc_process_setup(hsudc); in s3c_hsudc_handle_ep0_intr()
755 struct s3c_hsudc *hsudc; in s3c_hsudc_ep_enable() local
771 hsudc = hsep->dev; in s3c_hsudc_ep_enable()
772 if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) in s3c_hsudc_ep_enable()
775 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_ep_enable()
777 set_index(hsudc, hsep->bEndpointAddress); in s3c_hsudc_ep_enable()
779 writel(ecr, hsudc->regs + S3C_ECR); in s3c_hsudc_ep_enable()
786 __set_bit(ep_index(hsep), hsudc->regs + S3C_EIER); in s3c_hsudc_ep_enable()
788 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_ep_enable()
802 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_ep_disable() local
808 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_ep_disable()
810 set_index(hsudc, hsep->bEndpointAddress); in s3c_hsudc_ep_disable()
811 __clear_bit(ep_index(hsep), hsudc->regs + S3C_EIER); in s3c_hsudc_ep_disable()
818 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_ep_disable()
871 struct s3c_hsudc *hsudc; in s3c_hsudc_queue() local
882 hsudc = hsep->dev; in s3c_hsudc_queue()
883 if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) in s3c_hsudc_queue()
886 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_queue()
887 set_index(hsudc, hsep->bEndpointAddress); in s3c_hsudc_queue()
893 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_queue()
895 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_queue()
902 csr = readl(hsudc->regs + offset); in s3c_hsudc_queue()
907 csr = readl(hsudc->regs + offset); in s3c_hsudc_queue()
917 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_queue()
931 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_dequeue() local
939 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_dequeue()
946 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_dequeue()
950 set_index(hsudc, hsep->bEndpointAddress); in s3c_hsudc_dequeue()
953 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_dequeue()
976 static void s3c_hsudc_initep(struct s3c_hsudc *hsudc, in s3c_hsudc_initep() argument
997 list_add_tail(&hsep->ep.ep_list, &hsudc->gadget.ep_list); in s3c_hsudc_initep()
999 hsep->dev = hsudc; in s3c_hsudc_initep()
1003 hsep->fifo = hsudc->regs + S3C_BR(epnum); in s3c_hsudc_initep()
1023 set_index(hsudc, epnum); in s3c_hsudc_initep()
1024 writel(hsep->ep.maxpacket, hsudc->regs + S3C_MPR); in s3c_hsudc_initep()
1033 static void s3c_hsudc_setup_ep(struct s3c_hsudc *hsudc) in s3c_hsudc_setup_ep() argument
1037 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_setup_ep()
1038 INIT_LIST_HEAD(&hsudc->gadget.ep_list); in s3c_hsudc_setup_ep()
1039 for (epnum = 0; epnum < hsudc->pd->epnum; epnum++) in s3c_hsudc_setup_ep()
1040 s3c_hsudc_initep(hsudc, &hsudc->ep[epnum], epnum); in s3c_hsudc_setup_ep()
1049 static void s3c_hsudc_reconfig(struct s3c_hsudc *hsudc) in s3c_hsudc_reconfig() argument
1051 writel(0xAA, hsudc->regs + S3C_EDR); in s3c_hsudc_reconfig()
1052 writel(1, hsudc->regs + S3C_EIER); in s3c_hsudc_reconfig()
1053 writel(0, hsudc->regs + S3C_TR); in s3c_hsudc_reconfig()
1055 S3C_SCR_RST_EN, hsudc->regs + S3C_SCR); in s3c_hsudc_reconfig()
1056 writel(0, hsudc->regs + S3C_EP0CR); in s3c_hsudc_reconfig()
1058 s3c_hsudc_setup_ep(hsudc); in s3c_hsudc_reconfig()
1071 struct s3c_hsudc *hsudc = _dev; in s3c_hsudc_irq() local
1077 spin_lock(&hsudc->lock); in s3c_hsudc_irq()
1079 sys_status = readl(hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1080 ep_intr = readl(hsudc->regs + S3C_EIR) & 0x3FF; in s3c_hsudc_irq()
1083 spin_unlock(&hsudc->lock); in s3c_hsudc_irq()
1089 writel(S3C_SSR_VBUSON, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1092 writel(S3C_SSR_ERR, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1095 writel(S3C_SSR_SDE, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1096 hsudc->gadget.speed = (sys_status & S3C_SSR_HSP) ? in s3c_hsudc_irq()
1101 writel(S3C_SSR_SUSPEND, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1102 if (hsudc->gadget.speed != USB_SPEED_UNKNOWN in s3c_hsudc_irq()
1103 && hsudc->driver && hsudc->driver->suspend) in s3c_hsudc_irq()
1104 hsudc->driver->suspend(&hsudc->gadget); in s3c_hsudc_irq()
1108 writel(S3C_SSR_RESUME, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1109 if (hsudc->gadget.speed != USB_SPEED_UNKNOWN in s3c_hsudc_irq()
1110 && hsudc->driver && hsudc->driver->resume) in s3c_hsudc_irq()
1111 hsudc->driver->resume(&hsudc->gadget); in s3c_hsudc_irq()
1115 writel(S3C_SSR_RESET, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1116 for (ep_idx = 0; ep_idx < hsudc->pd->epnum; ep_idx++) { in s3c_hsudc_irq()
1117 hsep = &hsudc->ep[ep_idx]; in s3c_hsudc_irq()
1121 s3c_hsudc_reconfig(hsudc); in s3c_hsudc_irq()
1122 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_irq()
1127 writel(S3C_EIR_EP0, hsudc->regs + S3C_EIR); in s3c_hsudc_irq()
1128 set_index(hsudc, 0); in s3c_hsudc_irq()
1129 s3c_hsudc_handle_ep0_intr(hsudc); in s3c_hsudc_irq()
1136 hsep = &hsudc->ep[ep_idx]; in s3c_hsudc_irq()
1137 set_index(hsudc, ep_idx); in s3c_hsudc_irq()
1138 writel(1 << ep_idx, hsudc->regs + S3C_EIR); in s3c_hsudc_irq()
1140 s3c_hsudc_epin_intr(hsudc, ep_idx); in s3c_hsudc_irq()
1142 s3c_hsudc_epout_intr(hsudc, ep_idx); in s3c_hsudc_irq()
1148 spin_unlock(&hsudc->lock); in s3c_hsudc_irq()
1155 struct s3c_hsudc *hsudc = to_hsudc(gadget); in s3c_hsudc_start() local
1163 if (!hsudc) in s3c_hsudc_start()
1166 if (hsudc->driver) in s3c_hsudc_start()
1169 hsudc->driver = driver; in s3c_hsudc_start()
1171 ret = regulator_bulk_enable(ARRAY_SIZE(hsudc->supplies), in s3c_hsudc_start()
1172 hsudc->supplies); in s3c_hsudc_start()
1174 dev_err(hsudc->dev, "failed to enable supplies: %d\n", ret); in s3c_hsudc_start()
1179 if (!IS_ERR_OR_NULL(hsudc->transceiver)) { in s3c_hsudc_start()
1180 ret = otg_set_peripheral(hsudc->transceiver->otg, in s3c_hsudc_start()
1181 &hsudc->gadget); in s3c_hsudc_start()
1183 dev_err(hsudc->dev, "%s: can't bind to transceiver\n", in s3c_hsudc_start()
1184 hsudc->gadget.name); in s3c_hsudc_start()
1189 enable_irq(hsudc->irq); in s3c_hsudc_start()
1190 s3c_hsudc_reconfig(hsudc); in s3c_hsudc_start()
1192 pm_runtime_get_sync(hsudc->dev); in s3c_hsudc_start()
1195 if (hsudc->pd->gpio_init) in s3c_hsudc_start()
1196 hsudc->pd->gpio_init(); in s3c_hsudc_start()
1200 regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); in s3c_hsudc_start()
1202 hsudc->driver = NULL; in s3c_hsudc_start()
1208 struct s3c_hsudc *hsudc = to_hsudc(gadget); in s3c_hsudc_stop() local
1211 if (!hsudc) in s3c_hsudc_stop()
1214 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_stop()
1215 hsudc->gadget.speed = USB_SPEED_UNKNOWN; in s3c_hsudc_stop()
1218 pm_runtime_put(hsudc->dev); in s3c_hsudc_stop()
1220 if (hsudc->pd->gpio_uninit) in s3c_hsudc_stop()
1221 hsudc->pd->gpio_uninit(); in s3c_hsudc_stop()
1222 s3c_hsudc_stop_activity(hsudc); in s3c_hsudc_stop()
1223 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_stop()
1225 if (!IS_ERR_OR_NULL(hsudc->transceiver)) in s3c_hsudc_stop()
1226 (void) otg_set_peripheral(hsudc->transceiver->otg, NULL); in s3c_hsudc_stop()
1228 disable_irq(hsudc->irq); in s3c_hsudc_stop()
1230 regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); in s3c_hsudc_stop()
1231 hsudc->driver = NULL; in s3c_hsudc_stop()
1236 static inline u32 s3c_hsudc_read_frameno(struct s3c_hsudc *hsudc) in s3c_hsudc_read_frameno() argument
1238 return readl(hsudc->regs + S3C_FNR) & 0x3FF; in s3c_hsudc_read_frameno()
1248 struct s3c_hsudc *hsudc = to_hsudc(gadget); in s3c_hsudc_vbus_draw() local
1250 if (!hsudc) in s3c_hsudc_vbus_draw()
1253 if (!IS_ERR_OR_NULL(hsudc->transceiver)) in s3c_hsudc_vbus_draw()
1254 return usb_phy_set_power(hsudc->transceiver, mA); in s3c_hsudc_vbus_draw()
1270 struct s3c_hsudc *hsudc; in s3c_hsudc_probe() local
1274 hsudc = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsudc) + in s3c_hsudc_probe()
1277 if (!hsudc) in s3c_hsudc_probe()
1281 hsudc->dev = dev; in s3c_hsudc_probe()
1282 hsudc->pd = dev_get_platdata(&pdev->dev); in s3c_hsudc_probe()
1284 hsudc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); in s3c_hsudc_probe()
1286 for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++) in s3c_hsudc_probe()
1287 hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; in s3c_hsudc_probe()
1289 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsudc->supplies), in s3c_hsudc_probe()
1290 hsudc->supplies); in s3c_hsudc_probe()
1298 hsudc->regs = devm_ioremap_resource(&pdev->dev, res); in s3c_hsudc_probe()
1299 if (IS_ERR(hsudc->regs)) { in s3c_hsudc_probe()
1300 ret = PTR_ERR(hsudc->regs); in s3c_hsudc_probe()
1304 spin_lock_init(&hsudc->lock); in s3c_hsudc_probe()
1306 hsudc->gadget.max_speed = USB_SPEED_HIGH; in s3c_hsudc_probe()
1307 hsudc->gadget.ops = &s3c_hsudc_gadget_ops; in s3c_hsudc_probe()
1308 hsudc->gadget.name = dev_name(dev); in s3c_hsudc_probe()
1309 hsudc->gadget.ep0 = &hsudc->ep[0].ep; in s3c_hsudc_probe()
1310 hsudc->gadget.is_otg = 0; in s3c_hsudc_probe()
1311 hsudc->gadget.is_a_peripheral = 0; in s3c_hsudc_probe()
1312 hsudc->gadget.speed = USB_SPEED_UNKNOWN; in s3c_hsudc_probe()
1314 s3c_hsudc_setup_ep(hsudc); in s3c_hsudc_probe()
1321 hsudc->irq = ret; in s3c_hsudc_probe()
1323 ret = devm_request_irq(&pdev->dev, hsudc->irq, s3c_hsudc_irq, 0, in s3c_hsudc_probe()
1324 driver_name, hsudc); in s3c_hsudc_probe()
1330 hsudc->uclk = devm_clk_get(&pdev->dev, "usb-device"); in s3c_hsudc_probe()
1331 if (IS_ERR(hsudc->uclk)) { in s3c_hsudc_probe()
1333 ret = PTR_ERR(hsudc->uclk); in s3c_hsudc_probe()
1336 clk_enable(hsudc->uclk); in s3c_hsudc_probe()
1340 disable_irq(hsudc->irq); in s3c_hsudc_probe()
1343 ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget); in s3c_hsudc_probe()
1351 clk_disable(hsudc->uclk); in s3c_hsudc_probe()
1353 if (!IS_ERR_OR_NULL(hsudc->transceiver)) in s3c_hsudc_probe()
1354 usb_put_phy(hsudc->transceiver); in s3c_hsudc_probe()