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)