See also Notes on Linux SDHCI driver
SDIODriver Specification
Device discovery
SD host controllers may be attached via a PCI bus as was anticipated by the SD
standard. In this case, the SDIODriver would scan the PCI bus for devices of the
appropriate class. It should be noted however that at the present time there are
no RISC OS platforms with such an architecture, so this is considered a future
enhancement.
Host controllers with alternate attachments are discovered via the HAL Device
API. This potentially includes hot-pluggable host controllers, as is true of all
HAL Devices. The HAL Device would look something like this:
type bits 15-8 = 5 (a new type for controllers of peripheral buses)
bits 7-0 = 1 for SDIO controller
id bits 15-0 = 1 for generic SDHCI controller
location bits 31-28 = 5 (interconnect) for OMAP3
bits 27-24 = 1 (L4 interconnect) for OMAP3
bits 23-16 = 0 for OMAP3
bits 15-8 = 0 for OMAP3
bits 7-0 = 0 for OMAP3
version, description, address, reserved1, Activate, Deactivate, Reset, Sleep,
devicenumber, TestIRQ, ClearIRQ, reserved2 are standard device fields and
require no further description
flags bits 31-1 = reserved, 0
bit 0 set => all register reads and writes must use 32-bit accesses
slots bits 31-0 = number of slots (a.k.a. cards or hosts) supported by
this host controller
stdregs bits 31-0 = pointer to array of logical base addresses of standard
register sets, one for each slot
void SetActivity(device *, uint8_t) function pointer to turn on or off the disc
activity indicator LED(s) for the specified bitmask
of cards on this controller; may be a null pointer
if there are no indicators
uint8_t GetWriteProtect(device *) function pointer that returns a bitfield
describing the write-protect state of all the cards
controlled by this controller
The OMAP3530 has 3 host controllers with one slot on each, but since the
beagleboard and related boards tend to only track out one of them to an SD
connector, only this one will be reported by the HAL. (Actually, to simplify
initial development, this device will be implemented in a module, so that
complete ROM rebuilds are not required to test each incremental change, but when
the code becomes stable it will be moved into the HAL proper.)
The SDIODriver is responsible for probing cards, to identify which are memory
cards, which are IO cards and which are combo cards, and for IO cards,
discovering the set of functions available and the Function Interface Code for
each. However, it is not appropriate for it to create further HAL devices to
describe functions because to do so would mean hard-coding knowledge of the
meaning of each Function Interface Code into the SDIODriver, and additional
codes could be allocated at any time; it is better that this knowledge is
encapsulated within the driver module for that specific device.
SDIODriver announces the discovery and removal of devices using a pair of
service calls.
Service_SDIOAttached (Service Call &81040)
On entry
R0 bits 7-0 = unit number (0 => memory, 1-7 => function index, 8+ reserved)
bits 15-8 = card number (i.e. slot number)
bits 23-16 = bus number (i.e. SD host controller index)
bits 31-24 reserved, zero
R1 = &81040
R2 = 0 for memory device, or Function Interface Code for function device
(1 = UART, 2 = Bluetooth Type-A etc)
On exit
R1 preserved (do not claim)
Service_SDIODetached (Service Call &81041)
On entry
R0 bits 7-0 = unit number (0 => memory, 1-7 => function index, 8+ reserved)
bits 15-8 = card number (i.e. slot number)
bits 23-16 = bus number (i.e. SD host controller index)
bits 31-24 reserved, zero
R1 = &81041
R2 = 0 for memory device, or Function Interface Code for function device
(1 = UART, 2 = Bluetooth Type-A etc)
On exit
R1 preserved (do not claim)
A further service call is used to acquire a textual description of a device:
Service_SDIODescribe (Service Call &81042)
On entry
R0 = Function Interface Code
R1 = &81042
On exit
R1 = 0 to claim
R2 = pointer to zero-teminated string
SWI SDIO_Initialise 0
On entry
R0 = 0 (reason code: reset bus)
R1 bits 0-7 = bus number
This call resets the specified host controller and rescans its slots.
SWI SDIO_Control 0
On entry
R0 = 0 (reason code: abort all operations on device)
R1 bits 0-7 = card number
bits 8-15 = bus number
This call cancels all outstanding operations on a card. You should abort
individual operations instead wherever possible.
SWI SDIO_Control 1
On entry
R0 = 1 (reason code: abort operation)
R1 bits 0-7 = card number
bits 8-15 = bus number
R2 = operation ID as returned by SDIO_Op for background operations
This call cancels the specified background operation.
SWI SDIO_Op
On entry
R0 bits 0-7 = card number
bits 8-15 = bus number
bit 16 set => check busy after response (use for R1B, R5B)
bit 17 set => command CRC check enabled (use for R1(B), R2, R5(B), R6, R7)
bit 18 set => command index check enabled (use for R1(B), R5(B), R6, R7)
bits 24-25 = transfer direction (0 = no data transfer, 1 = read, 2 = write)
bit 26 set => scatter transfer
bit 29 set => background transfer
R1 = length of command and response block, must be 8, 12 or 23
R2 = pointer to command and response block. On entry this contains the command
index (padded to 32 bits) and bits 8-39 of the command argument. On exit,
bytes 8 upwards of the block are filled in with the response bytes (if
any), excluding the index and CRC bytes. For most commands, this will be
4 bytes, but for R2 will be 15 bytes, and a few commands (such as
GO_IDLE_STATE) have no response at all.
R3 = RAM ptr for start of transfer or pointer to scatter list of address length
pairs if bit 26 of R0 is set.
R4 = length of transfer (in bytes) - may only be 0 if no data transfer is
specified in R0 bits 24-25
R5 = if bit 29 of R0 is clear, this is timeout in centiseconds or 0 for
no timeout
if bit 29 of R0 is set, this is the value to pass in R5 to the callback
routine
R6 = address of callback routine, if bit 26 of R0 is set
R7 = value to pass in R12 to the callback routine, if bit 26 of R0 is set
On exit
If error was detected,
R0 -> error block
R4 updated to number of bytes not transferred
V set
If foreground transfer completed successfully,
R0 = 0 (consider as a flags word with all bits reserved)
R4 = 0
V clear
If background transfer has started,
R0 = 0 (consider as a flags word with all bits reserved)
R1 = operation handle, can be used to cancel the operation using SDIO_Control
V clear
The scatter list is not updated (note, this is also true of recent versions of
SCSIDriver, the documentation is out-of-date). FileCore-style wrapping is
accepted (ie if an address entry is between &FFFF0000 and &FFFFFFFF, and the
length field is 0, then that should be treated as an instruction to push the
scatter list pointer backwards by an offset of up to 64K).
The callback operates as follows:
The call is made in privileged mode with IRQs disabled.
If the operation completed, V is clear & R0 is set to 0.
If an error occurred, V is set and R0 is an error pointer.
R4 holds the amount of data not transferred.
R5 and R12 must be set to the values passed in.
All registers will be preserved.
SWI SDIO_ClaimDeviceVector
On entry
R0 bits 0-7 = function number (1-7, other values reserved)
bits 0-7 = card number
bits 8-15 = bus number
R1 = address of interrupt handler routine
R2 = value to pass in R12 to routine
To simplify SDIO interrupt dispatch, device drivers should use this instead of
calling OS_ClaimDeviceVector.
SWI SDIO_ReleaseDeviceVector
On entry
R0 bits 0-7 = function number (1-7, other values reserved)
bits 0-7 = card number
bits 8-15 = bus number
R1 = address of interrupt handler routine
R2 = value to pass in R12 to routine
*SDIODevices
This command prints out a table of information about the currently known SDIO
devices. Typical output would look like the following:
Bus Dev Fun Description
0 0 0 SD memory card
1 0 0 SD memory card
1 0 1 SDIO camera interface
2 0 1 SDIO standard UART
2 1 1 SDIO WLAN interface
2 2 1 Unrecognised SDIO function interface code (66)
2 2 2 Unrecognised SDIO function interface code (255)