diff options
Diffstat (limited to 'drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h')
-rw-r--r-- | drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h new file mode 100644 index 0000000..5c7972f --- /dev/null +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h @@ -0,0 +1,366 @@ +/* Cypress West Bridge API header file (cyaslowlevel.h) +## =========================== +## Copyright (C) 2010 Cypress Semiconductor +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either version 2 +## of the License, or (at your option) any later version. +## +## 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. +## +## 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 Street +## Fifth Floor, Boston, MA 02110-1301, USA. +## =========================== +*/ + +#ifndef _INCLUDED_CYASLOWLEVEL_H_ +#define _INCLUDED_CYASLOWLEVEL_H_ + +/*@@Low Level Communications + + Summary + The low level communications module is responsible for + communications between the West Bridge device and the P + port processor. Communications is organized as a series + of requests and subsequent responses. For each request + there is a one and only one response. Requests may go + from the West Bridge device to the P port processor, or + from the P Port processor to the West Bridge device. + + Description + Requests are issued across what is called a context. A + context is a single channel of communications from one + processor to another processor. There can be only a single + request outstanding on a context at a given time. Contexts + are used to identify subsystems that can only process a + single request at a time, but are independent of other + contexts in the system. For instance, there is a context + for communicating storage commands from the P port processor + to the West Bridge device. There is also a context for + communicating USB commands from the P port processor to the + West Bridge device. + + Requests and responses are identical with the exception of + the type bit in the request/response header. If the type + bit is one, the packet is a request. If this bit is zero, + the packet is a response. Also encoded within the header of + the request/response is the code. The code is a command + code for a request, or a response code for a response. For + a request, the code is a function of the context. The code + 0 has one meaning for the storage context and a different + meaning for the USB context. The code is treated differently + in the response. If the code in the response is less than 16, + then the meaning of the response is global across all + contexts. If the response is greater than or equal to 16, + then the response is specific to the associated context. + + Requests and responses are transferred between processors + through the mailbox registers. It may take one or more cycles + to transmit a complete request or response. The context is + encoded into each cycle of the transfer to insure the + receiving processor can route the data to the appropriate + context for processing. In this way, the traffic from multiple + contexts can be multiplexed into a single data stream through + the mailbox registers by the sending processor, and + demultiplexed from the mailbox registers by the receiving + processor. + + * Firmware Assumptions * + The firmware assumes that mailbox contents will be consumed + immediately. Therefore for multi-cycle packets, the data is + sent in a tight polling loop from the firmware. This implies + that the data must be read from the mailbox register on the P + port side and processed immediately or performance of the + firmware will suffer. In order to insure this is the case, + the data from the mailboxes is read and stored immediately + in a per context buffer. This occurs until the entire packet + is received at which time the request packet is processed. + Since the protocol is designed to allow for only one + outstanding packet at a time, the firmware can never be in a + position of waiting on the mailbox registers while the P port + is processing a request. Only after the response to the + previous request is sent will another request be sent. +*/ + +#include "cyashal.h" +#include "cyasdevice.h" + +#include "cyas_cplus_start.h" + +/* + * Constants + */ +#define CY_AS_REQUEST_RESPONSE_CODE_MASK (0x00ff) +#define CY_AS_REQUEST_RESPONSE_CONTEXT_MASK (0x0F00) +#define CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT (8) +#define CY_AS_REQUEST_RESPONSE_TYPE_MASK (0x4000) +#define CY_AS_REQUEST_RESPONSE_LAST_MASK (0x8000) +#define CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG (0x1000) + +/* + * These macros extract the data from a 16 bit value + */ +#define cy_as_mbox_get_code(c) \ + ((uint8_t)((c) & CY_AS_REQUEST_RESPONSE_CODE_MASK)) +#define cy_as_mbox_get_context(c) \ + ((uint8_t)(((c) & CY_AS_REQUEST_RESPONSE_CONTEXT_MASK) \ + >> CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT)) +#define cy_as_mbox_is_last(c) \ + ((c) & CY_AS_REQUEST_RESPONSE_LAST_MASK) +#define cy_as_mbox_is_request(c) \ + (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) != 0) +#define cy_as_mbox_is_response(c) \ + (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) == 0) + +/* + * These macros (not yet written) pack data into or extract data + * from the m_box0 field of the request or response + */ +#define cy_as_ll_request_response__set_code(req, code) \ + ((req)->box0 = \ + ((req)->box0 & ~CY_AS_REQUEST_RESPONSE_CODE_MASK) | \ + (code & CY_AS_REQUEST_RESPONSE_CODE_MASK)) + +#define cy_as_ll_request_response__get_code(req) \ + cy_as_mbox_get_code((req)->box0) + +#define cy_as_ll_request_response__set_context(req, context) \ + ((req)->box0 |= ((context) << \ + CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT)) + +#define cy_as_ll_request_response__set_clear_storage_flag(req) \ + ((req)->box0 |= CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG) + +#define cy_as_ll_request_response__get_context(req) \ + cy_as_mbox_get_context((req)->box0) + +#define cy_as_ll_request_response__is_last(req) \ + cy_as_mbox_is_last((req)->box0) + +#define CY_an_ll_request_response___set_last(req) \ + ((req)->box0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK) + +#define cy_as_ll_request_response__is_request(req) \ + cy_as_mbox_is_request((req)->box0) + +#define cy_as_ll_request_response__set_request(req) \ + ((req)->box0 |= CY_AS_REQUEST_RESPONSE_TYPE_MASK) + +#define cy_as_ll_request_response__set_response(req) \ + ((req)->box0 &= ~CY_AS_REQUEST_RESPONSE_TYPE_MASK) + +#define cy_as_ll_request_response__is_response(req) \ + cy_as_mbox_is_response((req)->box0) + +#define cy_as_ll_request_response__get_word(req, offset) \ + ((req)->data[(offset)]) + +#define cy_as_ll_request_response__set_word(req, offset, \ + value) ((req)->data[(offset)] = value) + +typedef enum cy_as_remove_request_result_t { + cy_as_remove_request_sucessful, + cy_as_remove_request_in_transit, + cy_as_remove_request_not_found +} cy_as_remove_request_result_t; + +/* Summary + Start the low level communications module + + Description +*/ +cy_as_return_status_t +cy_as_ll_start( + cy_as_device *dev_p + ); + +cy_as_return_status_t +cy_as_ll_stop( + cy_as_device *dev_p + ); + + +cy_as_ll_request_response * +cy_as_ll_create_request( + cy_as_device *dev_p, + uint16_t code, + uint8_t context, + /* Length of the request in 16 bit words */ + uint16_t length + ); + +void +cy_as_ll_init_request( + cy_as_ll_request_response *req_p, + uint16_t code, + uint16_t context, + uint16_t length); + +void +cy_as_ll_init_response( + cy_as_ll_request_response *req_p, + uint16_t length); + +void +cy_as_ll_destroy_request( + cy_as_device *dev_p, + cy_as_ll_request_response *); + +cy_as_ll_request_response * +cy_as_ll_create_response( + cy_as_device *dev_p, + /* Length of the request in 16 bit words */ + uint16_t length + ); + +cy_as_remove_request_result_t +cy_as_ll_remove_request( + cy_as_device *dev_p, + cy_as_context *ctxt_p, + cy_as_ll_request_response *req_p, + cy_bool force + ); +void +cy_as_ll_remove_all_requests(cy_as_device *dev_p, + cy_as_context *ctxt_p); + +void +cy_as_ll_destroy_response( + cy_as_device *dev_p, + cy_as_ll_request_response *); + +cy_as_return_status_t +cy_as_ll_send_request( + /* The West Bridge device */ + cy_as_device *dev_p, + /* The request to send */ + cy_as_ll_request_response *req, + /* Storage for a reply, must be sure it is of sufficient size */ + cy_as_ll_request_response *resp, + /* If true, this is a sync request */ + cy_bool sync, + /* Callback to call when reply is received */ + cy_as_response_callback cb +); + +cy_as_return_status_t +cy_as_ll_send_request_wait_reply( + /* The West Bridge device */ + cy_as_device *dev_p, + /* The request to send */ + cy_as_ll_request_response *req, + /* Storage for a reply, must be sure it is of sufficient size */ + cy_as_ll_request_response *resp +); + +/* Summary + This function registers a callback function to be called when a + request arrives on a given context. + + Description + + Returns + * CY_AS_ERROR_SUCCESS +*/ +extern cy_as_return_status_t +cy_as_ll_register_request_callback( + cy_as_device *dev_p, + uint8_t context, + cy_as_response_callback cb + ); + +/* Summary + This function packs a set of bytes given by the data_p pointer + into a request, reply structure. +*/ +extern void +cy_as_ll_request_response__pack( + /* The destintation request or response */ + cy_as_ll_request_response *req, + /* The offset of where to pack the data */ + uint32_t offset, + /* The length of the data to pack in bytes */ + uint32_t length, + /* The data to pack */ + void *data_p + ); + +/* Summary + This function unpacks a set of bytes from a request/reply + structure into a segment of memory given by the data_p pointer. +*/ +extern void +cy_as_ll_request_response__unpack( + /* The source of the data to unpack */ + cy_as_ll_request_response *req, + /* The offset of the data to unpack */ + uint32_t offset, + /* The length of the data to unpack in bytes */ + uint32_t length, + /* The destination of the unpack operation */ + void *data_p + ); + +/* Summary + This function sends a status response back to the West Bridge + device in response to a previously send request +*/ +extern cy_as_return_status_t +cy_as_ll_send_status_response( + /* The West Bridge device */ + cy_as_device *dev_p, + /* The context to send the response on */ + uint8_t context, + /* The success/failure code to send */ + uint16_t code, + /* Flag to clear wait on storage context */ + uint8_t clear_storage); + +/* Summary + This function sends a response back to the West Bridge device. + + Description + This function sends a response back to the West Bridge device. + The response is sent on the context given by the 'context' + variable. The code for the response is given by the 'code' + argument. The data for the response is given by the data and + length arguments. +*/ +extern cy_as_return_status_t +cy_as_ll_send_data_response( + /* The West Bridge device */ + cy_as_device *dev_p, + /* The context to send the response on */ + uint8_t context, + /* The response code to use */ + uint16_t code, + /* The length of the data for the response */ + uint16_t length, + /* The data for the response */ + void *data +); + +/* Summary + This function removes any requests of the given type + from the given context. + + Description + This function removes requests of a given type from the + context given via the context number. +*/ +extern cy_as_return_status_t +cy_as_ll_remove_ep_data_requests( + /* The West Bridge device */ + cy_as_device *dev_p, + cy_as_end_point_number_t ep + ); + +#include "cyas_cplus_end.h" + +#endif /* _INCLUDED_CYASLOWLEVEL_H_ */ |