linux/include/linux/usb/otg-fsm.h
<<
>>
Prefs
   1/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc.
   2 *
   3 * This program is free software; you can redistribute  it and/or modify it
   4 * under  the terms of  the GNU General  Public License as published by the
   5 * Free Software Foundation;  either version 2 of the  License, or (at your
   6 * option) any later version.
   7 *
   8 * This program is distributed in the hope that it will be useful, but
   9 * WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11 * General Public License for more details.
  12 *
  13 * You should have received a copy of the  GNU General Public License along
  14 * with this program; if not, write  to the Free Software Foundation, Inc.,
  15 * 675 Mass Ave, Cambridge, MA 02139, USA.
  16 */
  17
  18#ifndef __LINUX_USB_OTG_FSM_H
  19#define __LINUX_USB_OTG_FSM_H
  20
  21#include <linux/mutex.h>
  22#include <linux/errno.h>
  23
  24#undef VERBOSE
  25
  26#ifdef VERBOSE
  27#define VDBG(fmt, args...) pr_debug("[%s]  " fmt , \
  28                                 __func__, ## args)
  29#else
  30#define VDBG(stuff...)  do {} while (0)
  31#endif
  32
  33#ifdef VERBOSE
  34#define MPC_LOC printk("Current Location [%s]:[%d]\n", __FILE__, __LINE__)
  35#else
  36#define MPC_LOC do {} while (0)
  37#endif
  38
  39#define PROTO_UNDEF     (0)
  40#define PROTO_HOST      (1)
  41#define PROTO_GADGET    (2)
  42
  43enum otg_fsm_timer {
  44        /* Standard OTG timers */
  45        A_WAIT_VRISE,
  46        A_WAIT_VFALL,
  47        A_WAIT_BCON,
  48        A_AIDL_BDIS,
  49        B_ASE0_BRST,
  50        A_BIDL_ADIS,
  51
  52        /* Auxiliary timers */
  53        B_SE0_SRP,
  54        B_SRP_FAIL,
  55        A_WAIT_ENUM,
  56
  57        NUM_OTG_FSM_TIMERS,
  58};
  59
  60/* OTG state machine according to the OTG spec */
  61struct otg_fsm {
  62        /* Input */
  63        int id;
  64        int adp_change;
  65        int power_up;
  66        int test_device;
  67        int a_bus_drop;
  68        int a_bus_req;
  69        int a_srp_det;
  70        int a_vbus_vld;
  71        int b_conn;
  72        int a_bus_resume;
  73        int a_bus_suspend;
  74        int a_conn;
  75        int b_bus_req;
  76        int b_se0_srp;
  77        int b_ssend_srp;
  78        int b_sess_vld;
  79        /* Auxilary inputs */
  80        int a_sess_vld;
  81        int b_bus_resume;
  82        int b_bus_suspend;
  83
  84        /* Output */
  85        int data_pulse;
  86        int drv_vbus;
  87        int loc_conn;
  88        int loc_sof;
  89        int adp_prb;
  90        int adp_sns;
  91
  92        /* Internal variables */
  93        int a_set_b_hnp_en;
  94        int b_srp_done;
  95        int b_hnp_enable;
  96        int a_clr_err;
  97
  98        /* Informative variables */
  99        int a_bus_drop_inf;
 100        int a_bus_req_inf;
 101        int a_clr_err_inf;
 102        int b_bus_req_inf;
 103        /* Auxilary informative variables */
 104        int a_suspend_req_inf;
 105
 106        /* Timeout indicator for timers */
 107        int a_wait_vrise_tmout;
 108        int a_wait_vfall_tmout;
 109        int a_wait_bcon_tmout;
 110        int a_aidl_bdis_tmout;
 111        int b_ase0_brst_tmout;
 112        int a_bidl_adis_tmout;
 113
 114        struct otg_fsm_ops *ops;
 115        struct usb_otg *otg;
 116
 117        /* Current usb protocol used: 0:undefine; 1:host; 2:client */
 118        int protocol;
 119        struct mutex lock;
 120};
 121
 122struct otg_fsm_ops {
 123        void    (*chrg_vbus)(struct otg_fsm *fsm, int on);
 124        void    (*drv_vbus)(struct otg_fsm *fsm, int on);
 125        void    (*loc_conn)(struct otg_fsm *fsm, int on);
 126        void    (*loc_sof)(struct otg_fsm *fsm, int on);
 127        void    (*start_pulse)(struct otg_fsm *fsm);
 128        void    (*start_adp_prb)(struct otg_fsm *fsm);
 129        void    (*start_adp_sns)(struct otg_fsm *fsm);
 130        void    (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
 131        void    (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
 132        int     (*start_host)(struct otg_fsm *fsm, int on);
 133        int     (*start_gadget)(struct otg_fsm *fsm, int on);
 134};
 135
 136
 137static inline int otg_chrg_vbus(struct otg_fsm *fsm, int on)
 138{
 139        if (!fsm->ops->chrg_vbus)
 140                return -EOPNOTSUPP;
 141        fsm->ops->chrg_vbus(fsm, on);
 142        return 0;
 143}
 144
 145static inline int otg_drv_vbus(struct otg_fsm *fsm, int on)
 146{
 147        if (!fsm->ops->drv_vbus)
 148                return -EOPNOTSUPP;
 149        if (fsm->drv_vbus != on) {
 150                fsm->drv_vbus = on;
 151                fsm->ops->drv_vbus(fsm, on);
 152        }
 153        return 0;
 154}
 155
 156static inline int otg_loc_conn(struct otg_fsm *fsm, int on)
 157{
 158        if (!fsm->ops->loc_conn)
 159                return -EOPNOTSUPP;
 160        if (fsm->loc_conn != on) {
 161                fsm->loc_conn = on;
 162                fsm->ops->loc_conn(fsm, on);
 163        }
 164        return 0;
 165}
 166
 167static inline int otg_loc_sof(struct otg_fsm *fsm, int on)
 168{
 169        if (!fsm->ops->loc_sof)
 170                return -EOPNOTSUPP;
 171        if (fsm->loc_sof != on) {
 172                fsm->loc_sof = on;
 173                fsm->ops->loc_sof(fsm, on);
 174        }
 175        return 0;
 176}
 177
 178static inline int otg_start_pulse(struct otg_fsm *fsm)
 179{
 180        if (!fsm->ops->start_pulse)
 181                return -EOPNOTSUPP;
 182        if (!fsm->data_pulse) {
 183                fsm->data_pulse = 1;
 184                fsm->ops->start_pulse(fsm);
 185        }
 186        return 0;
 187}
 188
 189static inline int otg_start_adp_prb(struct otg_fsm *fsm)
 190{
 191        if (!fsm->ops->start_adp_prb)
 192                return -EOPNOTSUPP;
 193        if (!fsm->adp_prb) {
 194                fsm->adp_sns = 0;
 195                fsm->adp_prb = 1;
 196                fsm->ops->start_adp_prb(fsm);
 197        }
 198        return 0;
 199}
 200
 201static inline int otg_start_adp_sns(struct otg_fsm *fsm)
 202{
 203        if (!fsm->ops->start_adp_sns)
 204                return -EOPNOTSUPP;
 205        if (!fsm->adp_sns) {
 206                fsm->adp_sns = 1;
 207                fsm->ops->start_adp_sns(fsm);
 208        }
 209        return 0;
 210}
 211
 212static inline int otg_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
 213{
 214        if (!fsm->ops->add_timer)
 215                return -EOPNOTSUPP;
 216        fsm->ops->add_timer(fsm, timer);
 217        return 0;
 218}
 219
 220static inline int otg_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
 221{
 222        if (!fsm->ops->del_timer)
 223                return -EOPNOTSUPP;
 224        fsm->ops->del_timer(fsm, timer);
 225        return 0;
 226}
 227
 228static inline int otg_start_host(struct otg_fsm *fsm, int on)
 229{
 230        if (!fsm->ops->start_host)
 231                return -EOPNOTSUPP;
 232        return fsm->ops->start_host(fsm, on);
 233}
 234
 235static inline int otg_start_gadget(struct otg_fsm *fsm, int on)
 236{
 237        if (!fsm->ops->start_gadget)
 238                return -EOPNOTSUPP;
 239        return fsm->ops->start_gadget(fsm, on);
 240}
 241
 242int otg_statemachine(struct otg_fsm *fsm);
 243
 244#endif /* __LINUX_USB_OTG_FSM_H */
 245