- #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 cpu_s3c2410.h arch>
- #include <ASM io.h>
- #include <LINUX sched.h>
- unsigned long spi_gpgcon;//GPG Part define
- unsigned long spi_gpgdat;
- unsigned long spi_gpgup;
- unsigned long spi_spcon1;//SPI Part define
- unsigned 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_FS
- static 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=11
- spi_gpgcon |=0x0000fcc0;
- value=(int)spi_gpgcon;
- printk("spi_gpgcon=0x%x/n",value);
- spi_gpgup &=(0xff00);//GPGUP-3,7=1 GPGUP-5,6=0
- spi_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,nomal
- spi_sppin1=(0<<2)|(1<<1)|(0<<0);
- //Multi Master error detect disable,reserved,release
- config=(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);
- }
- else
- endSpiTx=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");
- else
- printk("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);
- #endif
- spi_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);
SPI_s3c2410.c 寄存器定义
最新推荐文章于 2023-07-13 17:33:31 发布