Reading/writing SPI 设备

Reading/writing SPI devices

(我真的不确定要应用哪些标签,如果我选择了错误的标签,请提前致歉。)

我希望这不是一个太愚蠢的问题,但我真的迷失在这里了。

一个客户借给我一个 Atmel SAMA5D2 Xplained board with Linux4SAM 玩玩。我正在尝试在其上连接 SPI 接口,但我不知道从哪里开始。

明确地说,我使用过类似的裸机板(不是这个特定的板)。我也使用 Linux 多年,几年前写了一些简单的设备驱动程序。我还是迷路了。

dmesg | grep spi 给我以下输出:

[    1.840000] atmel_spi f8000000.spi: version: 0x311
[    1.840000] atmel_spi f8000000.spi: Using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers
[    1.850000] atmel_spi f8000000.spi: Using FIFO (16 data)
[    1.860000] atmel_spi f8000000.spi: Atmel SPI Controller at 0xf8000000 (irq 32)
[    1.860000] m25p80 spi32766.0: at25df321a (4096 Kbytes)

据此我推断驱动程序已加载并且配置为使用 DMA。然而,在 /dev/ 中没有任何东西看起来像 SPI 设备(我期待找到类似 /dev/spidev/dev/spi32766.0 或类似的东西。)

这是否意味着没有加载实际的设备驱动程序?我必须写一个才能使用 SPI 吗?

如果我查看 Makefile in the Linux4SAM source tree,我会在第 1171 行看到内核不支持加载模块。这是否意味着我必须重新编译内核以包含我的新驱动程序?这似乎是一种愚蠢的做法;如果我无法使用它访问硬件,为什么还要提供 Linux 分发版?

我在这里错过了什么? (我觉得比较傻。。。)

编辑 明确一点:我想访问将连接到某些外部设备的外部 SPI 接口。我认为 m25p80 是一些内部闪存;我对那里 read/write 不感兴趣。

@0andriy 让我走上了正确的轨道。我必须将 SPI 资源添加到设备树并将编译设备树 Blob 闪存到电路板。 (因为我对Device Trees一无所知,所以这个资料真的不好找。。。)

我现在有一个 /dev/spidev32765.0。我将其添加到设备树中:

        spi1: spi@fc000000 {
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_spi1_default>;
            status = "okay";

            spidev@0 {
                compatible = "linux,spidev";
                spi-max-frequency = <83000000>;
                reg = <0>;
            };
        };

        pinctrl@fc038000 {
            pinctrl_spi1_default: spi1_default {
                pinmux = <PIN_PD25__SPI1_SPCK>,
                     <PIN_PD26__SPI1_MOSI>,
                     <PIN_PD27__SPI1_MISO>,
                     <PIN_PD28__SPI1_NPCS0>;
                bias-disable;
            };
        };

虽然我读到添加 spidev@0 并不是真正正确的做法(我确实在 dmesg 输出 "spidev spi32765.0: buggy DT: spidev listed directly in DT" 中看到)。

现在,如果我 运行 spidev_test 它仍然不起作用(超时),但我想这是另一个问题。

spidev 是一个标准的 Linux 设备驱动程序,它只是通过 /dev[=25 将低级别 API 导出到用户空间=]界面

如果你想访问特定的 SPI 客户端(从)你应该写你的驱动程序 根据 Linux SPI 驱动程序模型:

static const struct of_device_id myspi_dt_ids[] = {
{ .compatible = "xxxx,yyyyy" },
{},

static struct spi_driver xxx_spi_driver = {
.driver = {
    .name =     "myspi",
    .owner =    THIS_MODULE,
    .of_match_table = of_match_ptr(myspi_dt_ids),
},
.probe =    myspi_probe,
.remove =   myspi_remove,

例如定义 spi_driver 结构,of_device_id 结构,回调(挂钩),并注册它。 您应该使用兼容的 属性 字符串将其绑定到您的 DT 节点。

            myspi@0 {
            compatible = "xxxx,yyyyy";
            spi-max-frequency = <5000000>;
            reg = <0>;
        };

秒,

compatible = "linux,spidev";

Linux 不鼓励使用这个兼容的 属性 因为节点应该 描述真正的硬件设备而不是用户空间抽象