--- kernel-2.6.27.orig/Documentation/arm/OMAP/ssi/ssi +++ kernel-2.6.27/Documentation/arm/OMAP/ssi/ssi @@ -0,0 +1,232 @@ +OMAP SSI API's How To +===================== + +The Synchronous Serial Interface (SSI) is a high speed communication interface +that is used for connecting OMAP to a cellular modem engine. + +The SSI interface supports full duplex communication over multiple channels and +is capable of reaching speeds up to 110 Mbit/s + +I OMAP SSI driver API overview +----------------------------- + +A) SSI Bus, SSI channels and protocol drivers overview. + +The OMAP SSI driver is intended to be used inside the kernel by protocol drivers. + +The OMAP SSI abstracts the concept of SSI channels by creating an SSI bus an +attaching SSI channel devices to it.(see Figure 1) + +Protocol drivers will then claim one or more SSI channels, after registering with the OMAP SSI driver. + + +---------------------+ +----------------+ + + SSI channel device + + SSI protocol + + + (omap_ssi.pX-cY) + <-------+ driver + + +---------------------+ +----------------+ + | | +(/sys/bus/ssi/devices/omap_ssi.pX-cy) (/sys/bus/ssi/drivers/ssi_protocol) + | | ++---------------------------------------------------------------+ ++ SSI bus + ++---------------------------------------------------------------+ + + Figure 1. + +(NOTE: omap_ssi.pX-cY represents the SSI channel Y on port X from the omap_ssi +device) + +B) Data transfers + +The OMAP SSI driver exports an asynchronous interface for sending and receiving +data over the SSI channels. Protocol drivers will register a set of read and write +completion callbacks for each SSI channel they use. + +Protocol drivers call ssi_write/ssi_read functions to signal the OMAP SSI driver +that is willing to write/read data to/from a channel. Transfers are completed only +when the OMAP SSI driver calls the completion callback. + +An SSI channel can simultaneously have both a read and a write request +pending, however, requests cannot be queued. + +It is safe to call ssi_write/ssi_read functions inside the callbacks functions. +In fact, a protocol driver should normally re-issue the read request from within +the read callback, in order to not miss any incoming messages. + +C) Error handling + +SSI is a multi channel interface but the channels share the same physical wires. +Therefore, any transmission error potentially affects all the protocol drivers +that sit on top of the SSI driver. Whenever an error occurs, it is broadcasted to +all protocol drivers. + +Errors are signaled to the protocol drivers through the port_event callback. +Protocol drivers can avoid receiving those notifications by not setting the +SSI_EVENT_ERROR in the event_mask field.(see struct ssi_device_driver) + +Completion callbacks functions are only called when a transfer has succeed. + +II OMAP SSI API's +----------------- + +A) Include + +#include + +B) int register_ssi_driver(struct ssi_device_driver *driver); + +Description: Register an SSI protocol driver + +Parameter: A protocol driver declaration (see struct ssi_device_driver) + +B) void unregister_ssi_driver(struct ssi_device_driver *driver); + +Description: Unregister an SSI protocol driver + +Parameter: A protocol driver declaration (see struct ssi_device_driver) + +C) int ssi_open(struct ssi_device *dev); + +Description: Open an SSI device channel + +Parameter: The SSI channel + +D) int ssi_write(struct ssi_device *dev, u32 *data, unsigned int count); + +Description: Send data through an SSI channel. The transfer is only completed +when the write_complete callback is called + +Parameters: + - dev: SSI channel + - data: pointer to the data to send + - count: number of 32-bit words to be sent + +E) void ssi_write_cancel(struct ssi_device *dev); + +Description: Cancel current pending write operation + +Parameters: SSI channel + +F) int ssi_read(struct ssi_device *dev, u32 *data, unsigned int w_count); + +Description: Receive data through an SSI channel. The transfer is only completed +when the read_complete callback is called + +Parameters: + - dev: SSI channel + - data: pointer where to store the data + - count: number of 32-bit words to be read + + +G) void ssi_read_cancel(struct ssi_device *dev); + +Description: Cancel current pending read operation + +Parameters: SSI channel + +H) int ssi_ioctl(struct ssi_device *dev, unsigned int command, void *arg); + +Description: Apply some control command to the port associated to the given +SSI channel + +Parameters: + - dev: SSI channel + - command: command to execute + - arg: parameter for the control command + +Commands: + - SSI_IOCTL_WAKE_UP: + Description: Set SSI wakeup line for the channel + Parameters: None + - SSI_IOCTL_WAKE_DOWN: + Description: Unset SSI wakeup line for the channel + Parameters: None + - SSI_IOCTL_SEND_BREAK: + Description: Send a HW BREAK frame in FRAME mode + Parameters: None + - SSI_IOCTL_WAKE: + Description: Get wakeup line status + Parameters: Pointer to a u32 variable to return result + (Result: 0 means wakeline DOWN, other result means wakeline UP) + +I)void ssi_close(struct ssi_device *dev); + +Description: Close an SSI channel + +Parameters: The SSI channel to close + +J) void ssi_dev_set_cb( struct ssi_device *dev, + void (*r_cb)(struct ssi_device *dev), + void (*w_cb)(struct ssi_device *dev)); + +Description: Set the read and write callbacks for the SSI channel. This +function is usually called in the probe function of the SSI protocol driver to +set completion callbacks for the asynchronous read and write transfer + +Parameters: + - dev: SSI channel + - r_cb: Pointer to a callback function to signal that a read transfer is + completed + - w_cb: Pointer to a callback function to signal that a write transfer + is completed + +H) struct ssi_device_driver + +Description: Protocol drivers pass this struct to the register_ssi_driver function +in order to register with the OMAP SSI driver. Among other things it tells the +OMAP SSI driver which channels the protocol driver wants to allocate for its use + +Declaration: +struct ssi_device_driver { + unsigned long ctrl_mask; + unsigned long ch_mask[SSI_MAX_PORTS]; + unsigned long event_mask; + void (*port_event) (int c_id, unsigned int port, + unsigned int event, void *arg); + int (*probe)(struct ssi_device *dev); + int (*remove)(struct ssi_device *dev); + int (*suspend)(struct ssi_device *dev, + pm_message_t mesg); + int (*resume)(struct ssi_device *dev); + struct device_driver driver; +}; + +Fields description: + ctrl_mask: SSI block ids to use + ch_mask[SSI_MAX_PORTS]: SSI channels to use + event_mask: SSI events to be notified + port_event: Function callback for notifying SSI events + (i.e.: error transfer) + Parameters: + c_id: SSI Block id which generate the event + port: Port number which generate the event + event: Event code + probe: Probe function + Parameters: SSI channel + remove: Remove function + Parameters: SSI channel + +Example: + +static struct ssi_device_driver ssi_protocol_driver = { + .ctrl_mask = ANY_SSI_CONTROLLER, + .ch_mask[0] = CHANNEL(0) | CHANNEL(1), + .event_mask = SSI_EVENT_ERROR_MASK, + .port_event = port_event_callback, + .probe = ssi_proto_probe, + .remove = __devexit_p(ssi_proto_remove), + .driver = { + .name = "ssi_protocol", + }, +}; + + +III OMAP SSI platform_device +---------------------------- + +You can find a example of how to define an SSI platform device in: + +Documentation/arm/OMAP/ssi/board-ssi.c.example + +================================================= +Contact: Carlos Chinea +Copyright (C) 2008 Nokia Corporation.