📄 s3c2410_spi0.c
字号:
#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/ioport.h>#include <linux/miscdevice.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/poll.h> #include <linux/spinlock.h> #include <linux/delay.h> #include <linux/wait.h>#include <linux/device.h> #include <linux/devfs_fs_kernel.h> #include <linux/types.h> #include <linux/cdev.h> #include <linux/errno.h> #include <asm/uaccess.h> #include <asm/hardware.h>#include <asm/io.h>#include <asm/arch/regs-mem.h>#include <asm/arch/regs-gpio.h>#include <asm/arch/regs-spi.h>#define DEVICE_NAME "S3C2410_SPI0" static int spi_major = 0; static unsigned long *spi_clkcon; static unsigned long *spi_gpgcon; static unsigned long *spi_gpecon; //GPG Part define static unsigned long *spi_gpedat; static unsigned long *spi_gpeup; static unsigned long *spi_gpgdat; static unsigned long *spi_gpgup; static unsigned long *spi_spcon0; //SPI Part define static unsigned long *spi_spsta0; static unsigned long *spi_sppin0; static unsigned long *spi_sppre0; static unsigned long *spi_sptdat0; static unsigned long *spi_sprdat0; void spi_Initial(void){ *spi_clkcon |= (1<<18); *spi_sppre0=0x0f;//SPI Baud Rate Prescaler Register,Baud Rate=PCLK/2/(Prescaler value+1) *spi_spcon0=(0<<6)|(0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0); //polling,en-sck,slave,low,format A,nomal *spi_sppin0=(0<<2)|(1<<1)|(0<<0); //Multi Master error detect disable,reserved,release *spi_gpecon=(*spi_gpecon&(~((3<<22)|(3<<24)|(3<<26)))) | (2<<22) | (2<<24) | (2<<26); *spi_gpgcon=(3<<4); } static int spi_open(struct inode *inode,struct file *filp){ spi_Initial(); return 0;}static ssize_t spi_write(struct file *filp,const char *buf,size_t count,loff_t *f_ops){ int i; char *tmp; tmp = kmalloc(count,GFP_KERNEL); copy_from_user(tmp,buf,count); for(i = 0; i< count; i++) { while((*spi_spsta0&0x01)==0); *spi_sptdat0 = tmp[i]; } kfree(tmp); return 1;}static int spi_reay_wait(unsigned int delay){ unsigned long jiffies_new; jiffies_new = jiffies + delay; while((*spi_spsta0&0x01)==0) { if(jiffies > jiffies_new) return 0; } return 1;}static ssize_t spi_read(struct file *filp, char *buf,size_t count,loff_t *f_ops){ int i; char *tmp; tmp = kmalloc(count,GFP_KERNEL); for(i=0; i<count; i++) { if(spi_reay_wait(HZ/10)) { tmp[i] = *spi_sprdat0; } else { i++; break; } } copy_to_user(buf,tmp,i); return (i);}static int spi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ *spi_sppre0 = (unsigned long)cmd; return 0;}static struct file_operations spi_fops = { .owner = THIS_MODULE, .open = spi_open, .write = spi_write, .read = spi_read, .ioctl = spi_ioctl,};static int __init spi_init(void){ int ret; spi_gpedat = ioremap (0x56000044,4); spi_gpeup = ioremap (0x56000048,4); spi_clkcon = ioremap (0x4C00000C,4); spi_gpecon = ioremap (0x56000040,4); spi_gpgcon = ioremap (0x56000060,4); spi_gpgdat = ioremap (0x56000064,4); spi_gpgup = ioremap (0x56000068,4); spi_spcon0 = ioremap(0x59000000,4); spi_spsta0 = ioremap(0x59000004,4); spi_sppin0= ioremap(0x59000008,4); spi_sppre0 = ioremap(0x5900000c,4); spi_sptdat0 =ioremap(0x59000010,4); spi_sprdat0 =ioremap(0x59000014,4); ret = register_chrdev(0,DEVICE_NAME,&spi_fops); if(ret < 0) { printk("cpld_io: can't get major number\n"); return ret; } spi_major = ret; #ifdef CONFIG_DEVFS_FS ret = devfs_mk_cdev(MKDEV(spi_major,0), S_IFCHR | S_IRUGO | S_IWUSR,DEVICE_NAME); if(ret) { unregister_chrdev(spi_major,DEVICE_NAME); printk("s3c2410-spi0: can't make char device fo devfs\n"); return ret; }#endif printk("s3c2410-spi0 driver initial\n"); return 0;}static void __exit spi_exit(void){#ifdef CONFIG_DEVFS_FS devfs_remove(DEVICE_NAME);#endif unregister_chrdev(spi_major,DEVICE_NAME); printk("s3c2410-spi driver removed\n"); }MODULE_ALIAS("S3C2410_SPI0"); MODULE_DESCRIPTION("SPI0_driver for S3C2410");MODULE_AUTHOR("FENG");MODULE_LICENSE("GPL");module_init(spi_init);module_exit(spi_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -