freescale mx6q平台上添加spi资源

1:配置管脚为SPI功能

在board-mx6q_sabresd.h的最后添加,复制被重定义

(以添加SPI2为例)    

[cpp]  view plain  copy
  1.         
  2. /* ECSPI2*/  
    1. MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,  
    2. MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,  
    3. MX6Q_PAD_EIM_OE__ECSPI2_MISO,  
    4. MX6Q_PAD_CSI0_DAT11__GPIO_5_29,   

  3.  


之后再板级文件board-mx6q_sabresd.c中将有相关函数对管脚进行统一初始化。

完成寄存器配置的工作。

[cpp]  view plain  copy
  1. static int mx6q_sabresd_spi2_cs[] = {
    SABRESD_ECSPI2_CS0,
    };
    static const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {
    .chipselect     = mx6q_sabresd_spi2_cs,
    .num_chipselect = ARRAY_SIZE(mx6q_sabresd_spi2_cs),
    };



  2. static struct spi_board_info imx6_sabresd_spi2_device[] __initdata = {
    #if defined(CONFIG_SDSD2828)
    {  
    .modalias = "ssd2828",
    .max_speed_hz = 500000, /* max spi clock (SCK) speed in HZ */
    .bus_num = 1,
    .chip_select = 0,
    .mode = 0,
    .platform_data = &honmax_ssd2828_data,
    },
    #endif
    };


    static void spi2_device_init(void)
    {
    spi_register_board_info(imx6_sabresd_spi2_device,
    ARRAY_SIZE(imx6_sabresd_spi2_device));
    }

imx6q_add_ecspi(1, &mx6q_sabresd_spi2_data);
spi2_device_init();

2:在板级文件board-mx6q_sabresd.c中添加以下代码

将匹配到driver/spi/spidev.c文件中的驱动源码

2.1完成SPI master的注册

SPI2片选管脚宏定义:

[cpp]  view plain  copy
  1. #define SABRESD_ECSPI2_CS0 IMX_GPIO_NR(5, 29)


添加相关结构体

[cpp]  view plain  copy
  1. static int mx6q_marsboard_spi1_cs[] = {  
  2.         SABRESD_ECSPI2_CS0,  
  3. };  


 

[cpp]  view plain  copy
  1. static const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {  
  2.         .chipselect = mx6q_marsboard_spi2_cs,  
  3.         .num_chipselect = ARRAY_SIZE(mx6q_marsboard_spi1_cs),  
  4. };  


 

2.2在spi 总线上匹配spi2的驱动文件

mx6q平台有2路spi资源,0/1,其中的bus_num则为挂载驱动的总线选择。


[cpp]  view plain  copy
  1. "font-size:18px;">"font-size:14px;">static struct mtd_partition imx6_sabrelite_spi_nor_partitions[] = {  
  2.  {  
  3.   .name = "bootloader",  
  4.   .offset = 0,  
  5.   .size = 0x00100000,  
  6.  },  
  7.  {  
  8.   .name = "kernel",  
  9.   .offset = MTDPART_OFS_APPEND,  
  10.   .size = MTDPART_SIZ_FULL,  
  11.  },  
  12. };  
  13.   
  14.   
  15. static struct flash_platform_data imx6_sabrelite__spi_flash_data = {  
  16.  .name = "spidev",  / /匹配原则。  
  17.  .parts = imx6_sabrelite_spi_nor_partitions,  
  18.  .nr_parts = ARRAY_SIZE(imx6_sabrelite_spi_nor_partitions),  
  19.  .type = "sst25vf016b",  
  20. };  
  21.   
  22. static struct spi_board_info imx6_sabrelite_spi_nor_device[] __initdata = {  
  23.  {  
  24.   .modalias = "spidev",  
  25.   .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */  
  26.   .bus_num = 1,    //设备挂载第几号spi总线上  
  27.   .chip_select = 0,  
  28.   .platform_data = &imx6_sabrelite__spi_flash_data,  
  29.  },  
  30. };  
  31.   
  32.   
  33. spi_register_board_info(imx6_sabrelite_spi_nor_device,  
  34. ARRAY_SIZE(imx6_sabrelite_spi_nor_device));  
  35.   
  36. imx6q_add_ecspi(0, &mx6q_sabrelite_spi2_data);  
  37.   

 

3:内核配置

 

