static struct class *spi_class;
static struct cdev spicdev;
dev_t devno;
/*****************************************************/
volatile unsigned long *spi_gpecon=NULL;
volatile unsigned long *spi_gpedat=NULL;
volatile unsigned long *spi_gpeup=NULL;
volatile unsigned long *spi_gpgcon=NULL;
volatile unsigned long *spi_gpgdat=NULL;
volatile unsigned long *spi_gpgup=NULL;
volatile unsigned long *s3c2440_clkcon;
volatile unsigned long *spi_spcon0;
volatile unsigned long *spi_spsta0;
volatile unsigned long *spi_sppin0;
volatile unsigned long *spi_sppre0;
volatile unsigned long *spi_sptdat0;
volatile unsigned long *spi_sprdat0;
#define SPI_TXRX_READY (((*spi_spsta0)&0x1) == 0x1)
#define SPI_CS (((*spi_gpgdat)&0x4)==0x01)
/***********nSS_SPI GPG2 SPICLK GPE13 -26
SPIMOSI GPE12-25 SPIMISO GPE11-24************/
static int spi_open(struct inode *inode,struct file *filp)
{
*s3c2440_clkcon |=0x40000;//使能SPI
*spi_gpecon &=0xF03FFFF;//配置SPI
*spi_gpecon |=0xA800000;//
// *spi_gpeup &=0xc7ff;//使能上拉电阻
*spi_gpgcon|=(3<<4);//配置nSS0
//*spi_gpgup &= 0xFB;
*spi_sppre0=0x06; // > 5M
*spi_spcon0=(0<<6)|(0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1)|(1<<0);
printk("spi_spcon0=%02X\n",(unsigned int)*spi_spcon0);
*spi_sppin0=(0<<2)|(0<<0);
printk("spi_sppin0=%02X\n",(unsigned int)*spi_sppin0);
return 0;
}
static ssize_t spi_read(struct file *filp,char __user *buf,size_t count,loff_t *f_ops)
{
char ch;
while(!SPI_TXRX_READY);
ch= (char)*spi_sprdat0;
copy_to_user(buf,&ch,1);
return 1;
}
static int spi_release(struct inode *inode,struct file *filp)
{
printk("<1>release\n");
return 0;
}
static ssize_t spi_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_ops)
{
return 0;
}
static ssize_t spi_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long data)
{
return 0;
}
static struct file_operations spi_drv_fops = {
.owner=THIS_MODULE,
.open=spi_open,
.read=spi_read,
.ioctl=spi_ioctl,
.release=spi_release,
.write=spi_write,
};
static int __init spi_init(void)
{
int result;
result = alloc_chrdev_region(&devno, 0, 1, "spi_drv");
if (result < 0)
return result;
cdev_init(&spicdev, &spi_drv_fops);
spicdev.owner = THIS_MODULE;
spicdev.ops = &spi_drv_fops;
cdev_add(&spicdev, devno, 1);
spi_class = class_create(THIS_MODULE, "spi_drv");
device_create(spi_class, NULL, devno, NULL, "S3C2440_SPI"); /* /dev/S3C2440_SPI */
s3c2440_clkcon = (volatile unsigned long *)ioremap(0x4C00000c,3);
spi_gpgcon = (volatile unsigned long *)ioremap (0x56000060,4);
spi_gpgdat = (volatile unsigned long *)ioremap (0x56000064,2);
spi_gpgup = (volatile unsigned long *)ioremap (0x56000068,2);
spi_gpecon = (volatile unsigned long *)ioremap (0x56000040,2);
spi_gpedat = (volatile unsigned long *)ioremap (0x56000044,1);
spi_gpeup = (volatile unsigned long *)ioremap (0x56000048,1);
spi_spcon0 = (volatile unsigned long *)ioremap(0x59000000,1);
spi_spsta0 = (volatile unsigned long *)ioremap(0x59000004,1);
spi_sppin0 = (volatile unsigned long *)ioremap(0x59000008,1);
spi_sppre0 = (volatile unsigned long *)ioremap(0x5900000c,1);
spi_sptdat0 = (volatile unsigned long *)ioremap(0x59000010,1);
spi_sprdat0 = (volatile unsigned long *)ioremap(0x59000014,1);
printk("Init spi success!\n");
return result;
}
static void __exit spi_exit(void)
{
cdev_del(&spicdev);
unregister_chrdev_region(devno, 1);
device_destroy(spi_class,devno);
class_destroy(spi_class);
iounmap(s3c2440_clkcon);
iounmap(spi_gpgcon);
iounmap(spi_gpgdat);
iounmap(spi_gpgup);
iounmap(spi_gpecon);
iounmap(spi_gpedat);
iounmap(spi_gpeup);
iounmap(spi_spcon0);
iounmap(spi_spsta0);
iounmap(spi_sppin0);
iounmap(spi_sppre0);
iounmap(spi_sptdat0);
iounmap(spi_sprdat0);
printk("<1>spi_exit!\n");
}
module_init(spi_init);
module_exit(spi_exit);