📄 spi_s3c2410.c
字号:
#ifndef __KERNEL__#define __KERNEL__#endif#ifndef MODULE#define MODULE#endif#include <linux/config.h>#include <linux/module.h>MODULE_LICENSE("GPL");MODULE_AUTHOR("HHT<likehht@sohu.com>");MODULE_DESCRIPTION("SPI_driver for S3C2410");#ifdef CONFIG_SMP#define __SMP__#endif/***************************************************/#include <linux/kernel.h> /*printk()*/ #include <asm/uaccess.h> /*copy_to_user(),copy_from_user()*/#include <linux/fs.h> /*struct file_operations,register_chrdv()*/#include <linux/sched.h> /*和任务有关系*/#include <linux/types.h> /*u8,u16,u32...*/#include <linux/init.h>#include <asm/hardware.h>#include <asm/delay.h>#include <linux/version.h>#include <linux/iobuf.h>#include <linux/major.h>#include <linux/capability.h>#include <linux/smp_lock.h>#include <linux/fs.h>#include <linux/mm.h>#include <asm/arch/cpu_s3c2410.h>#include <asm/io.h>#include <linux/sched.h>unsigned long spi_gpgcon;//GPG Part defineunsigned long spi_gpgdat;unsigned long spi_gpgup;unsigned long spi_spcon1;//SPI Part defineunsigned long spi_spsta1;unsigned long spi_sppin1;unsigned long spi_sppre1;unsigned long spi_sptdat1;unsigned long spi_sprdat1;/*****************************************************/static int spi_open(struct inode *,struct file *);static int spi_release(struct inode *,struct file *);static ssize_t spi_write(struct file *filp,const char *buf,size_t count,loff_t *f_ops);/**********************************************************/static struct file_operations spi_fops = {owner: THIS_MODULE,open: spi_open,release:spi_release,write: spi_write,};static int spi_major = 0;#define spi_name "S3C2410_SPI"#define spi_minor 1#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t devfs_spi_dir,devfs_spiraw;#endif/********************************************************/static int spi_open(struct inode *inode,struct file *filp){int value;printk("<1>***************************");printk("<1>spi open program begin..\n");printk("<1>now,GPG port init...\n");spi_gpgcon &=0xffff033f;//GPGCON-3,5,6,7=11spi_gpgcon |=0x0000fcc0;value=(int)spi_gpgcon;printk("spi_gpgcon=0x%x\n",value);spi_gpgup &=(0xff00);//GPGUP-3,7=1 GPGUP-5,6=0spi_gpgup |=0x0088;value=(int)spi_gpgup;printk("spi_gpgup=0x%x\n",value);printk("<1>GPG port init end!\n");printk("<1>****************************");return 0;}static int spi_release(struct inode *inode,struct file *filp){ MOD_DEC_USE_COUNT; printk("<1>release\n"); return 0;}static ssize_t spi_write(struct file *filp,const char *buf,size_t count,loff_t *f_ops){int i=0;int config;char string;char str[20];char *txStr,*rxStr;volatile char *spiTxStr,*spiRxStr;volatile int endSpiTx; printk("<1>SPI polling TX/RX Test...\n");printk("<1>Connet SPIMOSI1 into SPIMISO1\n");endSpiTx=0;spiTxStr="ABCD0123";spiRxStr=str;txStr=(char *)spiTxStr;rxStr=(char *)spiRxStr; spi_sppre1=0x0;//SPI Baud Rate Prescaler Register,Baud Rate=PCLK/2/(Prescaler value+1)spi_spcon1=(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);config=(int)spi_spcon1;printk("<1>spi_spcon1=0x%x\n",config);//polling,en-sck,master,low,format A,nomalspi_sppin1=(0<<2)|(1<<1)|(0<<0);//Multi Master error detect disable,reserved,releaseconfig=(int)spi_sppin1;printk("spi_sppin1=0x%x\n",config); while(endSpiTx==0){//if(spi_sta1&0x1)if((spi_spsta1&0x01)==1) //data Tx/Rx ready{if(*spiTxStr !='\0'){spi_sptdat1=*spiTxStr++;string=spi_sptdat1;printk("transmit char=%c\n",string);}elseendSpiTx=1; //while(!(spi_sta1&0x1)) ;// while((spi_sta1&0x1)==0)// ;//check Rx ready state str[i]=spi_sprdat1;printk("receive char=%c\n",str[i]);i++; }}spi_spcon1=(0<<5)|(0<<4)|(1<<2)|(0<<1)|(0<<0);//Polling,dis-sck,master,low,format A,nomal*(spiRxStr-1)='\0';//remove last dummy data & attach End of String(Null)printk("Tx string:%s\n",txStr);printk("Rx string:%s\n",rxStr);/*if(strcmp(rxStr,txStr)==0)printk("transmit and receive is ok!\n");elseprintk("ERROR!\n");*/return 0;}static int __init spi_init(void){int ret;ret = register_chrdev(0,spi_name,&spi_fops);if(ret < 0){ printk("<1>cannot get major number\n"); return ret;}spi_major = ret;#ifdef CONFIG_DEVFS_FS devfs_spi_dir = devfs_mk_dir(NULL,"spi",NULL); devfs_spiraw = devfs_register(devfs_spi_dir,"0",DEVFS_FL_DEFAULT,spi_major,spi_minor,S_IFCHR | S_IRUSR | S_IWUSR,&spi_fops,NULL);#endifspi_gpgcon = *(volatile unsigned long *)ioremap (0x56000060,4);spi_gpgdat = *(volatile unsigned long *)ioremap (0x56000064,4);spi_gpgup = *(volatile unsigned long *)ioremap (0x56000068,4); spi_spcon1 = *(volatile unsigned long *)ioremap(0x59000020,4);spi_spsta1 = *(volatile unsigned long *)ioremap(0x59000024,4);spi_sppin1 = *(volatile unsigned long *)ioremap(0x59000028,4);spi_sppre1 = *(volatile unsigned long *)ioremap(0x5900002c,4);spi_sptdat1 = *(volatile unsigned long *)ioremap(0x59000030,4);spi_sprdat1 = *(volatile unsigned long *)ioremap(0x59000034,4); printk("Init spi success!\n");return 0;printk("<1>initialized!\n");return 0;}static void __exit spi_exit(void){#ifdef CONFIG_DEVFS_FS devfs_unregister(devfs_spiraw); devfs_unregister(devfs_spi_dir);#endif unregister_chrdev(spi_major,spi_name);}module_init(spi_init);module_exit(spi_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -