blob: bf80b75f96b5b404c7129760f2cc2bfc2f98ada9 [file] [log] [blame]
/*
* Intel Penwell USB OTG transceiver driver
* Copyright (C) 2009 - 2010, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef __PENWELL_OTG_H__
#define __PENWELL_OTG_H__
#include <linux/usb/intel_mid_otg.h>
#include <linux/power_supply.h>
#include <linux/wakelock.h>
#define PMU_OTG_WAKE_SOURCE 6
#define CI_USBCMD 0x30
# define USBCMD_RST BIT(1)
# define USBCMD_RS BIT(0)
#define CI_USBSTS 0x34
# define USBSTS_SLI BIT(8)
# define USBSTS_URI BIT(6)
# define USBSTS_PCI BIT(2)
#define CI_USBINTR 0x38
# define USBINTR_PCE BIT(2)
#define CI_ULPIVP 0x60
# define ULPI_WU BIT(31)
# define ULPI_RUN BIT(30)
# define ULPI_RW BIT(29)
# define ULPI_SS BIT(27)
# define ULPI_PORT (BIT(26) | BIT(25) | BIT(24))
# define ULPI_ADDR (0xff << 16)
# define ULPI_DATRD (0xff << 8)
# define ULPI_DATWR (0xff << 0)
#define CI_PORTSC1 0x74
# define PORTSC_PP BIT(12)
# define PORTSC_LS (BIT(11) | BIT(10))
# define PORTSC_SUSP BIT(7)
# define PORTSC_CCS BIT(0)
#define CI_HOSTPC1 0xb4
# define HOSTPC1_PHCD BIT(22)
#define CI_OTGSC 0xf4
# define OTGSC_DPIE BIT(30)
# define OTGSC_1MSE BIT(29)
# define OTGSC_BSEIE BIT(28)
# define OTGSC_BSVIE BIT(27)
# define OTGSC_ASVIE BIT(26)
# define OTGSC_AVVIE BIT(25)
# define OTGSC_IDIE BIT(24)
# define OTGSC_DPIS BIT(22)
# define OTGSC_1MSS BIT(21)
# define OTGSC_BSEIS BIT(20)
# define OTGSC_BSVIS BIT(19)
# define OTGSC_ASVIS BIT(18)
# define OTGSC_AVVIS BIT(17)
# define OTGSC_IDIS BIT(16)
# define OTGSC_DPS BIT(14)
# define OTGSC_1MST BIT(13)
# define OTGSC_BSE BIT(12)
# define OTGSC_BSV BIT(11)
# define OTGSC_ASV BIT(10)
# define OTGSC_AVV BIT(9)
# define OTGSC_ID BIT(8)
# define OTGSC_HABA BIT(7)
# define OTGSC_HADP BIT(6)
# define OTGSC_IDPU BIT(5)
# define OTGSC_DP BIT(4)
# define OTGSC_OT BIT(3)
# define OTGSC_HAAR BIT(2)
# define OTGSC_VC BIT(1)
# define OTGSC_VD BIT(0)
#define CI_USBMODE 0xf8
# define USBMODE_CM (BIT(1) | BIT(0))
# define USBMODE_IDLE 0
# define USBMODE_DEVICE 0x2
# define USBMODE_HOST 0x3
#define USBCFG_ADDR 0xff10801c
#define USBCFG_LEN 4
# define USBCFG_VBUSVAL BIT(14)
# define USBCFG_AVALID BIT(13)
# define USBCFG_BVALID BIT(12)
# define USBCFG_SESEND BIT(11)
#define OTGSC_INTEN_MASK \
(OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE \
| OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE)
#define OTGSC_INTSTS_MASK \
(OTGSC_DPIS | OTGSC_BSEIS | OTGSC_BSVIS \
| OTGSC_ASVIS | OTGSC_AVVIS | OTGSC_IDIS)
#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
#define HOST_REQUEST_FLAG BIT(0)
/* MSIC register for vbus power control */
#define MSIC_ID 0x00
# define ID0_VENDID0 (BIT(7) | BIT(6))
#define MSIC_ID1 0x01
# define ID1_VENDID1 (BIT(7) | BIT(6))
#define MSIC_VUSB330CNT 0xd4
#define MSIC_VOTGCNT 0xdf
# define VOTGEN BIT(7)
# define VOTGRAMP BIT(4)
#define MSIC_SPWRSRINT1 0x193
# define SUSBCHPDET BIT(6)
# define SUSBDCDET BIT(2)
# define MSIC_SPWRSRINT1_MASK (BIT(6) | BIT(2))
# define SPWRSRINT1_CDP BIT(6)
# define SPWRSRINT1_SDP 0
# define SPWRSRINT1_DCP BIT(2)
#define MSIC_USB_MISC 0x2c8 /* Intel Specific */
# define MISC_CHGDSERXDPINV BIT(5)
#define MSIC_OTGCTRL 0x39c
#define MSIC_OTGCTRLSET 0x340
#define MSIC_OTGCTRLCLR 0x341
#define ULPI_OTGCTRL 0x0a
#define ULPI_OTGCTRLSET 0x0b
#define ULPI_OTGCTRLCLR 0x0c
# define DRVVBUS_EXTERNAL BIT(6)
# define DRVVBUS BIT(5)
# define DMPULLDOWN BIT(2)
# define DPPULLDOWN BIT(1)
#define MSIC_USBINTEN_RISE 0x39d
#define MSIC_USBINTEN_RISESET 0x39e
#define MSIC_USBINTEN_RISECLR 0x39f
#define MSIC_USBINTEN_FALL 0x3a0
#define MSIC_USBINTEN_FALLSET 0x3a1
#define MSIC_USBINTEN_FALLCLR 0x3a2
/*
* For Clovertrail, due to change of USB PHY from MSIC to external standalone
* chip, USB Interrupt Enable Rising/Falling registers can be accessed only
* from ULPI interface.
*/
#define ULPI_USBINTEN_RISING 0xd
#define ULPI_USBINTEN_RISINGSET 0xe
#define ULPI_USBINTEN_RISINGCLR 0xf
#define ULPI_USBINTEN_FALLING 0x10
#define ULPI_USBINTEN_FALLINGSET 0x11
#define ULPI_USBINTEN_FALLINGCLR 0x12
# define IDGND BIT(4)
# define SESSEND BIT(3)
# define SESSVLD BIT(2)
# define VBUSVLD BIT(1)
# define HOSTDISCON BIT(0)
#define MSIC_PWRCTRL 0x3b5
#define MSIC_PWRCTRLSET 0x342
#define MSIC_PWRCTRLCLR 0x343
#define ULPI_PWRCTRL 0x3d
#define ULPI_PWRCTRLSET 0x3e
#define ULPI_PWRCTRLCLR 0x3f
# define HWDET BIT(7)
# define DPVSRCEN BIT(6)
# define VDATDET BIT(5)
# define DPWKPUEN BIT(4)
# define SWCNTRL BIT(0)
#define MSIC_FUNCTRL 0x398
#define MSIC_FUNCTRLSET 0x344
#define MSIC_FUNCTRLCLR 0x345
#define ULPI_FUNCTRL 0x04
#define ULPI_FUNCTRLSET 0x05
#define ULPI_FUNCTRLCLR 0x06
# define PHYRESET BIT(5)
# define OPMODE1 BIT(4)
# define OPMODE0 BIT(3)
# define TERMSELECT BIT(2)
# define XCVRSELECT1 BIT(1)
# define XCVRSELECT0 BIT(0)
#define MSIC_DEBUG 0x3a5
#define ULPI_DEBUG 0x15
# define LINESTATE_MSK (BIT(0) | BIT(1))
# define LINESTATE_SE1 (BIT(0) | BIT(1))
# define LINESTATE_SE0 (0)
# define LINESTATE_FSJ BIT(0)
# define LINESTATE_FSK BIT(1)
#define MSIC_VS1 0x3b6
#define MSIC_VS1SET 0x3a9
#define MSIC_VS1CLR 0x3aa
#define ULPI_VS1 0x80
#define ULPI_VS1SET 0x81
#define ULPI_VS1CLR 0x82
# define DATAPOLARITY BIT(6)
#define ULPI_VS2STS 0x83
#define ULPI_VS2LATCH 0x84
# define VBUS_MNTR_STS BIT(7)
# define REG3V3_MNTR_STS BIT(6)
# define SVLDCONWKB_WDOG_STS BIT(5)
# define IDFLOAT_STS BIT(4)
# define IDRARBRC_STS(d) (((d)>>2)&3)
# define IDRARBRC_STS1 BIT(3)
# define IDRARBRC_STS2 BIT(2)
# define IDRARBRC_MSK (BIT(2) | BIT(3))
# define IDRARBRC_A 1
# define IDRARBRC_B 2
# define IDRARBRC_C 3
# define BVALID_STS BIT(0)
#define MSIC_VS3 0x3b9
#define MSIC_VS3SET 0x346 /* Vendor Specific */
#define MSIC_VS3CLR 0x347
# define SWUSBDET BIT(4)
# define DATACONEN BIT(3)
#define ULPI_VS3 0x85
#define ULPI_VS3SET 0x86
#define ULPI_VS3CLR 0x87
# define CHGD_IDP_SRC BIT(6)
# define IDPULLUP_WK BIT(5)
# define SWUSBDET BIT(4)
# define DATACONEN BIT(3)
#define MSIC_VS4 0x3ba
#define MSIC_VS4SET 0x3ab
#define MSIC_VS4CLR 0x3ac
#define ULPI_VS4 0x88
#define ULPI_VS4SET 0x89
#define ULPI_VS4CLR 0x8a
# define ACADET BIT(6)
# define RABUSIN BIT(5)
# define R1KERIES BIT(4)
# define CHRG_SERX_DP BIT(1)
# define CHRG_SERX_DM BIT(0)
#define ULPI_VS5 0x8b
#define ULPI_VS5SET 0x8c
#define ULPI_VS5CLR 0x8d
# define AUTORESUME_WDOG BIT(6)
# define IDFLOAT_EN BIT(5)
# define IDRES_EN BIT(4)
# define SVLDCONWKB_WDOG BIT(3)
# define VBUS_MNTR_RISEEN BIT(2)
# define VBUS_MNTR_FALLEN BIT(1)
# define REG3V3IN_MNTR_EN BIT(0)
#define ULPI_VS6 0x8e
#define ULPI_VS6SET 0x8f
#define ULPI_VS6CLR 0x90
# define ACA_RID_B_CFG BIT(7)
# define ACA_RID_A_CFG BIT(6)
# define SOF_EN BIT(5)
#define MSIC_ULPIACCESSMODE 0x348
# define SPIMODE BIT(0)
#define MSIC_INT_EN_RISE 0x39D
#define MSIC_INT_EN_RISE_SET 0x39E
#define MSIC_INT_EN_RISE_CLR 0x39F
#define MSIC_INT_EN_FALL 0x3A0
#define MSIC_INT_EN_FALL_SET 0x3A1
#define MSIC_INT_EN_FALL_CLR 0x3A2
/* MSIC TI implementation for ADP/ACA */
#define SPI_TI_VS2 0x3B7
#define SPI_TI_VS2_LATCH 0x3B8
#define SPI_TI_VS4 0x3BA
#define SPI_TI_VS5 0x3BB
#define ULPI_TI_USB_INT_STS 0x13
#define ULPI_TI_USB_INT_LAT 0x14
# define USB_INT_IDGND BIT(4)
# define USB_INT_SESSEND BIT(3)
# define USB_INT_SESSVLD BIT(2)
# define USB_INT_VBUSVLD BIT(1)
#define ULPI_TI_VS2 0x83
# define TI_ID_FLOAT_STS BIT(4)
# define TI_ID_RARBRC_STS(d) (((d)>>2)&3)
# define TI_ID_RARBRC_STS_MASK (BIT(3) | BIT(2))
# define TI_ID_RARBRC_NONE 0
# define TI_ID_RARBRC_A 1
# define TI_ID_RARBRC_B 2
# define TI_ID_RARBRC_C 3
# define TI_ADP_INT_STS BIT(1)
#define ULPI_TI_VS4 0x88
# define TI_ACA_DET_EN BIT(6)
#define ULPI_TI_VS5 0x8b
# define TI_ADP_INT_EN BIT(7)
# define TI_ID_FLOAT_EN BIT(5)
# define TI_ID_RES_EN BIT(4)
#define ULPI_TI_VS6 0x8e
# define TI_HS_TXPREN BIT(4)
# define TI_ADP_MODE(d) (((d)>>2)&3)
# define TI_ADP_MODE_MASK (BIT(3) | BIT(2))
# define TI_ADP_MODE_DISABLE 0
# define TI_ADP_MODE_SENSE 1
# define TI_ADP_MODE_PRB_A 2
# define TI_ADP_MODE_PRB_B 3
# define TI_VBUS_IADP_SRC BIT(1)
# define TI_VBUS_IADP_SINK BIT(0)
#define ULPI_TI_VS7 0x91
# define TI_T_ADP_HIGH (0xff)
#define ULPI_TI_VS8 0x94
# define TI_T_ADP_LOW (0xff)
#define ULPI_TI_VS9 0x97
# define TI_T_ADP_RISE (0xff)
#define TI_PRB_DELTA 0x08
/* MSIC FreeScale Implementation for ADP */
#define ULPI_FS_ADPCL 0x28
# define ADPCL_PRBDSCHG (BIT(5) | BIT(6))
# define ADPCL_PRBDSCHG_4 0
# define ADPCL_PRBDSCHG_8 1
# define ADPCL_PRBDSCHG_16 2
# define ADPCL_PRBDSCHG_32 3
# define ADPCL_PRBPRD (BIT(3) | BIT(4))
# define ADPCL_PRBPRD_A_HALF 0
# define ADPCL_PRBPRD_B_HALF 1
# define ADPCL_PRBPRD_A 2
# define ADPCL_PRBPRD_B 3
# define ADPCL_SNSEN BIT(2)
# define ADPCL_PRBEN BIT(1)
# define ADPCL_ADPEN BIT(0)
#define ULPI_FS_ADPCH 0x29
# define ADPCH_PRBDELTA (0x1f << 0)
#define ULPI_FS_ADPIE 0x2a
# define ADPIE_ADPRAMPIE BIT(2)
# define ADPIE_SNSMISSIE BIT(1)
# define ADPIE_PRBTRGIE BIT(0)
#define ULPI_FS_ADPIS 0x2b
# define ADPIS_ADPRAMPS BIT(5)
# define ADPIS_SNSMISSS BIT(4)
# define ADPIS_PRBTRGS BIT(3)
# define ADPIS_ADPRAMPI BIT(2)
# define ADPIS_SNSMISSI BIT(1)
# define ADPIS_PRBTRGI BIT(0)
#define ULPI_FS_ADPRL 0x2c
# define ADPRL_ADPRAMP (0xff << 0)
#define ULPI_FS_ADPRH 0x2d
# define ADPRH_ADPRAMP (0x7 << 0)
#define FS_ADPI_MASK (ADPIS_ADPRAMPI | ADPIS_SNSMISSI | ADPIS_PRBTRGI)
/* define Data connect checking timeout and polling interval */
#define DATACON_TIMEOUT 750
#define DATACON_INTERVAL 20
enum penwell_otg_timer_type {
TA_WAIT_VRISE_TMR,
TA_WAIT_BCON_TMR,
TA_AIDL_BDIS_TMR,
TA_BIDL_ADIS_TMR,
TA_WAIT_VFALL_TMR,
TB_ASE0_BRST_TMR,
TB_SE0_SRP_TMR,
TB_SRP_FAIL_TMR, /* wait for response of SRP */
TB_BUS_SUSPEND_TMR,
TTST_MAINT_TMR,
TTST_NOADP_TMR,
};
#define TA_WAIT_VRISE 100
#define TA_WAIT_BCON 50000
#define TA_AIDL_BDIS 1500
#define TA_BIDL_ADIS 300
#define TA_WAIT_VFALL 950
#define TB_ASE0_BRST 300
#define TB_SE0_SRP 1200
#define TB_SSEND_SRP 1800
# define SRP_MON_INVAL 300 /* TODO: interval needs more tuning */
#define TB_SRP_FAIL 5500
#define TB_BUS_SUSPEND 500
#define THOS_REQ_POL 1500
/* Test mode */
#define TTST_MAINT 9900
#define TTST_NOADP 5000
/* MSIC vendor information */
enum msic_vendor {
MSIC_VD_FS,
MSIC_VD_TI,
MSIC_VD_UNKNOWN
};
/* charger defined in BC 1.2 */
enum usb_charger_type {
CHRG_UNKNOWN,
CHRG_SDP, /* Standard Downstream Port */
CHRG_CDP, /* Charging Downstream Port */
CHRG_SDP_INVAL, /* Invaild Standard Downstream Port */
CHRG_DCP, /* Dedicated Charging Port */
CHRG_ACA, /* Accessory Charger Adapter */
CHRG_ACA_DOCK, /* Accessory Charger Adapter - Dock */
CHRG_ACA_A, /* Accessory Charger Adapter - RID_A */
CHRG_ACA_B, /* Accessory Charger Adapter - RID_B */
CHRG_ACA_C, /* Accessory Charger Adapter - RID_C */
CHRG_SE1, /* SE1 (Apple)*/
CHRG_MHL /* Moblie High-Definition Link */
};
struct adp_status {
struct completion adp_comp;
u8 t_adp_rise;
};
/* Invalid SDP checking timeout */
#define INVALID_SDP_TIMEOUT (HZ * 15)
/* OTG Battery Charging capability is used in charger capability detection */
struct otg_bc_cap {
enum usb_charger_type chrg_type;
unsigned int ma;
#define CHRG_CURR_UNKNOWN 0
#define CHRG_CURR_DISCONN 0
#define CHRG_CURR_SDP_SUSP 2
#define CHRG_CURR_SDP_UNCONFIG 100
#define CHRG_CURR_SDP_LOW 100
#define CHRG_CURR_SDP_HIGH 500
#define CHRG_CURR_SDP_INVAL 500
#define CHRG_CURR_CDP 1500
#define CHRG_CURR_DCP 1500
#define CHRG_CURR_SE1 1500
#define CHRG_CURR_ACA 1500
unsigned int current_event;
};
struct otg_bc_event {
struct list_head node;
struct power_supply_cable_props cap;
};
/* Bus monitor action for b_ssend_srp/b_se0_srp */
#define BUS_MON_STOP 0
#define BUS_MON_START 1
#define BUS_MON_CONTINUE 2
/* define event ids to notify battery driver */
#define USBCHRG_EVENT_CONNECT 1
#define USBCHRG_EVENT_DISCONN 2
#define USBCHRG_EVENT_SUSPEND 3
#define USBCHRG_EVENT_RESUME 4
#define USBCHRG_EVENT_UPDATE 5
struct intel_mid_otg_pdata {
int gpio_vbus;
int gpio_cs;
int gpio_reset;
int charging_compliance;
int hnp_poll_support;
unsigned power_budget;
};
struct penwell_otg {
struct intel_mid_otg_xceiv iotg;
struct device *dev;
unsigned region;
unsigned cfg_region;
struct work_struct work;
struct work_struct hnp_poll_work;
struct work_struct psc_notify;
struct work_struct uevent_work;
struct delayed_work ulpi_poll_work;
struct delayed_work ulpi_check_work;
struct delayed_work sdp_check_work;
struct workqueue_struct *qwork;
struct workqueue_struct *chrg_qwork;
struct timer_list hsm_timer;
struct timer_list hnp_poll_timer;
struct timer_list bus_mon_timer;
unsigned long b_se0_srp_time;
unsigned long b_ssend_srp_time;
struct mutex msic_mutex;
enum msic_vendor msic;
struct notifier_block iotg_notifier;
int queue_stop;
struct adp_status adp;
spinlock_t charger_lock;
struct list_head chrg_evt_queue;
struct otg_bc_cap charging_cap;
spinlock_t cap_lock;
struct power_supply_cable_props psc_cap;
int (*bc_callback)(void *arg, int event, struct otg_bc_cap *cap);
void *bc_arg;
unsigned rt_resuming;
unsigned rt_quiesce;
struct intel_mid_otg_pdata *otg_pdata;
struct wake_lock wake_lock;
spinlock_t lock;
int phy_power_state;
};
static inline
struct penwell_otg *iotg_to_penwell(struct intel_mid_otg_xceiv *iotg)
{
return container_of(iotg, struct penwell_otg, iotg);
}
extern int penwell_otg_query_charging_cap(struct otg_bc_cap *cap);
extern int penwell_otg_query_power_supply_cap(
struct power_supply_cable_props *cap);
extern void *penwell_otg_register_bc_callback(
int (*cb)(void *, int, struct otg_bc_cap *), void *arg);
extern int penwell_otg_unregister_bc_callback(void *handler);
extern int pnw_otg_ulpi_write(u8 reg, u8 val);
extern int is_clovertrail(struct pci_dev *pdev);
#endif /* __PENWELL_OTG_H__ */