aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/modem_if_na/modem_link_device_usb.h
blob: 0db83b148a79ab9e52f9e15255c050958390d129 (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
/*
 * Copyright (C) 2010 Google, Inc.
 * Copyright (C) 2010 Samsung Electronics.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that 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.
 *
 */

#ifndef __MODEM_LINK_DEVICE_USB_H__
#define __MODEM_LINK_DEVICE_USB_H__

#include <linux/usb.h>
#include <linux/wakelock.h>

#define IF_USB_DEVNUM_MAX	3

#define IF_USB_FMT_EP		0
#define IF_USB_RAW_EP		1
#define IF_USB_RFS_EP		2

#define AUTOSUSPEND_DELAY_MS			500
#define HOST_WAKEUP_TIMEOUT_JIFFIES		msecs_to_jiffies(500)
#define WAIT_ENUMURATION_TIMEOUT_JIFFIES	msecs_to_jiffies(30000)
#define MAX_RETRY	3

enum RESUME_STATUS {
	CP_INITIATED_RESUME,
	AP_INITIATED_RESUME,
};

enum {
	EDC_MAX_ERRORS = 5,
	EDC_ERROR_TIMEFRAME = HZ,
};

struct edc {
	unsigned long timestart;
	u16 errorcount;
};

static inline void edc_init(struct edc *edc)
{
	edc->timestart = jiffies;
}

static inline int edc_inc(struct edc *edc, u16 max_err, u16 timeframe)
{
	unsigned long now;

	now = jiffies;
	if (now - edc->timestart > timeframe) {
		edc->errorcount = 1;
		edc->timestart = now;
	} else if (++edc->errorcount > max_err) {
		edc->errorcount = 0;
		edc->timestart = now;
		return 1;
	}
	return 0;
}

struct if_usb_devdata {
	struct usb_interface *data_intf;
	unsigned int tx_pipe;
	unsigned int rx_pipe;
	u8 disconnected;

	int format;
	struct usb_anchor urbs;
	struct usb_anchor reading;
	unsigned int rx_buf_size;
};

struct usb_link_device {
	/*COMMON LINK DEVICE*/
	struct link_device ld;

	struct modem_data *pdata;

	/*USB SPECIFIC LINK DEVICE*/
	struct usb_device	*usbdev;
	struct if_usb_devdata	devdata[IF_USB_DEVNUM_MAX];
	struct delayed_work	runtime_pm_work;
	struct delayed_work	post_resume_work;
	struct delayed_work     wait_enumeration;
	struct work_struct	disconnect_work;

	struct wake_lock	gpiolock;
	struct wake_lock	susplock;

	unsigned int		dev_count;
	unsigned int		suspended;
	atomic_t		suspend_count;
	enum RESUME_STATUS	resume_status;
	int if_usb_connected;
	int flow_suspend;
	int host_wake_timeout_flag;

	unsigned gpio_slave_wakeup;
	unsigned gpio_host_wakeup;
	unsigned gpio_host_active;
	int irq_host_wakeup;
	struct delayed_work dwork;
	struct work_struct resume_work;
	int cpcrash_flag;
	wait_queue_head_t l2_wait;

	spinlock_t		lock;
	struct usb_anchor	deferred;

	/* LINK PM DEVICE DATA */
	struct link_pm_data *link_pm_data;

	/*COMMON LINK DEVICE*/
	/* maybe -list of io devices for the link device to use */
	/* to find where to send incoming packets to */
	struct list_head list_of_io_devices;

	struct edc urb_edc;
};
/* converts from struct link_device* to struct xxx_link_device* */
#define to_usb_link_device(linkdev) \
			container_of(linkdev, struct usb_link_device, ld)

#define SET_SLAVE_WAKEUP(_pdata, _value)			\
do {								\
	gpio_set_value(_pdata->gpio_slave_wakeup, _value);	\
	mif_debug("> S-WUP %s\n", _value ? "1" : "0");	\
} while (0)

#define SET_HOST_ACTIVE(_pdata, _value)			\
do {								\
	gpio_set_value(_pdata->gpio_host_active, _value);	\
	mif_debug("> H-ACT %s\n", _value ? "1" : "0");	\
} while (0)

#define has_hub(usb_ld) ((usb_ld)->link_pm_data->has_usbhub)

irqreturn_t usb_resume_irq(int irq, void *data);

#endif