最近项目需要,需要在mini2440上移植SPI驱动,板子需要驱动SPI设备,上网找了很多资源,但是很多都是有问题,最终在基本理解驱动结构的前提下,将SPI驱动顺利移植到mini2440。
,我使用的内核版本是2.6.32.2,这个版本和2.6。29不一样,网上很多版本都是关于2.6.29,如果完全按照网上步骤,编译会出现问题,我做的步骤如下:
1,在Linux Source Code中修改arch/arm/mach-s3c2440/mach-mini2440.c文件,加入头文件:
- #include <linux/spi/spi.h>
- #include <../mach-s3c2410/include/mach/spi.h>
- static struct spi_board_info s3c2410_spi0_board[] =
- {
- [0] = {
- .modalias = "spidev",
- .bus_num = 0,
- .chip_select = 0,
- .irq = IRQ_EINT9,
- .max_speed_hz = 500 * 1000,
- }
- };
- static struct s3c2410_spi_info s3c2410_spi0_platdata = {
- .pin_cs = S3C2410_GPG(2),
- .num_cs = 1,
- .bus_num = 0,
- .gpio_setup = s3c24xx_spi_gpiocfg_bus0_gpe11_12_13,
- };
- static struct spi_board_info s3c2410_spi1_board[] =
- {
- [0] = {
- .modalias = "spidev",
- .bus_num = 1,
- .chip_select = 0,
- .irq = IRQ_EINT2,
- .max_speed_hz = 500 * 1000,
- }
- };
- static struct s3c2410_spi_info s3c2410_spi1_platdata = {
- .pin_cs = S3C2410_GPG(3),
- .num_cs = 1,
- .bus_num = 1,
- .gpio_setup = s3c24xx_spi_gpiocfg_bus1_gpg5_6_7,
- };
在mini2440_devices[]平台数组中添加如下代码:
- &s3c_device_spi0,
- &s3c_device_spi1,
- s3c_device_spi0.dev.platform_data= &s3c2410_spi0_platdata;
- spi_register_board_info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board));
- s3c_device_spi1.dev.platform_data= &s3c2410_spi1_platdata;
- spi_register_board_info(s3c2410_spi1_board, ARRAY_SIZE(s3c2410_spi1_board));
最后需要修改arch/arm/plat-s3c24xx/KConfig文件
找到如下代码段:
- config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
- bool
- help
- SPI GPIO configuration code for BUS0 when connected to
- GPE11, GPE12 and GPE13.
- config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
- bool
- help
- SPI GPIO configuration code for BUS 1 when connected to
- GPG5, GPG6 and GPG7.
修改为
- config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
- bool "S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13"
- help
- SPI GPIO configuration code for BUS0 when connected to
- GPE11, GPE12 and GPE13.
- config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
- bool "S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7"
- help
- SPI GPIO configuration code for BUS 1 when connected to
- GPG5, GPG6 and GPG7.
- make menuconfig
图2
图3
图4
图5
最后编译内核
- make zImage
交叉编译:
- arm-linux-gcc -I ~/linux-2.6.32.2/include/ spidev_test.c
- FF FF FF FF FF FF
- 40 00 00 00 00 95
- FF FF FF FF FF FF
- FF FF FF FF FF FF
- FF FF FF FF FF FF
- DE AD BE EF BA AD
- F0 0D
总结:这里叙述的是驱动移植详细过程,代码的具体含义以及开发板的针脚对应图需要自己去查阅相关资料,这里不再详述。
转载自:http://blog.csdn.net/lxmky/article/details/6858322
//-------------------------------------------------
一下是自己总结的应用层的操作
S3C2440的SPI驱动只是做了一个驱动总线,不关心读取或写入时,最高位的变化,如看手册才明白,有些芯片的SPI协议写操作最高位是1,则 写地址0x6d,则写入的数据是0xed;!!!!
static void write_data(int fd)
{
int ret;
uint8_t tx[2];
tx[0]=0xed; //write 0x6d address SI4432 spi protel write MSB is 1;so is 0xed
tx[1]=0x09;
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)&tx,
.rx_buf = (unsigned long)NULL, //
.len = 2,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
.cs_change = 0,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret == 1)
pabort("can't send spi message");
printf("ioctl write data operation return is %d---------\n",ret);
}
static void read_data(int fd)
{
int ret;
uint8_t address=0x6d; //from 0x6d address start read
uint8_t din[100];
memset(din,0,100);//only test
struct spi_ioc_transfer read[2] =
{
{
.tx_buf = (unsigned long)&address,
.rx_buf = (unsigned long)NULL, //when only write data operation, rx_buf must be null
.len = 1,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
.cs_change = 0,
},
{
.tx_buf = (unsigned long)NULL, // when only read data operation ,tx_buf must be null
.rx_buf = (unsigned long)din,
.len =1,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
.cs_change =0, // =0 or =1 ,result is same !!snoguo
}
};
ret = ioctl(fd, SPI_IOC_MESSAGE(2), read);
if (ret == 1)
pabort("can't send spi message");
printf("ioctl read return is %d\n",ret);
// for (ret = 0; ret < ARRAY_SIZE(din); ret++) {
// if (!(ret % 6))
// puts("");
printf("%.2X ", din[0]);
//}
puts("");
}