aboutsummaryrefslogtreecommitdiff
path: root/include/linux/tsif_api.h
blob: b69ddf595f3ae2824ba925ece6488da36c55af5a (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
/**
 * TSIF driver
 *
 * Kernel API
 *
 * Copyright (c) 2012-2013, 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 _TSIF_API_H_
#define _TSIF_API_H_
/**
 * Theory of operation
 *
 * TSIF driver maintains internal cyclic data buffer where
 * received TSIF packets are stored. Size of buffer, in packets,
 * and its address, may be obtained by tsif_get_info().
 *
 * TSIF stream delivered to the client that should register with
 * TSIF driver using tsif_attach()
 *
 * Producer-consumer pattern used. TSIF driver act as producer,
 * writing data to the buffer; clientis consumer.
 * 2 indexes maintained by the TSIF driver:
 * - wi (write index) points to the next item to be written by
 *   TSIF
 * - ri (read index) points to the next item available for read
 *   by the client.
 * Write index advanced by the TSIF driver when new data
 * received;
 * Read index advanced only when client tell so to the TSIF
 * driver by tsif_reclaim_packets()
 *
 * Consumer may directly access data TSIF buffer between ri and
 * wi. When ri==wi, buffer is empty.
 *
 * TSIF driver notifies client about any change by calling
 * notify function. Client should use tsif_get_state() to query
 * new state.
 */

/* bytes in TSIF packet. not customizable */
#define TSIF_PKT_SIZE             (192)

/**
 * tsif_pkt_status - get TSIF packet status
 *
 * @pkt: TSIF packet location
 *
 * Return last DWORD of packet, containing status.
 * Status dword consists of:
 * - 3 low bytes TTS
 * - 1 byte (last byte of packet) with status bits
 */
static inline u32 tsif_pkt_status(void *pkt)
{
	u32 *x = pkt;
	return x[TSIF_PKT_SIZE / sizeof(u32) - 1];
}

/**
 * Status dword parts for status returned by @tsif_pkt_status
 */
#define TSIF_STATUS_TTS(x)   ((x) & 0xffffff)
#define TSIF_STATUS_VALID(x) ((x) & (1<<24))
#define TSIF_STATUS_FIRST(x) ((x) & (1<<25))
#define TSIF_STATUS_OVFLW(x) ((x) & (1<<26))
#define TSIF_STATUS_ERROR(x) ((x) & (1<<27))
#define TSIF_STATUS_NULL(x)  ((x) & (1<<28))
#define TSIF_STATUS_TIMEO(x) ((x) & (1<<30))

/**
 * enum tsif_state - TSIF device state
 * @tsif_state_stopped:     Idle state, data acquisition not running
 * @tsif_state_running:     Data acquisition in progress
 * @tsif_state_flushing:    Device is flushing
 *
 * State transition diagram:
 *
 * init -> tsif_state_stopped
 *
 * tsif_state_stopped:
 *   - open -> tsif_state_running
 *
 * tsif_state_running:
 *   - close -> tsif_state_flushing
 *
 * tsif_state_flushing:
 *   - flushed -> tsif_state_stopped
 */
enum tsif_state {
	tsif_state_stopped  = 0,
	tsif_state_running  = 1,
	tsif_state_flushing = 2,
	tsif_state_error    = 3,
};

/**
 * tsif_get_active - return active tsif hardware instance
 *
 * Return     TSIF instance to use (selected by CONFIG_MSM_USE_TSIF1)
 */
int tsif_get_active(void);

/**
 * tsif_attach - Attach to the device.
 * @id:       TSIF device ID, used to identify TSIF instance.
 * @notify:   client callback, called when
 *            any client visible TSIF state changed.
 *            This includes new data available and device state change
 * @data:     client data, will be passed to @notify
 *
 * Return     TSIF cookie or error code
 *
 * Should be called prior to any other tsif_XXX function.
 */
void *tsif_attach(int id, void (*notify)(void *client_data), void *client_data);

/**
 * tsif_detach - detach from device
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 */
void tsif_detach(void *cookie);

/**
 * tsif_get_info - get data buffer info
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 * @pdata:     if not NULL, TSIF data buffer will be stored there
 * @psize:     if not NULL, TSIF data buffer size, in packets,
 *             will be stored there
 *
 * Data buffer information should be queried after each tsif_start() before
 * using data; since data buffer will be re-allocated on tsif_start()
 */
void tsif_get_info(void *cookie, void **pdata, int *psize);

/**
 * tsif_set_mode - set TSIF mode
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 * @mode:      desired mode of operation
 *
 * Return      error code
 *
 * Mode may be changed only when TSIF device is stopped.
 */
int tsif_set_mode(void *cookie, int mode);

/**
 * tsif_set_time_limit - set TSIF time limit
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 * @value:     desired time limit, 0 to disable
 *
 * Return      error code
 *
 * Time limit may be changed only when TSIF device is stopped.
 */
int tsif_set_time_limit(void *cookie, u32 value);

/**
 * tsif_set_buf_config - configure data buffer
 *
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 * @pkts_in_chunk: requested number of packets per chunk
 * @chunks_in_buf: requested number of chunks in buffer
 *
 * Return      error code
 *
 * Parameter selection criteria:
 *
 * - @pkts_in_chunk defines size of DMA transfer and, in turn, time between
 *   consecutive DMA transfers. Increase @pkts_in_chunk reduces chance for
 *   hardware overflow. If TSIF stats reports overflows, increase it.
 *
 * - @chunks_in_buf * @pkts_in_chunk defines total buffer size. Increase this
 *   parameter if client latency is large and TSIF reports "soft drop" in its
 *   stats
 */
int tsif_set_buf_config(void *cookie, u32 pkts_in_chunk, u32 chunks_in_buf);

/**
 * tsif_get_state - query current data buffer information
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 * @ri:        if not NULL, read index will be stored here
 * @wi:        if not NULL, write index will be stored here
 * @state:     if not NULL, state will be stored here
 */
void tsif_get_state(void *cookie, int *ri, int *wi, enum tsif_state *state);

/**
 * tsif_set_clk_inverse - set whether to inverse the clock signal.
 * @cookie:   TSIF cookie previously obtained with tsif_attach()
 * @inverse:  1 to inverse the clock, 0 otherwise. Default is 0.
 *
 * Return      error code
 *
 * Setting may be changed only when TSIF device is stopped.
 */
int tsif_set_clk_inverse(void *cookie, int inverse);

/**
 * tsif_set_data_inverse - set whether to inverse the data signal.
 * @cookie:   TSIF cookie previously obtained with tsif_attach()
 * @inverse:  1 to inverse the clock, 0 otherwise. Default is 0.
 *
 * Return      error code
 *
 * Setting may be changed only when TSIF device is stopped.
 */
int tsif_set_data_inverse(void *cookie, int inverse);

/**
 * tsif_set_sync_inverse - set whether to inverse the sync signal.
 * @cookie:   TSIF cookie previously obtained with tsif_attach()
 * @inverse:  1 to inverse the clock, 0 otherwise. Default is 0.
 *
 * Return      error code
 *
 * Setting may be changed only when TSIF device is stopped.
 */
int tsif_set_sync_inverse(void *cookie, int inverse);

/**
 * tsif_set_enable_inverse - set whether to inverse the enable signal.
 * @cookie:   TSIF cookie previously obtained with tsif_attach()
 * @inverse:  1 to inverse the clock, 0 otherwise. Default is 0.
 *
 * Return      error code
 *
 * Setting may be changed only when TSIF device is stopped.
 */
int tsif_set_enable_inverse(void *cookie, int inverse);

/**
 * tsif_start - start data acquisition
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 *
 * Return      error code
 */
int tsif_start(void *cookie);

/**
 * tsif_stop - stop data acquisition
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 *
 * Data buffer allocated during this function call; thus client should
 * query data buffer info using tsif_get_info() and reset its data pointers.
 */
void tsif_stop(void *cookie);

/**
 * tsif_get_ref_clk_counter - return the TSIF clock reference (TCR) counter.
 * @cookie:      TSIF cookie previously obtained with tsif_attach()
 * @tcr_counter: the value of TCR counter
 *
 * Return      error code
 *
 * TCR increments at a rate equal to 27 MHz/256 = 105.47 kHz.
 */
int tsif_get_ref_clk_counter(void *cookie, u32 *tcr_counter);

/**
 * tsif_reclaim_packets - inform that buffer space may be reclaimed
 * @cookie:    TSIF cookie previously obtained with tsif_attach()
 * @ri:        new value for read index
 */
void tsif_reclaim_packets(void *cookie, int ri);

#endif /* _TSIF_API_H_ */