Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1152738
  • 博文数量: 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 21:53:37

drivers/spi/spi_test.c 这个文件可以细看,是详细分析spi驱动的好文件。
kernel/arch/mips/xburst/soc-t10/chip-t10/isvp/mango/board.h

 kernel/arch/mips/xburst/soc-t10/chip-t10/isvp/common/spi_bus.c
#ifndef CONFIG_SPI_GPIO
#define GPIO_SPI_SCK  GPIO_PC(15)
#define GPIO_SPI_MOSI GPIO_PC(11)
#define GPIO_SPI_MISO GPIO_PC(12)
#endif

//////////////////////////////////////////////////////////////////////////////
 kernel/arch/mips/xburst/soc-t10/chip-t10/isvp/common/spi_bus.c
spidev
#if defined(CONFIG_SPI_GPIO)
static struct spi_gpio_platform_data jz4780_spi_gpio_data = {
    .sck    = GPIO_SPI_SCK,
    .mosi    = GPIO_SPI_MOSI,
    .miso    = GPIO_SPI_MISO,
    .num_chipselect    = 2,
};

static struct platform_device jz4780_spi_gpio_device = {
    .name    = "spi_gpio",
    .dev    = {
        .platform_data = &jz4780_spi_gpio_data,
    },
};

//spi_board_info作为SPI设备的板级信息,在spi_new_device函数中将该板级信息全部复制给spi_device
static struct spi_board_info jz_spi0_board_info[] = {
       [0] = {
           .modalias       = "spidev",
           .bus_num           = 0,
           .chip_select    = 0,
           .max_speed_hz   = 120000,
       },
};
#endif

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

#define DRIVER_NAME    "spi_gpio"

MODULE_ALIAS("platform:" DRIVER_NAME);

static struct platform_driver spi_gpio_driver = {
    .driver = {
        .name    = DRIVER_NAME,
        .owner    = THIS_MODULE,
//看这里的of,应该是设备树的匹配表吧?
        .of_match_table = of_match_ptr(spi_gpio_dt_ids),
    },
    .probe        = spi_gpio_probe,
    .remove        = spi_gpio_remove,
};
module_platform_driver(spi_gpio_driver);
//这个是模拟的SPI?????
MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO ");

//设备数里匹配名字也是 "spi-gpio"
static struct of_device_id spi_gpio_dt_ids[] = {
    { .compatible = "spi-gpio" },
    {}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

static int spi_gpio_probe(struct platform_device *pdev)
{
    int                status;
    struct spi_master        *master;
    struct spi_gpio            *spi_gpio;
    struct spi_gpio_platform_data    *pdata;
    u16 master_flags = 0;
    bool use_of = 0;

    status = spi_gpio_probe_dt(pdev);
    if (status < 0)
        return status;
    if (status > 0)
        use_of = 1;

    pdata = pdev->dev.platform_data;
#ifdef GENERIC_BITBANG
    if (!pdata || !pdata->num_chipselect)
        return -ENODEV;
#endif

    status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);
    if (status < 0)
        return status;

    master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) +
                    (sizeof(int) * SPI_N_CHIPSEL));
    if (!master) {
        status = -ENOMEM;
        goto gpio_free;
    }
    spi_gpio = spi_master_get_devdata(master);
    platform_set_drvdata(pdev, spi_gpio);

    spi_gpio->pdev = pdev;
    if (pdata)
        spi_gpio->pdata = *pdata;

    master->flags = master_flags;
    master->bus_num = pdev->id;
    master->num_chipselect = SPI_N_CHIPSEL;
    master->setup = spi_gpio_setup;
    master->cleanup = spi_gpio_cleanup;
#ifdef CONFIG_OF
    master->dev.of_node = pdev->dev.of_node;

    if (use_of) {
        int i;
        struct device_node *np = pdev->dev.of_node;

        /*
         * In DT environments, take the CS GPIO from the "cs-gpios"
         * property of the node.
         */

        for (i = 0; i < SPI_N_CHIPSEL; i++)
            spi_gpio->cs_gpios[i] =
                of_get_named_gpio(np, "cs-gpios", i);
    }
#endif

    spi_gpio->bitbang.master = spi_master_get(master);
    spi_gpio->bitbang.chipselect = spi_gpio_chipselect;

    if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
        spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
        spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
        spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
        spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3;
    } else {
        spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0;
        spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1;
        spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2;
        spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3;
    }
    spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer;
    spi_gpio->bitbang.flags = SPI_CS_HIGH;

    status = spi_bitbang_start(&spi_gpio->bitbang);
    if (status < 0) {
        spi_master_put(spi_gpio->bitbang.master);
gpio_free:
        if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
            gpio_free(SPI_MISO_GPIO);
        if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
            gpio_free(SPI_MOSI_GPIO);
        gpio_free(SPI_SCK_GPIO);
        spi_master_put(master);
    }

    return status;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

obj-$(CONFIG_JZ_SPI)                += jz_spi.o
可知
///////////////////////////////////////////////////////////////


MODULE_ALIAS("jz_ssi");            /* for platform bus hotplug */
static struct platform_driver jz_spidrv = {
    .remove        = __exit_p(jz_spi_remove),
    .suspend    = jz_spi_suspend,
    .resume        = jz_spi_resume,
    .driver        = {
        .name    = "jz-ssi",
        .owner    = THIS_MODULE,
    },
};

static int __init jz_spi_init(void)
{
        return platform_driver_probe(&jz_spidrv, jz_spi_probe);
}

module_init(jz_spi_init);
MODULE_DESCRIPTION("JZ SPI Driver");
///////////////////////////////////////////////////////////////////////////////


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