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