parent
b59d2802d2
commit
707a5e2226
@ -0,0 +1,200 @@ |
||||
The U-Boot Driver Model Project |
||||
=============================== |
||||
SPI analysis |
||||
============ |
||||
Viktor Krivak <viktor.krivak@gmail.com> |
||||
2012-03-03 |
||||
|
||||
I) Overview |
||||
----------- |
||||
|
||||
1) The SPI driver |
||||
----------------- |
||||
|
||||
At this moment U-Boot provides standard API that consist of 7 functions: |
||||
|
||||
void spi_init(void); |
||||
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, |
||||
unsigned int max_hz, unsigned int mode); |
||||
void spi_free_slave(struct spi_slave *slave); |
||||
int spi_claim_bus(struct spi_slave *slave); |
||||
void spi_release_bus(struct spi_slave *slave); |
||||
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, |
||||
const void *dout, void *din, unsigned long flags); |
||||
int spi_cs_is_valid(unsigned int bus, unsigned int cs); |
||||
void spi_cs_activate(struct spi_slave *slave); |
||||
void spi_cs_deactivate(struct spi_slave *slave); |
||||
void spi_set_speed(struct spi_slave *slave, uint hz); |
||||
|
||||
Method spi_init() is usually empty. All necessary configuration are sets by |
||||
spi_setup_slave(). But this configuration is usually stored only in memory. |
||||
No real hardware sets are made. All hardware settings are provided by method |
||||
spi_claim_bus(). This method claims the bus and it can't be claimed again |
||||
until it's release. That's mean all calls of method spi_claim_bus() will |
||||
fail. But lots of cpu implementation don't meet this behaviour. |
||||
Method spi_release_bus() does exact opposite. It release bus directly by |
||||
some hardware sets. spi_free_slave() only free memory allocated by |
||||
spi_setup_slave(). Method spi_xfer() do actually read and write operation |
||||
throw specified bus and cs. Other methods are self explanatory. |
||||
|
||||
2) Current limitations |
||||
---------------------- |
||||
|
||||
Theoretically at this moment api allows use more then one bus per device at |
||||
the time. But in real this can be achieved only when all buses have their |
||||
own base addresses in memory. |
||||
|
||||
|
||||
II) Approach |
||||
------------ |
||||
|
||||
1) Claiming bus |
||||
--------------- |
||||
|
||||
The current api cannot be used because struct spi_slave have to be in |
||||
private data. In that case user are prohibited to use different bus on one |
||||
device at same time. But when base memory address for bus are different. |
||||
It's possible make more instance of this driver. Otherwise it can't can be |
||||
done because of hardware limitation. |
||||
|
||||
2) API change |
||||
------------- |
||||
|
||||
Method spi_init() is moved to probe. Methods spi_setup_slave() and |
||||
spi_claim_bus() are joined to one method. This method checks if desired bus |
||||
exists and is available then configure necessary hardware and claims bus. |
||||
Method spi_release_bus() and spi_free_slave() are also joined to meet this |
||||
new approach. Other function remain same. Only struct spi_slave was change |
||||
to instance. |
||||
|
||||
struct ops { |
||||
int (*spi_request_bus)(struct instance *i, unsigned int bus, |
||||
unsigned int cs, unsigned int max_hz, |
||||
unsigned int mode); |
||||
void (*spi_release_bus)(struct instance *i); |
||||
int (*spi_xfer) (struct instance *i, unsigned int bitlen, |
||||
const void *dout, void *din, unsigned long flags); |
||||
int (*spi_cs_is_valid)(struct instance *i, unsigned int bus, |
||||
unsigned int cs); |
||||
void (*spi_cs_activate)(struct instance *i); |
||||
void (*spi_cs_deactivate)(struct instance *i); |
||||
void (*spi_set_speed)(struct instance *i, uint hz); |
||||
} |
||||
|
||||
3) Legacy API |
||||
------------- |
||||
|
||||
To easy conversion of the whole driver. Original and new api can exist next |
||||
to each other. New API is designed to be only a wrapper that extracts |
||||
necessary information from private_data and use old api. When driver can |
||||
use more than one bus at the time. New API require multiple instance. One |
||||
for each bus. In this case spi_slave have to be copied in each instance. |
||||
|
||||
4) Conversion TIME-LINE |
||||
----------------------- |
||||
|
||||
To prevent build corruption api conversion have to be processed in several |
||||
independent steps. In first step all old API methods are renamed. After that |
||||
new API and core function are implemented. Next step is conversion of all |
||||
board init methods to set platform data. After all these steps it is possible |
||||
to start conversion of all remaining calls. This procedure guarantees that |
||||
build procedure and binaries are never broken. |
||||
|
||||
III) Analysis of in-tree drivers |
||||
-------------------------------- |
||||
|
||||
1) altera_spi.c |
||||
--------------- |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
2) andes_spi.c |
||||
-------------- |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
3) andes_spi.h |
||||
-------------- |
||||
Support file for andes_spi.c. No conversion is needed. |
||||
|
||||
4) armada100_spi.c |
||||
------------------ |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
5) atmel_dataflash_spi.c |
||||
------------------------ |
||||
Wrong placement. Will be moved to another location. |
||||
|
||||
6) atmel_spi.c |
||||
-------------- |
||||
Supports more than one bus. Need some minor change. |
||||
|
||||
7) atmel_spi.h |
||||
-------------- |
||||
Support file for andes_spi.c. No conversion is needed. |
||||
|
||||
8) bfin_spi.c |
||||
------------- |
||||
Supports more than one bus. Need some minor change. |
||||
|
||||
9) cf_spi.c |
||||
----------- |
||||
Cooperate with some cpu specific methods from other files. Hard conversion. |
||||
|
||||
10) davinci_spi.c |
||||
----------------- |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
11) davinci_spi.h |
||||
----------------- |
||||
Support file for davinci_spi.h. No conversion is needed. |
||||
|
||||
12) fsl_espi.c |
||||
-------------- |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
13) kirkwood_spi.c |
||||
------------------ |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
14) mpc8xxx_spi.c |
||||
----------------- |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
15) mpc52xx_spi.c |
||||
----------------- |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
16) mxc_spi.c |
||||
------------- |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
17) mxs_spi.c |
||||
------------- |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
18) oc_tiny_spi.c |
||||
----------------- |
||||
Supports more than one bus. Need some minor change. |
||||
|
||||
19) omap3_spi.c |
||||
--------------- |
||||
Supports more than one bus. Need some minor change. |
||||
|
||||
20) omap3_spi.h |
||||
--------------- |
||||
Support file for omap3_spi.c. No conversion is needed. |
||||
|
||||
21) sh_spi.c |
||||
------------ |
||||
All methods have designated structure. Simple conversion possible. |
||||
|
||||
22) sh_spi.h |
||||
------------ |
||||
Support file for sh_spi.h. No conversion is needed. |
||||
|
||||
23) soft_spi.c |
||||
-------------- |
||||
Use many board specific method linked from other files. Need careful debugging. |
||||
|
||||
24) tegra2_spi.c |
||||
---------------- |
||||
Some hardware specific problem when releasing bus. |
Loading…
Reference in new issue