aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/usb/penwell_otg.h
blob: 77776caa87a1584925331f80766650baadf764f5 (plain)
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/*
 * 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>

#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_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_IS4SET		0x2c8	/* Intel Specific */
#	define IS4_CHGDSERXDPINV	BIT(5)
#define MSIC_OTGCTRL		0x39c
#define MSIC_OTGCTRLSET		0x340
#define MSIC_OTGCTRLCLR		0x341
#	define DMPULLDOWN		BIT(2)
#	define DPPULLDOWN		BIT(1)
#define MSIC_PWRCTRL		0x3b5
#define MSIC_PWRCTRLSET		0x342
#define MSIC_PWRCTRLCLR		0x343
#	define HWDET			BIT(7)
#	define DPVSRCEN			BIT(6)
#	define DPWKPUEN			BIT(4)
#	define SWCNTRL			BIT(0)
#define MSIC_FUNCTRL		0x398
#define MSIC_FUNCTRLSET		0x344
#define MSIC_FUNCTRLCLR		0x345
#	define OPMODE1			BIT(4)
#	define OPMODE0			BIT(3)
#define MSIC_VS3		0x3b9
#define MSIC_VS3SET		0x346	/* Vendor Specific */
#define MSIC_VS3CLR		0x347
#	define SWUSBDET			BIT(4)
#	define DATACONEN		BIT(3)
#define MSIC_ULPIACCESSMODE	0x348
#	define SPIMODE			BIT(0)

/* MSIC TI implementation for ADP/ACA */
#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		1000
#define DATACON_INTERVAL	50

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
};

#define TA_WAIT_VRISE		100
#define TA_WAIT_BCON		30000
#define TA_AIDL_BDIS		1500
#define TA_BIDL_ADIS		300
#define TA_WAIT_VFALL		950
#define TB_ASE0_BRST		300
#define TB_SE0_SRP		1800
#define TB_SSEND_SRP		1800
#	define SRP_MON_INVAL	200
#define TB_SRP_FAIL		5500
#define TB_BUS_SUSPEND		500
#define THOS_REQ_POL		1500

/* MSIC vendor information */
enum msic_vendor {
	MSIC_VD_FS,
	MSIC_VD_TI,
	MSIC_VD_UNKNOWN
};

/* charger defined in BC 1.1 */
enum usb_charger_type {
	CHRG_UNKNOWN,
	CHRG_SDP,	/* Standard Downstream Port */
	CHRG_CDP,	/* Charging Downstream Port */
	CHRG_DCP,	/* Dedicated Charging Port */
	CHRG_ACA	/* Accessory Charger Adapter */
};

struct adp_status {
	struct completion	adp_comp;
	u8			t_adp_rise;
};

/* 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_LOW	100
#define CHRG_CURR_SDP_HIGH	500
#define CHRG_CURR_CDP		500
#define CHRG_CURR_CDP_HS	950
#define CHRG_CURR_DCP	1500
#define CHRG_CURR_ACA	1500
};

/* 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 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 workqueue_struct		*qwork;

	struct timer_list		hsm_timer;
	struct timer_list		hnp_poll_timer;

	struct mutex			msic_mutex;
	enum msic_vendor		msic;

	struct notifier_block		iotg_notifier;

	struct adp_status		adp;

	spinlock_t			charger_lock;
	struct otg_bc_cap		charging_cap;
	int (*bc_callback)(void *arg, int event, struct otg_bc_cap *cap);
	void				*bc_arg;
};

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 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);

#endif /* __PENWELL_OTG_H__ */