Linux 驱动 SPI EEPROM(M95080W)

 M95080W 是 意法半导体的一款 SPI 接口的 EEPROM,容量大小为 8K bit。如果还没看 M95080W 的数据手册,赶紧去看! 
  https://blog.csdn.net/lu_embedded/article/details/80682912

硬件连接
  i.MX6q 是基于 NXP 四核 ARM Cortex-A9 架构的高性能处理器,它上面有 5 个 SPI 控制器,分别是 ECSPI1~5。在我们这里的测试平台上的硬件连接的情况是这样的:

  EEPROM 连接到 ECSPI5(SMARC 接口的 SPI0),具体管脚描述如下:

驱动模型

修改驱动文件
  实际上,Linux 内核已经支持 EEPROM 设备了,通常将其注册为 misc 杂项设备。其驱动模板位于 drivers/misc/eeprom 目录中,其中 at24.c 对应的是 I2C 设备,at25.c 对应的是 SPI 设备。M95080W 是 SPI 接口的 EEPROM,所以我们重点关注 at25.c 文件。 
  drivers/misc/eeprom/at25.c 是比较简单的驱动文件,其中定义了一些操作指令和参数:

#define AT25_WREN       0x06            /* latch the write enable */
#define AT25_WRDI       0x04            /* reset the write enable */
#define AT25_RDSR       0x05            /* read status register */
#define AT25_WRSR       0x01            /* write status register */
#define AT25_READ       0x03            /* read byte(s) */
#define AT25_WRITE      0x02            /* write byte(s)/sector */

#define AT25_SR_nRDY    0x01            /* nRDY = write-in-progress */
#define AT25_SR_WEN     0x02            /* write enable (latched) */
#define AT25_SR_BP0     0x04            /* BP for software writeprotect */
#define AT25_SR_BP1     0x08
#define AT25_SR_WPEN    0x80            /* writeprotect enable */

#define AT25_INSTR_BIT3 0x08            /* Additional address bit in instr */

#define EE_MAXADDRLEN   3               /* 24 bit addresses, up to 2 MBytes */

/* Specs often allow 5 msec for a page write, sometimes 20 msec;
 * it's important to recover from write timeouts.
 */
#define EE_TIMEOUT      25

  对比 M95080W 的数据手册,发现是兼容的,所以这部分不需要修改。 
  驱动程序提供了以下接口函数:

at25_bin_read()
at25_bin_write()
at25_ee_read()
at25_ee_write()
at25_mem_read()
at25_mem_write()
at25_np_to_chip()
at25_probe()
at25_remove()
  其中驱动注册部分代码是这样的:

static struct spi_driver at25_driver = {
        .driver = {
                .name           = "at25",
                .owner          = THIS_MODULE,
        },
        .probe          = at25_probe,
        .remove         = at25_remove,
};

module_spi_driver(at25_driver);

MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
MODULE_AUTHOR("David Brownell");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:at25");

  并没有设备匹配相关的代码,所以我们要给它加上,如下:

static const struct of_device_id at25_spi_of_match[] = {

        { .compatible = "st,m95080", },
        { },
};

MODULE_DEVICE_TABLE(of, at25_spi_of_match);

static struct spi_driver at25_driver = {
        .driver = {
                .name           = "at25",
                .owner          = THIS_MODULE,
                .of_match_table = at25_spi_of_match,
        },
        .probe          = at25_probe,
        .remove         = at25_remove,
};

module_spi_driver(at25_driver);

MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
MODULE_AUTHOR("David Brownell");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:at25");

  在 at25_driver 结构体中的 driver 成员中增加 of_match_table,它是我们在前面定义的一张设备匹配表,其中有一个 .compatible = "st,m95080" 兼容设备。这个名字是我自己取的,待会在设备树里面填写的也要一致。 
  别忘了还要调用 MODULE_DEVICE_TABLE(of, at25_spi_of_match);,这样就修改好了。

添加设备树节点
  参考:Documentation/devicetree/bindings/misc/at25.txt 
  在 ecspi5 节点中添加子节点 at25,兼容设备 "st,m95080",如下:

&ecspi5 {
    fsl,spi-num-chipselects = <1>;
    cs-gpios = <&gpio1 17 0>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi5_1 &pinctrl_ecspi5_cs_0>;
    status = "okay";

    at25@0 {
        compatible = "st,m95080";
        spi-max-frequency = <10000000>;
        pagesize = <32>;
        size = <1024>;
        address-width = <16>;
        spi-cpha;
        spi-cpol;
        reg = <0>;
    };
};

编译
  编译之前先 make menuconfig,确保 CONFIG_EEPROM_AT25 被选上,我这里选择编译进内核。

$ make menuconfig

Device Drivers
    |---> Misc devices 
        |---> EEPROM support 
            |---> <*> SPI EEPROMs from most vendors

  接着编译内核和设备树:

$ source /opt/poky/1.5.3/environment-setup-cortexa9hf-vfp-neon-poky-linux-gnueabi
$ make uImage LOADADDR=0x10008000
$ make imx6q-rom5420-b1.dtb

  更新系统!

文件I/O测试
  我们可以通过 sysfs 进行简单的读写测试,通过 cat 命令查看 eeprom 的数据,通过 echo 和重定向操作将数据写入 eeprom。

# cat /sys/bus/spi/drivers/at25/spi32764.0/eeprom
# echo "hello" > /sys/bus/spi/drivers/at25/spi32764.0/eeprom

  然后断电重启,再 cat 下看看“hello”还在不在吧!

测试程序
  放在 GitHub 了: https://github.com/luhuadong/Linux-programming/blob/master/driver/eeprom/test/eeprom_go.c
--------------------- 
作者:阿基米东 
来源:CSDN 
原文:https://blog.csdn.net/lu_embedded/article/details/80684042 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值