USB: MSM: Drop unsupported drivers

Change-Id: If2acdeab8ac44b328906744587fd55442065556b
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
This commit is contained in:
Manu Gautam 2013-07-26 16:47:56 +05:30 committed by Stephen Boyd
parent e052561593
commit 94e68c66c0
11 changed files with 0 additions and 8344 deletions

View file

@ -1,206 +0,0 @@
/* linux/include/mach/hsusb.h
*
* Copyright (C) 2008 Google, Inc.
* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ASM_ARCH_MSM_HSUSB_H
#define __ASM_ARCH_MSM_HSUSB_H
#include <linux/types.h>
#include <linux/pm_qos.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#define PHY_TYPE_MASK 0x0F
#define PHY_TYPE_MODE 0xF0
#define PHY_MODEL_MASK 0xFF00
#define PHY_TYPE(x) ((x) & PHY_TYPE_MASK)
#define PHY_MODEL(x) ((x) & PHY_MODEL_MASK)
#define USB_PHY_MODEL_65NM 0x100
#define USB_PHY_MODEL_180NM 0x200
#define USB_PHY_MODEL_45NM 0x400
#define USB_PHY_UNDEFINED 0x00
#define USB_PHY_INTEGRATED 0x01
#define USB_PHY_EXTERNAL 0x02
#define USB_PHY_SERIAL_PMIC 0x04
#define REQUEST_STOP 0
#define REQUEST_START 1
#define REQUEST_RESUME 2
#define REQUEST_HNP_SUSPEND 3
#define REQUEST_HNP_RESUME 4
/* Flags required to read ID state of PHY for ACA */
#define PHY_ID_MASK 0xB0
#define PHY_ID_GND 0
#define PHY_ID_C 0x10
#define PHY_ID_B 0x30
#define PHY_ID_A 0x90
#define phy_id_state(ints) ((ints) & PHY_ID_MASK)
#define phy_id_state_gnd(ints) (phy_id_state((ints)) == PHY_ID_GND)
#define phy_id_state_a(ints) (phy_id_state((ints)) == PHY_ID_A)
/* RID_B and RID_C states does not exist with standard ACA */
#ifdef CONFIG_USB_MSM_STANDARD_ACA
#define phy_id_state_b(ints) 0
#define phy_id_state_c(ints) 0
#else
#define phy_id_state_b(ints) (phy_id_state((ints)) == PHY_ID_B)
#define phy_id_state_c(ints) (phy_id_state((ints)) == PHY_ID_C)
#endif
/*
* The following are bit fields describing the usb_request.udc_priv word.
* These bit fields are set by function drivers that wish to queue
* usb_requests with sps/bam parameters.
*/
#define MSM_PIPE_ID_MASK (0x1F)
#define MSM_TX_PIPE_ID_OFS (16)
#define MSM_SPS_MODE BIT(5)
#define MSM_IS_FINITE_TRANSFER BIT(6)
#define MSM_PRODUCER BIT(7)
#define MSM_DISABLE_WB BIT(8)
#define MSM_ETD_IOC BIT(9)
#define MSM_INTERNAL_MEM BIT(10)
#define MSM_VENDOR_ID BIT(16)
/* used to detect the OTG Mode */
enum otg_mode {
OTG_ID = 0, /* ID pin detection */
OTG_USER_CONTROL, /* User configurable */
OTG_VCHG, /* Based on VCHG interrupt */
};
/* used to configure the default mode,if otg_mode is USER_CONTROL */
enum usb_mode {
USB_HOST_MODE,
USB_PERIPHERAL_MODE,
};
enum chg_type {
USB_CHG_TYPE__SDP,
USB_CHG_TYPE__CARKIT,
USB_CHG_TYPE__WALLCHARGER,
USB_CHG_TYPE__INVALID
};
enum pre_emphasis_level {
PRE_EMPHASIS_DEFAULT,
PRE_EMPHASIS_DISABLE,
PRE_EMPHASIS_WITH_10_PERCENT = (1 << 5),
PRE_EMPHASIS_WITH_20_PERCENT = (3 << 4),
};
enum cdr_auto_reset {
CDR_AUTO_RESET_DEFAULT,
CDR_AUTO_RESET_ENABLE,
CDR_AUTO_RESET_DISABLE,
};
enum se1_gate_state {
SE1_GATING_DEFAULT,
SE1_GATING_ENABLE,
SE1_GATING_DISABLE,
};
enum hs_drv_amplitude {
HS_DRV_AMPLITUDE_DEFAULT,
HS_DRV_AMPLITUDE_ZERO_PERCENT,
HS_DRV_AMPLITUDE_25_PERCENTI = (1 << 2),
HS_DRV_AMPLITUDE_5_PERCENT = (1 << 3),
HS_DRV_AMPLITUDE_75_PERCENT = (3 << 2),
};
#define HS_DRV_SLOPE_DEFAULT (-1)
/* used to configure the analog switch to select b/w host and peripheral */
enum usb_switch_control {
USB_SWITCH_PERIPHERAL = 0, /* Configure switch in peripheral mode*/
USB_SWITCH_HOST, /* Host mode */
USB_SWITCH_DISABLE, /* No mode selected, shutdown power */
};
struct msm_hsusb_gadget_platform_data {
int *phy_init_seq;
void (*phy_reset)(void);
int self_powered;
int is_phy_status_timer_on;
bool prop_chg;
};
struct msm_otg_platform_data {
int (*rpc_connect)(int);
int (*phy_reset)(void __iomem *);
int pmic_vbus_irq;
int pmic_id_irq;
/* if usb link is in sps there is no need for
* usb pclk as dayatona fabric clock will be
* used instead
*/
int usb_in_sps;
enum pre_emphasis_level pemp_level;
enum cdr_auto_reset cdr_autoreset;
enum hs_drv_amplitude drv_ampl;
enum se1_gate_state se1_gating;
int hsdrvslope;
int phy_reset_sig_inverted;
int phy_can_powercollapse;
int pclk_required_during_lpm;
int bam_disable;
/* HSUSB core in 8660 has the capability to gate the
* pclk when not being used. Though this feature is
* now being disabled because of H/w issues
*/
int pclk_is_hw_gated;
int (*ldo_init) (int init);
int (*ldo_enable) (int enable);
int (*ldo_set_voltage) (int mV);
u32 swfi_latency;
/* pmic notfications apis */
int (*pmic_vbus_notif_init) (void (*callback)(int online), int init);
int (*pmic_id_notif_init) (void (*callback)(int online), int init);
int (*phy_id_setup_init) (int init);
int (*pmic_register_vbus_sn) (void (*callback)(int online));
void (*pmic_unregister_vbus_sn) (void (*callback)(int online));
int (*pmic_enable_ldo) (int);
int (*init_gpio)(int on);
void (*setup_gpio)(enum usb_switch_control mode);
u8 otg_mode;
u8 usb_mode;
void (*vbus_power) (unsigned phy_info, int on);
/* charger notification apis */
void (*chg_connected)(enum chg_type chg_type);
void (*chg_vbus_draw)(unsigned ma);
int (*chg_init)(int init);
int (*config_vddcx)(int high);
int (*init_vddcx)(int init);
struct pm_qos_request pm_qos_req_dma;
};
struct msm_usb_host_platform_data {
unsigned phy_info;
unsigned int power_budget;
void (*config_gpio)(unsigned int config);
void (*vbus_power) (unsigned phy_info, int on);
int (*vbus_init)(int init);
struct clk *ebi1_clk;
};
#endif

View file

