ÔÚ±àдlinuxÇý¶¯µÄʱºò£¬Èç¹ûÒÔÀàµÄ˼ÏëÀ´±àд£¬¾Í¿ÉÒÔʵÏÖ×î´óÏ޶ȵÄÇý¶¯Í¨ÓÃÐÔ£¬ËäÈ»¶ÔÓÚµ¥¸öµÄÇý¶¯³ÌÐòÂÔÏÔ¸´ÔÓ£¬µ«ÊǶÔÓÚͬһÀàÐ͵Ķà¸öÉ豸Çý¶¯µÄ×¢²á£¬¾ÍÏÔµÃÌرðµÄ·½±ãÁË¡£ÏÂÃæ¾ÍÊÇÒÔÀàµÄ˼Ïë½øÐбà³ÌµÄÀý×Ó£¬ÒÔW25Q64Çý¶¯ÎªÀýµÄSPIÇý¶¯³ÌÐò£ºÔ´´úÂëÈçÏ£º
#include <linux/delay.h>
#include <linux/spi/spidriver.h>
#include <linux/module.h>
static void w25q64_cs(struct Spidevice_Operations *ops, int status); //Ƭѡ½Å¿ØÖÆ
static void w25q64_clk(struct Spidevice_Operations *ops, int status);//Õâ¸öÊÇÉèÖÃʱÖӵĺ¯Êý
static unsigned char w25q64_read_byte(struct Spidevice_Operations *ops); //¶ÁÒ»¸ö×Ö½Úº¯Êý
static void w25q64_write_byte(struct Spidevice_Operations *ops, unsigned char data, int mode); //дһ¸ö×Ö½Úº¯Êý
struct Spidevice_Operations w25q64_myops = {//SPI²Ù×÷½á¹¹Ìå
.name = "w25q64", //É豸Ãû
.spidevice_cs = w25q64_cs,
.spidevice_clk = w25q64_clk, //Õâ¸öÊÇÉèÖÃʱÖӸߵ͵çƽµÄº¯Êý
.spidevice_read_byte = w25q64_read_byte, //¶ÁÒ»¸ö×Ö½Úº¯Êý
.spidevice_write_byte = w25q64_write_byte,//дһ¸ö×Ö½Úº¯Êý
.prev = NULL, //Ö¸ÏòÉÏÒ»¸ö½Úµã
.pnext = NULL, //Ö¸ÏòÏÂÒ»¸ö½Úµã
};
EXPORT_SYMBOL_GPL(w25q64_myops); //ÉùÃ÷ΪÆäËûÄ£¿é¿ÉÒÔµ÷ÓÃ
//pincsΪ¼Ä´æÆ÷Ö¸Õ룬numΪ×óÒƼ¸Î»£¬statusΪÏëÒªÉèÖõÄ״̬
static void w25q64_cs(struct Spidevice_Operations *ops, int status) //Ƭѡ½Å¿ØÖÆ
{
if(status) //±íʾƬѡÖÃΪ¸ßµçƽ
{
*ops->pincs |= 0x01 << ops->csnum; //ÖÃÓڸߵçƽ
}
else
{
*ops->pincs &= ~(0x01 << ops->csnum); //ÖÃÓڵ͵çƽ
}
}
static void w25q64_clk(struct Spidevice_Operations *ops, int status)//Õâ¸öÊÇÉèÖÃʱÖӵĺ¯Êý
{
if(status) //±íʾƬѡÖÃΪ¸ßµçƽ
{
*ops->pinclk |= 0x01 << ops->clknum; //ÖÃÓڸߵçƽ
}
else
{
*ops->pinclk &= ~(0x01 << ops->clknum); //ÖÃÓڵ͵çƽ
}
}
static unsigned char w25q64_read_byte(struct Spidevice_Operations *ops) //¶ÁÒ»¸ö×Ö½Úº¯Êý
{
int i;
unsigned char value = 0;
for(i = 0; i < 8; i++)
{
printk("w25q64_read_byte\r\n");
ops->spidevice_clk(ops, 1); //ʱÖÓÖÃÓڸߵçƽ½ÓÊÕÊý¾Ý
if(*ops->pinin & 0x01 << ops->innum)
{
value |= 0x80 >> i; //ÊÕµ½Ò»¸ö1
}
else
{
value &= ~(0x80 >> i);
}
ops->spidevice_clk(ops, 0); //ʱÖÓÖÃÓڵ͵çƽµÈ´ý´ÓÉ豸׼±¸Êý¾Ý
}
return value; //·µ»ØvalueÖµ
}
static void w25q64_write_byte(struct Spidevice_Operations *ops, unsigned char data, int mode) //дһ¸ö×Ö½Úº¯Êý
{
int i;
for(i = 0; i < 8; i++)
{
printk("w25q64_write_byte\r\n");
ops->spidevice_clk(ops, 0); //ʱÖӵ͵çƽ£¬×¼±¸Êý¾Ý
if(data & 0x80 >> i) //´Ó¸ß×Ö½Ú¿ªÊ¼·¢Êý¾Ý ×¼±¸Êý¾Ý
{
*ops->pinout |= 0x01 << ops->outnum; //·¢³ö1
}
else
{
*ops->pinout &= ~(0x01 << ops->outnum); //·¢³ö0
}
ops->spidevice_clk(ops, 1); //ʱÖӸߵçƽ·¢ËÍÊý¾Ý
}
ops->spidevice_clk(ops, 0); //ʱÖӵ͵çƽ
}
MODULE_LICENSE("GPL");