aboutsummaryrefslogtreecommitdiff
path: root/include/linux/msm_mhi_dev.h
blob: cb978a137be5af89dd5ec8da89be29ea7c6b9e4d (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
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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 __MSM_MHI_DEV_H
#define __MSM_MHI_DEV_H

#include <linux/types.h>
#include <linux/dma-mapping.h>

#define DMA_SYNC		1
#define DMA_ASYNC		0

enum cb_reason {
	MHI_DEV_TRE_AVAILABLE = 0,
	MHI_DEV_CTRL_UPDATE,
};

struct mhi_dev_client_cb_reason {
	uint32_t		ch_id;
	enum cb_reason		reason;
};

struct mhi_dev_client {
	struct list_head		list;
	struct mhi_dev_channel		*channel;
	void (*event_trigger)(struct mhi_dev_client_cb_reason *cb);

	/* mhi_dev calls are fully synchronous -- only one call may be
	 * active per client at a time for now.
	 */
	struct mutex			write_lock;
	wait_queue_head_t		wait;

	/* trace logs */
	spinlock_t			tr_lock;
	unsigned int			tr_head;
	unsigned int			tr_tail;
	struct mhi_dev_trace		*tr_log;

	/* client buffers */
	struct mhi_dev_iov		*iov;
	uint32_t			nr_iov;
};

enum mhi_ctrl_info {
	MHI_STATE_CONFIGURED = 0,
	MHI_STATE_CONNECTED = 1,
	MHI_STATE_DISCONNECTED = 2,
	MHI_STATE_INVAL,
};

struct mhi_req {
	u32                             chan;
	u32                             mode;
	u32				chain;
	void                            *buf;
	dma_addr_t                      dma;
	u32                             snd_cmpl;
	void                            *context;
	size_t                          len;
	size_t                          transfer_len;
	uint32_t                        rd_offset;
	struct mhi_dev_client           *client;
	struct list_head                list;
	union mhi_dev_ring_element_type *el;
	void (*client_cb)(void *req);
};

/* SW channel client list */
enum mhi_client_channel {
	MHI_CLIENT_LOOPBACK_OUT = 0,
	MHI_CLIENT_LOOPBACK_IN = 1,
	MHI_CLIENT_SAHARA_OUT = 2,
	MHI_CLIENT_SAHARA_IN = 3,
	MHI_CLIENT_DIAG_OUT = 4,
	MHI_CLIENT_DIAG_IN = 5,
	MHI_CLIENT_SSR_OUT = 6,
	MHI_CLIENT_SSR_IN = 7,
	MHI_CLIENT_QDSS_OUT = 8,
	MHI_CLIENT_QDSS_IN = 9,
	MHI_CLIENT_EFS_OUT = 10,
	MHI_CLIENT_EFS_IN = 11,
	MHI_CLIENT_MBIM_OUT = 12,
	MHI_CLIENT_MBIM_IN = 13,
	MHI_CLIENT_QMI_OUT = 14,
	MHI_CLIENT_QMI_IN = 15,
	MHI_CLIENT_IP_CTRL_0_OUT = 16,
	MHI_CLIENT_IP_CTRL_0_IN = 17,
	MHI_CLIENT_IP_CTRL_1_OUT = 18,
	MHI_CLIENT_IP_CTRL_1_IN = 19,
	MHI_CLIENT_IPCR_OUT = 20,
	MHI_CLIENT_IPCR_IN = 21,
	MHI_CLIENT_IP_CTRL_3_OUT = 22,
	MHI_CLIENT_IP_CTRL_3_IN = 23,
	MHI_CLIENT_IP_CTRL_4_OUT = 24,
	MHI_CLIENT_IP_CTRL_4_IN = 25,
	MHI_CLIENT_IP_CTRL_5_OUT = 26,
	MHI_CLIENT_IP_CTRL_5_IN = 27,
	MHI_CLIENT_IP_CTRL_6_OUT = 28,
	MHI_CLIENT_IP_CTRL_6_IN = 29,
	MHI_CLIENT_IP_CTRL_7_OUT = 30,
	MHI_CLIENT_IP_CTRL_7_IN = 31,
	MHI_CLIENT_DUN_OUT = 32,
	MHI_CLIENT_DUN_IN = 33,
	MHI_CLIENT_IP_SW_0_OUT = 34,
	MHI_CLIENT_IP_SW_0_IN = 35,
	MHI_CLIENT_ADB_OUT = 36,
	MHI_CLIENT_ADB_IN = 37,
	MHI_CLIENT_IP_SW_2_OUT = 38,
	MHI_CLIENT_IP_SW_2_IN = 39,
	MHI_CLIENT_IP_SW_3_OUT = 40,
	MHI_CLIENT_IP_SW_3_IN = 41,
	MHI_CLIENT_CSVT_OUT = 42,
	MHI_CLIENT_CSVT_IN = 43,
	MHI_CLIENT_SMCT_OUT = 44,
	MHI_CLIENT_SMCT_IN = 45,
	MHI_CLIENT_IP_SW_4_OUT  = 46,
	MHI_CLIENT_IP_SW_4_IN  = 47,
	MHI_MAX_SOFTWARE_CHANNELS,
	MHI_CLIENT_TEST_OUT = 60,
	MHI_CLIENT_TEST_IN = 61,
	MHI_CLIENT_RESERVED_1_LOWER = 62,
	MHI_CLIENT_RESERVED_1_UPPER = 99,
	MHI_CLIENT_IP_HW_0_OUT = 100,
	MHI_CLIENT_IP_HW_0_IN = 101,
	MHI_CLIENT_ADPL_IN = 102,
	MHI_CLIENT_IP_HW_QDSS = 103,
	MHI_CLIENT_QMAP_FLOW_CTRL_OUT = 109,
	MHI_CLIENT_QMAP_FLOW_CTRL_IN = 110,
	MHI_MAX_CHANNELS = 255,
	MHI_CLIENT_INVALID = 0xFFFFFFFF
};

struct mhi_dev_client_cb_data {
	void			*user_data;
	enum mhi_client_channel	channel;
	enum mhi_ctrl_info	ctrl_info;
};

typedef void (*mhi_state_cb)(struct mhi_dev_client_cb_data *cb_dat);

struct mhi_dev_ready_cb_info {
	struct list_head		list;
	mhi_state_cb			cb;
	struct mhi_dev_client_cb_data	cb_data;
};

#if defined(CONFIG_MSM_MHI_DEV)
/**
 * mhi_dev_open_channel() - Channel open for a given client done prior
 *		to read/write.
 * @chan_id:	Software Channel ID for the assigned client.
 * @handle_client: Structure device for client handle.
 * @notifier: Client issued callback notification.
 */
int mhi_dev_open_channel(uint32_t chan_id,
		struct mhi_dev_client **handle_client,
		void (*event_trigger)(struct mhi_dev_client_cb_reason *cb));

/**
 * mhi_dev_close_channel() - Channel close for a given client.
 */
void mhi_dev_close_channel(struct mhi_dev_client *handle_client);

/**
 * mhi_dev_read_channel() - Channel read for a given client
 * @mreq:       mreq is the client argument which includes meta info
 *              like write data location, buffer len, read offset, mode,
 *              chain and client call back function which will be invoked
 *              when data read is completed.
 */
int mhi_dev_read_channel(struct mhi_req *mreq);

/**
 * mhi_dev_write_channel() - Channel write for a given software client.
 * @wreq	wreq is the client argument which includes meta info like
 *              client handle, read data location, buffer length, mode,
 *              and client call back function which will free the packet.
 *              when data write is completed.
 */
int mhi_dev_write_channel(struct mhi_req *wreq);

/**
 * mhi_dev_channel_isempty() - Checks if there is any pending TRE's to process.
 * @handle_client:	Client Handle issued during mhi_dev_open_channel
 */
int mhi_dev_channel_isempty(struct mhi_dev_client *handle);

/**
* mhi_dev_channel_has_pending_write() - Checks if there are any pending writes
*					to be completed on inbound channel
* @handle_client:	Client Handle issued during mhi_dev_open_channel
*/
bool mhi_dev_channel_has_pending_write(struct mhi_dev_client *handle);

/**
 * mhi_ctrl_state_info() - Provide MHI state info
 *		@idx: Channel number idx. Look at channel_state_info and
 *		pass the index for the corresponding channel.
 *		@info: Return the control info.
 *		MHI_STATE=CONFIGURED - MHI device is present but not ready
 *					for data traffic.
 *		MHI_STATE=CONNECTED - MHI device is ready for data transfer.
 *		MHI_STATE=DISCONNECTED - MHI device has its pipes suspended.
 *		exposes device nodes for the supported MHI software
 *		channels.
 */
int mhi_ctrl_state_info(uint32_t idx, uint32_t *info);

/**
 * mhi_register_state_cb() - Clients can register and receive callback after
 *		MHI channel is connected or disconnected.
 */
int mhi_register_state_cb(void (*mhi_state_cb)
			(struct mhi_dev_client_cb_data *cb_data), void *data,
			enum mhi_client_channel channel);

#else
static inline int mhi_dev_open_channel(uint32_t chan_id,
		struct mhi_dev_client **handle_client,
		void (*event_trigger)(struct mhi_dev_client_cb_reason *cb))
{
	return -EINVAL;
};

static inline int mhi_dev_close_channel(struct mhi_dev_client *handle_client)
{
	return -EINVAL;
};

static inline int mhi_dev_read_channel(struct mhi_req *mreq)
{
	return -EINVAL;
};

static inline int mhi_dev_write_channel(struct mhi_req *wreq)
{
	return -EINVAL;
};

static inline int mhi_dev_channel_isempty(struct mhi_dev_client *handle)
{
	return -EINVAL;
};

static inline bool mhi_dev_channel_has_pending_write
	(struct mhi_dev_client *handle)
{
	return false;
}

static inline int mhi_ctrl_state_info(uint32_t idx, uint32_t *info)
{
	return -EINVAL;
};

static inline int mhi_register_state_cb(void (*mhi_state_cb)
			(struct mhi_dev_client_cb_data *cb_data), void *data,
			enum mhi_client_channel channel)
{
	return -EINVAL;
};
#endif

#endif /* _MSM_MHI_DEV_H*/