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