aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/usb/intel_mid_otg.h
blob: 756cf5543ffddcc31e2a76bbaf333aefce726ee0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * Intel MID (Langwell/Penwell) USB OTG Transceiver driver
 * Copyright (C) 2008 - 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 __INTEL_MID_OTG_H
#define __INTEL_MID_OTG_H

#include <linux/pm.h>
#include <linux/usb/otg.h>
#include <linux/notifier.h>

struct intel_mid_otg_xceiv;

/* This is a common data structure for Intel MID platform to
 * save values of the OTG state machine */
struct otg_hsm {
	/* Input */
	int a_bus_resume;
	int a_bus_suspend;
	int a_conn;
	int a_sess_vld;
	int a_srp_det;
	int a_vbus_vld;
	int b_bus_resume;
	int b_bus_suspend;
	int b_conn;
	int b_se0_srp;
	int b_ssend_srp;
	int b_sess_end;
	int b_sess_vld;
	int id;
/* id values */
#define ID_B		0x05
#define ID_A		0x04
#define ID_ACA_C	0x03
#define ID_ACA_B	0x02
#define ID_ACA_A	0x01
	int power_up;
	int adp_change;
	int test_device;

	/* Internal variables */
	int a_set_b_hnp_en;
	int b_srp_done;
	int b_hnp_enable;
	int hnp_poll_enable;

	/* Timeout indicator for timers */
	int a_wait_vrise_tmout;
	int a_wait_bcon_tmout;
	int a_aidl_bdis_tmout;
	int a_bidl_adis_tmout;
	int a_bidl_adis_tmr;
	int a_wait_vfall_tmout;
	int b_ase0_brst_tmout;
	int b_bus_suspend_tmout;
	int b_srp_init_tmout;
	int b_srp_fail_tmout;
	int b_srp_fail_tmr;
	int b_adp_sense_tmout;

	/* Informative variables */
	int a_bus_drop;
	int a_bus_req;
	int a_clr_err;
	int b_bus_req;
	int a_suspend_req;
	int b_bus_suspend_vld;

	/* Output */
	int drv_vbus;
	int loc_conn;
	int loc_sof;

	/* Others */
	int vbus_srp_up;
};

/* must provide ULPI access function to read/write registers implemented in
 * ULPI address space */
struct iotg_ulpi_access_ops {
	int	(*read)(struct intel_mid_otg_xceiv *iotg, u8 reg, u8 *val);
	int	(*write)(struct intel_mid_otg_xceiv *iotg, u8 reg, u8 val);
};

#define OTG_A_DEVICE	0x0
#define OTG_B_DEVICE	0x1

/*
 * the Intel MID (Langwell/Penwell) otg transceiver driver needs to interact
 * with device and host drivers to implement the USB OTG related feature. More
 * function members are added based on usb_phy data structure for this
 * purpose.
 */
struct intel_mid_otg_xceiv {
	struct usb_phy		otg;
	struct otg_hsm		hsm;

	/* base address */
	void __iomem		*base;

	/* ops to access ulpi */
	struct iotg_ulpi_access_ops	ulpi_ops;

	/* atomic notifier for interrupt context */
	struct atomic_notifier_head	iotg_notifier;

	/* start/stop USB Host function */
	int	(*start_host)(struct intel_mid_otg_xceiv *iotg);
	int	(*stop_host)(struct intel_mid_otg_xceiv *iotg);

	/* start/stop USB Peripheral function */
	int	(*start_peripheral)(struct intel_mid_otg_xceiv *iotg);
	int	(*stop_peripheral)(struct intel_mid_otg_xceiv *iotg);

	/* start/stop ADP sense/probe function */
	int	(*set_adp_probe)(struct intel_mid_otg_xceiv *iotg,
					bool enabled, int dev);
	int	(*set_adp_sense)(struct intel_mid_otg_xceiv *iotg,
					bool enabled);

#ifdef CONFIG_PM
	/* suspend/resume USB host function */
	int	(*suspend_host)(struct intel_mid_otg_xceiv *iotg,
					pm_message_t message);
	int	(*resume_host)(struct intel_mid_otg_xceiv *iotg);

	int	(*suspend_peripheral)(struct intel_mid_otg_xceiv *iotg,
					pm_message_t message);
	int	(*resume_peripheral)(struct intel_mid_otg_xceiv *iotg);
#endif

};
static inline
struct intel_mid_otg_xceiv *otg_to_mid_xceiv(struct usb_phy *otg)
{
	return container_of(otg, struct intel_mid_otg_xceiv, otg);
}

#define MID_OTG_NOTIFY_CONNECT		0x0001
#define MID_OTG_NOTIFY_DISCONN		0x0002
#define MID_OTG_NOTIFY_HSUSPEND		0x0003
#define MID_OTG_NOTIFY_HRESUME		0x0004
#define MID_OTG_NOTIFY_CSUSPEND		0x0005
#define MID_OTG_NOTIFY_CRESUME		0x0006
#define MID_OTG_NOTIFY_HOSTADD		0x0007
#define MID_OTG_NOTIFY_HOSTREMOVE	0x0008
#define MID_OTG_NOTIFY_CLIENTADD	0x0009
#define MID_OTG_NOTIFY_CLIENTREMOVE	0x000a

static inline int
intel_mid_otg_register_notifier(struct intel_mid_otg_xceiv *iotg,
				struct notifier_block *nb)
{
	return atomic_notifier_chain_register(&iotg->iotg_notifier, nb);
}

static inline void
intel_mid_otg_unregister_notifier(struct intel_mid_otg_xceiv *iotg,
				struct notifier_block *nb)
{
	atomic_notifier_chain_unregister(&iotg->iotg_notifier, nb);
}

#endif /* __INTEL_MID_OTG_H */