@ -1,288 +0,0 @@
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__
#define __LINUX_USB_GADGET_MSM72K_UDC_H__
#define USB_ID (MSM_USB_BASE + 0x0000)
#define USB_HWGENERAL (MSM_USB_BASE + 0x0004)
#define USB_HWHOST (MSM_USB_BASE + 0x0008)
#define USB_HWDEVICE (MSM_USB_BASE + 0x000C)
#define USB_HWTXBUF (MSM_USB_BASE + 0x0010)
#define USB_HWRXBUF (MSM_USB_BASE + 0x0014)
#define USB_AHB_BURST (MSM_USB_BASE + 0x0090)
#define USB_AHB_MODE (MSM_USB_BASE + 0x0098)
#define USB_GEN_CONFIG (MSM_USB_BASE + 0x009C)
#define USB_BAM_DISABLE (1 << 13)
#define USB_ROC_AHB_MODE (MSM_USB_BASE + 0x0090)
#define USB_SBUSCFG (MSM_USB_BASE + 0x0090)
#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */
#define USB_HCIVERSION (MSM_USB_BASE + 0x0102) /* 16 bit */
#define USB_HCSPARAMS (MSM_USB_BASE + 0x0104)
#define USB_HCCPARAMS (MSM_USB_BASE + 0x0108)
#define USB_DCIVERSION (MSM_USB_BASE + 0x0120) /* 16 bit */
#define USB_USBCMD (MSM_USB_BASE + 0x0140)
#define USB_USBSTS (MSM_USB_BASE + 0x0144)
#define USB_USBINTR (MSM_USB_BASE + 0x0148)
#define USB_FRINDEX (MSM_USB_BASE + 0x014C)
#define USB_DEVICEADDR (MSM_USB_BASE + 0x0154)
#define USB_ENDPOINTLISTADDR (MSM_USB_BASE + 0x0158)
#define USB_BURSTSIZE (MSM_USB_BASE + 0x0160)
#define USB_TXFILLTUNING (MSM_USB_BASE + 0x0164)
#define USB_ULPI_VIEWPORT (MSM_USB_BASE + 0x0170)
#define USB_ENDPTNAK (MSM_USB_BASE + 0x0178)
#define USB_ENDPTNAKEN (MSM_USB_BASE + 0x017C)
#define USB_PORTSC (MSM_USB_BASE + 0x0184)
#define USB_OTGSC (MSM_USB_BASE + 0x01A4)
#define USB_USBMODE (MSM_USB_BASE + 0x01A8)
#define USB_ENDPTSETUPSTAT (MSM_USB_BASE + 0x01AC)
#define USB_ENDPTPRIME (MSM_USB_BASE + 0x01B0)
#define USB_ENDPTFLUSH (MSM_USB_BASE + 0x01B4)
#define USB_ENDPTSTAT (MSM_USB_BASE + 0x01B8)
#define USB_ENDPTCOMPLETE (MSM_USB_BASE + 0x01BC)
#define USB_ENDPTCTRL(n) (MSM_USB_BASE + 0x01C0 + (4 * (n)))
#define USBCMD_RESET 2
#define USBCMD_ATTACH 1
#define USBCMD_RS (1 << 0) /* run/stop bit */
#define USBCMD_ATDTW (1 << 14)
#define USBCMD_ITC(n) (n << 16)
#define USBCMD_ITC_MASK (0xFF << 16)
#define ASYNC_INTR_CTRL (1 << 29)
#define ULPI_STP_CTRL (1 << 30)
#define USBMODE_DEVICE 2
#define USBMODE_HOST 3
#define USBMODE_VBUS (1 << 5) /* vbus power select */
/* Redefining SDIS bit as it defined incorrectly in ehci.h. */
#ifdef USBMODE_SDIS
#undef USBMODE_SDIS
#endif
#define USBMODE_SDIS (1 << 4) /* stream disable */
struct ept_queue_head {
unsigned config;
unsigned active; /* read-only */
unsigned next;
unsigned info;
unsigned page0;
unsigned page1;
unsigned page2;
unsigned page3;
unsigned page4;
unsigned reserved_0;
unsigned char setup_data[8];
unsigned reserved_1;
unsigned reserved_2;
unsigned reserved_3;
unsigned reserved_4;
};
#define CONFIG_MAX_PKT(n) ((n) << 16)
#define CONFIG_ZLT (1 << 29) /* stop on zero-len xfer */
#define CONFIG_IOS (1 << 15) /* IRQ on setup */
#define CONFIG_MULT (3 << 30)
#define CONFIG_MULT_SHIFT 11
struct ept_queue_item {
unsigned next;
unsigned info;
unsigned page0;
unsigned page1;
unsigned page2;
unsigned page3;
unsigned page4;
unsigned reserved;
};
#define TERMINATE 1
#define INFO_BYTES(n) ((n) << 16)
#define INFO_IOC (1 << 15)
#define INFO_ACTIVE (1 << 7)
#define INFO_HALTED (1 << 6)
#define INFO_BUFFER_ERROR (1 << 5)
#define INFO_TXN_ERROR (1 << 3)
#define STS_NAKI (1 << 16) /* */
#define STS_SLI (1 << 8) /* R/WC - suspend state entered */
#define STS_SRI (1 << 7) /* R/WC - SOF recv'd */
#define STS_URI (1 << 6) /* R/WC - RESET recv'd */
#define STS_FRI (1 << 3) /* R/WC - Frame List Rollover */
#define STS_PCI (1 << 2) /* R/WC - Port Change Detect */
#define STS_UEI (1 << 1) /* R/WC - USB Error */
#define STS_UI (1 << 0) /* R/WC - USB Transaction Complete */
/* bits used in all the endpoint status registers */
#define EPT_TX(n) (1 << ((n) + 16))
#define EPT_RX(n) (1 << (n))
#define CTRL_TXE (1 << 23)
#define CTRL_TXR (1 << 22)
#define CTRL_TXI (1 << 21)
#define CTRL_TXD (1 << 17)
#define CTRL_TXS (1 << 16)
#define CTRL_RXE (1 << 7)
#define CTRL_RXR (1 << 6)
#define CTRL_RXI (1 << 5)
#define CTRL_RXD (1 << 1)
#define CTRL_RXS (1 << 0)
#define CTRL_TXT_MASK (3 << 18)
#define CTRL_TXT_CTRL (0 << 18)
#define CTRL_TXT_ISOCH (1 << 18)
#define CTRL_TXT_BULK (2 << 18)
#define CTRL_TXT_INT (3 << 18)
#define CTRL_TXT_EP_TYPE_SHIFT 18
#define CTRL_RXT_MASK (3 << 2)
#define CTRL_RXT_CTRL (0 << 2)
#define CTRL_RXT_ISOCH (1 << 2)
#define CTRL_RXT_BULK (2 << 2)
#define CTRL_RXT_INT (3 << 2)
#define CTRL_RXT_EP_TYPE_SHIFT 2
#define ULPI_CONFIG_REG 0x31
#if (defined(CONFIG_ARCH_MSM7X27) && !defined(CONFIG_ARCH_MSM7X27A)) \
|| defined(CONFIG_ARCH_QSD8X50)
#define ULPI_DIGOUT_CTRL 0X31
#define ULPI_CDR_AUTORESET (1 << 5)
#else
#define ULPI_DIGOUT_CTRL 0X36
#define ULPI_CDR_AUTORESET (1 << 1)
#endif
#define ULPI_SE1_GATE (1 << 2)
#define ULPI_CONFIG_REG1 0x30
#define ULPI_CONFIG_REG2 0X31
#define ULPI_CONFIG_REG3 0X32
#define ULPI_IFC_CTRL_CLR 0x09
#define ULPI_AMPLITUDE_MAX 0x0C
#define ULPI_OTG_CTRL 0x0B
#define ULPI_OTG_CTRL_CLR 0x0C
#define ULPI_INT_RISE_CLR 0x0F
#define ULPI_INT_FALL_CLR 0x12
#define ULPI_PRE_EMPHASIS_MASK (3 << 4)
#define ULPI_HSDRVSLOPE_MASK (0x0F)
#define ULPI_DRV_AMPL_MASK (3 << 2)
#define ULPI_ONCLOCK (1 << 6)
#define ULPI_IDPU (1 << 0)
#define ULPI_HOST_DISCONNECT (1 << 0)
#define ULPI_VBUS_VALID (1 << 1)
#define ULPI_SESS_END (1 << 3)
#define ULPI_ID_GND (1 << 4)
#define ULPI_WAKEUP (1 << 31)
#define ULPI_RUN (1 << 30)
#define ULPI_WRITE (1 << 29)
#define ULPI_READ (0 << 29)
#define ULPI_STATE_NORMAL (1 << 27)
#define ULPI_ADDR(n) (((n) & 255) << 16)
#define ULPI_DATA(n) ((n) & 255)
#define ULPI_DATA_READ(n) (((n) >> 8) & 255)
/* USB_PORTSC bits for determining port speed */
#define PORTSC_PSPD_FS (0 << 26)
#define PORTSC_PSPD_LS (1 << 26)
#define PORTSC_PSPD_HS (2 << 26)
#define PORTSC_PSPD_MASK (3 << 26)
#define OTGSC_BSVIE (1 << 27) /* R/W - BSV Interrupt Enable */
#define OTGSC_DPIE (1 << 30) /* R/W - DataPulse Interrupt Enable */
#define OTGSC_1MSE (1 << 29) /* R/W - 1ms Interrupt Enable */
#define OTGSC_BSEIE (1 << 28) /* R/W - BSE Interrupt Enable */
#define OTGSC_ASVIE (1 << 26) /* R/W - ASV Interrupt Enable */
#define OTGSC_ASEIE (1 << 25) /* R/W - ASE Interrupt Enable */
#define OTGSC_IDIE (1 << 24) /* R/W - ID Interrupt Enable */
#define OTGSC_BSVIS (1 << 19) /* R/W - BSV Interrupt Status */
#define OTGSC_IDPU (1 << 5)
#define OTGSC_ID (1 << 8)
#define OTGSC_IDIS (1 << 16)
#define B_SESSION_VALID (1 << 11)
#define OTGSC_INTR_MASK (OTGSC_BSVIE | OTGSC_DPIE | OTGSC_1MSE | \
OTGSC_BSEIE | OTGSC_ASVIE | OTGSC_ASEIE | \
OTGSC_IDIE)
#define OTGSC_INTR_STS_MASK (0x7f << 16)
#define CURRENT_CONNECT_STATUS (1 << 0)
#define PORTSC_FPR (1 << 6) /* R/W - State normal => suspend */
#define PORTSC_SUSP (1 << 7) /* Read - Port in suspend state */
#define PORTSC_LS (3 << 10) /* Read - Port's Line status */
#define PORTSC_PHCD (1 << 23) /* phy suspend mode */
#define PORTSC_CCS (1 << 0) /* current connect status */
#define PORTSC_PORT_RESET 0x00000100
#define PORTSC_PTS (3 << 30)
#define PORTSC_PTS_ULPI (2 << 30)
#define PORTSC_PTS_SERIAL (3 << 30)
#define PORTSC_PORT_SPEED_FULL 0x00000000
#define PORTSC_PORT_SPEED_LOW 0x04000000
#define PORTSC_PORT_SPEED_HIGH 0x08000000
#define PORTSC_PORT_SPEED_MASK 0x0c000000
#define SBUSCFG_AHBBRST_INCR4 0x01
#define ULPI_USBINTR_ENABLE_RASING_C 0x0F
#define ULPI_USBINTR_ENABLE_FALLING_C 0x12
#define ULPI_USBINTR_STATUS 0x13
#define ULPI_USBINTR_ENABLE_RASING_S 0x0E
#define ULPI_USBINTR_ENABLE_FALLING_S 0x11
#define ULPI_SESSION_END_RAISE (1 << 3)
#define ULPI_SESSION_END_FALL (1 << 3)
#define ULPI_SESSION_VALID_RAISE (1 << 2)
#define ULPI_SESSION_VALID_FALL (1 << 2)
#define ULPI_VBUS_VALID_RAISE (1 << 1)
#define ULPI_VBUS_VALID_FALL (1 << 1)
#define ULPI_CHG_DETECT_REG 0x34
/* control charger detection by ULPI or externally */
#define ULPI_EXTCHGCTRL_65NM (1 << 2)
#define ULPI_EXTCHGCTRL_180NM (1 << 3)
/* charger detection power on control */
#define ULPI_CHGDETON (1 << 1)
/* enable charger detection */
#define ULPI_CHGDETEN (1 << 0)
#define ULPI_CHGTYPE_65NM (1 << 3)
#define ULPI_CHGTYPE_180NM (1 << 4)
/* test mode support */
#define J_TEST (0x0100)
#define K_TEST (0x0200)
#define SE0_NAK_TEST (0x0300)
#define TST_PKT_TEST (0x0400)
#define PORTSC_PTC (0xf << 16)
#define PORTSC_PTC_J_STATE (0x01 << 16)
#define PORTSC_PTC_K_STATE (0x02 << 16)
#define PORTSC_PTC_SE0_NAK (0x03 << 16)
#define PORTSC_PTC_TST_PKT (0x04 << 16)
#define USBH (1 << 15)
#define USB_PHY (1 << 18)
#define ULPI_DEBUG 0x15
#define ULPI_FUNC_CTRL_CLR 0x06
#define ULPI_SUSPENDM (1 << 6)
#define ULPI_CLOCK_SUSPENDM (1 << 3)
#define ULPI_CALIB_STS (1 << 7)
#define ULPI_CALIB_VAL(x) (x & 0x7C)
#endif /* __LINUX_USB_GADGET_MSM72K_UDC_H__ */

View file

@ -1,99 +0,0 @@
/* linux/include/mach/rpc_hsusb.h
*
* Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
*
* All source code in this file is licensed under the following license except
* where indicated.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can find it at http://www.fsf.org
*/
#ifndef __ASM_ARCH_MSM_RPC_HSUSB_H
#define __ASM_ARCH_MSM_RPC_HSUSB_H
#include <mach/msm_rpcrouter.h>
#include <mach/msm_otg.h>
#include <mach/msm_hsusb.h>
#if defined(CONFIG_MSM_ONCRPCROUTER) && !defined(CONFIG_ARCH_MSM8X60)
int msm_hsusb_rpc_connect(void);
int msm_hsusb_phy_reset(void);
int msm_hsusb_vbus_powerup(void);
int msm_hsusb_vbus_shutdown(void);
int msm_hsusb_reset_rework_installed(void);
int msm_hsusb_enable_pmic_ulpidata0(void);
int msm_hsusb_disable_pmic_ulpidata0(void);
int msm_hsusb_rpc_close(void);
int msm_chg_rpc_connect(void);
int msm_chg_usb_charger_connected(uint32_t type);
int msm_chg_usb_i_is_available(uint32_t sample);
int msm_chg_usb_i_is_not_available(void);
int msm_chg_usb_charger_disconnected(void);
int msm_chg_rpc_close(void);
#ifdef CONFIG_USB_MSM_72K
int hsusb_chg_init(int connect);
void hsusb_chg_vbus_draw(unsigned mA);
void hsusb_chg_connected(enum chg_type chgtype);
#endif
int msm_fsusb_rpc_init(struct msm_otg_ops *ops);
int msm_fsusb_init_phy(void);
int msm_fsusb_reset_phy(void);
int msm_fsusb_suspend_phy(void);
int msm_fsusb_resume_phy(void);
int msm_fsusb_rpc_close(void);
int msm_fsusb_remote_dev_disconnected(void);
int msm_fsusb_set_remote_wakeup(void);
void msm_fsusb_rpc_deinit(void);
/* wrapper to send pid and serial# info to bootloader */
int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum);
#else
static inline int msm_hsusb_rpc_connect(void) { return 0; }
static inline int msm_hsusb_phy_reset(void) { return 0; }
static inline int msm_hsusb_vbus_powerup(void) { return 0; }
static inline int msm_hsusb_vbus_shutdown(void) { return 0; }
static inline int msm_hsusb_reset_rework_installed(void) { return 0; }
static inline int msm_hsusb_enable_pmic_ulpidata0(void) { return 0; }
static inline int msm_hsusb_disable_pmic_ulpidata0(void) { return 0; }
static inline int msm_hsusb_rpc_close(void) { return 0; }
static inline int msm_chg_rpc_connect(void) { return 0; }
static inline int msm_chg_usb_charger_connected(uint32_t type) { return 0; }
static inline int msm_chg_usb_i_is_available(uint32_t sample) { return 0; }
static inline int msm_chg_usb_i_is_not_available(void) { return 0; }
static inline int msm_chg_usb_charger_disconnected(void) { return 0; }
static inline int msm_chg_rpc_close(void) { return 0; }
#ifdef CONFIG_USB_MSM_72K
static inline int hsusb_chg_init(int connect) { return 0; }
static inline void hsusb_chg_vbus_draw(unsigned mA) { }
static inline void hsusb_chg_connected(enum chg_type chgtype) { }
#endif
static inline int msm_fsusb_rpc_init(struct msm_otg_ops *ops) { return 0; }
static inline int msm_fsusb_init_phy(void) { return 0; }
static inline int msm_fsusb_reset_phy(void) { return 0; }
static inline int msm_fsusb_suspend_phy(void) { return 0; }
static inline int msm_fsusb_resume_phy(void) { return 0; }
static inline int msm_fsusb_rpc_close(void) { return 0; }
static inline int msm_fsusb_remote_dev_disconnected(void) { return 0; }
static inline int msm_fsusb_set_remote_wakeup(void) { return 0; }
static inline void msm_fsusb_rpc_deinit(void) { }
static inline int
usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum) { return 0; }
#endif
#endif

View file

@ -1,244 +0,0 @@
/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/err.h>
#include <linux/module.h>
#include <mach/rpc_hsusb.h>
#include <mach/msm_hsusb.h>
#include <mach/msm_rpcrouter.h>
#include <mach/board.h>
#define PM_APP_OTG_PROG 0x30000080
#define PM_APP_OTG_VERS 0x00010001
#define PM_APP_OTG_INIT_PHY 17
#define PM_APP_OTG_RESET_PHY 18
#define PM_APP_OTG_SUSPEND_PHY 7
#define PM_APP_OTG_RESUME_PHY 8
#define PM_APP_OTG_DEV_DISCONNECTED 9
#define PM_APP_OTG_SET_WAKEUP 10
#define PM_APP_OTG_ACQUIRE_BUS 3
#define PM_APP_OTG_RELINQUISH_BUS 4
#define PM_APP_OTG_INIT_DONE_CB_PROC 1
#define PM_APP_OTG_HOST_INIT_CB_PROC 3
#define PM_APP_OTG_REMOTE_DEV_LOST_CB_PROC 8
#define PM_APP_OTG_REMOTE_DEV_RESUMED_CB_PROC 9
#define PM_APP_OTG_ERROR_NOTIFY_CB_PROC 11
#define NUM_OF_CALLBACKS 11
static struct msm_rpc_client *client;
static struct msm_otg_ops *host_ops;
static int msm_fsusb_rpc_arg(struct msm_rpc_client *client,
void *buf, void *data)
{
int i, size = 0;
uint32_t proc = *(uint32_t *)data;
switch (proc) {
case PM_APP_OTG_INIT_PHY: {
for (i = 0; i < NUM_OF_CALLBACKS; i++) {
*((uint32_t *)buf) = cpu_to_be32(0x11111111);
size += sizeof(uint32_t);
buf += sizeof(uint32_t);
}
/* sleep_assert callback fucntion will be registered locally*/
*((uint32_t *)buf) = cpu_to_be32(0xffffffff);
size += sizeof(uint32_t);
break;
}
case PM_APP_OTG_SET_WAKEUP: {
*((uint32_t *)buf) = cpu_to_be32(1);
size += sizeof(uint32_t);
break;
}
case PM_APP_OTG_ACQUIRE_BUS: {
*((uint32_t *)buf) = cpu_to_be32(0xffffffff);
size += sizeof(uint32_t);
break;
}
default:
pr_info("%s: No arguments expected\n", __func__);
}
return size;
}
int msm_fsusb_init_phy(void)
{
uint32_t data = PM_APP_OTG_INIT_PHY;
return msm_rpc_client_req(client,
PM_APP_OTG_INIT_PHY,
msm_fsusb_rpc_arg, &data,
NULL, NULL, -1);
}
EXPORT_SYMBOL(msm_fsusb_init_phy);
int msm_fsusb_reset_phy(void)
{
return msm_rpc_client_req(client,
PM_APP_OTG_RESET_PHY,
NULL, NULL,
NULL, NULL, -1);
}
EXPORT_SYMBOL(msm_fsusb_reset_phy);
int msm_fsusb_suspend_phy(void)
{
return msm_rpc_client_req(client,
PM_APP_OTG_SUSPEND_PHY,
NULL, NULL,
NULL, NULL, -1);
}
EXPORT_SYMBOL(msm_fsusb_suspend_phy);
int msm_fsusb_resume_phy(void)
{
return msm_rpc_client_req(client,
PM_APP_OTG_RESUME_PHY,
NULL, NULL,
NULL, NULL, -1);
}
EXPORT_SYMBOL(msm_fsusb_resume_phy);
int msm_fsusb_remote_dev_disconnected(void)
{
return msm_rpc_client_req(client,
PM_APP_OTG_DEV_DISCONNECTED,
NULL, NULL,
NULL, NULL, -1);
}
EXPORT_SYMBOL(msm_fsusb_remote_dev_disconnected);
int msm_fsusb_set_remote_wakeup(void)
{
uint32_t data = PM_APP_OTG_SET_WAKEUP;
return msm_rpc_client_req(client,
PM_APP_OTG_SET_WAKEUP,
msm_fsusb_rpc_arg, &data,
NULL, NULL, -1);
}
EXPORT_SYMBOL(msm_fsusb_set_remote_wakeup);
static int msm_fsusb_acquire_bus(void)
{
uint32_t data = PM_APP_OTG_ACQUIRE_BUS;
return msm_rpc_client_req(client,
PM_APP_OTG_ACQUIRE_BUS,
msm_fsusb_rpc_arg, &data,
NULL, NULL, -1);
}
static int msm_fsusb_relinquish_bus(void)
{
return msm_rpc_client_req(client,
PM_APP_OTG_RELINQUISH_BUS,
NULL, NULL,
NULL, NULL, -1);
}
static void msm_fsusb_request_session(void)
{
int ret;
ret = msm_fsusb_relinquish_bus();
if (ret < 0)
pr_err("relinquish_bus rpc failed\n");
ret = msm_fsusb_acquire_bus();
if (ret < 0)
pr_err("acquire_bus rpc failed\n");
}
static int msm_fsusb_cb_func(struct msm_rpc_client *client,
void *buffer, int in_size)
{
struct rpc_request_hdr *req;
int rc;
req = buffer;
msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid),
RPC_ACCEPTSTAT_SUCCESS);
rc = msm_rpc_send_accepted_reply(client, 0);
if (rc) {
pr_err("%s: sending reply failed: %d\n", __func__, rc);
return rc;
}
switch (be32_to_cpu(req->procedure)) {
case PM_APP_OTG_INIT_DONE_CB_PROC: {
pr_debug("pm_app_otg_init_done callback received");
msm_fsusb_request_session();
break;
}
case PM_APP_OTG_HOST_INIT_CB_PROC: {
pr_debug("pm_app_otg_host_init_cb_proc callback received");
host_ops->request(host_ops->handle, REQUEST_START);
break;
}
case PM_APP_OTG_REMOTE_DEV_LOST_CB_PROC: {
pr_debug("pm_app_otg_remote_dev_lost_cb_proc"
" callback received");
msm_fsusb_acquire_bus();
host_ops->request(host_ops->handle, REQUEST_STOP);
break;
}
case PM_APP_OTG_REMOTE_DEV_RESUMED_CB_PROC: {
pr_debug("pm_app_otg_remote_dev_resumed_cb_proc"
"callback received");
host_ops->request(host_ops->handle, REQUEST_RESUME);
break;
}
case PM_APP_OTG_ERROR_NOTIFY_CB_PROC: {
pr_err("pm_app_otg_error_notify_cb_proc callback received");
break;
}
default:
pr_err("%s: unknown callback(proc = %d) received\n",
__func__, req->procedure);
}
return 0;
}
int msm_fsusb_rpc_init(struct msm_otg_ops *ops)
{
host_ops = ops;
client = msm_rpc_register_client("fsusb",
PM_APP_OTG_PROG,
PM_APP_OTG_VERS, 1,
msm_fsusb_cb_func);
if (IS_ERR(client)) {
pr_err("%s: couldn't open rpc client\n", __func__);
return PTR_ERR(client);
}
return 0;
}
EXPORT_SYMBOL(msm_fsusb_rpc_init);
void msm_fsusb_rpc_deinit(void)
{
msm_rpc_unregister_client(client);
}
EXPORT_SYMBOL(msm_fsusb_rpc_deinit);

View file

@ -1,660 +0,0 @@
/* linux/arch/arm/mach-msm/rpc_hsusb.c
*
* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
*
* All source code in this file is licensed under the following license except
* where indicated.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can find it at http://www.fsf.org
*/
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <mach/rpc_hsusb.h>
#include <asm/mach-types.h>
static struct msm_rpc_endpoint *usb_ep;
static struct msm_rpc_endpoint *chg_ep;
#define MSM_RPC_CHG_PROG 0x3000001a
struct msm_chg_rpc_ids {
unsigned long vers_comp;
unsigned chg_usb_charger_connected_proc;
unsigned chg_usb_charger_disconnected_proc;
unsigned chg_usb_i_is_available_proc;
unsigned chg_usb_i_is_not_available_proc;
};
struct msm_hsusb_rpc_ids {
unsigned long prog;
unsigned long vers_comp;
unsigned long init_phy;
unsigned long vbus_pwr_up;
unsigned long vbus_pwr_down;
unsigned long update_product_id;
unsigned long update_serial_num;
unsigned long update_is_serial_num_null;
unsigned long reset_rework_installed;
unsigned long enable_pmic_ulpi_data0;
unsigned long disable_pmic_ulpi_data0;
};
static struct msm_hsusb_rpc_ids usb_rpc_ids;
static struct msm_chg_rpc_ids chg_rpc_ids;
static int msm_hsusb_init_rpc_ids(unsigned long vers)
{
if (vers == 0x00010001) {
usb_rpc_ids.prog = 0x30000064;
usb_rpc_ids.vers_comp = 0x00010001;
usb_rpc_ids.init_phy = 2;
usb_rpc_ids.vbus_pwr_up = 6;
usb_rpc_ids.vbus_pwr_down = 7;
usb_rpc_ids.update_product_id = 8;
usb_rpc_ids.update_serial_num = 9;
usb_rpc_ids.update_is_serial_num_null = 10;
usb_rpc_ids.reset_rework_installed = 17;
usb_rpc_ids.enable_pmic_ulpi_data0 = 18;
usb_rpc_ids.disable_pmic_ulpi_data0 = 19;
return 0;
} else if (vers == 0x00010002) {
usb_rpc_ids.prog = 0x30000064;
usb_rpc_ids.vers_comp = 0x00010002;
usb_rpc_ids.init_phy = 2;
usb_rpc_ids.vbus_pwr_up = 6;
usb_rpc_ids.vbus_pwr_down = 7;
usb_rpc_ids.update_product_id = 8;
usb_rpc_ids.update_serial_num = 9;
usb_rpc_ids.update_is_serial_num_null = 10;
usb_rpc_ids.reset_rework_installed = 17;
usb_rpc_ids.enable_pmic_ulpi_data0 = 18;
usb_rpc_ids.disable_pmic_ulpi_data0 = 19;
return 0;
} else {
pr_err("%s: no matches found for version\n",
__func__);
return -ENODATA;
}
}
static int msm_chg_init_rpc(unsigned long vers)
{
if (((vers & RPC_VERSION_MAJOR_MASK) == 0x00010000) ||
((vers & RPC_VERSION_MAJOR_MASK) == 0x00020000) ||
((vers & RPC_VERSION_MAJOR_MASK) == 0x00030000) ||
((vers & RPC_VERSION_MAJOR_MASK) == 0x00040000)) {
chg_ep = msm_rpc_connect_compatible(MSM_RPC_CHG_PROG, vers,
MSM_RPC_UNINTERRUPTIBLE);
if (IS_ERR(chg_ep))
return -ENODATA;
chg_rpc_ids.vers_comp = vers;
chg_rpc_ids.chg_usb_charger_connected_proc = 7;
chg_rpc_ids.chg_usb_charger_disconnected_proc = 8;
chg_rpc_ids.chg_usb_i_is_available_proc = 9;
chg_rpc_ids.chg_usb_i_is_not_available_proc = 10;
return 0;
} else
return -ENODATA;
}
/* rpc connect for hsusb */
int msm_hsusb_rpc_connect(void)
{
if (usb_ep && !IS_ERR(usb_ep)) {
pr_debug("%s: usb_ep already connected\n", __func__);
return 0;
}
/* Initialize rpc ids */
if (msm_hsusb_init_rpc_ids(0x00010001)) {
pr_err("%s: rpc ids initialization failed\n"
, __func__);
return -ENODATA;
}
usb_ep = msm_rpc_connect_compatible(usb_rpc_ids.prog,
usb_rpc_ids.vers_comp,
MSM_RPC_UNINTERRUPTIBLE);
if (IS_ERR(usb_ep)) {
pr_err("%s: connect compatible failed vers = %lx\n",
__func__, usb_rpc_ids.vers_comp);
/* Initialize rpc ids */
if (msm_hsusb_init_rpc_ids(0x00010002)) {
pr_err("%s: rpc ids initialization failed\n",
__func__);
return -ENODATA;
}
usb_ep = msm_rpc_connect_compatible(usb_rpc_ids.prog,
usb_rpc_ids.vers_comp,
MSM_RPC_UNINTERRUPTIBLE);
}
if (IS_ERR(usb_ep)) {
pr_err("%s: connect compatible failed vers = %lx\n",
__func__, usb_rpc_ids.vers_comp);
return -EAGAIN;
} else
pr_debug("%s: rpc connect success vers = %lx\n",
__func__, usb_rpc_ids.vers_comp);
return 0;
}
EXPORT_SYMBOL(msm_hsusb_rpc_connect);
/* rpc connect for charging */
int msm_chg_rpc_connect(void)
{
uint32_t chg_vers;
if (machine_is_msm7x27_surf() || machine_is_qsd8x50_surf())
return -ENOTSUPP;
if (chg_ep && !IS_ERR(chg_ep)) {
pr_debug("%s: chg_ep already connected\n", __func__);
return 0;
}
chg_vers = 0x00040001;
if (!msm_chg_init_rpc(chg_vers))
goto chg_found;
chg_vers = 0x00030001;
if (!msm_chg_init_rpc(chg_vers))
goto chg_found;
chg_vers = 0x00020001;
if (!msm_chg_init_rpc(chg_vers))
goto chg_found;
chg_vers = 0x00010001;
if (!msm_chg_init_rpc(chg_vers))
goto chg_found;
pr_err("%s: connect compatible failed \n",
__func__);
return -EAGAIN;
chg_found:
pr_debug("%s: connected to rpc vers = %x\n",
__func__, chg_vers);
return 0;
}
EXPORT_SYMBOL(msm_chg_rpc_connect);
/* rpc call for phy_reset */
int msm_hsusb_phy_reset(void)
{
int rc = 0;
struct hsusb_phy_start_req {
struct rpc_request_hdr hdr;
} req;
if (!usb_ep || IS_ERR(usb_ep)) {
pr_err("%s: phy_reset rpc failed before call,"
"rc = %ld\n", __func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
rc = msm_rpc_call(usb_ep, usb_rpc_ids.init_phy,
&req, sizeof(req), 5 * HZ);
if (rc < 0) {
pr_err("%s: phy_reset rpc failed! rc = %d\n",
__func__, rc);
} else
pr_debug("msm_hsusb_phy_reset\n");
return rc;
}
EXPORT_SYMBOL(msm_hsusb_phy_reset);
/* rpc call for vbus powerup */
int msm_hsusb_vbus_powerup(void)
{
int rc = 0;
struct hsusb_phy_start_req {
struct rpc_request_hdr hdr;
} req;
if (!usb_ep || IS_ERR(usb_ep)) {
pr_err("%s: vbus_powerup rpc failed before call,"
"rc = %ld\n", __func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
rc = msm_rpc_call(usb_ep, usb_rpc_ids.vbus_pwr_up,
&req, sizeof(req), 5 * HZ);
if (rc < 0) {
pr_err("%s: vbus_powerup failed! rc = %d\n",
__func__, rc);
} else
pr_debug("msm_hsusb_vbus_powerup\n");
return rc;
}
EXPORT_SYMBOL(msm_hsusb_vbus_powerup);
/* rpc call for vbus shutdown */
int msm_hsusb_vbus_shutdown(void)
{
int rc = 0;
struct hsusb_phy_start_req {
struct rpc_request_hdr hdr;
} req;
if (!usb_ep || IS_ERR(usb_ep)) {
pr_err("%s: vbus_shutdown rpc failed before call,"
"rc = %ld\n", __func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
rc = msm_rpc_call(usb_ep, usb_rpc_ids.vbus_pwr_down,
&req, sizeof(req), 5 * HZ);
if (rc < 0) {
pr_err("%s: vbus_shutdown failed! rc = %d\n",
__func__, rc);
} else
pr_debug("msm_hsusb_vbus_shutdown\n");
return rc;
}
EXPORT_SYMBOL(msm_hsusb_vbus_shutdown);
int msm_hsusb_send_productID(uint32_t product_id)
{
int rc = 0;
struct hsusb_phy_start_req {
struct rpc_request_hdr hdr;
uint32_t product_id;
} req;
if (!usb_ep || IS_ERR(usb_ep)) {
pr_err("%s: rpc connect failed: rc = %ld\n",
__func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
req.product_id = cpu_to_be32(product_id);
rc = msm_rpc_call(usb_ep, usb_rpc_ids.update_product_id,
&req, sizeof(req),
5 * HZ);
if (rc < 0)
pr_err("%s: rpc call failed! error: %d\n",
__func__, rc);
else
pr_debug("%s: rpc call success\n" , __func__);
return rc;
}
EXPORT_SYMBOL(msm_hsusb_send_productID);
int msm_hsusb_send_serial_number(const char *serial_number)
{
int rc = 0, serial_len, rlen;
struct hsusb_send_sn_req {
struct rpc_request_hdr hdr;
uint32_t length;
char sn[0];
} *req;
if (!usb_ep || IS_ERR(usb_ep)) {
pr_err("%s: rpc connect failed: rc = %ld\n",
__func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
/*
* USB driver passes null terminated string to us. Modem processor
* expects serial number to be 32 bit aligned.
*/
serial_len = strlen(serial_number)+1;
rlen = sizeof(struct rpc_request_hdr) + sizeof(uint32_t) +
((serial_len + 3) & ~3);
req = kmalloc(rlen, GFP_KERNEL);
if (!req)
return -ENOMEM;
req->length = cpu_to_be32(serial_len);
strncpy(req->sn , serial_number, serial_len);
rc = msm_rpc_call(usb_ep, usb_rpc_ids.update_serial_num,
req, rlen, 5 * HZ);
if (rc < 0)
pr_err("%s: rpc call failed! error: %d\n",
__func__, rc);
else
pr_debug("%s: rpc call success\n", __func__);
kfree(req);
return rc;
}
EXPORT_SYMBOL(msm_hsusb_send_serial_number);
int msm_hsusb_is_serial_num_null(uint32_t val)
{
int rc = 0;
struct hsusb_phy_start_req {
struct rpc_request_hdr hdr;
uint32_t value;
} req;
if (!usb_ep || IS_ERR(usb_ep)) {
pr_err("%s: rpc connect failed: rc = %ld\n",
__func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
if (!usb_rpc_ids.update_is_serial_num_null) {
pr_err("%s: proc id not supported \n", __func__);
return -ENODATA;
}
req.value = cpu_to_be32(val);
rc = msm_rpc_call(usb_ep, usb_rpc_ids.update_is_serial_num_null,
&req, sizeof(req),
5 * HZ);
if (rc < 0)
pr_err("%s: rpc call failed! error: %d\n" ,
__func__, rc);
else
pr_debug("%s: rpc call success\n", __func__);
return rc;
}
EXPORT_SYMBOL(msm_hsusb_is_serial_num_null);
int msm_chg_usb_charger_connected(uint32_t device)
{
int rc = 0;
struct hsusb_start_req {
struct rpc_request_hdr hdr;
uint32_t otg_dev;
} req;
if (!chg_ep || IS_ERR(chg_ep))
return -EAGAIN;
req.otg_dev = cpu_to_be32(device);
rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_charger_connected_proc,
&req, sizeof(req), 5 * HZ);
if (rc < 0) {
pr_err("%s: charger_connected failed! rc = %d\n",
__func__, rc);
} else
pr_debug("msm_chg_usb_charger_connected\n");
return rc;
}
EXPORT_SYMBOL(msm_chg_usb_charger_connected);
int msm_chg_usb_i_is_available(uint32_t sample)
{
int rc = 0;
struct hsusb_start_req {
struct rpc_request_hdr hdr;
uint32_t i_ma;
} req;
if (!chg_ep || IS_ERR(chg_ep))
return -EAGAIN;
req.i_ma = cpu_to_be32(sample);
rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_i_is_available_proc,
&req, sizeof(req), 5 * HZ);
if (rc < 0) {
pr_err("%s: charger_i_available failed! rc = %d\n",
__func__, rc);
} else
pr_debug("msm_chg_usb_i_is_available(%u)\n", sample);
return rc;
}
EXPORT_SYMBOL(msm_chg_usb_i_is_available);
int msm_chg_usb_i_is_not_available(void)
{
int rc = 0;
struct hsusb_start_req {
struct rpc_request_hdr hdr;
} req;
if (!chg_ep || IS_ERR(chg_ep))
return -EAGAIN;
rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_i_is_not_available_proc,
&req, sizeof(req), 5 * HZ);
if (rc < 0) {
pr_err("%s: charger_i_not_available failed! rc ="
"%d \n", __func__, rc);
} else
pr_debug("msm_chg_usb_i_is_not_available\n");
return rc;
}
EXPORT_SYMBOL(msm_chg_usb_i_is_not_available);
int msm_chg_usb_charger_disconnected(void)
{
int rc = 0;
struct hsusb_start_req {
struct rpc_request_hdr hdr;
} req;
if (!chg_ep || IS_ERR(chg_ep))
return -EAGAIN;
rc = msm_rpc_call(chg_ep, chg_rpc_ids.chg_usb_charger_disconnected_proc,
&req, sizeof(req), 5 * HZ);
if (rc < 0) {
pr_err("%s: charger_disconnected failed! rc = %d\n",
__func__, rc);
} else
pr_debug("msm_chg_usb_charger_disconnected\n");
return rc;
}
EXPORT_SYMBOL(msm_chg_usb_charger_disconnected);
/* rpc call to close connection */
int msm_hsusb_rpc_close(void)
{
int rc = 0;
if (IS_ERR(usb_ep)) {
pr_err("%s: rpc_close failed before call, rc = %ld\n",
__func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
rc = msm_rpc_close(usb_ep);
usb_ep = NULL;
if (rc < 0) {
pr_err("%s: close rpc failed! rc = %d\n",
__func__, rc);
return -EAGAIN;
} else
pr_debug("rpc close success\n");
return rc;
}
EXPORT_SYMBOL(msm_hsusb_rpc_close);
/* rpc call to close charging connection */
int msm_chg_rpc_close(void)
{
int rc = 0;
if (IS_ERR(chg_ep)) {
pr_err("%s: rpc_close failed before call, rc = %ld\n",
__func__, PTR_ERR(chg_ep));
return -EAGAIN;
}
rc = msm_rpc_close(chg_ep);
chg_ep = NULL;
if (rc < 0) {
pr_err("%s: close rpc failed! rc = %d\n",
__func__, rc);
return -EAGAIN;
} else
pr_debug("rpc close success\n");
return rc;
}
EXPORT_SYMBOL(msm_chg_rpc_close);
int msm_hsusb_reset_rework_installed(void)
{
int rc = 0;
struct hsusb_start_req {
struct rpc_request_hdr hdr;
} req;
struct hsusb_rpc_rep {
struct rpc_reply_hdr hdr;
uint32_t rework;
} rep;
memset(&rep, 0, sizeof(rep));
if (!usb_ep || IS_ERR(usb_ep)) {
pr_err("%s: hsusb rpc connection not initialized, rc = %ld\n",
__func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
rc = msm_rpc_call_reply(usb_ep, usb_rpc_ids.reset_rework_installed,
&req, sizeof(req),
&rep, sizeof(rep), 5 * HZ);
if (rc < 0) {
pr_err("%s: rpc call failed! error: (%d)"
"proc id: (%lx)\n",
__func__, rc,
usb_rpc_ids.reset_rework_installed);
return rc;
}
pr_info("%s: rework: (%d)\n", __func__, rep.rework);
return be32_to_cpu(rep.rework);
}
EXPORT_SYMBOL(msm_hsusb_reset_rework_installed);
static int msm_hsusb_pmic_ulpidata0_config(int enable)
{
int rc = 0;
struct hsusb_start_req {
struct rpc_request_hdr hdr;
} req;
if (!usb_ep || IS_ERR(usb_ep)) {
pr_err("%s: hsusb rpc connection not initialized, rc = %ld\n",
__func__, PTR_ERR(usb_ep));
return -EAGAIN;
}
if (enable)
rc = msm_rpc_call(usb_ep, usb_rpc_ids.enable_pmic_ulpi_data0,
&req, sizeof(req), 5 * HZ);
else
rc = msm_rpc_call(usb_ep, usb_rpc_ids.disable_pmic_ulpi_data0,
&req, sizeof(req), 5 * HZ);
if (rc < 0)
pr_err("%s: rpc call failed! error: %d\n",
__func__, rc);
return rc;
}
int msm_hsusb_enable_pmic_ulpidata0(void)
{
return msm_hsusb_pmic_ulpidata0_config(1);
}
EXPORT_SYMBOL(msm_hsusb_enable_pmic_ulpidata0);
int msm_hsusb_disable_pmic_ulpidata0(void)
{
return msm_hsusb_pmic_ulpidata0_config(0);
}
EXPORT_SYMBOL(msm_hsusb_disable_pmic_ulpidata0);
/* wrapper for sending pid and serial# info to bootloader */
int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum)
{
int ret;
ret = msm_hsusb_send_productID(pid);
if (ret)
return ret;
if (!snum) {
ret = msm_hsusb_is_serial_num_null(1);
if (ret)
return ret;
}
ret = msm_hsusb_is_serial_num_null(0);
if (ret)
return ret;
ret = msm_hsusb_send_serial_number(snum);
if (ret)
return ret;
return 0;
}
#ifdef CONFIG_USB_MSM_72K
/* charger api wrappers */
int hsusb_chg_init(int connect)
{
if (connect)
return msm_chg_rpc_connect();
else
return msm_chg_rpc_close();
}
EXPORT_SYMBOL(hsusb_chg_init);
void hsusb_chg_vbus_draw(unsigned mA)
{
msm_chg_usb_i_is_available(mA);
}
EXPORT_SYMBOL(hsusb_chg_vbus_draw);
void hsusb_chg_connected(enum chg_type chgtype)
{
char *chg_types[] = {"STD DOWNSTREAM PORT",
"CARKIT",
"DEDICATED CHARGER",
"INVALID"};
if (chgtype == USB_CHG_TYPE__INVALID) {
msm_chg_usb_i_is_not_available();
msm_chg_usb_charger_disconnected();
return;
}
pr_info("\nCharger Type: %s\n", chg_types[chgtype]);
msm_chg_usb_charger_connected(chgtype);
}
EXPORT_SYMBOL(hsusb_chg_connected);
#endif

View file

@ -515,17 +515,6 @@ config USB_DWC3_OMAP
# LAST -- dummy/emulated controller
#
config USB_MSM_72K
tristate "MSM 72K Device Controller"
depends on ARCH_MSM
select USB_GADGET_DUALSPEED
help
USB gadget driver for Qualcomm MSM 72K architecture.
Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "msm72k" and force all
gadget drivers to also be dynamically linked.
config USB_DUMMY_HCD
tristate "Dummy HCD (DEVELOPMENT)"
depends on USB=y || (USB=m && USB_GADGET=m)

View file

@ -36,7 +36,6 @@ obj-$(CONFIG_USB_CI13XXX_MSM_HSIC) += ci13xxx_msm_hsic.o
obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o
obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o
obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o
obj-$(CONFIG_USB_MSM_72K) += msm72k_udc.o
# USB Functions
usb_f_acm-y := f_acm.o

File diff suppressed because it is too large Load diff

View file

@ -1,813 +0,0 @@
/* ehci-msm.c - HSUSB Host Controller Driver Implementation
*
* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
*
* Partly derived from ehci-fsl.c and ehci-hcd.c
* Copyright (c) 2000-2004 by David Brownell
* Copyright (c) 2005 MontaVista Software
*
* All source code in this file is licensed under the following license except
* where indicated.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can find it at http://www.fsf.org
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/wakelock.h>
#include <linux/pm_runtime.h>
#include <mach/board.h>
#include <mach/rpc_hsusb.h>
#include <mach/msm_hsusb.h>
#include <mach/msm_hsusb_hw.h>
#include <mach/msm_otg.h>
#include <mach/clk.h>
#include <mach/msm72k_otg.h>
#define DRIVER_DESC "Qualcomm On-Chip EHCI Host Controller"
static const char hcd_name[] = "ehci-msm";
#define MSM_USB_BASE (hcd->regs)
struct msmusb_hcd {
struct ehci_hcd ehci;
struct clk *alt_core_clk;
struct clk *iface_clk;
unsigned in_lpm;
struct work_struct lpm_exit_work;
spinlock_t lock;
struct wake_lock wlock;
unsigned int clk_enabled;
struct msm_usb_host_platform_data *pdata;
unsigned running;
struct usb_phy *xceiv;
struct work_struct otg_work;
unsigned flags;
struct msm_otg_ops otg_ops;
};
static inline struct msmusb_hcd *hcd_to_mhcd(struct usb_hcd *hcd)
{
return (struct msmusb_hcd *) (hcd->hcd_priv);
}
static inline struct usb_hcd *mhcd_to_hcd(struct msmusb_hcd *mhcd)
{
return container_of((void *) mhcd, struct usb_hcd, hcd_priv);
}
static void msm_xusb_pm_qos_update(struct msmusb_hcd *mhcd, int vote)
{
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
/* if otg driver is available, it would take
* care of voting for appropriate pclk source
*/
if (mhcd->xceiv)
return;
if (vote)
clk_prepare_enable(pdata->ebi1_clk);
else
clk_disable_unprepare(pdata->ebi1_clk);
}
static void msm_xusb_enable_clks(struct msmusb_hcd *mhcd)
{
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
if (mhcd->clk_enabled)
return;
switch (PHY_TYPE(pdata->phy_info)) {
case USB_PHY_INTEGRATED:
/* OTG driver takes care of clock management */
break;
case USB_PHY_SERIAL_PMIC:
clk_prepare_enable(mhcd->alt_core_clk);
clk_prepare_enable(mhcd->iface_clk);
break;
default:
pr_err("%s: undefined phy type ( %X )\n", __func__,
pdata->phy_info);
return;
}
mhcd->clk_enabled = 1;
}
static void msm_xusb_disable_clks(struct msmusb_hcd *mhcd)
{
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
if (!mhcd->clk_enabled)
return;
switch (PHY_TYPE(pdata->phy_info)) {
case USB_PHY_INTEGRATED:
/* OTG driver takes care of clock management */
break;
case USB_PHY_SERIAL_PMIC:
clk_disable_unprepare(mhcd->alt_core_clk);
clk_disable_unprepare(mhcd->iface_clk);
break;
default:
pr_err("%s: undefined phy type ( %X )\n", __func__,
pdata->phy_info);
return;
}
mhcd->clk_enabled = 0;
}
static int usb_wakeup_phy(struct usb_hcd *hcd)
{
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
int ret = -ENODEV;
switch (PHY_TYPE(pdata->phy_info)) {
case USB_PHY_INTEGRATED:
break;
case USB_PHY_SERIAL_PMIC:
ret = msm_fsusb_resume_phy();
break;
default:
pr_err("%s: undefined phy type ( %X ) \n", __func__,
pdata->phy_info);
}
return ret;
}
#ifdef CONFIG_PM
static int usb_suspend_phy(struct usb_hcd *hcd)
{
int ret = 0;
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
switch (PHY_TYPE(pdata->phy_info)) {
case USB_PHY_INTEGRATED:
break;
case USB_PHY_SERIAL_PMIC:
ret = msm_fsusb_set_remote_wakeup();
ret = msm_fsusb_suspend_phy();
break;
default:
pr_err("%s: undefined phy type ( %X ) \n", __func__,
pdata->phy_info);
ret = -ENODEV;
break;
}
return ret;
}
static int usb_lpm_enter(struct usb_hcd *hcd)
{
struct device *dev = container_of((void *)hcd, struct device,
platform_data);
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
disable_irq(hcd->irq);
if (mhcd->in_lpm) {
pr_info("%s: already in lpm. nothing to do\n", __func__);
enable_irq(hcd->irq);
return 0;
}
if (HC_IS_RUNNING(hcd->state)) {
pr_info("%s: can't enter into lpm. controller is runnning\n",
__func__);
enable_irq(hcd->irq);
return -1;
}
pr_info("%s: lpm enter procedure started\n", __func__);
mhcd->in_lpm = 1;
if (usb_suspend_phy(hcd)) {
mhcd->in_lpm = 0;
enable_irq(hcd->irq);
pr_info("phy suspend failed\n");
pr_info("%s: lpm enter procedure end\n", __func__);
return -1;
}
msm_xusb_disable_clks(mhcd);
if (mhcd->xceiv && mhcd->xceiv->set_suspend)
mhcd->xceiv->set_suspend(mhcd->xceiv, 1);
if (device_may_wakeup(dev))
enable_irq_wake(hcd->irq);
enable_irq(hcd->irq);
pr_info("%s: lpm enter procedure end\n", __func__);
return 0;
}
#endif
void usb_lpm_exit_w(struct work_struct *work)
{
struct msmusb_hcd *mhcd = container_of((void *) work,
struct msmusb_hcd, lpm_exit_work);
struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
struct device *dev = container_of((void *)hcd, struct device,
platform_data);
msm_xusb_enable_clks(mhcd);
if (usb_wakeup_phy(hcd)) {
pr_err("fatal error: cannot bring phy out of lpm\n");
return;
}
/* If resume signalling finishes before lpm exit, PCD is not set in
* USBSTS register. Drive resume signal to the downstream device now
* so that EHCI can process the upcoming port change interrupt.*/
writel(readl(USB_PORTSC) | PORTSC_FPR, USB_PORTSC);
if (mhcd->xceiv && mhcd->xceiv->set_suspend)
mhcd->xceiv->set_suspend(mhcd->xceiv, 0);
if (device_may_wakeup(dev))
disable_irq_wake(hcd->irq);
enable_irq(hcd->irq);
}
static void usb_lpm_exit(struct usb_hcd *hcd)
{
unsigned long flags;
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
spin_lock_irqsave(&mhcd->lock, flags);
if (!mhcd->in_lpm) {
spin_unlock_irqrestore(&mhcd->lock, flags);
return;
}
mhcd->in_lpm = 0;
disable_irq_nosync(hcd->irq);
schedule_work(&mhcd->lpm_exit_work);
spin_unlock_irqrestore(&mhcd->lock, flags);
}
static irqreturn_t ehci_msm_irq(struct usb_hcd *hcd)
{
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
struct msm_otg *otg = container_of(mhcd->xceiv, struct msm_otg, phy);
/*
* OTG scheduled a work to get Integrated PHY out of LPM,
* WAIT till then */
if (PHY_TYPE(mhcd->pdata->phy_info) == USB_PHY_INTEGRATED)
if (atomic_read(&otg->in_lpm))
return IRQ_HANDLED;
return ehci_irq(hcd);
}
#ifdef CONFIG_PM
static int ehci_msm_bus_suspend(struct usb_hcd *hcd)
{
int ret;
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
struct device *dev = hcd->self.controller;
ret = ehci_bus_suspend(hcd);
if (ret) {
pr_err("ehci_bus suspend faield\n");
return ret;
}
if (PHY_TYPE(mhcd->pdata->phy_info) == USB_PHY_INTEGRATED)
ret = usb_phy_set_suspend(mhcd->xceiv, 1);
else
ret = usb_lpm_enter(hcd);
pm_runtime_put_noidle(dev);
pm_runtime_suspend(dev);
wake_unlock(&mhcd->wlock);
return ret;
}
static int ehci_msm_bus_resume(struct usb_hcd *hcd)
{
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
struct device *dev = hcd->self.controller;
wake_lock(&mhcd->wlock);
pm_runtime_get_noresume(dev);
pm_runtime_resume(dev);
if (PHY_TYPE(mhcd->pdata->phy_info) == USB_PHY_INTEGRATED) {
usb_phy_set_suspend(mhcd->xceiv, 0);
} else { /* PMIC serial phy */
usb_lpm_exit(hcd);
if (cancel_work_sync(&(mhcd->lpm_exit_work)))
usb_lpm_exit_w(&mhcd->lpm_exit_work);
}
return ehci_bus_resume(hcd);
}
#else
#define ehci_msm_bus_suspend NULL
#define ehci_msm_bus_resume NULL
#endif /* CONFIG_PM */
static int ehci_msm_reset(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
ehci->caps = USB_CAPLENGTH;
ehci->regs = USB_CAPLENGTH +
HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
/* cache the data to minimize the chip reads*/
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
retval = ehci_init(hcd);
if (retval)
return retval;
hcd->has_tt = 1;
ehci->sbrn = HCD_USB2;
retval = ehci_reset(ehci);
/* SW workaround for USB stability issues*/
writel(0x0, USB_AHB_MODE);
writel(0x0, USB_AHB_BURST);
return retval;
}
#define PTS_VAL(x) (PHY_TYPE(x) == USB_PHY_SERIAL_PMIC) ? PORTSC_PTS_SERIAL : \
PORTSC_PTS_ULPI
static int ehci_msm_run(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
int retval = 0;
int port = HCS_N_PORTS(ehci->hcs_params);
u32 __iomem *reg_ptr;
u32 hcc_params;
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
hcd->uses_new_polling = 1;
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
/* set hostmode */
reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
ehci_writel(ehci, (USBMODE_VBUS | USBMODE_SDIS), reg_ptr);
/* port configuration - phy, port speed, port power, port enable */
while (port--)
ehci_writel(ehci, (PTS_VAL(pdata->phy_info) | PORT_POWER |
PORT_PE), &ehci->regs->port_status[port]);
ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next);
hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
if (HCC_64BIT_ADDR(hcc_params))
ehci_writel(ehci, 0, &ehci->regs->segment);
ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
ehci->command |= CMD_RUN;
ehci_writel(ehci, ehci->command, &ehci->regs->command);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
ehci->rh_state = EHCI_RH_RUNNING;
/*Enable appropriate Interrupts*/
ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
return retval;
}
static const struct ehci_driver_overrides ehci_msm_overrides __initdata = {
.reset = ehci_msm_reset,
.extra_priv_size = sizeof(struct msmusb_hcd),
.irq = ehci_msm_irq,
.urb_enqueue = ehci_hsic_urb_enqueue,
.bus_suspend = ehci_msm_bus_suspend,
.bus_resume = ehci_msm_bus_resume,
.start = ehci_msm_run,
};
static struct hc_driver __read_mostly ehci_msm_hc_driver;
static void msm_hsusb_request_host(void *handle, int request)
{
struct msmusb_hcd *mhcd = handle;
struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
struct msm_otg *otg = container_of(mhcd->xceiv, struct msm_otg, phy);
#ifdef CONFIG_USB_OTG
struct usb_device *udev = hcd->self.root_hub;
#endif
struct device *dev = hcd->self.controller;
switch (request) {
#ifdef CONFIG_USB_OTG
case REQUEST_HNP_SUSPEND:
/* disable Root hub auto suspend. As hardware is configured
* for peripheral mode, mark hardware is not available.
*/
if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) {
pm_runtime_disable(&udev->dev);
/* Mark root hub as disconnected. This would
* protect suspend/resume via sysfs.
*/
udev->state = USB_STATE_NOTATTACHED;
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
hcd->state = HC_STATE_HALT;
pm_runtime_put_noidle(dev);
pm_runtime_suspend(dev);
}
break;
case REQUEST_HNP_RESUME:
if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) {
pm_runtime_get_noresume(dev);
pm_runtime_resume(dev);
disable_irq(hcd->irq);
ehci_msm_reset(hcd);
ehci_msm_run(hcd);
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
pm_runtime_enable(&udev->dev);
udev->state = USB_STATE_CONFIGURED;
enable_irq(hcd->irq);
}
break;
#endif
case REQUEST_RESUME:
usb_hcd_resume_root_hub(hcd);
break;
case REQUEST_START:
if (mhcd->running)
break;
pm_runtime_get_noresume(dev);
pm_runtime_resume(dev);
wake_lock(&mhcd->wlock);
msm_xusb_pm_qos_update(mhcd, 1);
msm_xusb_enable_clks(mhcd);
if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED)
if (otg->set_clk)
otg->set_clk(mhcd->xceiv, 1);
if (pdata->vbus_power)
pdata->vbus_power(pdata->phy_info, 1);
if (pdata->config_gpio)
pdata->config_gpio(1);
usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
mhcd->running = 1;
if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED)
if (otg->set_clk)
otg->set_clk(mhcd->xceiv, 0);
break;
case REQUEST_STOP:
if (!mhcd->running)
break;
mhcd->running = 0;
/* come out of lpm before deregistration */
if (PHY_TYPE(pdata->phy_info) == USB_PHY_SERIAL_PMIC) {
usb_lpm_exit(hcd);
if (cancel_work_sync(&(mhcd->lpm_exit_work)))
usb_lpm_exit_w(&mhcd->lpm_exit_work);
}
usb_remove_hcd(hcd);
if (pdata->config_gpio)
pdata->config_gpio(0);
if (pdata->vbus_power)
pdata->vbus_power(pdata->phy_info, 0);
msm_xusb_disable_clks(mhcd);
wake_lock_timeout(&mhcd->wlock, HZ/2);
msm_xusb_pm_qos_update(mhcd, 0);
pm_runtime_put_noidle(dev);
pm_runtime_suspend(dev);
break;
}
}
static void msm_hsusb_otg_work(struct work_struct *work)
{
struct msmusb_hcd *mhcd;
mhcd = container_of(work, struct msmusb_hcd, otg_work);
msm_hsusb_request_host((void *)mhcd, mhcd->flags);
}
static void msm_hsusb_start_host(struct usb_bus *bus, int start)
{
struct usb_hcd *hcd = bus_to_hcd(bus);
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
mhcd->flags = start;
if (in_interrupt())
schedule_work(&mhcd->otg_work);
else
msm_hsusb_request_host((void *)mhcd, mhcd->flags);
}
static int msm_xusb_init_phy(struct msmusb_hcd *mhcd)
{
int ret = -ENODEV;
struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
switch (PHY_TYPE(pdata->phy_info)) {
case USB_PHY_INTEGRATED:
ret = 0;
case USB_PHY_SERIAL_PMIC:
msm_xusb_enable_clks(mhcd);
writel(0, USB_USBINTR);
ret = msm_fsusb_rpc_init(&mhcd->otg_ops);
if (!ret)
msm_fsusb_init_phy();
msm_xusb_disable_clks(mhcd);
break;
default:
pr_err("%s: undefined phy type ( %X ) \n", __func__,
pdata->phy_info);
}
return ret;
}
static int msm_xusb_rpc_close(struct msmusb_hcd *mhcd)
{
int retval = -ENODEV;
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
switch (PHY_TYPE(pdata->phy_info)) {
case USB_PHY_INTEGRATED:
if (!mhcd->xceiv)
retval = msm_hsusb_rpc_close();
break;
case USB_PHY_SERIAL_PMIC:
retval = msm_fsusb_reset_phy();
msm_fsusb_rpc_deinit();
break;
default:
pr_err("%s: undefined phy type ( %X ) \n", __func__,
pdata->phy_info);
}
return retval;
}
static int msm_xusb_init_host(struct platform_device *pdev,
struct msmusb_hcd *mhcd)
{
int ret = 0;
struct msm_otg *otg;
struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
switch (PHY_TYPE(pdata->phy_info)) {
case USB_PHY_INTEGRATED:
msm_hsusb_rpc_connect();
if (pdata->vbus_init)
pdata->vbus_init(1);
/* VBUS might be present. Turn off vbus */
if (pdata->vbus_power)
pdata->vbus_power(pdata->phy_info, 0);
INIT_WORK(&mhcd->otg_work, msm_hsusb_otg_work);
mhcd->xceiv = usb_get_transceiver();
if (!mhcd->xceiv)
return -ENODEV;
otg = container_of(mhcd->xceiv, struct msm_otg, phy);
hcd->regs = otg->regs;
otg->start_host = msm_hsusb_start_host;
ret = otg_set_host(mhcd->xceiv->otg, &hcd->self);
ehci->transceiver = mhcd->xceiv;
break;
case USB_PHY_SERIAL_PMIC:
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs)
return -EFAULT;
/* get usb clocks */
mhcd->alt_core_clk = clk_get(&pdev->dev, "alt_core_clk");
if (IS_ERR(mhcd->alt_core_clk)) {
iounmap(hcd->regs);
return PTR_ERR(mhcd->alt_core_clk);
}
mhcd->iface_clk = clk_get(&pdev->dev, "iface_clk");
if (IS_ERR(mhcd->iface_clk)) {
iounmap(hcd->regs);
clk_put(mhcd->alt_core_clk);
return PTR_ERR(mhcd->iface_clk);
}
mhcd->otg_ops.request = msm_hsusb_request_host;
mhcd->otg_ops.handle = (void *) mhcd;
ret = msm_xusb_init_phy(mhcd);
if (ret < 0) {
iounmap(hcd->regs);
clk_put(mhcd->alt_core_clk);
clk_put(mhcd->iface_clk);
}
break;
default:
pr_err("phy type is bad\n");
}
return ret;
}
static int ehci_msm_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct resource *res;
struct msm_usb_host_platform_data *pdata;
int retval;
struct msmusb_hcd *mhcd;
hcd = usb_create_hcd(&ehci_msm_hc_driver, &pdev->dev,
dev_name(&pdev->dev));
if (!hcd)
return -ENOMEM;
hcd_to_bus(hcd)->skip_resume = true;
hcd->irq = platform_get_irq(pdev, 0);
if (hcd->irq < 0) {
usb_put_hcd(hcd);
return hcd->irq;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
usb_put_hcd(hcd);
return -ENODEV;
}
hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);
mhcd = hcd_to_mhcd(hcd);
spin_lock_init(&mhcd->lock);
mhcd->in_lpm = 0;
mhcd->running = 0;
device_init_wakeup(&pdev->dev, 1);
pdata = pdev->dev.platform_data;
if (PHY_TYPE(pdata->phy_info) == USB_PHY_UNDEFINED) {
usb_put_hcd(hcd);
return -ENODEV;
}
hcd->power_budget = pdata->power_budget;
mhcd->pdata = pdata;
INIT_WORK(&mhcd->lpm_exit_work, usb_lpm_exit_w);
wake_lock_init(&mhcd->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
pdata->ebi1_clk = clk_get(&pdev->dev, "core_clk");
if (IS_ERR(pdata->ebi1_clk))
pdata->ebi1_clk = NULL;
else
clk_set_rate(pdata->ebi1_clk, INT_MAX);
retval = msm_xusb_init_host(pdev, mhcd);
if (retval < 0) {
wake_lock_destroy(&mhcd->wlock);
usb_put_hcd(hcd);
clk_put(pdata->ebi1_clk);
}
pm_runtime_enable(&pdev->dev);
return retval;
}
static void msm_xusb_uninit_host(struct msmusb_hcd *mhcd)
{
struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
struct msm_usb_host_platform_data *pdata = mhcd->pdata;
switch (PHY_TYPE(pdata->phy_info)) {
case USB_PHY_INTEGRATED:
if (pdata->vbus_init)
pdata->vbus_init(0);
hcd_to_ehci(hcd)->transceiver = NULL;
otg_set_host(mhcd->xceiv->otg, NULL);
usb_put_transceiver(mhcd->xceiv);
cancel_work_sync(&mhcd->otg_work);
break;
case USB_PHY_SERIAL_PMIC:
iounmap(hcd->regs);
clk_put(mhcd->alt_core_clk);
clk_put(mhcd->iface_clk);
msm_fsusb_reset_phy();
msm_fsusb_rpc_deinit();
break;
default:
pr_err("phy type is bad\n");
}
}
static int ehci_msm_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
struct msm_usb_host_platform_data *pdata;
int retval = 0;
pdata = pdev->dev.platform_data;
device_init_wakeup(&pdev->dev, 0);
msm_hsusb_request_host((void *)mhcd, REQUEST_STOP);
msm_xusb_uninit_host(mhcd);
retval = msm_xusb_rpc_close(mhcd);
wake_lock_destroy(&mhcd->wlock);
usb_put_hcd(hcd);
clk_put(pdata->ebi1_clk);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
return retval;
}
static int ehci_msm_runtime_suspend(struct device *dev)
{
dev_dbg(dev, "pm_runtime: suspending...\n");
return 0;
}
static int ehci_msm_runtime_resume(struct device *dev)
{
dev_dbg(dev, "pm_runtime: resuming...\n");
return 0;
}
static int ehci_msm_runtime_idle(struct device *dev)
{
dev_dbg(dev, "pm_runtime: idling...\n");
return 0;
}
static const struct dev_pm_ops ehci_msm_dev_pm_ops = {
.runtime_suspend = ehci_msm_runtime_suspend,
.runtime_resume = ehci_msm_runtime_resume,
.runtime_idle = ehci_msm_runtime_idle
};
static struct platform_driver ehci_msm_driver = {
.probe = ehci_msm_probe,
.remove = ehci_msm_remove,
.driver = {
.name = "msm_hsusb_host",
.pm = &ehci_msm_dev_pm_ops,
},
};
static int __init ehci_msm_init(void)
{
if (usb_disabled())
return -ENODEV;
pr_info("%s: " DRIVER_DESC "\n", hcd_name);
ehci_init_driver(&ehci_msm_hc_driver, &ehci_msm_overrides);
return platform_driver_register(&ehci_msm_driver);
}
module_init(ehci_msm_init);
static void __exit ehci_msm_cleanup(void)
{
platform_driver_unregister(&ehci_msm_driver);
}
module_exit(ehci_msm_hsic_cleanup);

View file

@ -26,7 +26,6 @@ obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o
obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o
obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o
obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o
obj-$(CONFIG_USB_MSM_OTG_72K) += msm72k_otg.o
obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o
obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o
obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o

File diff suppressed because it is too large Load diff