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");
///////////////////////////////////////////////////////////////////////////////
阅读(1587) | 评论(0) | 转发(0) |