📄 fmc.c~
字号:
#include <linux/kernel.h> /* We're doing kernel work */
#include <linux/module.h> /* Specifically, a module */
#include <linux/fs.h>#include <asm/uaccess.h> /* for get_user and put_user */#include <asm-arm/io.h>#include <linux/mm.h>#include <linux/vmalloc.h>#include <linux/init.h>#include <linux/stat.h>#include <linux/param.h>#include <linux/sched.h>#include <linux/time.h>#include <linux/timer.h>#include <linux/ioctl.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/dma-mapping.h>#include <linux/slab.h>#include <asm/dma.h>#include <asm/dma-mapping.h>
#include <asm/arch/dma.h>#include <asm/io.h>//#include "tp1.c"#include "fst2_c.c"//#include "fstc.c"//#include "pst_e.c"//#include "pst_3.c"#include "pst_c.c"//#include "smain_e.c"//#include "sm2.c"//#include "smv2.c"//#include "smv3.c"//#include "smv3_2.c"#include "smv4c.c"//#include "set3.c"#define SUCCESS 0
#define DEVICE_NAME "fmc"
#define BUF_LEN 80
#define RLEN 10#define BZBASE 0x08000000#define BZSIZE 0x158#define BZ_OFFSET 0x08#define INTERVAL 2#define LCDSADDR1 0x4d000014#define LCDSADDR2 0x4d000018#define LCDR1 0x4d000000#define LCDR2 0x4d000004#define LCDR3 0x4d000008#define LCDR4 0x4d00000c#define LCDR5 0x4d000010#define rINTMSK 0x4a000008 //Interrupt mask control#define rSRCPND 0x4a000000 //Interrupt request status#define rINTPND 0x4a000010 //Interrupt request status#define LCD_XSIZE_TFT (640)
#define LCD_YSIZE_TFT (480)#define SCR_XSIZE_TFT (640)
#define SCR_YSIZE_TFT (480)
#define FM_IOC_MAGIC 'F'#define FM_IOC_VIDEO_SWITCH _IOWR(FM_IOC_MAGIC, 1, int)typedef struct tagDMA
{
unsigned int DISRC; //0x0
unsigned int DISRCC; //0x4
unsigned int DIDST; //0x8
unsigned int DIDSTC; //0xc
unsigned int DCON; //0x10
unsigned int DSTAT; //0x14
unsigned int DCSRC; //0x18
unsigned int DCDST; //0x1c
unsigned int DMASKTRIG; //0x20
}DMA; static struct s3c2410_dma_client s3c2410mem_dma_client = { .name = "s3c2410-mem",};irqreturn_t intdone(int irq,void *dev_id,struct pt_regs *regs);static int Device_Open = 0;
static char Message[BUF_LEN];
static char *Message_Ptr;
struct vm_area_struct *vma;unsigned long addrs, lcda1,lcda2,lcdr1,lcdr2,lcdr3,lcdr4,lcdr5,buf_add;struct timer_list jiq_timer;int beep_time=0,cd=0;//unsigned char tfbuf[LCD_XSIZE_TFT*LCD_YSIZE_TFT*2];unsigned char* fbp;dma_addr_t dma_ad;extern int Request_a_DMA(int channel);extern void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst);extern void PaintBi_ValueBitmap(unsigned char* pp,unsigned int x,unsigned int y,unsigned int width,unsigned int high,unsigned int color0,unsigned int color1);extern void PaintBitmap(unsigned char* pp,int x,int y,int width,int high);static int device_open(struct inode *inode, struct file *filp)
{ unsigned int buf_l,i; printk("In open\n");
/*if (Device_Open) { printk("fm_re_open! error!!--Open_count=%d\n",Device_Open);
return -EBUSY; }*/
Device_Open++;
Message_Ptr = Message; lcda1=(unsigned long)ioremap(LCDSADDR1,8); if(!lcda1) { printk("lcda1_remap error!!\n"); return -EIO; } buf_l=ioread32(lcda1+0); fbp=(unsigned char*)((buf_l)<<1); printk("BUF_add=%x\n",fbp); lcda1=(unsigned long)ioremap((buf_l)<<1,0x96000); if(!lcda1) { printk("lcda1_remap error!!\n"); return -EIO; } /* buf_add=(void *)__get_free_pages(__GFP_DMA,8); if(!buf_add) printk("No_free_memory!\n"); else { //PaintBi_ValueBitmap(fst,0,0,640,480,0x07ff,0x1f); PaintBitmap(fstc,0,0,640,480); dma_ad=dma_map_single(NULL,buf_add,PAGE_SIZE<<4,DMA_TO_DEVICE); //buf_add=dma_ad; printk("buf_add=%x\n",dma_ad); //memset(buf_add,0,PAGE_SIZE<<4); }*/ return SUCCESS;
}static void PutPixel(unsigned int x,unsigned int y,unsigned int c)
{
if(x<SCR_XSIZE_TFT && y<SCR_YSIZE_TFT) {
*((unsigned char *)buf_add+(y*LCD_XSIZE_TFT+x)*2)=c%256; *((unsigned char *)buf_add+(y*LCD_XSIZE_TFT+x)*2+1)=c/256;;
// frameBuffer16BitTft[(y)][(x)] = c; }
}
void PaintBitmap(unsigned char* pp,int x,int y,int width,int high){ printk("In PaintBitmap\n"); int i,j,k; for(j=0;j<high;j++) { for(i=0;i<width;i++) { k=*(pp+(j*width+i)*2)<<8; PutPixel(i+x,j+y,k+(*(pp+(j*width+i)*2+1))); } }}void PaintBi_ValueBitmap(unsigned char* pp,unsigned int x,unsigned int y,unsigned int width,unsigned int high,unsigned int color0,unsigned int color1) //xy
{
int i,j,k,l;
unsigned char tmp;
for(j=0;j<high;j++)
{
for(i=0;i<width/8;i++)
{
k=*(pp+j*width/8+i);
tmp=0x80;
for(l=0;l<8;l++)
{
if(l>0)
tmp=tmp>>1;
if(((tmp&k)&0xff)!=0)
{
PutPixel(i*8+l+x,j+y,color1);
}
else
{
PutPixel(i*8+l+x,j+y,color0);
}
}
}
}
}static ssize_t device_write(struct file *filp,
const char * buffer, size_t length, loff_t * offset)
{
int i,mf=0;
printk("In Write.\n"); buf_add=(void *)__get_free_pages(__GFP_DMA,8); if(!buf_add) printk("No_free_memory!\n"); else { //PaintBi_ValueBitmap(fst,0,0,640,480,0x07ff,0x1f); //PaintBitmap(fstc,0,0,640,480); //dma_ad=dma_map_single(NULL,buf_add,PAGE_SIZE<<4,DMA_TO_DEVICE); //buf_add=dma_ad; printk("buf_add=%x\n",dma_ad); //memset(buf_add,0,PAGE_SIZE<<4); }
for (i = 0; (i < length) && (i < BUF_LEN); i++)
get_user(Message[i], buffer + i);
Message_Ptr = Message; switch(Message[0]) { case 0: PaintBitmap(fst2_c,0,0,640,480); break; case 1: PaintBitmap(pst_c,0,0,640,480); break; case 2: PaintBitmap(smv4c,0,0,640,480); break; //case 3: PaintBitmap(set3,0,0,640,480); // break; } i=0; do { mf=Request_a_DMA(i); if(mf!=0) { printk("Burst channel%d busy.\n",i); i++; } }while((i<4)&&(mf!=0)); printk("BurstID=%d.\n",i); if(i==4) { printk("All burst channel busy!!\n"); return -1; } dma_ad=dma_map_single(NULL,buf_add,PAGE_SIZE<<4,DMA_TO_DEVICE);
DMA_M2M(i,dma_ad,fbp, 0x9600,2,1); //word,burst*/ dma_unmap_single(NULL,buf_add,PAGE_SIZE<<4,DMA_TO_DEVICE); free_pages(buf_add,8);
return i;
}static int device_release(struct inode *inode, struct file *filp)
{
if(Device_Open>0) Device_Open--;
printk("In release Open_count=%d\n",Device_Open);// free_pages(buf_add,8);
//module_put(THIS_MODULE);
return SUCCESS;
}int Request_a_DMA(int channel){ DMA *pDMA; printk("In Request_a_DMA.\n"); switch(channel)
{
case 0:
pDMA=(unsigned long)ioremap(0x4b000000,0x40);
break;
case 1:
pDMA=(unsigned long)ioremap(0x4b000040,0x40);
break;
case 2:
pDMA=(unsigned long)ioremap(0x4b000080,0x40);
break;
case 3:
pDMA=(unsigned long)ioremap(0x4b0000c0,0x40);
break;
} if(((pDMA->DSTAT)&0x300000)!=0) return 1; //busy else return 0; //ready}void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst)
{
DMA *pDMA;
int length,buf;
printk("In burst.\n");
length=tc*(burst ? 4:1)*((dsz==0)+(dsz==1)*2+(dsz==2)*4);
switch(ch)
{
case 0:
pDMA=(unsigned long)ioremap(0x4b000000,0x40);
break;
case 1:
pDMA=(unsigned long)ioremap(0x4b000040,0x40);
break;
case 2:
pDMA=(unsigned long)ioremap(0x4b000080,0x40);
break;
case 3:
pDMA=(unsigned long)ioremap(0x4b0000c0,0x40);
break;
} pDMA->DISRC=srcAddr;
pDMA->DISRCC=(0<<1)|(0<<0); // inc,AHB
pDMA->DIDST=dstAddr;
pDMA->DIDSTC=(0<<1)|(0<<0); // inc,AHB
pDMA->DCON=tc|(1<<31)|(1<<30)|(0<<29)|(burst<<28)|(1<<27)|(0<<23)|(1<<22)|(dsz<<20)|(tc);
//HS,AHB,TC no-interrupt,whole, SW request mode,relaod off
pDMA->DMASKTRIG=(1<<1)|1; //DMA on, SW_TRIG
printk("Burst started!\n"); buf=ioread32(pDMA+0x14);
while((buf&0xfffff)!=0) { buf=ioread32(pDMA+0x14); } ; //CTRR_TC
printk("Burst finished\n");
}
struct file_operations Fops = {
// .read = device_read,
.write = device_write,
// .ioctl = device_ioctl,
.open = device_open,
.release = device_release, /* a.k.a. close */
};int ret_val;
int init_module()
{
ret_val = register_chrdev(0, DEVICE_NAME, &Fops);
if (ret_val < 0) {
printk("failed with %d\n",ret_val);
return ret_val;
}
printk("The major device number is %d.\n", ret_val);
printk("If you want to talk to the device driver,\n");
printk("you'll have to create a device file. \n");
printk("We suggest you use:\n");
printk("mknod %s c %d 0\n", DEVICE_NAME, ret_val);
printk("The device file name is important, because\n");
printk("the ioctl program assumes that's the\n");
printk("file you'll use.\n");
return 0;
}
void cleanup_module()
{
int ret;
ret = unregister_chrdev(ret_val, DEVICE_NAME);
if (ret < 0)
printk("Error in module_unregister_chrdev: %d\n", ret);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -