1/* 2 * Intel MID (Langwell/Penwell) USB OTG Transceiver driver 3 * Copyright (C) 2008 - 2010, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 */ 19 20#ifndef __INTEL_MID_OTG_H 21#define __INTEL_MID_OTG_H 22 23#include <linux/pm.h> 24#include <linux/usb/otg.h> 25#include <linux/notifier.h> 26 27struct intel_mid_otg_xceiv; 28 29/* This is a common data structure for Intel MID platform to 30 * save values of the OTG state machine */ 31struct otg_hsm { 32 /* Input */ 33 int a_bus_resume; 34 int a_bus_suspend; 35 int a_conn; 36 int a_sess_vld; 37 int a_srp_det; 38 int a_vbus_vld; 39 int b_bus_resume; 40 int b_bus_suspend; 41 int b_conn; 42 int b_se0_srp; 43 int b_ssend_srp; 44 int b_sess_end; 45 int b_sess_vld; 46 int id; 47/* id values */ 48#define ID_B 0x05 49#define ID_A 0x04 50#define ID_ACA_C 0x03 51#define ID_ACA_B 0x02 52#define ID_ACA_A 0x01 53 int power_up; 54 int adp_change; 55 int test_device; 56 57 /* Internal variables */ 58 int a_set_b_hnp_en; 59 int b_srp_done; 60 int b_hnp_enable; 61 int hnp_poll_enable; 62 63 /* Timeout indicator for timers */ 64 int a_wait_vrise_tmout; 65 int a_wait_bcon_tmout; 66 int a_aidl_bdis_tmout; 67 int a_bidl_adis_tmout; 68 int a_bidl_adis_tmr; 69 int a_wait_vfall_tmout; 70 int b_ase0_brst_tmout; 71 int b_bus_suspend_tmout; 72 int b_srp_init_tmout; 73 int b_srp_fail_tmout; 74 int b_srp_fail_tmr; 75 int b_adp_sense_tmout; 76 77 /* Informative variables */ 78 int a_bus_drop; 79 int a_bus_req; 80 int a_clr_err; 81 int b_bus_req; 82 int a_suspend_req; 83 int b_bus_suspend_vld; 84 85 /* Output */ 86 int drv_vbus; 87 int loc_conn; 88 int loc_sof; 89 90 /* Others */ 91 int vbus_srp_up; 92}; 93 94/* must provide ULPI access function to read/write registers implemented in 95 * ULPI address space */ 96struct iotg_ulpi_access_ops { 97 int (*read)(struct intel_mid_otg_xceiv *iotg, u8 reg, u8 *val); 98 int (*write)(struct intel_mid_otg_xceiv *iotg, u8 reg, u8 val); 99}; 100 101#define OTG_A_DEVICE 0x0 102#define OTG_B_DEVICE 0x1 103 104/* 105 * the Intel MID (Langwell/Penwell) otg transceiver driver needs to interact 106 * with device and host drivers to implement the USB OTG related feature. More 107 * function members are added based on usb_phy data structure for this 108 * purpose. 109 */ 110struct intel_mid_otg_xceiv { 111 struct usb_phy otg; 112 struct otg_hsm hsm; 113 114 /* base address */ 115 void __iomem *base; 116 117 /* ops to access ulpi */ 118 struct iotg_ulpi_access_ops ulpi_ops; 119 120 /* atomic notifier for interrupt context */ 121 struct atomic_notifier_head iotg_notifier; 122 123 /* start/stop USB Host function */ 124 int (*start_host)(struct intel_mid_otg_xceiv *iotg); 125 int (*stop_host)(struct intel_mid_otg_xceiv *iotg); 126 127 /* start/stop USB Peripheral function */ 128 int (*start_peripheral)(struct intel_mid_otg_xceiv *iotg); 129 int (*stop_peripheral)(struct intel_mid_otg_xceiv *iotg); 130 131 /* start/stop ADP sense/probe function */ 132 int (*set_adp_probe)(struct intel_mid_otg_xceiv *iotg, 133 bool enabled, int dev); 134 int (*set_adp_sense)(struct intel_mid_otg_xceiv *iotg, 135 bool enabled); 136 137#ifdef CONFIG_PM 138 /* suspend/resume USB host function */ 139 int (*suspend_host)(struct intel_mid_otg_xceiv *iotg, 140 pm_message_t message); 141 int (*resume_host)(struct intel_mid_otg_xceiv *iotg); 142 143 int (*suspend_peripheral)(struct intel_mid_otg_xceiv *iotg, 144 pm_message_t message); 145 int (*resume_peripheral)(struct intel_mid_otg_xceiv *iotg); 146#endif 147 148}; 149static inline 150struct intel_mid_otg_xceiv *otg_to_mid_xceiv(struct usb_phy *otg) 151{ 152 return container_of(otg, struct intel_mid_otg_xceiv, otg); 153} 154 155#define MID_OTG_NOTIFY_CONNECT 0x0001 156#define MID_OTG_NOTIFY_DISCONN 0x0002 157#define MID_OTG_NOTIFY_HSUSPEND 0x0003 158#define MID_OTG_NOTIFY_HRESUME 0x0004 159#define MID_OTG_NOTIFY_CSUSPEND 0x0005 160#define MID_OTG_NOTIFY_CRESUME 0x0006 161#define MID_OTG_NOTIFY_HOSTADD 0x0007 162#define MID_OTG_NOTIFY_HOSTREMOVE 0x0008 163#define MID_OTG_NOTIFY_CLIENTADD 0x0009 164#define MID_OTG_NOTIFY_CLIENTREMOVE 0x000a 165 166static inline int 167intel_mid_otg_register_notifier(struct intel_mid_otg_xceiv *iotg, 168 struct notifier_block *nb) 169{ 170 return atomic_notifier_chain_register(&iotg->iotg_notifier, nb); 171} 172 173static inline void 174intel_mid_otg_unregister_notifier(struct intel_mid_otg_xceiv *iotg, 175 struct notifier_block *nb) 176{ 177 atomic_notifier_chain_unregister(&iotg->iotg_notifier, nb); 178} 179 180#endif /* __INTEL_MID_OTG_H */ 181