Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1145661
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2279
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(241)

文章存档

2023年(8)

2022年(2)

2021年(3)

2020年(30)

2019年(11)

2018年(27)

2017年(54)

2016年(83)

2015年(23)

我的朋友

分类: LINUX

2018-12-16 22:03:25

drivers/spi/spi_test.c 这个文件可以细看,是详细分析spi驱动的好文件。


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void __init smdk6410_machine_init(void)
{
    spi_register_board_info(sam_spi_devs, ARRAY_SIZE(sam_spi_devs));
    platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
   
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
第12章:和platform_driver对应这一个platform_device一样,spi_driver也对应着一个spi_device;platform_device需要在BSP的板文件中添加板信息数据,而spi_device也同样需要。spi_device的板信息用spi_board_info结构体描述,该结构记录着spi外设使用的主机控制器(spi_master)序号,片选序号,数据比特率,spi传输模式(CPOL,CPHA)

static struct spi_board_info __initdata sam_spi_devs[] = {
    [0] = {
////设备与驱动匹配的唯一标识 
        .modalias     = "spidev", /* Test Interface */
        .mode         = SPI_MODE_2,    /* CPOL=1, CPHA=0 */
        .max_speed_hz     = 2468013,
        /* Connected to SPI-0 as 1st Slave */
        .bus_num     = 0,
        .irq         = IRQ_SPI0,
        .chip_select     = 0,
//        .controller_data = (void *)&spidev_b0_cs0,
    },
};



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*---------------------------------------------------------------------------*/

/*
 * INTERFACE between board init code and SPI infrastructure.
 *
 * No SPI driver ever sees these SPI device table segments, but
 * it's how the SPI core (or adapters that get hotplugged) grows
 * the driver model tree.
 *
 * As a rule, SPI devices can't be probed.  Instead, board init code
 * provides a table listing the devices which are present, with enough
 * information to bind and set up the device's driver.  There's basic
 * support for nonstatic configurations too; enough to handle adding
 * parport adapters, or microcontrollers acting as USB-to-SPI bridges.
 */

/**
 * struct spi_board_info - board-specific template for a SPI device
 * @modalias: Initializes spi_device.modalias; identifies the driver.
 * @platform_data: Initializes spi_device.platform_data; the particular
 *    data stored there is driver-specific.
 * @controller_data: Initializes spi_device.controller_data; some
 *    controllers need hints about hardware setup, e.g. for DMA.
 * @irq: Initializes spi_device.irq; depends on how the board is wired.
 * @max_speed_hz: Initializes spi_device.max_speed_hz; based on limits
 *    from the chip datasheet and board-specific signal quality issues.
 * @bus_num: Identifies which spi_master parents the spi_device; unused
 *    by spi_new_device(), and otherwise depends on board wiring.
 * @chip_select: Initializes spi_device.chip_select; depends on how
 *    the board is wired.
 * @mode: Initializes spi_device.mode; based on the chip datasheet, board
 *    wiring (some devices support both 3WIRE and standard modes), and
 *    possibly presence of an inverter in the chipselect path.
 *
 * When adding new SPI devices to the device tree, these structures serve
 * as a partial device template.  They hold information which can't always
 * be determined by drivers.  Information that probe() can establish (such
 * as the default transfer wordsize) is not included here.
 *
 * 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 platform_device *smdk6410_devices[] __initdata = {
    &s3c_device_i2c0,
    &s3c_device_spi0,
    &s3c_device_spi1,

    &s3c_device_keypad,
    &s3c_device_ts,
    &s3c_device_dm9000_cs1,
    &s3c_device_nand,
    &s3c_device_usb,
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 /* SPI (0) */
static struct resource s3c_spi0_resource[] = {
    [0] = {
        .start = S3C_PA_SPI0,
        .end   = S3C_PA_SPI0 + S3C_SZ_SPI0 - 1,
        .flags = IORESOURCE_MEM,
    },
    [1] = {
        .start = IRQ_SPI0,
        .end   = IRQ_SPI0,
        .flags = IORESOURCE_IRQ,
    }

};

static u64 s3c_device_spi0_dmamask = 0xffffffffUL;

struct platform_device s3c_device_spi0 = {
    .name          = "sam-spi",
    .id          = 0,
    .num_resources      = ARRAY_SIZE(s3c_spi0_resource),
    .resource      = s3c_spi0_resource,
        .dev              = {
                .dma_mask = &s3c_device_spi0_dmamask,
                .coherent_dma_mask = 0xffffffffUL
        }
};
EXPORT_SYMBOL(s3c_device_spi0);

/* SPI (1) */
static struct resource s3c_spi1_resource[] = {
    [0] = {
        .start = S3C_PA_SPI1,
        .end   = S3C_PA_SPI1 + S3C_SZ_SPI1 - 1,
        .flags = IORESOURCE_MEM,
    },
    [1] = {
        .start = IRQ_SPI1,
        .end   = IRQ_SPI1,
        .flags = IORESOURCE_IRQ,
    }

};

static u64 s3c_device_spi1_dmamask = 0xffffffffUL;

struct platform_device s3c_device_spi1 = {
    .name          = "sam-spi",
    .id          = 1,
    .num_resources      = ARRAY_SIZE(s3c_spi1_resource),
    .resource      = s3c_spi1_resource,
        .dev              = {
                .dma_mask = &s3c_device_spi1_dmamask,
                .coherent_dma_mask = 0xffffffffUL
        }
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define S3C_PA_SPI        S3C64XX_PA_SPI
#define S3C_PA_SPI0        S3C64XX_PA_SPI0
#define S3C_PA_SPI1        S3C64XX_PA_SPI1
#define S3C_SZ_SPI        S3C64XX_SZ_SPI
#define S3C_SZ_SPI0        S3C64XX_SZ_SPI0
#define S3C_SZ_SPI1        S3C64XX_SZ_SPI1

图片
/* SPI */
#define S3C64XX_PA_SPI           (0x7F00B000)
#define S3C64XX_PA_SPI0           (0x7F00B000)
#define S3C64XX_PA_SPI1           (0x7F00C000)
#define S3C64XX_SZ_SPI        SZ_8K
#define S3C64XX_SZ_SPI0        SZ_4K
#define S3C64XX_SZ_SPI1        SZ_4K
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////









阅读(1177) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~