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