Wednesday, April 15, 2009

bfin spi device


从小就有种强烈的恐惧感。在空间中渺小无比,在时间中如流星一瞬而又无法重复。没有“我”的宇宙依然如故,而“我”却最终空无一物,无踪无影。这一切残酷,却又是无法回避的现实。

想到这里,万物皆空,万念俱灰。


-------------------------------------------------------------------------------

struct spi_device {
struct device dev;
struct spi_master *master;
u32 max_speed_hz;
u8 chip_select;
u8 mode;
#define SPI_CPHA 0x01 /* clock phase */
#define SPI_CPOL 0x02 /* clock polarity */
#define SPI_MODE_0 (0|0) /* (original MicroWire) */
#define SPI_MODE_1 (0|SPI_CPHA)
#define SPI_MODE_2 (SPI_CPOL|0)
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
#define SPI_CS_HIGH 0x04 /* chipselect active high? */
#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */
#define SPI_3WIRE 0x10 /* SI/SO signals shared */
#define SPI_LOOP 0x20 /* loopback mode */
u8 bits_per_word;
int irq;
void *controller_state;
void *controller_data;
const char *modalias;
};

-------------------------------------------------------------------------------
struct bfin5xx_spi_chip {
u16 ctl_reg;
u8 enable_dma;
u8 bits_per_word;
u8 cs_change_per_word;
u16 cs_chg_udelay; /* Some devices require 16-bit delays */
u32 cs_gpio;
/* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */
u16 idle_tx_val;
};


#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
static struct bfin5xx_spi_chip enc28j60_spi_chip_info = {
.enable_dma = 1,
.bits_per_word = 8,
.cs_gpio = GPIO_PF10,
};
#endif



------------------------------------------------------------------------------

/*
* These structures are used in two places. Their primary role is to
* be stored in tables of board-specific device descriptors, which are
* declared early in board initialization and then used (much later) to
* populate a controller's device tree after the that controller's driver
* initializes. A secondary (and atypical) role is as a parameter to
* spi_new_device() call, which happens after those controller drivers
* are active in some dynamic board configuration models.
*/
struct spi_board_info {
/* the device name and module name are coupled, like platform_bus;
* "modalias" is normally the driver name.
*
* platform_data goes to spi_device.dev.platform_data,
* controller_data goes to spi_device.controller_data,
* irq is copied too
*/
char modalias[32];
const void *platform_data;
void *controller_data;
int irq;

/* slower signaling on noisy or low voltage boards */
u32 max_speed_hz;


/* bus_num is board specific and matches the bus_num of some
* spi_master that will probably be registered later.
*
* chip_select reflects how this chip is wired to that master;
* it's less than num_chipselect.
*/
u16 bus_num;
u16 chip_select;

/* mode becomes spi_device.mode, and is essential for chips
* where the default of SPI_CS_HIGH = 0 is wrong.
*/
u8 mode;

/* ... may need additional spi_device chip config data here.
* avoid stuff protocol drivers can set; but include stuff
* needed to behave without being bound to a driver:
* - quirks like clock rate mattering when not selected
*/
};

static struct spi_board_info bfin_spi_board_info[] __initdata = {

[snip]

#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
{
.modalias = "enc28j60",
.max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
.irq = IRQ_PF6,
.bus_num = 0,
.chip_select = 0, /* GPIO controlled SSEL */
.controller_data = &enc28j60_spi_chip_info,
.mode = SPI_MODE_0,
},
#endif

[snip]

}

static int __init stamp_init(void)
{
printk(KERN_INFO "%s(): registering device resources\n", __func__);
i2c_register_board_info(0, bfin_i2c_board_info,
ARRAY_SIZE(bfin_i2c_board_info));
bfin_plat_nand_init();
platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));

[snip]
}

later in:
int spi_register_master(struct spi_master *master) -->
static void scan_boardinfo(struct spi_master *master) -->
struct spi_device *spi_new_device(struct spi_master *master, struct spi_board_info *chip)

in spi_new_device(), spi_board_info will be copied to struct spi_device.

spi_board_info.controller_data (i.e enc28j60_spi_chip_info) will be copied to spi_device.controller_data.

In bfin_spi_setup() --> spi_set_ctldata(spi, chip); // this will set spi_device.controller_state.

--------------------------------------------------------------------------

Blog Archive