查看spidev.c文件目录下的Kconfig以及Makefile得知内核驱动的添加方法

 

选择蓝色部分选项,将spidev.c文件添加到内核中。

 

4:查看开发板/sys/bus/spi/drivers/spidev目录

 

在/dev下生成设备文件/dev/spidev1.0

 

5:使用freescale官方的bsp包中的spi测试程序对接口进行测试

[cpp]  view plain  copy
  1. "font-size:12px;">/* 
  2.  * SPI testing utility (using spidev driver) 
  3.  * 
  4.  * Copyright (c) 2007  MontaVista Software, Inc. 
  5.  * Copyright (c) 2007  Anton Vorontsov  
  6.  * 
  7.  * This program is free software; you can redistribute it and/or modify 
  8.  * it under the terms of the GNU General Public License as published by 
  9.  * the Free Software Foundation; either version 2 of the License. 
  10.  * 
  11.  * Cross-compile with cross-gcc -I/path/to/cross-kernel/include 
  12.  */  
  13.   
  14. #include   
  15. #include   
  16. #include   
  17. #include   
  18. #include   
  19. #include   
  20. #include   
  21. #include   
  22. #include   
  23.   
  24. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))  
  25.   
  26. static void pabort(const char *s)  
  27. {  
  28.     perror(s);  
  29.     abort();  
  30. }  
  31.   
  32. static const char *device = "/dev/spidev1.0";  
  33. static uint8_t mode;  
  34. static uint8_t bits = 8;  
  35. static uint32_t speed = 500000;  
  36. static uint16_t delay;  
  37.   
  38. static void transfer(int fd)  
  39. {  
  40.     int ret;  
  41.     uint8_t tx[] = {  
  42.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  43.         0x40, 0x00, 0x00, 0x00, 0x00, 0x95,  
  44.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  45.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  46.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  47.         0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,  
  48.         0xF0, 0x0D,  
  49.     };  
  50.     uint8_t rx[ARRAY_SIZE(tx)] = {0, };  
  51.     struct spi_ioc_transfer tr = {  
  52.         .tx_buf = (unsigned long)tx,  
  53.         .rx_buf = (unsigned long)rx,  
  54.         .len = ARRAY_SIZE(tx),  
  55.         .delay_usecs = delay,  
  56.         .speed_hz = speed,  
  57.         .bits_per_word = bits,  
  58.     };  
  59.   
  60.     ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);  
  61.     if (ret < 1)  
  62.         pabort("can't send spi message");  
  63.   
  64.     for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {  
  65.         if (!(ret % 6))  
  66.             puts("");  
  67.         printf("%.2X ", rx[ret]);  
  68.     }  
  69.     puts("");  
  70. }  
  71.   
  72.   
  73. int main(int argc, char *argv[])  
  74. {  
  75.     int ret = 0;  
  76.     int fd;  
  77.   
  78.     //parse_opts(argc, argv); /* for what ,unknow*/  
  79.   
  80.     fd = open(device, O_RDWR);  
  81.     if (fd < 0)  
  82.         pabort("can't open device");  
  83.   
  84.     /* 
  85.      * spi mode 
  86.      */  
  87.     ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);  
  88.     if (ret == -1)  
  89.         pabort("can't set spi mode");  
  90.   
  91.     ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);  
  92.     if (ret == -1)  
  93.         pabort("can't get spi mode");  
  94.   
  95.     /* 
  96.      * bits per word 
  97.      */  
  98.     ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);  
  99.     if (ret == -1)  
  100.         pabort("can't set bits per word");  
  101.   
  102.     ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);  
  103.     if (ret == -1)  
  104.         pabort("can't get bits per word");  
  105.   
  106.     /* 
  107.      * max speed hz 
  108.      */  
  109.     ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);  
  110.     if (ret == -1)  
  111.         pabort("can't set max speed hz");  
  112.   
  113.     ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);  
  114.     if (ret == -1)  
  115.         pabort("can't get max speed hz");  
  116.   
  117.     printf("spi mode: %d\n", mode);  
  118.     printf("bits per word: %d\n", bits);  
  119.     printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);  
  120.   
  121.     transfer(fd);  
  122.   
  123.     close(fd);  
  124.   
  125.     return ret;  
  126. }  
  127.   


 

执行应用程序,可以看到时序模式(spi 4种时序模式第0种),时钟频率等参数。

 

你可能感兴趣的:(imx6驱动)