Merge branch 'for-2.6.37' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc...
[pandora-kernel.git] / drivers / staging / westbridge / astoria / include / linux / westbridge / cyaslowlevel.h
1 /* Cypress West Bridge API header file (cyaslowlevel.h)
2 ## ===========================
3 ## Copyright (C) 2010  Cypress Semiconductor
4 ##
5 ## This program is free software; you can redistribute it and/or
6 ## modify it under the terms of the GNU General Public License
7 ## as published by the Free Software Foundation; either version 2
8 ## of the License, or (at your option) any later version.
9 ##
10 ## This program is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ## GNU General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with this program; if not, write to the Free Software
17 ## Foundation, Inc., 51 Franklin Street
18 ## Fifth Floor, Boston, MA  02110-1301, USA.
19 ## ===========================
20 */
21
22 #ifndef _INCLUDED_CYASLOWLEVEL_H_
23 #define _INCLUDED_CYASLOWLEVEL_H_
24
25 /*@@Low Level Communications
26
27         Summary
28         The low level communications module is responsible for
29         communications between the West Bridge device and the P
30         port processor.  Communications is organized as a series
31         of requests and subsequent responses. For each request
32         there is a one and only one response. Requests may go
33         from the West Bridge device to the P port processor, or
34         from the P Port processor to the West Bridge device.
35
36         Description
37         Requests are issued across what is called a context. A
38         context is a single channel of communications from one
39         processor to another processor. There can be only a single
40         request outstanding on a context at a given time. Contexts
41         are used to identify subsystems that can only process a
42         single request at a time, but are independent of other
43         contexts in the system. For instance, there is a context
44         for communicating storage commands from the P port processor
45         to the West Bridge device.  There is also a context for
46         communicating USB commands from the P port processor to the
47         West Bridge device.
48
49         Requests and responses are identical with the exception of
50         the type bit in the request/response header.  If the type
51         bit is one, the packet is a request. If this bit is zero,
52         the packet is a response. Also encoded within the header of
53         the request/response is the code. The code is a command
54         code for a request, or a response code for a response.  For
55         a request, the code is a function of the context.  The code
56         0 has one meaning for the storage context and a different
57         meaning for the USB context.  The code is treated differently
58         in the response. If the code in the response is less than 16,
59         then the meaning of the response is global across all
60         contexts. If the response is greater than or equal to 16,
61         then the response is specific to the associated context.
62
63         Requests and responses are transferred between processors
64         through the mailbox registers.  It may take one or more cycles
65         to transmit a complete request or response.  The context is
66         encoded into each cycle of the transfer to insure the
67         receiving processor can route the data to the appropriate
68         context for processing. In this way, the traffic from multiple
69         contexts can be multiplexed into a single data stream through
70         the mailbox registers by the sending processor, and
71         demultiplexed from the mailbox registers by the receiving
72         processor.
73
74         * Firmware Assumptions *
75         The firmware assumes that mailbox contents will be consumed
76         immediately. Therefore for multi-cycle packets, the data is
77         sent in a tight polling loop from the firmware. This implies
78         that the data must be read from the mailbox register on the P
79         port side and processed immediately or performance of the
80         firmware will suffer. In order to insure this is the case,
81         the data from the mailboxes is read and stored immediately
82         in a per context buffer. This occurs until the entire packet
83         is received at which time the request packet is processed.
84         Since the protocol is designed to allow for only one
85         outstanding packet at a time, the firmware can never be in a
86         position of waiting on the mailbox registers while the P port
87         is processing a request.  Only after the response to the
88         previous request is sent will another request be sent.
89 */
90
91 #include "cyashal.h"
92 #include "cyasdevice.h"
93
94 #include "cyas_cplus_start.h"
95
96 /*
97  * Constants
98  */
99 #define CY_AS_REQUEST_RESPONSE_CODE_MASK (0x00ff)
100 #define CY_AS_REQUEST_RESPONSE_CONTEXT_MASK     (0x0F00)
101 #define CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT (8)
102 #define CY_AS_REQUEST_RESPONSE_TYPE_MASK (0x4000)
103 #define CY_AS_REQUEST_RESPONSE_LAST_MASK (0x8000)
104 #define CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG (0x1000)
105
106 /*
107  * These macros extract the data from a 16 bit value
108  */
109 #define cy_as_mbox_get_code(c) \
110         ((uint8_t)((c) & CY_AS_REQUEST_RESPONSE_CODE_MASK))
111 #define cy_as_mbox_get_context(c) \
112         ((uint8_t)(((c) & CY_AS_REQUEST_RESPONSE_CONTEXT_MASK) \
113                 >> CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT))
114 #define cy_as_mbox_is_last(c) \
115         ((c) & CY_AS_REQUEST_RESPONSE_LAST_MASK)
116 #define cy_as_mbox_is_request(c) \
117         (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) != 0)
118 #define cy_as_mbox_is_response(c) \
119         (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) == 0)
120
121 /*
122  * These macros (not yet written) pack data into or extract data
123  * from the m_box0 field of the request or response
124  */
125 #define cy_as_ll_request_response__set_code(req, code) \
126                 ((req)->box0 = \
127                 ((req)->box0 & ~CY_AS_REQUEST_RESPONSE_CODE_MASK) | \
128                         (code & CY_AS_REQUEST_RESPONSE_CODE_MASK))
129
130 #define cy_as_ll_request_response__get_code(req) \
131         cy_as_mbox_get_code((req)->box0)
132
133 #define cy_as_ll_request_response__set_context(req, context) \
134                 ((req)->box0 |= ((context) << \
135                         CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT))
136
137 #define cy_as_ll_request_response__set_clear_storage_flag(req) \
138                 ((req)->box0 |= CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG)
139
140 #define cy_as_ll_request_response__get_context(req) \
141         cy_as_mbox_get_context((req)->box0)
142
143 #define cy_as_ll_request_response__is_last(req) \
144         cy_as_mbox_is_last((req)->box0)
145
146 #define CY_an_ll_request_response___set_last(req) \
147                 ((req)->box0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK)
148
149 #define cy_as_ll_request_response__is_request(req) \
150         cy_as_mbox_is_request((req)->box0)
151
152 #define cy_as_ll_request_response__set_request(req) \
153                 ((req)->box0 |= CY_AS_REQUEST_RESPONSE_TYPE_MASK)
154
155 #define cy_as_ll_request_response__set_response(req) \
156                 ((req)->box0 &= ~CY_AS_REQUEST_RESPONSE_TYPE_MASK)
157
158 #define cy_as_ll_request_response__is_response(req) \
159         cy_as_mbox_is_response((req)->box0)
160
161 #define cy_as_ll_request_response__get_word(req, offset) \
162         ((req)->data[(offset)])
163
164 #define cy_as_ll_request_response__set_word(req, offset, \
165         value) ((req)->data[(offset)] = value)
166
167 typedef enum cy_as_remove_request_result_t {
168         cy_as_remove_request_sucessful,
169         cy_as_remove_request_in_transit,
170         cy_as_remove_request_not_found
171 } cy_as_remove_request_result_t;
172
173 /* Summary
174    Start the low level communications module
175
176    Description
177 */
178 cy_as_return_status_t
179 cy_as_ll_start(
180                 cy_as_device *dev_p
181                 );
182
183 cy_as_return_status_t
184 cy_as_ll_stop(
185    cy_as_device *dev_p
186    );
187
188
189 cy_as_ll_request_response *
190 cy_as_ll_create_request(
191                 cy_as_device *dev_p,
192                 uint16_t code,
193                 uint8_t context,
194                 /* Length of the request in 16 bit words */
195                 uint16_t length
196                 );
197
198 void
199 cy_as_ll_init_request(
200         cy_as_ll_request_response *req_p,
201         uint16_t code,
202         uint16_t context,
203         uint16_t length);
204
205 void
206 cy_as_ll_init_response(
207         cy_as_ll_request_response *req_p,
208         uint16_t length);
209
210 void
211 cy_as_ll_destroy_request(
212                 cy_as_device *dev_p,
213                 cy_as_ll_request_response *);
214
215 cy_as_ll_request_response *
216 cy_as_ll_create_response(
217                 cy_as_device *dev_p,
218                 /* Length of the request in 16 bit words */
219                 uint16_t length
220                 );
221
222 cy_as_remove_request_result_t
223 cy_as_ll_remove_request(
224                 cy_as_device *dev_p,
225                 cy_as_context *ctxt_p,
226                 cy_as_ll_request_response *req_p,
227                 cy_bool force
228                 );
229 void
230 cy_as_ll_remove_all_requests(cy_as_device *dev_p,
231         cy_as_context *ctxt_p);
232
233 void
234 cy_as_ll_destroy_response(
235         cy_as_device *dev_p,
236         cy_as_ll_request_response *);
237
238 cy_as_return_status_t
239 cy_as_ll_send_request(
240         /* The West Bridge device */
241         cy_as_device *dev_p,
242         /* The request to send */
243         cy_as_ll_request_response *req,
244         /* Storage for a reply, must be sure it is of sufficient size */
245         cy_as_ll_request_response *resp,
246         /* If true, this is a sync request */
247         cy_bool sync,
248         /* Callback to call when reply is received */
249         cy_as_response_callback cb
250 );
251
252 cy_as_return_status_t
253 cy_as_ll_send_request_wait_reply(
254         /* The West Bridge device */
255         cy_as_device *dev_p,
256         /* The request to send */
257         cy_as_ll_request_response *req,
258         /* Storage for a reply, must be sure it is of sufficient size */
259         cy_as_ll_request_response *resp
260 );
261
262 /* Summary
263    This function registers a callback function to be called when a
264    request arrives on a given context.
265
266    Description
267
268    Returns
269    * CY_AS_ERROR_SUCCESS
270 */
271 extern cy_as_return_status_t
272 cy_as_ll_register_request_callback(
273                 cy_as_device *dev_p,
274                 uint8_t context,
275                 cy_as_response_callback cb
276                 );
277
278 /* Summary
279    This function packs a set of bytes given by the data_p pointer
280    into a request, reply structure.
281 */
282 extern void
283 cy_as_ll_request_response__pack(
284         /* The destintation request or response */
285         cy_as_ll_request_response *req,
286         /* The offset of where to pack the data */
287         uint32_t offset,
288         /* The length of the data to pack in bytes */
289         uint32_t length,
290         /* The data to pack */
291         void *data_p
292         );
293
294 /* Summary
295    This function unpacks a set of bytes from a request/reply
296    structure into a segment of memory given by the data_p pointer.
297 */
298 extern void
299 cy_as_ll_request_response__unpack(
300         /* The source of the data to unpack */
301         cy_as_ll_request_response *req,
302         /* The offset of the data to unpack */
303         uint32_t offset,
304         /* The length of the data to unpack in bytes */
305         uint32_t length,
306         /* The destination of the unpack operation */
307         void *data_p
308         );
309
310 /* Summary
311    This function sends a status response back to the West Bridge
312    device in response to a previously send request
313 */
314 extern cy_as_return_status_t
315 cy_as_ll_send_status_response(
316          /* The West Bridge device */
317         cy_as_device *dev_p,
318         /* The context to send the response on */
319         uint8_t context,
320         /* The success/failure code to send */
321         uint16_t code,
322         /* Flag to clear wait on storage context */
323         uint8_t clear_storage);
324
325 /* Summary
326    This function sends a response back to the West Bridge device.
327
328    Description
329    This function sends a response back to the West Bridge device.
330    The response is sent on the context given by the 'context'
331    variable.  The code for the response is given by the 'code'
332    argument.  The data for the response is given by the data and
333    length arguments.
334 */
335 extern cy_as_return_status_t
336 cy_as_ll_send_data_response(
337         /* The West Bridge device */
338         cy_as_device *dev_p,
339         /* The context to send the response on */
340         uint8_t context,
341         /* The response code to use */
342         uint16_t code,
343         /* The length of the data for the response */
344         uint16_t length,
345         /* The data for the response */
346         void *data
347 );
348
349 /* Summary
350    This function removes any requests of the given type
351    from the given context.
352
353    Description
354    This function removes requests of a given type from the
355    context given via the context number.
356 */
357 extern cy_as_return_status_t
358 cy_as_ll_remove_ep_data_requests(
359         /* The West Bridge device */
360         cy_as_device *dev_p,
361         cy_as_end_point_number_t ep
362         );
363
364 #include "cyas_cplus_end.h"
365
366 #endif                            /* _INCLUDED_CYASLOWLEVEL_H_ */