📄 pe4302.c
字号:
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/iobuf.h>
#include <linux/highmem.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/tqueue.h>
#include <linux/wait.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <linux/devfs_fs_kernel.h>
unsigned char *dbuf;
unsigned char TXdata;
#define PE4302_MAJOR 241
typedef char dsa_device_t;
devfs_handle_t dsa_devfs_dir;
static dsa_device_t dsa_devices[256];
unsigned long r_GPECON;//GPE define
unsigned long r_GPEDAT;
unsigned long r_GPEUP;
#define rGPECON (*(volatile unsigned long *)r_GPECON)
#define rGPEDAT (*(volatile unsigned long *)r_GPEDAT)
#define rGPEUP (*(volatile unsigned long *)r_GPEUP)
int dsa_open(struct inode *,struct file *);
int dsa_close(struct inode *,struct file *);
int dsa_ioctl(struct inode *,struct file *,unsigned int,unsigned long);
//ssize_t da_read(struct file *, char *,size_t);
static ssize_t dsa_write(struct file *, char *, size_t, loff_t *);
void dsa_data_send(void);
void init_dsa(void);
int address_map(void)
{
//I/O registers
r_GPECON = ioremap(0x56000040,4);
r_GPEUP = ioremap(0x56000048,4);
r_GPEDAT = ioremap(0x56000044,4);
return 0;
}
void init_dsa(void)
{
rGPECON |= 0x00000054;
rGPECON &= (~0x000000a8);
printk("rGPECON: %x\n",rGPECON);
}
void dsa_data_send(void)
{
unsigned int i;
//unsigned char length;
//length = strlen(TXdata);
rGPEDAT &= (~0x0008);
for(i=0;i<6;i++)
{
if((TXdata&0x20)==0x20)
{
rGPEDAT |= 0x0002;
}
else
{
rGPEDAT &= (~0x0002);
}
TXdata=TXdata<<1;
rGPEDAT &= (~0x0004); //PE4302 clk =0
rGPEDAT |= 0x0004; //PE4302 clk =1
rGPEDAT &= (~0x0004); //PE4302 clk =0
}
udelay(1);
rGPEDAT &= (~0x0010);
rGPEDAT |= 0x0010;
rGPEDAT &= (~0x0010);
printk("Transmit is over!\n");
}
static ssize_t dsa_write(struct file *file, char *buf, size_t count, loff_t *offset)
{
int ret;
dbuf = kmalloc(count*sizeof(unsigned char) , GFP_KERNEL);
ret=copy_from_user(dbuf,buf,count);
if(ret)
{
return -EFAULT;
}
printk("*dbuf: %x\n",*dbuf);
TXdata = *dbuf;
printk("TXdata: %x\n",TXdata);
//Transmit data to PE4302
dsa_data_send();
kfree(dbuf);
return count;
}
int dsa_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd) {
default:
return -ENOIOCTLCMD;
}
}
int dsa_open(struct inode *inode, struct file *file)
{
int minor;
minor = MINOR(inode->i_rdev);
printk("open ok\n");
dsa_devices[minor]++;
return 0;
}
int dsa_close(struct inode *inode, struct file *file)
{
int minor;
minor = MINOR(inode->i_rdev);
if (dsa_devices[minor])
dsa_devices[minor]--;
printk("release ok\n");
return 0;
}
static struct file_operations dsa_fops = {
owner: THIS_MODULE,
//read: da_read,
write: dsa_write,
ioctl: dsa_ioctl,
open: dsa_open,
release: dsa_close,
};
static int __init dsa_init(void)
{
//Register device
dsa_devfs_dir= devfs_register(NULL,"PE4302",DEVFS_FL_DEFAULT,PE4302_MAJOR,
0, S_IFCHR |S_IRUSR |S_IWUSR |S_IRGRP |S_IWGRP,
&dsa_fops, NULL);
printk ("PE4302 driver installed OK\n");
address_map();
init_dsa();
return 0;
}
// Remove the PE4302 driver
static void dsa_exit(void)
{
devfs_unregister(dsa_devfs_dir);
printk ("PE4302 driver uninstalled OK\n");
}
module_init(dsa_init);
module_exit(dsa_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -