mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 03:43:03 +00:00
USB: MSM: Drop unsupported drivers
Change-Id: If2acdeab8ac44b328906744587fd55442065556b Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
This commit is contained in:
parent
e052561593
commit
94e68c66c0
|
@ -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
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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);
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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
|
@ -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);
|
|
@ -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
Loading…
Reference in a new issue