博客
关于我
强烈建议你试试无所不能的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://bnpci.baihongyu.com/

你可能感兴趣的文章
JavaScript的一些基础-数据类型
查看>>
转载一个webview开车指南以及实际项目中的使用
查看>>
android中对于非属性动画的整理
查看>>
一个简单的TabLayout的使用
查看>>
ReactNative使用Redux例子
查看>>
Promise的基本使用
查看>>
coursesa课程 Python 3 programming 统计文件有多少单词
查看>>
coursesa课程 Python 3 programming 输出每一行句子的第三个单词
查看>>
Returning a value from a function
查看>>
coursesa课程 Python 3 programming Functions can call other functions 函数调用另一个函数
查看>>
course_2_assessment_6
查看>>
coursesa课程 Python 3 programming course_2_assessment_7 多参数函数练习题
查看>>
coursesa课程 Python 3 programming course_2_assessment_8 sorted练习题
查看>>
在unity中建立最小的shader(Minimal Shader)
查看>>
1.3 Debugging of Shaders (调试着色器)
查看>>
关于phpcms中模块_tag.class.php中的pc_tag()方法的含义
查看>>
vsftp 配置具有匿名登录也有系统用户登录,系统用户有管理权限,匿名只有下载权限。
查看>>
linux安装usb wifi接收器
查看>>
多线程使用随机函数需要注意的一点
查看>>
getpeername,getsockname
查看>>