2spi
1spi_board_info参数
.modalias = "rc522", //初始化设备的名称
.platform_data = NULL,
.max_speed_hz = 10*1000*1000, //初始化传输速率
.bus_num = 2, //控制器编号
.chip_select = 0, //控制器片选的编号
.mode = SPI_MODE_0, //spi的模式
.controller_data = &spi2_csi[0], //片选IO的信息
spi2_board_info设备描述结构体,设备注册函数spi_register_board_info
2设备查询
2.1添加rfid驱动的内核:
cat sys/bus/spi/devices/spi2.0/modalias
rfid的设备名称rc522
2.2增加一个spi设备my_rc522,然后去掉rfid和can驱动
cat sys/bus/spi/devices/spi2.0/modalias
rfid的设备名称my_rc522,我没有rfid,驱动的是flash
3.驱动-SPI驱动注册和卸载。SPI设备驱动初始化完成-进入probe函数。
4.驱动-spi数据的传输
1.本节实验需要RFID的硬件模块
2.
2.1平台文件中RC522的设备名称直接改为my_rc522
2.2需要配置rfid对应的menuconfig
2.3 drivers/spi/Makefile中注释掉rc522.c文件的编译
3.从rc522驱动中提取spi传输的核心代码
4.直接在probe中做复位,读,写测试
写:rc522_write→rc522_sync_write→rc522_sync→spi_async
读:rc522_read→rc522_sync_read→rc522_sync→spi_async
5.Liux-spi利用字符驱动完成应用层对spi的读和写(驱动只管机制,不管策略)
1.在驱动中,使用杂项设备的方式产生设备节点,提供对spi接口的打开、读和写操作
2.在应用中,完成对rc522的读和写→读卡
6具体操作方法,在match_itop4412.c中把
把
#ifdef CONFIG_SPI_RC522
{
.modalias = "rc522",
.platform_data = NULL,
.max_speed_hz = 10*1000*1000,
.bus_num = 2,
.chip_select = 0,
.mode = SPI_MODE_0,
.controller_data = &spi2_csi[0],
}
#endif
改为
#ifdef CONFIG_SPI_RC522
{
.modalias = "spi_flash",
.platform_data = NULL,
.max_speed_hz = 10*1000*1000,
.bus_num = 2,
.chip_select = 0,
.mode = SPI_MODE_0,
.controller_data = &spi2_csi[0],
}
#endif
spi_flash
把driver/spi 中的makefile修改
注释掉对rc522.c的编译
#add by cym 20141222
#obj-$(CONFIG_SPI_RC522) += rc522.o
make menuconfig中
使能rc522 去掉 can的编译
上面修改的原因是 使能CONFIG_SPI_RC522 ,失能CONFIG_CAN_MCP251X
防止管脚编译成i2c6 (根据mach_itop4412.c 的代码)
#if !defined(CONFIG_CAN_MCP251X) && !defined(CONFIG_SPI_RC522)
#define I2C_SDA6 EXYNOS4_GPC1(3)
#define I2C_SCL6 EXYNOS4_GPC1(4)
#endif
7驱动源码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/compat.h>
#include <linux/spi/spi.h>
#include <linux/spi/spidev.h>
#include <asm/uaccess.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
//#include <mach/gpio-bank.h>
#include <mach/regs-gpio.h>
#include <asm/io.h>
#include <linux/regulator/consumer.h>
//#include "gps.h"
#include <linux/delay.h>
#include <linux/sched.h>
#if 0
void rc522_reset()
{
//printk("************************ %s\n", __FUNCTION__);
if(gpio_request_one(RC522_RESET_PIN, GPIOF_OUT_INIT_HIGH, "RC522_RESET"))
pr_err("failed to request GPK1_0 for RC522 reset control\n");
s3c_gpio_setpull(RC522_RESET_PIN, S3C_GPIO_PULL_UP);
gpio_set_value(RC522_RESET_PIN, 0);
mdelay(5);
gpio_set_value(RC522_RESET_PIN, 1);
gpio_free(RC522_RESET_PIN);
}
#endif
#define DRIVER_NAME "spi_flash"
struct spi_device *this_spi ;
#define MAX_BUF 20
static char gbuf[MAX_BUF];
int flash_sync_data(char *data,int len,char rd_flg)
{
int status=0;
struct spi_message m;
DECLARE_COMPLETION_ONSTACK(done);
struct spi_transfer t = {
.len = len,
};
if(rd_flg)
{
t.rx_buf=data;
}else
{
t.tx_buf=data;
}
spi_message_init(&m);
spi_message_add_tail(&t, &m);
m.complete = complete;
m.context = &done;
if (spi_async(this_spi, &m)==0)
{
wait_for_completion(&done);
status =m.status;
if (status == 0)
status = m.actual_length;
}
return status;
}
/* Read-only message with current device setup */
static ssize_t flash_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
ssize_t status;
status = flash_sync_data(gbuf,count,1);
copy_to_user(buf,gbuf, status);
printk(KERN_EMERG "%s len;%d\n",__FUNCTION__,status);
return status;
}
/* Write-only message with current device setup */
static ssize_t flash_write(struct file *filp, const char __user *buf,size_t count, loff_t *f_pos)
{
ssize_t status;
copy_from_user(gbuf, buf, count);
status=flash_sync_data(gbuf,count,0);
printk(KERN_EMERG "%s len;%d\n",__FUNCTION__,status);
return status;
}
long read_ExFlash_id(void)
{
char sendbuf[10];
long flashid=0;
#define ID_READ 0x9f
#define Dummy_Byte 0xff
sendbuf[0]=ID_READ;
sendbuf[1]=Dummy_Byte;
sendbuf[2]=Dummy_Byte;
sendbuf[3]=Dummy_Byte;
flash_sync_data(sendbuf,1,0);
flash_sync_data(&sendbuf[1],3,0);
flashid=sendbuf[1];
flashid|=sendbuf[2]<<8;
flashid|=sendbuf[3]<<16;
return flashid;
}
static long flash_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int err = 0;
printk(KERN_EMERG "%s ops\n",__FUNCTION__);
return err;
}
static int flash_open(struct inode *inode, struct file *filp)
{
printk(KERN_EMERG "%s ops\n",__FUNCTION__);
return 0;
}
static int rc522_release(struct inode *inode, struct file *filp)
{
printk(KERN_EMERG "%s ops\n",__FUNCTION__);
return 0;
}
static const struct file_operations flash_fops = {
.owner = THIS_MODULE,
.write = flash_write,
.read = flash_read,
.unlocked_ioctl = flash_ioctl,
.open = flash_open,
.release = rc522_release,
};
/*-------------------------------------------------------------------------*/
static struct miscdevice flash_mic = {
.minor = MISC_DYNAMIC_MINOR,
.fops = &flash_fops,
.name = DRIVER_NAME,
};
/*-------------------------------------------------------------------------*/
static int __devinit flash_probe(struct spi_device *spi)
{
int status;
/* Initialize the driver data */
this_spi = spi;
//
printk(KERN_EMERG "%s match success \n",__FUNCTION__);
misc_register(&flash_mic);
printk(KERN_EMERG "read_ExFlash_id:%x \n",read_ExFlash_id());
return status;
}
static int __devexit flash_remove(struct spi_device *spi)
{
misc_deregister(&flash_mic);
return 0;
}
static struct spi_driver flash_spi_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = flash_probe,
.remove = __devexit_p(flash_remove),
};
/*-------------------------------------------------------------------------*/
static int __init flash_init(void)
{
int status;
status = spi_register_driver(&flash_spi_driver);
return status;
}
static void __exit flash_exit(void)
{
spi_unregister_driver(&flash_spi_driver);
}
module_exit(flash_exit);
module_init(flash_init);
MODULE_AUTHOR("kerwin");
MODULE_LICENSE("GPL");
//MODULE_ALIAS("spi:spidev");