博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
S3C2440 SPI驱动简单测试
阅读量:4052 次
发布时间:2019-05-25

本文共 5099 字,大约阅读时间需要 16 分钟。

#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/gpio.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <asm/system.h>
#include <asm/signal.h>
#include <asm/io.h>
#define DBG(msg...) do{ \
if(debug)\
printk(KERN_INFO msg);\
}while(0)
static int debug=1;
static int spi_major=0;
module_param(spi_major,int,S_IRUGO);
static struct class *spi_class;
static struct semaphore sem;  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//static struct clk *spi_clock;
#define DEVICE_NAME "tq2440_spi"
struct cdev spiCdev;
static DECLARE_WAIT_QUEUE_HEAD(spi_waitq);
static int ack=0;
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 ssize_t spi_read(struct file *filp,char *buf,size_t count,loff_t *f_ops);
static ssize_t spi_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long data);
volatile unsigned long *spi_gpfcon=NULL;//GPF Part define
volatile unsigned long *spi_gpfdat=NULL;
volatile unsigned long *spi_gpfup=NULL;
volatile unsigned long *spi_gpgcon=NULL;//GPG Part define
volatile unsigned long *spi_gpgdat=NULL;
volatile unsigned long *spi_gpgup=NULL;
volatile unsigned long *s3c2440_clkcon;
volatile unsigned long *spi_spcon1;//SPI Part define
volatile unsigned long *spi_spsta1;
volatile unsigned long *spi_sppin1;
volatile unsigned long *spi_sppre1;
volatile unsigned long *spi_sptdat1;
volatile unsigned long *spi_sprdat1;
static const struct file_operations spi_fops = 
{
.owner=THIS_MODULE,
.open=spi_open,
.read=spi_read,
.ioctl=spi_ioctl,
.release=spi_release,
.write=spi_write,
};
static irqreturn_t spi_interrupt(int irq,void *dev_id,struct pt_regs *regs)
{
ack=1;
DBG("irq\n");
wake_up_interruptible(&spi_waitq);
return IRQ_HANDLED;
}
static int spi_open(struct inode *inode,struct file *filp)
{
if(down_interruptible(&sem))
return -ERESTARTSYS;
filp->private_data =&spiCdev;
return 0;
}
static int spi_release(struct inode *inode,struct file *filp)
{
up(&sem);
DBG("release\n");
return 0;
}
static void writeByte(const char c)
{
*spi_sptdat1 = c;
wait_event_interruptible(spi_waitq,ack);
ack=0;
}
static char readByte(void)
{
char ch = 0;
*spi_sptdat1 = (char)0xff;
wait_event_interruptible(spi_waitq,ack);
ack=0;
ch=*spi_sprdat1;
return ch;
}
static ssize_t spi_read(struct file *filp,char __user *buf,size_t count,loff_t *f_ops)
{
char ch;
DBG("spi read!\n");
ch=readByte();
copy_to_user(buf,&ch,1);
return 1;
}
static ssize_t spi_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_ops)
{
int i;
char *kbuf;
DBG("spi write!,count=%d\n",count);
kbuf=kmalloc(count,GFP_KERNEL);
if(copy_from_user(kbuf,buf,count))
{
printk("no enough memory!\n");
return -1;
}
for(i=0;i<count;i++)
{
writeByte(*kbuf);
DBG("write 0xX!\n",*kbuf);
kbuf++;
}
kfree(kbuf);
kbuf=NULL;
return count;
}
static ssize_t spi_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long data)
{
return 0;
}
static int __init spi_init(void)
{
int result;
int ret;
dev_t devno;
init_MUTEX(&sem);
if(spi_major)
{
devno = MKDEV(spi_major, 0);
result = register_chrdev_region(devno, 1, DEVICE_NAME);
}
 
else
{
result = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);
spi_major = MAJOR(devno);
}
if (result < 0)
 
 
return result;  
 
 
 
cdev_init(&spiCdev, &spi_fops);
 
spiCdev.owner = THIS_MODULE;
spiCdev.ops = &spi_fops;
if (cdev_add(&spiCdev, devno, 1))
printk(KERN_NOTICE "Error adding spi %d\n", 0);
s3c2440_clkcon = (unsigned long *)ioremap(0x4C00000c,3);
spi_spcon1 = (unsigned long *)ioremap(0x59000020,1);
spi_spsta1 = (unsigned long *)ioremap(0x59000024,1);
spi_sppin1 = (unsigned long *)ioremap(0x59000028,1);
spi_sppre1 = (unsigned long *)ioremap(0x5900002c,1);
spi_sptdat1 = (unsigned long *)ioremap(0x59000030,1);
spi_sprdat1 = (unsigned long *)ioremap(0x59000034,1);
*s3c2440_clkcon |=0x40000;
s3c2410_gpio_cfgpin(S3C2410_GPG5,S3C2410_GPG5_SPIMISO1);
s3c2410_gpio_cfgpin(S3C2410_GPG6,S3C2410_GPG6_SPIMOSI1);
s3c2410_gpio_cfgpin(S3C2410_GPG7,S3C2410_GPG7_SPICLK1);
s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_nSS1);
s3c2410_gpio_pullup(S3C2410_GPG5,1);
s3c2410_gpio_pullup(S3C2410_GPG6,1);
s3c2410_gpio_pullup(S3C2410_GPG7,1);
 
writel(0x18,spi_sppre1);
/
iounmap (s3c2440_clkcon);
iounmap (spi_spcon1);
iounmap (spi_spsta1);
iounmap (spi_sppin1);
iounmap (spi_sppre1);
iounmap (spi_sptdat1);
iounmap (spi_sprdat1);
printk("spi_exit!\n");
}
module_init(spi_init);
module_exit(spi_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("syw");
MODULE_DESCRIPTION("SPI driver for S3C2440");

转载地址:http://fnpci.baihongyu.com/

你可能感兴趣的文章
01Java基础语法-19. 循环跳转控制语句
查看>>
Django框架全面讲解 -- Form
查看>>
socket,accept函数解析
查看>>
今日互联网关注(写在清明节后):每天都有值得关注的大变化
查看>>
”舍得“大法:把自己的优点当缺点倒出去
查看>>
[今日关注]鼓吹“互联网泡沫,到底为了什么”
查看>>
[互联网学习]如何提高网站的GooglePR值
查看>>
[关注大学生]求职不可不知——怎样的大学生不受欢迎
查看>>
[关注大学生]读“贫困大学生的自白”
查看>>
[互联网关注]李开复教大学生回答如何学好编程
查看>>
[关注大学生]李开复给中国计算机系大学生的7点建议
查看>>
[茶余饭后]10大毕业生必听得歌曲
查看>>
VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
查看>>
VUE-Vue.js之$refs,父组件访问、修改子组件中 的数据
查看>>
Vue-子组件改变父级组件的信息
查看>>
Python自动化之pytest常用插件
查看>>
Python自动化之pytest框架使用详解
查看>>
【正则表达式】以个人的理解帮助大家认识正则表达式
查看>>
性能调优之iostat命令详解
查看>>
性能调优之iftop命令详解
查看>>