<!--[if gte mso 9]>
ashim
ashim
2
4
2012-10-11T06:22:00Z
2012-10-11T06:28:00Z
2
803
4582
38
10
5375
14.00
<![endif]
-->
-->
Earlier there was no support of SDIO in Linux
mainline kernel. Developers had to rely on proprietary stacks. Starting
from 2.6.24 version SDIO support is part of mainline kernel. The mainline
kernel SDIO stack is very different from other proprietary stacks. It
hides all the details of SDIO protocol in well-designed API. In other
implementations SDIO function drivers need to handle details of
SDIO protocol. Mainline kernel implementation provides simple readX /writeX kind of
routines as available for PCI. In fact its model is largely based on PCI.
SDIO device IRQ handler is called in
process-context hence all SDIO I/O API can sleep. Support for asynchronous
transfers doesn’t exist.
API for SDIO function
drivers
sdio_register_driver
Registers SDIO function driver
to the SDIO sub-system. Driver
specifies probe, remove routines and deiceID
table.
sdio_unregister_driver
Un-Registers SDIO function
driver from the SDIO sub-system.
sdio_claim_irq
Claims and activates the IRQ for the given SDIO
function. The provided handler will be called when interrupt is asserted.
sdio_release_irq
Releases and de-activates the IRQ for the given
SDIO function.
sdio_claim_host
Exclusively claims a bus for a certain SDIO
function. It provides locking mechanism. This lock must be held before
doing any I/O operation for the function.
sdio_release_host
Release a bus for a certain SDIO function.
sdio_enable_func
Enables a SDIO function for
usage. SDIO function driver’s first need to call
this function after the SDIO device is successfully probed.
sdio_disable_func
Disables a SDIO function. Drivers call it when SDIO device is removed.
sdio_set_block_size
Sets the block size of an
SDIO function. Though SDIO stack
automatically sets block size, drivers can alter it.
sdio_max_byte_size
Returns the maximum byte
mode transfer size.
sdio_align_size
Pads a transfer size to a
more optimal value. Sometimes due to
limitations of DMA controller transfers need padding. This function
facilitates that.
sdio_readb
Reads a single byte from a
SDIO function. This uses direct transfer
mode of SDIO protocol.
sdio_writeb
Write a single byte to a SDIO function. This
uses direct transfer mode(CMD52) of SDIO
protocol.
sdio_memcpy_fromio
Reads a chunk of memory
from a SDIO function. This uses
extended transfer mode(CMD53) of SDIO protocol.
If count is multiple of block size, it uses block transfer. If count is
not multiple of block size, it uses byte transfer for the last transfer.
sdio_memcpy_toio
Writes a chunk of memory to
a SDIO function. This uses extended
transfer mode of SDIO protocol. If count is multiple of block size, it
uses block transfer. If count is not multiple of block size, it uses byte
transfer for the last transfer.
sdio_readsb
Reads from a FIFO on a SDIO
function. This uses extended
transfer mode of SDIO protocol. If count is multiple of block size, it
uses block transfer. If count is not multiple of block size, it uses byte
transfer for the last transfer.
sdio_writesb
Writes to a FIFO of a SDIO
function. This uses extended
transfer mode of SDIO protocol. If count is multiple of block size, it
uses block transfer. If count is not multiple of block size, it uses byte
transfer for the last transfer.
sdio_readw
Reads 16 bit integer from a
SDIO function. This uses extended
byte transfer mode of SDIO protocol.
sdio_writew
Writes 16 bit integer to a
SDIO function. This uses extended byte
transfer mode of SDIO protocol.
sdio_readl
Reads 32 bit integer from a
SDIO function. This uses extended
byte transfer mode of SDIO protocol.
sdio_writel
Writes 32 bit integer to a
SDIO function. This uses extended byte
transfer mode of SDIO protocol.
Writing SDIO function
driver
- In
module_init of our driver, register probe and
remove routines for SDIO function device using sdio_register_driver.
Device ID table is also specified in this step.
- Whenever
the device is inserted in SDIO socket, based on vendorIDdeviceID pair,
SDIO sub-system calls our probe routine.
- In
probe routine, allocate the private data for our function driver.
- Enable
the SDIO function using sdio_enable_func
- Register
IRQ handler using sdio_claim_irq
- If
required set the block size using sdio_set_block_size
- SDIO
IRQ handler is called from dedicated kernel thread for all the SDIO
function drivers. So it is advisable not to do very large
I/O operations from SDIO IRQ handler. Large I/O operation can
be differed to work-queue. Create work-queue as our bottom
half handler mechanism.
- Based
on device architecture, device can signal data read FIFO full or write
FIFO empty through interrupt. SDIO sub-system calls our IRQ handler.
Find
cause of interrupt and submit SDIO I/O operation work to the workqueue. Inside work-queue function any of the following
API can be used to perform read/write.
<![if !supportLineBreakNewLine]>
<![endif]>
<![if !supportLineBreakNewLine]>
<![endif]>
sdio_readb/sdio_writeb
sdio_readw/sdio_writew
sdio_readl/sdio_writel
sdio_readsb/sdio_writesb
sdio_memcpy_fromio/sdio_memcpy_toio
sdio_readw/sdio_writew
sdio_readl/sdio_writel
sdio_readsb/sdio_writesb
sdio_memcpy_fromio/sdio_memcpy_toio
- In
module_exit of our driver unregister our probe
and remove methods using sdio_unregister_driver.
This calls our remove routine.
- In
remove routine, wait for pending transfers and then release
IRQ handler using sdio_release_irq
- Disable
SDIO function using sdio_disable_func
- Free
private data for our driver.
Remove
routine is also called when device is hot-unplugged from SDIO bus. In this
case cleanup is tricky and 100% cleanup may not be possible.
-->
No comments:
Post a Comment