15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+ 294ae9843SFelipe Balbi /* 394ae9843SFelipe Balbi * Copyright (C) 2007,2008 Freescale semiconductor, Inc. 494ae9843SFelipe Balbi * 594ae9843SFelipe Balbi * Author: Li Yang <LeoLi@freescale.com> 694ae9843SFelipe Balbi * Jerry Huang <Chang-Ming.Huang@freescale.com> 794ae9843SFelipe Balbi * 894ae9843SFelipe Balbi * Initialization based on code from Shlomi Gridish. 994ae9843SFelipe Balbi */ 1094ae9843SFelipe Balbi 1194ae9843SFelipe Balbi #include <linux/module.h> 1294ae9843SFelipe Balbi #include <linux/kernel.h> 1394ae9843SFelipe Balbi #include <linux/delay.h> 1494ae9843SFelipe Balbi #include <linux/slab.h> 1594ae9843SFelipe Balbi #include <linux/proc_fs.h> 1694ae9843SFelipe Balbi #include <linux/errno.h> 1794ae9843SFelipe Balbi #include <linux/interrupt.h> 1894ae9843SFelipe Balbi #include <linux/io.h> 1994ae9843SFelipe Balbi #include <linux/timer.h> 2094ae9843SFelipe Balbi #include <linux/usb.h> 2194ae9843SFelipe Balbi #include <linux/device.h> 2294ae9843SFelipe Balbi #include <linux/usb/ch9.h> 2394ae9843SFelipe Balbi #include <linux/usb/gadget.h> 2494ae9843SFelipe Balbi #include <linux/workqueue.h> 2594ae9843SFelipe Balbi #include <linux/time.h> 2694ae9843SFelipe Balbi #include <linux/fsl_devices.h> 2794ae9843SFelipe Balbi #include <linux/platform_device.h> 2894ae9843SFelipe Balbi #include <linux/uaccess.h> 2994ae9843SFelipe Balbi 3094ae9843SFelipe Balbi #include <asm/unaligned.h> 3194ae9843SFelipe Balbi 3294ae9843SFelipe Balbi #include "phy-fsl-usb.h" 3394ae9843SFelipe Balbi 34e92634cdSRoger Quadros #ifdef VERBOSE 35e92634cdSRoger Quadros #define VDBG(fmt, args...) pr_debug("[%s] " fmt, \ 36e92634cdSRoger Quadros __func__, ## args) 37e92634cdSRoger Quadros #else 38e92634cdSRoger Quadros #define VDBG(stuff...) do {} while (0) 39e92634cdSRoger Quadros #endif 40e92634cdSRoger Quadros 4194ae9843SFelipe Balbi #define DRIVER_VERSION "Rev. 1.55" 4294ae9843SFelipe Balbi #define DRIVER_AUTHOR "Jerry Huang/Li Yang" 4394ae9843SFelipe Balbi #define DRIVER_DESC "Freescale USB OTG Transceiver Driver" 4494ae9843SFelipe Balbi #define DRIVER_INFO DRIVER_DESC " " DRIVER_VERSION 4594ae9843SFelipe Balbi 4694ae9843SFelipe Balbi static const char driver_name[] = "fsl-usb2-otg"; 4794ae9843SFelipe Balbi 4894ae9843SFelipe Balbi const pm_message_t otg_suspend_state = { 4994ae9843SFelipe Balbi .event = 1, 5094ae9843SFelipe Balbi }; 5194ae9843SFelipe Balbi 5294ae9843SFelipe Balbi #define HA_DATA_PULSE 5394ae9843SFelipe Balbi 5494ae9843SFelipe Balbi static struct usb_dr_mmap *usb_dr_regs; 5594ae9843SFelipe Balbi static struct fsl_otg *fsl_otg_dev; 5694ae9843SFelipe Balbi static int srp_wait_done; 5794ae9843SFelipe Balbi 5894ae9843SFelipe Balbi /* FSM timers */ 5994ae9843SFelipe Balbi struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, *a_aidl_bdis_tmr, 6094ae9843SFelipe Balbi *b_ase0_brst_tmr, *b_se0_srp_tmr; 6194ae9843SFelipe Balbi 6294ae9843SFelipe Balbi /* Driver specific timers */ 6394ae9843SFelipe Balbi struct fsl_otg_timer *b_data_pulse_tmr, *b_vbus_pulse_tmr, *b_srp_fail_tmr, 6494ae9843SFelipe Balbi *b_srp_wait_tmr, *a_wait_enum_tmr; 6594ae9843SFelipe Balbi 6694ae9843SFelipe Balbi static struct list_head active_timers; 6794ae9843SFelipe Balbi 68f1b19006SNishka Dasgupta static const struct fsl_otg_config fsl_otg_initdata = { 6994ae9843SFelipe Balbi .otg_port = 1, 7094ae9843SFelipe Balbi }; 7194ae9843SFelipe Balbi 7294ae9843SFelipe Balbi #ifdef CONFIG_PPC32 7394ae9843SFelipe Balbi static u32 _fsl_readl_be(const unsigned __iomem *p) 7494ae9843SFelipe Balbi { 7594ae9843SFelipe Balbi return in_be32(p); 7694ae9843SFelipe Balbi } 7794ae9843SFelipe Balbi 7894ae9843SFelipe Balbi static u32 _fsl_readl_le(const unsigned __iomem *p) 7994ae9843SFelipe Balbi { 8094ae9843SFelipe Balbi return in_le32(p); 8194ae9843SFelipe Balbi } 8294ae9843SFelipe Balbi 8394ae9843SFelipe Balbi static void _fsl_writel_be(u32 v, unsigned __iomem *p) 8494ae9843SFelipe Balbi { 8594ae9843SFelipe Balbi out_be32(p, v); 8694ae9843SFelipe Balbi } 8794ae9843SFelipe Balbi 8894ae9843SFelipe Balbi static void _fsl_writel_le(u32 v, unsigned __iomem *p) 8994ae9843SFelipe Balbi { 9094ae9843SFelipe Balbi out_le32(p, v); 9194ae9843SFelipe Balbi } 9294ae9843SFelipe Balbi 9394ae9843SFelipe Balbi static u32 (*_fsl_readl)(const unsigned __iomem *p); 9494ae9843SFelipe Balbi static void (*_fsl_writel)(u32 v, unsigned __iomem *p); 9594ae9843SFelipe Balbi 9694ae9843SFelipe Balbi #define fsl_readl(p) (*_fsl_readl)((p)) 9794ae9843SFelipe Balbi #define fsl_writel(v, p) (*_fsl_writel)((v), (p)) 9894ae9843SFelipe Balbi 9994ae9843SFelipe Balbi #else 10094ae9843SFelipe Balbi #define fsl_readl(addr) readl(addr) 10194ae9843SFelipe Balbi #define fsl_writel(val, addr) writel(val, addr) 10294ae9843SFelipe Balbi #endif /* CONFIG_PPC32 */ 10394ae9843SFelipe Balbi 10494ae9843SFelipe Balbi int write_ulpi(u8 addr, u8 data) 10594ae9843SFelipe Balbi { 10694ae9843SFelipe Balbi u32 temp; 10794ae9843SFelipe Balbi 10894ae9843SFelipe Balbi temp = 0x60000000 | (addr << 16) | data; 10994ae9843SFelipe Balbi fsl_writel(temp, &usb_dr_regs->ulpiview); 11094ae9843SFelipe Balbi return 0; 11194ae9843SFelipe Balbi } 11294ae9843SFelipe Balbi 11394ae9843SFelipe Balbi /* -------------------------------------------------------------*/ 11494ae9843SFelipe Balbi /* Operations that will be called from OTG Finite State Machine */ 11594ae9843SFelipe Balbi 11694ae9843SFelipe Balbi /* Charge vbus for vbus pulsing in SRP */ 117da8cc167SAnton Tikhomirov void fsl_otg_chrg_vbus(struct otg_fsm *fsm, int on) 11894ae9843SFelipe Balbi { 11994ae9843SFelipe Balbi u32 tmp; 12094ae9843SFelipe Balbi 12194ae9843SFelipe Balbi tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; 12294ae9843SFelipe Balbi 12394ae9843SFelipe Balbi if (on) 12494ae9843SFelipe Balbi /* stop discharging, start charging */ 12594ae9843SFelipe Balbi tmp = (tmp & ~OTGSC_CTRL_VBUS_DISCHARGE) | 12694ae9843SFelipe Balbi OTGSC_CTRL_VBUS_CHARGE; 12794ae9843SFelipe Balbi else 12894ae9843SFelipe Balbi /* stop charging */ 12994ae9843SFelipe Balbi tmp &= ~OTGSC_CTRL_VBUS_CHARGE; 13094ae9843SFelipe Balbi 13194ae9843SFelipe Balbi fsl_writel(tmp, &usb_dr_regs->otgsc); 13294ae9843SFelipe Balbi } 13394ae9843SFelipe Balbi 13494ae9843SFelipe Balbi /* Discharge vbus through a resistor to ground */ 13594ae9843SFelipe Balbi void fsl_otg_dischrg_vbus(int on) 13694ae9843SFelipe Balbi { 13794ae9843SFelipe Balbi u32 tmp; 13894ae9843SFelipe Balbi 13994ae9843SFelipe Balbi tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; 14094ae9843SFelipe Balbi 14194ae9843SFelipe Balbi if (on) 14294ae9843SFelipe Balbi /* stop charging, start discharging */ 14394ae9843SFelipe Balbi tmp = (tmp & ~OTGSC_CTRL_VBUS_CHARGE) | 14494ae9843SFelipe Balbi OTGSC_CTRL_VBUS_DISCHARGE; 14594ae9843SFelipe Balbi else 14694ae9843SFelipe Balbi /* stop discharging */ 14794ae9843SFelipe Balbi tmp &= ~OTGSC_CTRL_VBUS_DISCHARGE; 14894ae9843SFelipe Balbi 14994ae9843SFelipe Balbi fsl_writel(tmp, &usb_dr_regs->otgsc); 15094ae9843SFelipe Balbi } 15194ae9843SFelipe Balbi 15294ae9843SFelipe Balbi /* A-device driver vbus, controlled through PP bit in PORTSC */ 153da8cc167SAnton Tikhomirov void fsl_otg_drv_vbus(struct otg_fsm *fsm, int on) 15494ae9843SFelipe Balbi { 15594ae9843SFelipe Balbi u32 tmp; 15694ae9843SFelipe Balbi 15794ae9843SFelipe Balbi if (on) { 15894ae9843SFelipe Balbi tmp = fsl_readl(&usb_dr_regs->portsc) & ~PORTSC_W1C_BITS; 15994ae9843SFelipe Balbi fsl_writel(tmp | PORTSC_PORT_POWER, &usb_dr_regs->portsc); 16094ae9843SFelipe Balbi } else { 16194ae9843SFelipe Balbi tmp = fsl_readl(&usb_dr_regs->portsc) & 16294ae9843SFelipe Balbi ~PORTSC_W1C_BITS & ~PORTSC_PORT_POWER; 16394ae9843SFelipe Balbi fsl_writel(tmp, &usb_dr_regs->portsc); 16494ae9843SFelipe Balbi } 16594ae9843SFelipe Balbi } 16694ae9843SFelipe Balbi 16794ae9843SFelipe Balbi /* 16894ae9843SFelipe Balbi * Pull-up D+, signalling connect by periperal. Also used in 16994ae9843SFelipe Balbi * data-line pulsing in SRP 17094ae9843SFelipe Balbi */ 171da8cc167SAnton Tikhomirov void fsl_otg_loc_conn(struct otg_fsm *fsm, int on) 17294ae9843SFelipe Balbi { 17394ae9843SFelipe Balbi u32 tmp; 17494ae9843SFelipe Balbi 17594ae9843SFelipe Balbi tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; 17694ae9843SFelipe Balbi 17794ae9843SFelipe Balbi if (on) 17894ae9843SFelipe Balbi tmp |= OTGSC_CTRL_DATA_PULSING; 17994ae9843SFelipe Balbi else 18094ae9843SFelipe Balbi tmp &= ~OTGSC_CTRL_DATA_PULSING; 18194ae9843SFelipe Balbi 18294ae9843SFelipe Balbi fsl_writel(tmp, &usb_dr_regs->otgsc); 18394ae9843SFelipe Balbi } 18494ae9843SFelipe Balbi 18594ae9843SFelipe Balbi /* 18694ae9843SFelipe Balbi * Generate SOF by host. This is controlled through suspend/resume the 18794ae9843SFelipe Balbi * port. In host mode, controller will automatically send SOF. 18894ae9843SFelipe Balbi * Suspend will block the data on the port. 18994ae9843SFelipe Balbi */ 190da8cc167SAnton Tikhomirov void fsl_otg_loc_sof(struct otg_fsm *fsm, int on) 19194ae9843SFelipe Balbi { 19294ae9843SFelipe Balbi u32 tmp; 19394ae9843SFelipe Balbi 19494ae9843SFelipe Balbi tmp = fsl_readl(&fsl_otg_dev->dr_mem_map->portsc) & ~PORTSC_W1C_BITS; 19594ae9843SFelipe Balbi if (on) 19694ae9843SFelipe Balbi tmp |= PORTSC_PORT_FORCE_RESUME; 19794ae9843SFelipe Balbi else 19894ae9843SFelipe Balbi tmp |= PORTSC_PORT_SUSPEND; 19994ae9843SFelipe Balbi 20094ae9843SFelipe Balbi fsl_writel(tmp, &fsl_otg_dev->dr_mem_map->portsc); 20194ae9843SFelipe Balbi 20294ae9843SFelipe Balbi } 20394ae9843SFelipe Balbi 20494ae9843SFelipe Balbi /* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */ 205da8cc167SAnton Tikhomirov void fsl_otg_start_pulse(struct otg_fsm *fsm) 20694ae9843SFelipe Balbi { 20794ae9843SFelipe Balbi u32 tmp; 20894ae9843SFelipe Balbi 20994ae9843SFelipe Balbi srp_wait_done = 0; 21094ae9843SFelipe Balbi #ifdef HA_DATA_PULSE 21194ae9843SFelipe Balbi tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; 21294ae9843SFelipe Balbi tmp |= OTGSC_HA_DATA_PULSE; 21394ae9843SFelipe Balbi fsl_writel(tmp, &usb_dr_regs->otgsc); 21494ae9843SFelipe Balbi #else 21594ae9843SFelipe Balbi fsl_otg_loc_conn(1); 21694ae9843SFelipe Balbi #endif 21794ae9843SFelipe Balbi 218da8cc167SAnton Tikhomirov fsl_otg_add_timer(fsm, b_data_pulse_tmr); 21994ae9843SFelipe Balbi } 22094ae9843SFelipe Balbi 22194ae9843SFelipe Balbi void b_data_pulse_end(unsigned long foo) 22294ae9843SFelipe Balbi { 22394ae9843SFelipe Balbi #ifdef HA_DATA_PULSE 22494ae9843SFelipe Balbi #else 22594ae9843SFelipe Balbi fsl_otg_loc_conn(0); 22694ae9843SFelipe Balbi #endif 22794ae9843SFelipe Balbi 22894ae9843SFelipe Balbi /* Do VBUS pulse after data pulse */ 22994ae9843SFelipe Balbi fsl_otg_pulse_vbus(); 23094ae9843SFelipe Balbi } 23194ae9843SFelipe Balbi 23294ae9843SFelipe Balbi void fsl_otg_pulse_vbus(void) 23394ae9843SFelipe Balbi { 23494ae9843SFelipe Balbi srp_wait_done = 0; 235da8cc167SAnton Tikhomirov fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 1); 23694ae9843SFelipe Balbi /* start the timer to end vbus charge */ 237da8cc167SAnton Tikhomirov fsl_otg_add_timer(&fsl_otg_dev->fsm, b_vbus_pulse_tmr); 23894ae9843SFelipe Balbi } 23994ae9843SFelipe Balbi 24094ae9843SFelipe Balbi void b_vbus_pulse_end(unsigned long foo) 24194ae9843SFelipe Balbi { 242da8cc167SAnton Tikhomirov fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 0); 24394ae9843SFelipe Balbi 24494ae9843SFelipe Balbi /* 24594ae9843SFelipe Balbi * As USB3300 using the same a_sess_vld and b_sess_vld voltage 24694ae9843SFelipe Balbi * we need to discharge the bus for a while to distinguish 24794ae9843SFelipe Balbi * residual voltage of vbus pulsing and A device pull up 24894ae9843SFelipe Balbi */ 24994ae9843SFelipe Balbi fsl_otg_dischrg_vbus(1); 250da8cc167SAnton Tikhomirov fsl_otg_add_timer(&fsl_otg_dev->fsm, b_srp_wait_tmr); 25194ae9843SFelipe Balbi } 25294ae9843SFelipe Balbi 25394ae9843SFelipe Balbi void b_srp_end(unsigned long foo) 25494ae9843SFelipe Balbi { 25594ae9843SFelipe Balbi fsl_otg_dischrg_vbus(0); 25694ae9843SFelipe Balbi srp_wait_done = 1; 25794ae9843SFelipe Balbi 258e5ba1c02SFelipe Balbi if ((fsl_otg_dev->phy.otg->state == OTG_STATE_B_SRP_INIT) && 25994ae9843SFelipe Balbi fsl_otg_dev->fsm.b_sess_vld) 26094ae9843SFelipe Balbi fsl_otg_dev->fsm.b_srp_done = 1; 26194ae9843SFelipe Balbi } 26294ae9843SFelipe Balbi 26394ae9843SFelipe Balbi /* 26494ae9843SFelipe Balbi * Workaround for a_host suspending too fast. When a_bus_req=0, 26594ae9843SFelipe Balbi * a_host will start by SRP. It needs to set b_hnp_enable before 26694ae9843SFelipe Balbi * actually suspending to start HNP 26794ae9843SFelipe Balbi */ 26894ae9843SFelipe Balbi void a_wait_enum(unsigned long foo) 26994ae9843SFelipe Balbi { 27094ae9843SFelipe Balbi VDBG("a_wait_enum timeout\n"); 27194ae9843SFelipe Balbi if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) 272da8cc167SAnton Tikhomirov fsl_otg_add_timer(&fsl_otg_dev->fsm, a_wait_enum_tmr); 27394ae9843SFelipe Balbi else 27494ae9843SFelipe Balbi otg_statemachine(&fsl_otg_dev->fsm); 27594ae9843SFelipe Balbi } 27694ae9843SFelipe Balbi 27794ae9843SFelipe Balbi /* The timeout callback function to set time out bit */ 27894ae9843SFelipe Balbi void set_tmout(unsigned long indicator) 27994ae9843SFelipe Balbi { 28094ae9843SFelipe Balbi *(int *)indicator = 1; 28194ae9843SFelipe Balbi } 28294ae9843SFelipe Balbi 28394ae9843SFelipe Balbi /* Initialize timers */ 28494ae9843SFelipe Balbi int fsl_otg_init_timers(struct otg_fsm *fsm) 28594ae9843SFelipe Balbi { 28694ae9843SFelipe Balbi /* FSM used timers */ 28794ae9843SFelipe Balbi a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, 28894ae9843SFelipe Balbi (unsigned long)&fsm->a_wait_vrise_tmout); 28994ae9843SFelipe Balbi if (!a_wait_vrise_tmr) 29094ae9843SFelipe Balbi return -ENOMEM; 29194ae9843SFelipe Balbi 29294ae9843SFelipe Balbi a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON, 29394ae9843SFelipe Balbi (unsigned long)&fsm->a_wait_bcon_tmout); 29494ae9843SFelipe Balbi if (!a_wait_bcon_tmr) 29594ae9843SFelipe Balbi return -ENOMEM; 29694ae9843SFelipe Balbi 29794ae9843SFelipe Balbi a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, 29894ae9843SFelipe Balbi (unsigned long)&fsm->a_aidl_bdis_tmout); 29994ae9843SFelipe Balbi if (!a_aidl_bdis_tmr) 30094ae9843SFelipe Balbi return -ENOMEM; 30194ae9843SFelipe Balbi 30294ae9843SFelipe Balbi b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, 30394ae9843SFelipe Balbi (unsigned long)&fsm->b_ase0_brst_tmout); 30494ae9843SFelipe Balbi if (!b_ase0_brst_tmr) 30594ae9843SFelipe Balbi return -ENOMEM; 30694ae9843SFelipe Balbi 30794ae9843SFelipe Balbi b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, 30894ae9843SFelipe Balbi (unsigned long)&fsm->b_se0_srp); 30994ae9843SFelipe Balbi if (!b_se0_srp_tmr) 31094ae9843SFelipe Balbi return -ENOMEM; 31194ae9843SFelipe Balbi 31294ae9843SFelipe Balbi b_srp_fail_tmr = otg_timer_initializer(&set_tmout, TB_SRP_FAIL, 31394ae9843SFelipe Balbi (unsigned long)&fsm->b_srp_done); 31494ae9843SFelipe Balbi if (!b_srp_fail_tmr) 31594ae9843SFelipe Balbi return -ENOMEM; 31694ae9843SFelipe Balbi 31794ae9843SFelipe Balbi a_wait_enum_tmr = otg_timer_initializer(&a_wait_enum, 10, 31894ae9843SFelipe Balbi (unsigned long)&fsm); 31994ae9843SFelipe Balbi if (!a_wait_enum_tmr) 32094ae9843SFelipe Balbi return -ENOMEM; 32194ae9843SFelipe Balbi 32294ae9843SFelipe Balbi /* device driver used timers */ 32394ae9843SFelipe Balbi b_srp_wait_tmr = otg_timer_initializer(&b_srp_end, TB_SRP_WAIT, 0); 32494ae9843SFelipe Balbi if (!b_srp_wait_tmr) 32594ae9843SFelipe Balbi return -ENOMEM; 32694ae9843SFelipe Balbi 32794ae9843SFelipe Balbi b_data_pulse_tmr = otg_timer_initializer(&b_data_pulse_end, 32894ae9843SFelipe Balbi TB_DATA_PLS, 0); 32994ae9843SFelipe Balbi if (!b_data_pulse_tmr) 33094ae9843SFelipe Balbi return -ENOMEM; 33194ae9843SFelipe Balbi 33294ae9843SFelipe Balbi b_vbus_pulse_tmr = otg_timer_initializer(&b_vbus_pulse_end, 33394ae9843SFelipe Balbi TB_VBUS_PLS, 0); 33494ae9843SFelipe Balbi if (!b_vbus_pulse_tmr) 33594ae9843SFelipe Balbi return -ENOMEM; 33694ae9843SFelipe Balbi 33794ae9843SFelipe Balbi return 0; 33894ae9843SFelipe Balbi } 33994ae9843SFelipe Balbi 34094ae9843SFelipe Balbi /* Uninitialize timers */ 34194ae9843SFelipe Balbi void fsl_otg_uninit_timers(void) 34294ae9843SFelipe Balbi { 34394ae9843SFelipe Balbi /* FSM used timers */ 34494ae9843SFelipe Balbi kfree(a_wait_vrise_tmr); 34594ae9843SFelipe Balbi kfree(a_wait_bcon_tmr); 34694ae9843SFelipe Balbi kfree(a_aidl_bdis_tmr); 34794ae9843SFelipe Balbi kfree(b_ase0_brst_tmr); 34894ae9843SFelipe Balbi kfree(b_se0_srp_tmr); 34994ae9843SFelipe Balbi kfree(b_srp_fail_tmr); 35094ae9843SFelipe Balbi kfree(a_wait_enum_tmr); 35194ae9843SFelipe Balbi 35294ae9843SFelipe Balbi /* device driver used timers */ 35394ae9843SFelipe Balbi kfree(b_srp_wait_tmr); 35494ae9843SFelipe Balbi kfree(b_data_pulse_tmr); 35594ae9843SFelipe Balbi kfree(b_vbus_pulse_tmr); 35694ae9843SFelipe Balbi } 35794ae9843SFelipe Balbi 358f6de27eeSAnton Tikhomirov static struct fsl_otg_timer *fsl_otg_get_timer(enum otg_fsm_timer t) 359f6de27eeSAnton Tikhomirov { 360f6de27eeSAnton Tikhomirov struct fsl_otg_timer *timer; 361f6de27eeSAnton Tikhomirov 362f6de27eeSAnton Tikhomirov /* REVISIT: use array of pointers to timers instead */ 363f6de27eeSAnton Tikhomirov switch (t) { 364f6de27eeSAnton Tikhomirov case A_WAIT_VRISE: 365f6de27eeSAnton Tikhomirov timer = a_wait_vrise_tmr; 366f6de27eeSAnton Tikhomirov break; 367f6de27eeSAnton Tikhomirov case A_WAIT_BCON: 368f6de27eeSAnton Tikhomirov timer = a_wait_vrise_tmr; 369f6de27eeSAnton Tikhomirov break; 370f6de27eeSAnton Tikhomirov case A_AIDL_BDIS: 371f6de27eeSAnton Tikhomirov timer = a_wait_vrise_tmr; 372f6de27eeSAnton Tikhomirov break; 373f6de27eeSAnton Tikhomirov case B_ASE0_BRST: 374f6de27eeSAnton Tikhomirov timer = a_wait_vrise_tmr; 375f6de27eeSAnton Tikhomirov break; 376f6de27eeSAnton Tikhomirov case B_SE0_SRP: 377f6de27eeSAnton Tikhomirov timer = a_wait_vrise_tmr; 378f6de27eeSAnton Tikhomirov break; 379f6de27eeSAnton Tikhomirov case B_SRP_FAIL: 380f6de27eeSAnton Tikhomirov timer = a_wait_vrise_tmr; 381f6de27eeSAnton Tikhomirov break; 382f6de27eeSAnton Tikhomirov case A_WAIT_ENUM: 383f6de27eeSAnton Tikhomirov timer = a_wait_vrise_tmr; 384f6de27eeSAnton Tikhomirov break; 385f6de27eeSAnton Tikhomirov default: 386f6de27eeSAnton Tikhomirov timer = NULL; 387f6de27eeSAnton Tikhomirov } 388f6de27eeSAnton Tikhomirov 389f6de27eeSAnton Tikhomirov return timer; 390f6de27eeSAnton Tikhomirov } 391f6de27eeSAnton Tikhomirov 39294ae9843SFelipe Balbi /* Add timer to timer list */ 393da8cc167SAnton Tikhomirov void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer) 39494ae9843SFelipe Balbi { 39594ae9843SFelipe Balbi struct fsl_otg_timer *timer = gtimer; 39694ae9843SFelipe Balbi struct fsl_otg_timer *tmp_timer; 39794ae9843SFelipe Balbi 39894ae9843SFelipe Balbi /* 39994ae9843SFelipe Balbi * Check if the timer is already in the active list, 40094ae9843SFelipe Balbi * if so update timer count 40194ae9843SFelipe Balbi */ 40294ae9843SFelipe Balbi list_for_each_entry(tmp_timer, &active_timers, list) 40394ae9843SFelipe Balbi if (tmp_timer == timer) { 40494ae9843SFelipe Balbi timer->count = timer->expires; 40594ae9843SFelipe Balbi return; 40694ae9843SFelipe Balbi } 40794ae9843SFelipe Balbi timer->count = timer->expires; 40894ae9843SFelipe Balbi list_add_tail(&timer->list, &active_timers); 40994ae9843SFelipe Balbi } 41094ae9843SFelipe Balbi 411f6de27eeSAnton Tikhomirov static void fsl_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) 412f6de27eeSAnton Tikhomirov { 413f6de27eeSAnton Tikhomirov struct fsl_otg_timer *timer; 414f6de27eeSAnton Tikhomirov 415f6de27eeSAnton Tikhomirov timer = fsl_otg_get_timer(t); 416f6de27eeSAnton Tikhomirov if (!timer) 417f6de27eeSAnton Tikhomirov return; 418f6de27eeSAnton Tikhomirov 419f6de27eeSAnton Tikhomirov fsl_otg_add_timer(fsm, timer); 420f6de27eeSAnton Tikhomirov } 421f6de27eeSAnton Tikhomirov 42294ae9843SFelipe Balbi /* Remove timer from the timer list; clear timeout status */ 423da8cc167SAnton Tikhomirov void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer) 42494ae9843SFelipe Balbi { 42594ae9843SFelipe Balbi struct fsl_otg_timer *timer = gtimer; 42694ae9843SFelipe Balbi struct fsl_otg_timer *tmp_timer, *del_tmp; 42794ae9843SFelipe Balbi 42894ae9843SFelipe Balbi list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) 42994ae9843SFelipe Balbi if (tmp_timer == timer) 43094ae9843SFelipe Balbi list_del(&timer->list); 43194ae9843SFelipe Balbi } 43294ae9843SFelipe Balbi 433f6de27eeSAnton Tikhomirov static void fsl_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) 434f6de27eeSAnton Tikhomirov { 435f6de27eeSAnton Tikhomirov struct fsl_otg_timer *timer; 436f6de27eeSAnton Tikhomirov 437f6de27eeSAnton Tikhomirov timer = fsl_otg_get_timer(t); 438f6de27eeSAnton Tikhomirov if (!timer) 439f6de27eeSAnton Tikhomirov return; 440f6de27eeSAnton Tikhomirov 441f6de27eeSAnton Tikhomirov fsl_otg_del_timer(fsm, timer); 442f6de27eeSAnton Tikhomirov } 443f6de27eeSAnton Tikhomirov 44494ae9843SFelipe Balbi /* Reset controller, not reset the bus */ 44594ae9843SFelipe Balbi void otg_reset_controller(void) 44694ae9843SFelipe Balbi { 44794ae9843SFelipe Balbi u32 command; 44894ae9843SFelipe Balbi 44994ae9843SFelipe Balbi command = fsl_readl(&usb_dr_regs->usbcmd); 45094ae9843SFelipe Balbi command |= (1 << 1); 45194ae9843SFelipe Balbi fsl_writel(command, &usb_dr_regs->usbcmd); 45294ae9843SFelipe Balbi while (fsl_readl(&usb_dr_regs->usbcmd) & (1 << 1)) 45394ae9843SFelipe Balbi ; 45494ae9843SFelipe Balbi } 45594ae9843SFelipe Balbi 45694ae9843SFelipe Balbi /* Call suspend/resume routines in host driver */ 45794ae9843SFelipe Balbi int fsl_otg_start_host(struct otg_fsm *fsm, int on) 45894ae9843SFelipe Balbi { 45994ae9843SFelipe Balbi struct usb_otg *otg = fsm->otg; 46094ae9843SFelipe Balbi struct device *dev; 46119c1eac2SAntoine Tenart struct fsl_otg *otg_dev = 46219c1eac2SAntoine Tenart container_of(otg->usb_phy, struct fsl_otg, phy); 46394ae9843SFelipe Balbi u32 retval = 0; 46494ae9843SFelipe Balbi 46594ae9843SFelipe Balbi if (!otg->host) 46694ae9843SFelipe Balbi return -ENODEV; 46794ae9843SFelipe Balbi dev = otg->host->controller; 46894ae9843SFelipe Balbi 46994ae9843SFelipe Balbi /* 47094ae9843SFelipe Balbi * Update a_vbus_vld state as a_vbus_vld int is disabled 47194ae9843SFelipe Balbi * in device mode 47294ae9843SFelipe Balbi */ 47394ae9843SFelipe Balbi fsm->a_vbus_vld = 47494ae9843SFelipe Balbi !!(fsl_readl(&usb_dr_regs->otgsc) & OTGSC_STS_A_VBUS_VALID); 47594ae9843SFelipe Balbi if (on) { 47694ae9843SFelipe Balbi /* start fsl usb host controller */ 47794ae9843SFelipe Balbi if (otg_dev->host_working) 47894ae9843SFelipe Balbi goto end; 47994ae9843SFelipe Balbi else { 48094ae9843SFelipe Balbi otg_reset_controller(); 48194ae9843SFelipe Balbi VDBG("host on......\n"); 48294ae9843SFelipe Balbi if (dev->driver->pm && dev->driver->pm->resume) { 48394ae9843SFelipe Balbi retval = dev->driver->pm->resume(dev); 48494ae9843SFelipe Balbi if (fsm->id) { 48594ae9843SFelipe Balbi /* default-b */ 486da8cc167SAnton Tikhomirov fsl_otg_drv_vbus(fsm, 1); 48794ae9843SFelipe Balbi /* 48894ae9843SFelipe Balbi * Workaround: b_host can't driver 48994ae9843SFelipe Balbi * vbus, but PP in PORTSC needs to 49094ae9843SFelipe Balbi * be 1 for host to work. 49194ae9843SFelipe Balbi * So we set drv_vbus bit in 49294ae9843SFelipe Balbi * transceiver to 0 thru ULPI. 49394ae9843SFelipe Balbi */ 49494ae9843SFelipe Balbi write_ulpi(0x0c, 0x20); 49594ae9843SFelipe Balbi } 49694ae9843SFelipe Balbi } 49794ae9843SFelipe Balbi 49894ae9843SFelipe Balbi otg_dev->host_working = 1; 49994ae9843SFelipe Balbi } 50094ae9843SFelipe Balbi } else { 50194ae9843SFelipe Balbi /* stop fsl usb host controller */ 50294ae9843SFelipe Balbi if (!otg_dev->host_working) 50394ae9843SFelipe Balbi goto end; 50494ae9843SFelipe Balbi else { 50594ae9843SFelipe Balbi VDBG("host off......\n"); 50694ae9843SFelipe Balbi if (dev && dev->driver) { 50794ae9843SFelipe Balbi if (dev->driver->pm && dev->driver->pm->suspend) 50894ae9843SFelipe Balbi retval = dev->driver->pm->suspend(dev); 50994ae9843SFelipe Balbi if (fsm->id) 51094ae9843SFelipe Balbi /* default-b */ 511da8cc167SAnton Tikhomirov fsl_otg_drv_vbus(fsm, 0); 51294ae9843SFelipe Balbi } 51394ae9843SFelipe Balbi otg_dev->host_working = 0; 51494ae9843SFelipe Balbi } 51594ae9843SFelipe Balbi } 51694ae9843SFelipe Balbi end: 51794ae9843SFelipe Balbi return retval; 51894ae9843SFelipe Balbi } 51994ae9843SFelipe Balbi 52094ae9843SFelipe Balbi /* 52194ae9843SFelipe Balbi * Call suspend and resume function in udc driver 52294ae9843SFelipe Balbi * to stop and start udc driver. 52394ae9843SFelipe Balbi */ 52494ae9843SFelipe Balbi int fsl_otg_start_gadget(struct otg_fsm *fsm, int on) 52594ae9843SFelipe Balbi { 52694ae9843SFelipe Balbi struct usb_otg *otg = fsm->otg; 52794ae9843SFelipe Balbi struct device *dev; 52894ae9843SFelipe Balbi 52994ae9843SFelipe Balbi if (!otg->gadget || !otg->gadget->dev.parent) 53094ae9843SFelipe Balbi return -ENODEV; 53194ae9843SFelipe Balbi 53294ae9843SFelipe Balbi VDBG("gadget %s\n", on ? "on" : "off"); 53394ae9843SFelipe Balbi dev = otg->gadget->dev.parent; 53494ae9843SFelipe Balbi 53594ae9843SFelipe Balbi if (on) { 53694ae9843SFelipe Balbi if (dev->driver->resume) 53794ae9843SFelipe Balbi dev->driver->resume(dev); 53894ae9843SFelipe Balbi } else { 53994ae9843SFelipe Balbi if (dev->driver->suspend) 54094ae9843SFelipe Balbi dev->driver->suspend(dev, otg_suspend_state); 54194ae9843SFelipe Balbi } 54294ae9843SFelipe Balbi 54394ae9843SFelipe Balbi return 0; 54494ae9843SFelipe Balbi } 54594ae9843SFelipe Balbi 54694ae9843SFelipe Balbi /* 54794ae9843SFelipe Balbi * Called by initialization code of host driver. Register host controller 54894ae9843SFelipe Balbi * to the OTG. Suspend host for OTG role detection. 54994ae9843SFelipe Balbi */ 55094ae9843SFelipe Balbi static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) 55194ae9843SFelipe Balbi { 55294ae9843SFelipe Balbi struct fsl_otg *otg_dev; 55394ae9843SFelipe Balbi 55494ae9843SFelipe Balbi if (!otg) 55594ae9843SFelipe Balbi return -ENODEV; 55694ae9843SFelipe Balbi 55719c1eac2SAntoine Tenart otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); 55894ae9843SFelipe Balbi if (otg_dev != fsl_otg_dev) 55994ae9843SFelipe Balbi return -ENODEV; 56094ae9843SFelipe Balbi 56194ae9843SFelipe Balbi otg->host = host; 56294ae9843SFelipe Balbi 56394ae9843SFelipe Balbi otg_dev->fsm.a_bus_drop = 0; 56494ae9843SFelipe Balbi otg_dev->fsm.a_bus_req = 1; 56594ae9843SFelipe Balbi 56694ae9843SFelipe Balbi if (host) { 56794ae9843SFelipe Balbi VDBG("host off......\n"); 56894ae9843SFelipe Balbi 56994ae9843SFelipe Balbi otg->host->otg_port = fsl_otg_initdata.otg_port; 57094ae9843SFelipe Balbi otg->host->is_b_host = otg_dev->fsm.id; 57194ae9843SFelipe Balbi /* 57237ebb549SPetr Mladek * must leave time for hub_wq to finish its thing 57394ae9843SFelipe Balbi * before yanking the host driver out from under it, 57494ae9843SFelipe Balbi * so suspend the host after a short delay. 57594ae9843SFelipe Balbi */ 57694ae9843SFelipe Balbi otg_dev->host_working = 1; 57794ae9843SFelipe Balbi schedule_delayed_work(&otg_dev->otg_event, 100); 57894ae9843SFelipe Balbi return 0; 57994ae9843SFelipe Balbi } else { 58094ae9843SFelipe Balbi /* host driver going away */ 58194ae9843SFelipe Balbi if (!(fsl_readl(&otg_dev->dr_mem_map->otgsc) & 58294ae9843SFelipe Balbi OTGSC_STS_USB_ID)) { 58394ae9843SFelipe Balbi /* Mini-A cable connected */ 58494ae9843SFelipe Balbi struct otg_fsm *fsm = &otg_dev->fsm; 58594ae9843SFelipe Balbi 586e5ba1c02SFelipe Balbi otg->state = OTG_STATE_UNDEFINED; 58794ae9843SFelipe Balbi fsm->protocol = PROTO_UNDEF; 58894ae9843SFelipe Balbi } 58994ae9843SFelipe Balbi } 59094ae9843SFelipe Balbi 59194ae9843SFelipe Balbi otg_dev->host_working = 0; 59294ae9843SFelipe Balbi 59394ae9843SFelipe Balbi otg_statemachine(&otg_dev->fsm); 59494ae9843SFelipe Balbi 59594ae9843SFelipe Balbi return 0; 59694ae9843SFelipe Balbi } 59794ae9843SFelipe Balbi 59894ae9843SFelipe Balbi /* Called by initialization code of udc. Register udc to OTG. */ 59994ae9843SFelipe Balbi static int fsl_otg_set_peripheral(struct usb_otg *otg, 60094ae9843SFelipe Balbi struct usb_gadget *gadget) 60194ae9843SFelipe Balbi { 60294ae9843SFelipe Balbi struct fsl_otg *otg_dev; 60394ae9843SFelipe Balbi 60494ae9843SFelipe Balbi if (!otg) 60594ae9843SFelipe Balbi return -ENODEV; 60694ae9843SFelipe Balbi 60719c1eac2SAntoine Tenart otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); 60894ae9843SFelipe Balbi VDBG("otg_dev 0x%x\n", (int)otg_dev); 60994ae9843SFelipe Balbi VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev); 61094ae9843SFelipe Balbi if (otg_dev != fsl_otg_dev) 61194ae9843SFelipe Balbi return -ENODEV; 61294ae9843SFelipe Balbi 61394ae9843SFelipe Balbi if (!gadget) { 61494ae9843SFelipe Balbi if (!otg->default_a) 61594ae9843SFelipe Balbi otg->gadget->ops->vbus_draw(otg->gadget, 0); 61694ae9843SFelipe Balbi usb_gadget_vbus_disconnect(otg->gadget); 61794ae9843SFelipe Balbi otg->gadget = 0; 61894ae9843SFelipe Balbi otg_dev->fsm.b_bus_req = 0; 61994ae9843SFelipe Balbi otg_statemachine(&otg_dev->fsm); 62094ae9843SFelipe Balbi return 0; 62194ae9843SFelipe Balbi } 62294ae9843SFelipe Balbi 62394ae9843SFelipe Balbi otg->gadget = gadget; 62494ae9843SFelipe Balbi otg->gadget->is_a_peripheral = !otg_dev->fsm.id; 62594ae9843SFelipe Balbi 62694ae9843SFelipe Balbi otg_dev->fsm.b_bus_req = 1; 62794ae9843SFelipe Balbi 62894ae9843SFelipe Balbi /* start the gadget right away if the ID pin says Mini-B */ 629523e531eSGreg Kroah-Hartman pr_debug("ID pin=%d\n", otg_dev->fsm.id); 63094ae9843SFelipe Balbi if (otg_dev->fsm.id == 1) { 63194ae9843SFelipe Balbi fsl_otg_start_host(&otg_dev->fsm, 0); 63294ae9843SFelipe Balbi otg_drv_vbus(&otg_dev->fsm, 0); 63394ae9843SFelipe Balbi fsl_otg_start_gadget(&otg_dev->fsm, 1); 63494ae9843SFelipe Balbi } 63594ae9843SFelipe Balbi 63694ae9843SFelipe Balbi return 0; 63794ae9843SFelipe Balbi } 63894ae9843SFelipe Balbi 63994ae9843SFelipe Balbi /* 64094ae9843SFelipe Balbi * Delayed pin detect interrupt processing. 64194ae9843SFelipe Balbi * 64294ae9843SFelipe Balbi * When the Mini-A cable is disconnected from the board, 64394ae9843SFelipe Balbi * the pin-detect interrupt happens before the disconnect 64494ae9843SFelipe Balbi * interrupts for the connected device(s). In order to 64594ae9843SFelipe Balbi * process the disconnect interrupt(s) prior to switching 64694ae9843SFelipe Balbi * roles, the pin-detect interrupts are delayed, and handled 64794ae9843SFelipe Balbi * by this routine. 64894ae9843SFelipe Balbi */ 64994ae9843SFelipe Balbi static void fsl_otg_event(struct work_struct *work) 65094ae9843SFelipe Balbi { 65194ae9843SFelipe Balbi struct fsl_otg *og = container_of(work, struct fsl_otg, otg_event.work); 65294ae9843SFelipe Balbi struct otg_fsm *fsm = &og->fsm; 65394ae9843SFelipe Balbi 65494ae9843SFelipe Balbi if (fsm->id) { /* switch to gadget */ 65594ae9843SFelipe Balbi fsl_otg_start_host(fsm, 0); 65694ae9843SFelipe Balbi otg_drv_vbus(fsm, 0); 65794ae9843SFelipe Balbi fsl_otg_start_gadget(fsm, 1); 65894ae9843SFelipe Balbi } 65994ae9843SFelipe Balbi } 66094ae9843SFelipe Balbi 66194ae9843SFelipe Balbi /* B-device start SRP */ 66294ae9843SFelipe Balbi static int fsl_otg_start_srp(struct usb_otg *otg) 66394ae9843SFelipe Balbi { 66494ae9843SFelipe Balbi struct fsl_otg *otg_dev; 66594ae9843SFelipe Balbi 666e5ba1c02SFelipe Balbi if (!otg || otg->state != OTG_STATE_B_IDLE) 66794ae9843SFelipe Balbi return -ENODEV; 66894ae9843SFelipe Balbi 66919c1eac2SAntoine Tenart otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); 67094ae9843SFelipe Balbi if (otg_dev != fsl_otg_dev) 67194ae9843SFelipe Balbi return -ENODEV; 67294ae9843SFelipe Balbi 67394ae9843SFelipe Balbi otg_dev->fsm.b_bus_req = 1; 67494ae9843SFelipe Balbi otg_statemachine(&otg_dev->fsm); 67594ae9843SFelipe Balbi 67694ae9843SFelipe Balbi return 0; 67794ae9843SFelipe Balbi } 67894ae9843SFelipe Balbi 67994ae9843SFelipe Balbi /* A_host suspend will call this function to start hnp */ 68094ae9843SFelipe Balbi static int fsl_otg_start_hnp(struct usb_otg *otg) 68194ae9843SFelipe Balbi { 68294ae9843SFelipe Balbi struct fsl_otg *otg_dev; 68394ae9843SFelipe Balbi 68494ae9843SFelipe Balbi if (!otg) 68594ae9843SFelipe Balbi return -ENODEV; 68694ae9843SFelipe Balbi 68719c1eac2SAntoine Tenart otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); 68894ae9843SFelipe Balbi if (otg_dev != fsl_otg_dev) 68994ae9843SFelipe Balbi return -ENODEV; 69094ae9843SFelipe Balbi 691523e531eSGreg Kroah-Hartman pr_debug("start_hnp...\n"); 69294ae9843SFelipe Balbi 69394ae9843SFelipe Balbi /* clear a_bus_req to enter a_suspend state */ 69494ae9843SFelipe Balbi otg_dev->fsm.a_bus_req = 0; 69594ae9843SFelipe Balbi otg_statemachine(&otg_dev->fsm); 69694ae9843SFelipe Balbi 69794ae9843SFelipe Balbi return 0; 69894ae9843SFelipe Balbi } 69994ae9843SFelipe Balbi 70094ae9843SFelipe Balbi /* 70194ae9843SFelipe Balbi * Interrupt handler. OTG/host/peripheral share the same int line. 70294ae9843SFelipe Balbi * OTG driver clears OTGSC interrupts and leaves USB interrupts 70394ae9843SFelipe Balbi * intact. It needs to have knowledge of some USB interrupts 70494ae9843SFelipe Balbi * such as port change. 70594ae9843SFelipe Balbi */ 70694ae9843SFelipe Balbi irqreturn_t fsl_otg_isr(int irq, void *dev_id) 70794ae9843SFelipe Balbi { 70894ae9843SFelipe Balbi struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; 70994ae9843SFelipe Balbi struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; 71094ae9843SFelipe Balbi u32 otg_int_src, otg_sc; 71194ae9843SFelipe Balbi 71294ae9843SFelipe Balbi otg_sc = fsl_readl(&usb_dr_regs->otgsc); 71394ae9843SFelipe Balbi otg_int_src = otg_sc & OTGSC_INTSTS_MASK & (otg_sc >> 8); 71494ae9843SFelipe Balbi 71594ae9843SFelipe Balbi /* Only clear otg interrupts */ 71694ae9843SFelipe Balbi fsl_writel(otg_sc, &usb_dr_regs->otgsc); 71794ae9843SFelipe Balbi 71894ae9843SFelipe Balbi /*FIXME: ID change not generate when init to 0 */ 71994ae9843SFelipe Balbi fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; 72094ae9843SFelipe Balbi otg->default_a = (fsm->id == 0); 72194ae9843SFelipe Balbi 72294ae9843SFelipe Balbi /* process OTG interrupts */ 72394ae9843SFelipe Balbi if (otg_int_src) { 72494ae9843SFelipe Balbi if (otg_int_src & OTGSC_INTSTS_USB_ID) { 72594ae9843SFelipe Balbi fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; 72694ae9843SFelipe Balbi otg->default_a = (fsm->id == 0); 72794ae9843SFelipe Balbi /* clear conn information */ 72894ae9843SFelipe Balbi if (fsm->id) 72994ae9843SFelipe Balbi fsm->b_conn = 0; 73094ae9843SFelipe Balbi else 73194ae9843SFelipe Balbi fsm->a_conn = 0; 73294ae9843SFelipe Balbi 73394ae9843SFelipe Balbi if (otg->host) 73494ae9843SFelipe Balbi otg->host->is_b_host = fsm->id; 73594ae9843SFelipe Balbi if (otg->gadget) 73694ae9843SFelipe Balbi otg->gadget->is_a_peripheral = !fsm->id; 73794ae9843SFelipe Balbi VDBG("ID int (ID is %d)\n", fsm->id); 73894ae9843SFelipe Balbi 73994ae9843SFelipe Balbi if (fsm->id) { /* switch to gadget */ 74094ae9843SFelipe Balbi schedule_delayed_work( 74194ae9843SFelipe Balbi &((struct fsl_otg *)dev_id)->otg_event, 74294ae9843SFelipe Balbi 100); 74394ae9843SFelipe Balbi } else { /* switch to host */ 74494ae9843SFelipe Balbi cancel_delayed_work(& 74594ae9843SFelipe Balbi ((struct fsl_otg *)dev_id)-> 74694ae9843SFelipe Balbi otg_event); 74794ae9843SFelipe Balbi fsl_otg_start_gadget(fsm, 0); 74894ae9843SFelipe Balbi otg_drv_vbus(fsm, 1); 74994ae9843SFelipe Balbi fsl_otg_start_host(fsm, 1); 75094ae9843SFelipe Balbi } 75194ae9843SFelipe Balbi return IRQ_HANDLED; 75294ae9843SFelipe Balbi } 75394ae9843SFelipe Balbi } 75494ae9843SFelipe Balbi return IRQ_NONE; 75594ae9843SFelipe Balbi } 75694ae9843SFelipe Balbi 75794ae9843SFelipe Balbi static struct otg_fsm_ops fsl_otg_ops = { 75894ae9843SFelipe Balbi .chrg_vbus = fsl_otg_chrg_vbus, 75994ae9843SFelipe Balbi .drv_vbus = fsl_otg_drv_vbus, 76094ae9843SFelipe Balbi .loc_conn = fsl_otg_loc_conn, 76194ae9843SFelipe Balbi .loc_sof = fsl_otg_loc_sof, 76294ae9843SFelipe Balbi .start_pulse = fsl_otg_start_pulse, 76394ae9843SFelipe Balbi 764f6de27eeSAnton Tikhomirov .add_timer = fsl_otg_fsm_add_timer, 765f6de27eeSAnton Tikhomirov .del_timer = fsl_otg_fsm_del_timer, 76694ae9843SFelipe Balbi 76794ae9843SFelipe Balbi .start_host = fsl_otg_start_host, 76894ae9843SFelipe Balbi .start_gadget = fsl_otg_start_gadget, 76994ae9843SFelipe Balbi }; 77094ae9843SFelipe Balbi 77194ae9843SFelipe Balbi /* Initialize the global variable fsl_otg_dev and request IRQ for OTG */ 77294ae9843SFelipe Balbi static int fsl_otg_conf(struct platform_device *pdev) 77394ae9843SFelipe Balbi { 77494ae9843SFelipe Balbi struct fsl_otg *fsl_otg_tc; 77594ae9843SFelipe Balbi int status; 77694ae9843SFelipe Balbi 77794ae9843SFelipe Balbi if (fsl_otg_dev) 77894ae9843SFelipe Balbi return 0; 77994ae9843SFelipe Balbi 78094ae9843SFelipe Balbi /* allocate space to fsl otg device */ 78194ae9843SFelipe Balbi fsl_otg_tc = kzalloc(sizeof(struct fsl_otg), GFP_KERNEL); 78294ae9843SFelipe Balbi if (!fsl_otg_tc) 78394ae9843SFelipe Balbi return -ENOMEM; 78494ae9843SFelipe Balbi 78594ae9843SFelipe Balbi fsl_otg_tc->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); 78694ae9843SFelipe Balbi if (!fsl_otg_tc->phy.otg) { 78794ae9843SFelipe Balbi kfree(fsl_otg_tc); 78894ae9843SFelipe Balbi return -ENOMEM; 78994ae9843SFelipe Balbi } 79094ae9843SFelipe Balbi 79194ae9843SFelipe Balbi INIT_DELAYED_WORK(&fsl_otg_tc->otg_event, fsl_otg_event); 79294ae9843SFelipe Balbi 79394ae9843SFelipe Balbi INIT_LIST_HEAD(&active_timers); 79494ae9843SFelipe Balbi status = fsl_otg_init_timers(&fsl_otg_tc->fsm); 79594ae9843SFelipe Balbi if (status) { 79694ae9843SFelipe Balbi pr_info("Couldn't init OTG timers\n"); 79794ae9843SFelipe Balbi goto err; 79894ae9843SFelipe Balbi } 79916e569e9SAnton Tikhomirov mutex_init(&fsl_otg_tc->fsm.lock); 80094ae9843SFelipe Balbi 80194ae9843SFelipe Balbi /* Set OTG state machine operations */ 80294ae9843SFelipe Balbi fsl_otg_tc->fsm.ops = &fsl_otg_ops; 80394ae9843SFelipe Balbi 80494ae9843SFelipe Balbi /* initialize the otg structure */ 80594ae9843SFelipe Balbi fsl_otg_tc->phy.label = DRIVER_DESC; 8061abd8b31SRobert Jarzmik fsl_otg_tc->phy.dev = &pdev->dev; 80794ae9843SFelipe Balbi 80819c1eac2SAntoine Tenart fsl_otg_tc->phy.otg->usb_phy = &fsl_otg_tc->phy; 80994ae9843SFelipe Balbi fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host; 81094ae9843SFelipe Balbi fsl_otg_tc->phy.otg->set_peripheral = fsl_otg_set_peripheral; 81194ae9843SFelipe Balbi fsl_otg_tc->phy.otg->start_hnp = fsl_otg_start_hnp; 81294ae9843SFelipe Balbi fsl_otg_tc->phy.otg->start_srp = fsl_otg_start_srp; 81394ae9843SFelipe Balbi 81494ae9843SFelipe Balbi fsl_otg_dev = fsl_otg_tc; 81594ae9843SFelipe Balbi 81694ae9843SFelipe Balbi /* Store the otg transceiver */ 81794ae9843SFelipe Balbi status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); 81894ae9843SFelipe Balbi if (status) { 81994ae9843SFelipe Balbi pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); 82094ae9843SFelipe Balbi goto err; 82194ae9843SFelipe Balbi } 82294ae9843SFelipe Balbi 82394ae9843SFelipe Balbi return 0; 82494ae9843SFelipe Balbi err: 82594ae9843SFelipe Balbi fsl_otg_uninit_timers(); 82694ae9843SFelipe Balbi kfree(fsl_otg_tc->phy.otg); 82794ae9843SFelipe Balbi kfree(fsl_otg_tc); 82894ae9843SFelipe Balbi return status; 82994ae9843SFelipe Balbi } 83094ae9843SFelipe Balbi 83194ae9843SFelipe Balbi /* OTG Initialization */ 83294ae9843SFelipe Balbi int usb_otg_start(struct platform_device *pdev) 83394ae9843SFelipe Balbi { 83494ae9843SFelipe Balbi struct fsl_otg *p_otg; 83594ae9843SFelipe Balbi struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2); 83694ae9843SFelipe Balbi struct otg_fsm *fsm; 83794ae9843SFelipe Balbi int status; 83894ae9843SFelipe Balbi struct resource *res; 83994ae9843SFelipe Balbi u32 temp; 84019f9e188SJingoo Han struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); 84194ae9843SFelipe Balbi 84294ae9843SFelipe Balbi p_otg = container_of(otg_trans, struct fsl_otg, phy); 84394ae9843SFelipe Balbi fsm = &p_otg->fsm; 84494ae9843SFelipe Balbi 84594ae9843SFelipe Balbi /* Initialize the state machine structure with default values */ 84694ae9843SFelipe Balbi SET_OTG_STATE(otg_trans, OTG_STATE_UNDEFINED); 84794ae9843SFelipe Balbi fsm->otg = p_otg->phy.otg; 84894ae9843SFelipe Balbi 84994ae9843SFelipe Balbi /* We don't require predefined MEM/IRQ resource index */ 85094ae9843SFelipe Balbi res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 85194ae9843SFelipe Balbi if (!res) 85294ae9843SFelipe Balbi return -ENXIO; 85394ae9843SFelipe Balbi 85494ae9843SFelipe Balbi /* We don't request_mem_region here to enable resource sharing 85594ae9843SFelipe Balbi * with host/device */ 85694ae9843SFelipe Balbi 85794ae9843SFelipe Balbi usb_dr_regs = ioremap(res->start, sizeof(struct usb_dr_mmap)); 85894ae9843SFelipe Balbi p_otg->dr_mem_map = (struct usb_dr_mmap *)usb_dr_regs; 85994ae9843SFelipe Balbi pdata->regs = (void *)usb_dr_regs; 86094ae9843SFelipe Balbi 86194ae9843SFelipe Balbi if (pdata->init && pdata->init(pdev) != 0) 86294ae9843SFelipe Balbi return -EINVAL; 86394ae9843SFelipe Balbi 864a39ba90aSRandy Dunlap #ifdef CONFIG_PPC32 86594ae9843SFelipe Balbi if (pdata->big_endian_mmio) { 86694ae9843SFelipe Balbi _fsl_readl = _fsl_readl_be; 86794ae9843SFelipe Balbi _fsl_writel = _fsl_writel_be; 86894ae9843SFelipe Balbi } else { 86994ae9843SFelipe Balbi _fsl_readl = _fsl_readl_le; 87094ae9843SFelipe Balbi _fsl_writel = _fsl_writel_le; 87194ae9843SFelipe Balbi } 872a39ba90aSRandy Dunlap #endif 87394ae9843SFelipe Balbi 87494ae9843SFelipe Balbi /* request irq */ 87594ae9843SFelipe Balbi p_otg->irq = platform_get_irq(pdev, 0); 87694ae9843SFelipe Balbi status = request_irq(p_otg->irq, fsl_otg_isr, 87794ae9843SFelipe Balbi IRQF_SHARED, driver_name, p_otg); 87894ae9843SFelipe Balbi if (status) { 87994ae9843SFelipe Balbi dev_dbg(p_otg->phy.dev, "can't get IRQ %d, error %d\n", 88094ae9843SFelipe Balbi p_otg->irq, status); 88194ae9843SFelipe Balbi iounmap(p_otg->dr_mem_map); 88294ae9843SFelipe Balbi kfree(p_otg->phy.otg); 88394ae9843SFelipe Balbi kfree(p_otg); 88494ae9843SFelipe Balbi return status; 88594ae9843SFelipe Balbi } 88694ae9843SFelipe Balbi 88794ae9843SFelipe Balbi /* stop the controller */ 88894ae9843SFelipe Balbi temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); 88994ae9843SFelipe Balbi temp &= ~USB_CMD_RUN_STOP; 89094ae9843SFelipe Balbi fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); 89194ae9843SFelipe Balbi 89294ae9843SFelipe Balbi /* reset the controller */ 89394ae9843SFelipe Balbi temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); 89494ae9843SFelipe Balbi temp |= USB_CMD_CTRL_RESET; 89594ae9843SFelipe Balbi fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); 89694ae9843SFelipe Balbi 89794ae9843SFelipe Balbi /* wait reset completed */ 89894ae9843SFelipe Balbi while (fsl_readl(&p_otg->dr_mem_map->usbcmd) & USB_CMD_CTRL_RESET) 89994ae9843SFelipe Balbi ; 90094ae9843SFelipe Balbi 90194ae9843SFelipe Balbi /* configure the VBUSHS as IDLE(both host and device) */ 90294ae9843SFelipe Balbi temp = USB_MODE_STREAM_DISABLE | (pdata->es ? USB_MODE_ES : 0); 90394ae9843SFelipe Balbi fsl_writel(temp, &p_otg->dr_mem_map->usbmode); 90494ae9843SFelipe Balbi 90594ae9843SFelipe Balbi /* configure PHY interface */ 90694ae9843SFelipe Balbi temp = fsl_readl(&p_otg->dr_mem_map->portsc); 90794ae9843SFelipe Balbi temp &= ~(PORTSC_PHY_TYPE_SEL | PORTSC_PTW); 90894ae9843SFelipe Balbi switch (pdata->phy_mode) { 90994ae9843SFelipe Balbi case FSL_USB2_PHY_ULPI: 91094ae9843SFelipe Balbi temp |= PORTSC_PTS_ULPI; 91194ae9843SFelipe Balbi break; 91294ae9843SFelipe Balbi case FSL_USB2_PHY_UTMI_WIDE: 91394ae9843SFelipe Balbi temp |= PORTSC_PTW_16BIT; 91494ae9843SFelipe Balbi /* fall through */ 91594ae9843SFelipe Balbi case FSL_USB2_PHY_UTMI: 91694ae9843SFelipe Balbi temp |= PORTSC_PTS_UTMI; 91794ae9843SFelipe Balbi /* fall through */ 91894ae9843SFelipe Balbi default: 91994ae9843SFelipe Balbi break; 92094ae9843SFelipe Balbi } 92194ae9843SFelipe Balbi fsl_writel(temp, &p_otg->dr_mem_map->portsc); 92294ae9843SFelipe Balbi 92394ae9843SFelipe Balbi if (pdata->have_sysif_regs) { 92494ae9843SFelipe Balbi /* configure control enable IO output, big endian register */ 92594ae9843SFelipe Balbi temp = __raw_readl(&p_otg->dr_mem_map->control); 92694ae9843SFelipe Balbi temp |= USB_CTRL_IOENB; 92794ae9843SFelipe Balbi __raw_writel(temp, &p_otg->dr_mem_map->control); 92894ae9843SFelipe Balbi } 92994ae9843SFelipe Balbi 93094ae9843SFelipe Balbi /* disable all interrupt and clear all OTGSC status */ 93194ae9843SFelipe Balbi temp = fsl_readl(&p_otg->dr_mem_map->otgsc); 93294ae9843SFelipe Balbi temp &= ~OTGSC_INTERRUPT_ENABLE_BITS_MASK; 93394ae9843SFelipe Balbi temp |= OTGSC_INTERRUPT_STATUS_BITS_MASK | OTGSC_CTRL_VBUS_DISCHARGE; 93494ae9843SFelipe Balbi fsl_writel(temp, &p_otg->dr_mem_map->otgsc); 93594ae9843SFelipe Balbi 93694ae9843SFelipe Balbi /* 93794ae9843SFelipe Balbi * The identification (id) input is FALSE when a Mini-A plug is inserted 93894ae9843SFelipe Balbi * in the devices Mini-AB receptacle. Otherwise, this input is TRUE. 93994ae9843SFelipe Balbi * Also: record initial state of ID pin 94094ae9843SFelipe Balbi */ 94194ae9843SFelipe Balbi if (fsl_readl(&p_otg->dr_mem_map->otgsc) & OTGSC_STS_USB_ID) { 942e5ba1c02SFelipe Balbi p_otg->phy.otg->state = OTG_STATE_UNDEFINED; 94394ae9843SFelipe Balbi p_otg->fsm.id = 1; 94494ae9843SFelipe Balbi } else { 945e5ba1c02SFelipe Balbi p_otg->phy.otg->state = OTG_STATE_A_IDLE; 94694ae9843SFelipe Balbi p_otg->fsm.id = 0; 94794ae9843SFelipe Balbi } 94894ae9843SFelipe Balbi 949523e531eSGreg Kroah-Hartman pr_debug("initial ID pin=%d\n", p_otg->fsm.id); 95094ae9843SFelipe Balbi 95194ae9843SFelipe Balbi /* enable OTG ID pin interrupt */ 95294ae9843SFelipe Balbi temp = fsl_readl(&p_otg->dr_mem_map->otgsc); 95394ae9843SFelipe Balbi temp |= OTGSC_INTR_USB_ID_EN; 95494ae9843SFelipe Balbi temp &= ~(OTGSC_CTRL_VBUS_DISCHARGE | OTGSC_INTR_1MS_TIMER_EN); 95594ae9843SFelipe Balbi fsl_writel(temp, &p_otg->dr_mem_map->otgsc); 95694ae9843SFelipe Balbi 95794ae9843SFelipe Balbi return 0; 95894ae9843SFelipe Balbi } 95994ae9843SFelipe Balbi 96094ae9843SFelipe Balbi /* 96194ae9843SFelipe Balbi * state file in sysfs 96294ae9843SFelipe Balbi */ 963a39ba90aSRandy Dunlap static ssize_t show_fsl_usb2_otg_state(struct device *dev, 96494ae9843SFelipe Balbi struct device_attribute *attr, char *buf) 96594ae9843SFelipe Balbi { 96694ae9843SFelipe Balbi struct otg_fsm *fsm = &fsl_otg_dev->fsm; 96794ae9843SFelipe Balbi char *next = buf; 96894ae9843SFelipe Balbi unsigned size = PAGE_SIZE; 96994ae9843SFelipe Balbi int t; 97094ae9843SFelipe Balbi 97116e569e9SAnton Tikhomirov mutex_lock(&fsm->lock); 97294ae9843SFelipe Balbi 97394ae9843SFelipe Balbi /* basic driver infomation */ 97494ae9843SFelipe Balbi t = scnprintf(next, size, 97594ae9843SFelipe Balbi DRIVER_DESC "\n" "fsl_usb2_otg version: %s\n\n", 97694ae9843SFelipe Balbi DRIVER_VERSION); 97794ae9843SFelipe Balbi size -= t; 97894ae9843SFelipe Balbi next += t; 97994ae9843SFelipe Balbi 98094ae9843SFelipe Balbi /* Registers */ 98194ae9843SFelipe Balbi t = scnprintf(next, size, 98294ae9843SFelipe Balbi "OTGSC: 0x%08x\n" 98394ae9843SFelipe Balbi "PORTSC: 0x%08x\n" 98494ae9843SFelipe Balbi "USBMODE: 0x%08x\n" 98594ae9843SFelipe Balbi "USBCMD: 0x%08x\n" 98694ae9843SFelipe Balbi "USBSTS: 0x%08x\n" 98794ae9843SFelipe Balbi "USBINTR: 0x%08x\n", 98894ae9843SFelipe Balbi fsl_readl(&usb_dr_regs->otgsc), 98994ae9843SFelipe Balbi fsl_readl(&usb_dr_regs->portsc), 99094ae9843SFelipe Balbi fsl_readl(&usb_dr_regs->usbmode), 99194ae9843SFelipe Balbi fsl_readl(&usb_dr_regs->usbcmd), 99294ae9843SFelipe Balbi fsl_readl(&usb_dr_regs->usbsts), 99394ae9843SFelipe Balbi fsl_readl(&usb_dr_regs->usbintr)); 99494ae9843SFelipe Balbi size -= t; 99594ae9843SFelipe Balbi next += t; 99694ae9843SFelipe Balbi 99794ae9843SFelipe Balbi /* State */ 99894ae9843SFelipe Balbi t = scnprintf(next, size, 99994ae9843SFelipe Balbi "OTG state: %s\n\n", 1000e5ba1c02SFelipe Balbi usb_otg_state_string(fsl_otg_dev->phy.otg->state)); 100194ae9843SFelipe Balbi size -= t; 100294ae9843SFelipe Balbi next += t; 100394ae9843SFelipe Balbi 100494ae9843SFelipe Balbi /* State Machine Variables */ 100594ae9843SFelipe Balbi t = scnprintf(next, size, 100694ae9843SFelipe Balbi "a_bus_req: %d\n" 100794ae9843SFelipe Balbi "b_bus_req: %d\n" 100894ae9843SFelipe Balbi "a_bus_resume: %d\n" 100994ae9843SFelipe Balbi "a_bus_suspend: %d\n" 101094ae9843SFelipe Balbi "a_conn: %d\n" 101194ae9843SFelipe Balbi "a_sess_vld: %d\n" 101294ae9843SFelipe Balbi "a_srp_det: %d\n" 101394ae9843SFelipe Balbi "a_vbus_vld: %d\n" 101494ae9843SFelipe Balbi "b_bus_resume: %d\n" 101594ae9843SFelipe Balbi "b_bus_suspend: %d\n" 101694ae9843SFelipe Balbi "b_conn: %d\n" 101794ae9843SFelipe Balbi "b_se0_srp: %d\n" 101868041785SAnton Tikhomirov "b_ssend_srp: %d\n" 101994ae9843SFelipe Balbi "b_sess_vld: %d\n" 102094ae9843SFelipe Balbi "id: %d\n", 102194ae9843SFelipe Balbi fsm->a_bus_req, 102294ae9843SFelipe Balbi fsm->b_bus_req, 102394ae9843SFelipe Balbi fsm->a_bus_resume, 102494ae9843SFelipe Balbi fsm->a_bus_suspend, 102594ae9843SFelipe Balbi fsm->a_conn, 102694ae9843SFelipe Balbi fsm->a_sess_vld, 102794ae9843SFelipe Balbi fsm->a_srp_det, 102894ae9843SFelipe Balbi fsm->a_vbus_vld, 102994ae9843SFelipe Balbi fsm->b_bus_resume, 103094ae9843SFelipe Balbi fsm->b_bus_suspend, 103194ae9843SFelipe Balbi fsm->b_conn, 103294ae9843SFelipe Balbi fsm->b_se0_srp, 103368041785SAnton Tikhomirov fsm->b_ssend_srp, 103494ae9843SFelipe Balbi fsm->b_sess_vld, 103594ae9843SFelipe Balbi fsm->id); 103694ae9843SFelipe Balbi size -= t; 103794ae9843SFelipe Balbi next += t; 103894ae9843SFelipe Balbi 103916e569e9SAnton Tikhomirov mutex_unlock(&fsm->lock); 104094ae9843SFelipe Balbi 104194ae9843SFelipe Balbi return PAGE_SIZE - size; 104294ae9843SFelipe Balbi } 104394ae9843SFelipe Balbi 104494ae9843SFelipe Balbi static DEVICE_ATTR(fsl_usb2_otg_state, S_IRUGO, show_fsl_usb2_otg_state, NULL); 104594ae9843SFelipe Balbi 104694ae9843SFelipe Balbi 104794ae9843SFelipe Balbi /* Char driver interface to control some OTG input */ 104894ae9843SFelipe Balbi 104994ae9843SFelipe Balbi /* 105094ae9843SFelipe Balbi * Handle some ioctl command, such as get otg 105194ae9843SFelipe Balbi * status and set host suspend 105294ae9843SFelipe Balbi */ 105394ae9843SFelipe Balbi static long fsl_otg_ioctl(struct file *file, unsigned int cmd, 105494ae9843SFelipe Balbi unsigned long arg) 105594ae9843SFelipe Balbi { 105694ae9843SFelipe Balbi u32 retval = 0; 105794ae9843SFelipe Balbi 105894ae9843SFelipe Balbi switch (cmd) { 105994ae9843SFelipe Balbi case GET_OTG_STATUS: 106094ae9843SFelipe Balbi retval = fsl_otg_dev->host_working; 106194ae9843SFelipe Balbi break; 106294ae9843SFelipe Balbi 106394ae9843SFelipe Balbi case SET_A_SUSPEND_REQ: 1064cff4dab4SAnton Tikhomirov fsl_otg_dev->fsm.a_suspend_req_inf = arg; 106594ae9843SFelipe Balbi break; 106694ae9843SFelipe Balbi 106794ae9843SFelipe Balbi case SET_A_BUS_DROP: 106894ae9843SFelipe Balbi fsl_otg_dev->fsm.a_bus_drop = arg; 106994ae9843SFelipe Balbi break; 107094ae9843SFelipe Balbi 107194ae9843SFelipe Balbi case SET_A_BUS_REQ: 107294ae9843SFelipe Balbi fsl_otg_dev->fsm.a_bus_req = arg; 107394ae9843SFelipe Balbi break; 107494ae9843SFelipe Balbi 107594ae9843SFelipe Balbi case SET_B_BUS_REQ: 107694ae9843SFelipe Balbi fsl_otg_dev->fsm.b_bus_req = arg; 107794ae9843SFelipe Balbi break; 107894ae9843SFelipe Balbi 107994ae9843SFelipe Balbi default: 108094ae9843SFelipe Balbi break; 108194ae9843SFelipe Balbi } 108294ae9843SFelipe Balbi 108394ae9843SFelipe Balbi otg_statemachine(&fsl_otg_dev->fsm); 108494ae9843SFelipe Balbi 108594ae9843SFelipe Balbi return retval; 108694ae9843SFelipe Balbi } 108794ae9843SFelipe Balbi 108894ae9843SFelipe Balbi static int fsl_otg_open(struct inode *inode, struct file *file) 108994ae9843SFelipe Balbi { 109094ae9843SFelipe Balbi return 0; 109194ae9843SFelipe Balbi } 109294ae9843SFelipe Balbi 109394ae9843SFelipe Balbi static int fsl_otg_release(struct inode *inode, struct file *file) 109494ae9843SFelipe Balbi { 109594ae9843SFelipe Balbi return 0; 109694ae9843SFelipe Balbi } 109794ae9843SFelipe Balbi 109894ae9843SFelipe Balbi static const struct file_operations otg_fops = { 109994ae9843SFelipe Balbi .owner = THIS_MODULE, 110094ae9843SFelipe Balbi .llseek = NULL, 110194ae9843SFelipe Balbi .read = NULL, 110294ae9843SFelipe Balbi .write = NULL, 110394ae9843SFelipe Balbi .unlocked_ioctl = fsl_otg_ioctl, 110494ae9843SFelipe Balbi .open = fsl_otg_open, 110594ae9843SFelipe Balbi .release = fsl_otg_release, 110694ae9843SFelipe Balbi }; 110794ae9843SFelipe Balbi 110894ae9843SFelipe Balbi static int fsl_otg_probe(struct platform_device *pdev) 110994ae9843SFelipe Balbi { 111094ae9843SFelipe Balbi int ret; 111194ae9843SFelipe Balbi 111219f9e188SJingoo Han if (!dev_get_platdata(&pdev->dev)) 111394ae9843SFelipe Balbi return -ENODEV; 111494ae9843SFelipe Balbi 111594ae9843SFelipe Balbi /* configure the OTG */ 111694ae9843SFelipe Balbi ret = fsl_otg_conf(pdev); 111794ae9843SFelipe Balbi if (ret) { 111894ae9843SFelipe Balbi dev_err(&pdev->dev, "Couldn't configure OTG module\n"); 111994ae9843SFelipe Balbi return ret; 112094ae9843SFelipe Balbi } 112194ae9843SFelipe Balbi 112294ae9843SFelipe Balbi /* start OTG */ 112394ae9843SFelipe Balbi ret = usb_otg_start(pdev); 112494ae9843SFelipe Balbi if (ret) { 112594ae9843SFelipe Balbi dev_err(&pdev->dev, "Can't init FSL OTG device\n"); 112694ae9843SFelipe Balbi return ret; 112794ae9843SFelipe Balbi } 112894ae9843SFelipe Balbi 112994ae9843SFelipe Balbi ret = register_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME, &otg_fops); 113094ae9843SFelipe Balbi if (ret) { 113194ae9843SFelipe Balbi dev_err(&pdev->dev, "unable to register FSL OTG device\n"); 113294ae9843SFelipe Balbi return ret; 113394ae9843SFelipe Balbi } 113494ae9843SFelipe Balbi 113594ae9843SFelipe Balbi ret = device_create_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); 113694ae9843SFelipe Balbi if (ret) 113794ae9843SFelipe Balbi dev_warn(&pdev->dev, "Can't register sysfs attribute\n"); 113894ae9843SFelipe Balbi 113994ae9843SFelipe Balbi return ret; 114094ae9843SFelipe Balbi } 114194ae9843SFelipe Balbi 114294ae9843SFelipe Balbi static int fsl_otg_remove(struct platform_device *pdev) 114394ae9843SFelipe Balbi { 114419f9e188SJingoo Han struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); 114594ae9843SFelipe Balbi 114694ae9843SFelipe Balbi usb_remove_phy(&fsl_otg_dev->phy); 114794ae9843SFelipe Balbi free_irq(fsl_otg_dev->irq, fsl_otg_dev); 114894ae9843SFelipe Balbi 114994ae9843SFelipe Balbi iounmap((void *)usb_dr_regs); 115094ae9843SFelipe Balbi 115194ae9843SFelipe Balbi fsl_otg_uninit_timers(); 115294ae9843SFelipe Balbi kfree(fsl_otg_dev->phy.otg); 115394ae9843SFelipe Balbi kfree(fsl_otg_dev); 115494ae9843SFelipe Balbi 115594ae9843SFelipe Balbi device_remove_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); 115694ae9843SFelipe Balbi 115794ae9843SFelipe Balbi unregister_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME); 115894ae9843SFelipe Balbi 115994ae9843SFelipe Balbi if (pdata->exit) 116094ae9843SFelipe Balbi pdata->exit(pdev); 116194ae9843SFelipe Balbi 116294ae9843SFelipe Balbi return 0; 116394ae9843SFelipe Balbi } 116494ae9843SFelipe Balbi 116594ae9843SFelipe Balbi struct platform_driver fsl_otg_driver = { 116694ae9843SFelipe Balbi .probe = fsl_otg_probe, 116794ae9843SFelipe Balbi .remove = fsl_otg_remove, 116894ae9843SFelipe Balbi .driver = { 116994ae9843SFelipe Balbi .name = driver_name, 117094ae9843SFelipe Balbi .owner = THIS_MODULE, 117194ae9843SFelipe Balbi }, 117294ae9843SFelipe Balbi }; 117394ae9843SFelipe Balbi 117494ae9843SFelipe Balbi module_platform_driver(fsl_otg_driver); 117594ae9843SFelipe Balbi 117694ae9843SFelipe Balbi MODULE_DESCRIPTION(DRIVER_INFO); 117794ae9843SFelipe Balbi MODULE_AUTHOR(DRIVER_AUTHOR); 117894ae9843SFelipe Balbi MODULE_LICENSE("GPL"); 1179