⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 led_driver.c

📁 LINUX下控制LED屏的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	$Id: scan_keyb.c,v 1.2 2000/07/04 06:24:42 yaegashi Exp $  *	Copyright (C) 2000 YAEGASHI Takeshi *	Generic scan keyboard driver GPIO                  EXT     Direct     LED PIN ---------------------------------------------------------------------------------- EINT9/GPG1             6      output     A EINT16/GPG8            7      output     B EINT17/GPG9            8      output     C nSS1/EINT11/GPG3       9      output     D SPICLK1/EINT15/GPG7    10     output     ST SPIMISI1/EINT14/GPG6   11     output     EN SPIMISO1/EINT13/GPG5   12     output     CK TXD1/GPH4              13     output     R1 RXD1/GPH5              14     output     G1 nRTS1/TXD2/GPH6        15     output     R2 nCTS01/RXD2/GPH7       16     output     G2  */#include <linux/config.h>#include <linux/kernel.h>#include <linux/list.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/wait.h>#include <linux/errno.h>#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/poll.h>#include <asm/byteorder.h>#include <asm/atomic.h>#include <asm/io.h>#include <asm/uaccess.h>#include <linux/proc_fs.h>#include <linux/delay.h>#include <linux/devfs_fs_kernel.h>#include <asm/pgtable.h>#include <asm/page.h>#include <linux/sched.h>#include <asm/segment.h>#include <linux/types.h>#include <linux/wrapper.h>#include <linux/vmalloc.h>#include <linux/mm.h>#include <linux/major.h>#include <linux/string.h>//#include <linux/tty.h>#include <linux/signal.h>#include <linux/timer.h>#include <asm/hardware.h>#include "led_driver.h"
#define DEBUG 1#ifdef DPRINTK#undef DPRINTK#endif#ifdef DEBUG#define DPRINTK(x... ) printk( ##x )#else#define DPRINTK(x... )#endif#define TWH           10#define TWL           10#define TCS           15#define TCH           20#define TCR           30#define TCKS          20#define TCKH          20#define TDS           50#define TDH           50#define TRD           25#define TRZ           10#define TRF           20#define TPHL          60#define TPHZ          50#define TSU           30#define TH            10#define GPIO_LED_A             (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_G1)#define GPIO_LED_B             (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_G8)#define GPIO_LED_C             (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_G9)#define GPIO_LED_D             (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_G3)#define GPIO_LED_ST            (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_G7)#define GPIO_LED_EN            (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_G6)#define GPIO_LED_CK            (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_G5)#define GPIO_LED_R1            (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_H4)#define GPIO_LED_G1            (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_H5)#define GPIO_LED_R2            (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_H6)#define GPIO_LED_G2            (GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_H7)#define ENABLE  1#define DISABLE 0#define SCANHZ	(HZ/2)#ifndef virt_to_page#define virt_to_page(x) MAP_NR(x)#endif#ifndef vmalloc_32#define vmalloc_32(x) vmalloc(x)#endiftypedef struct led_screen_para {	u16 screenwidth;	u16 screenheight;	u8  depth;	u8  scanline;	u8  pages;        u16 linestep;        u16 datasize;	void* vram;} LED_SCREEN_PARA;static int scan_jiffies=0;struct timer_list scan_timer;static int disp_frame = 0;static devfs_handle_t devfs_handle;
static LED_SCREEN_PARA *ledscreens;static u32 RED_GPIO[2] = {GPIO_LED_R1, GPIO_LED_R2};static u32 GREEN_GPIO[2] = {GPIO_LED_G1, GPIO_LED_G2};static int LEDScreen_open(struct inode *minode, struct file *mfile);static int LEDScreen_release(struct inode *minode, struct file *mfile);static int LEDScreen_mmap(struct file *file, struct vm_area_struct *vma);static int LEDScreen_ioctl(struct inode *inode, struct file *file,
			   unsigned int cmd, unsigned long arg);
static int SetScreenMemory(LED_SCREEN_PARA *screen);static void LEDScreen_Enable(void);static void LED_Disable(LED_SCREEN_PARA *screen);static void write_pixel(LED_SCREEN_PARA *screen, int frame, int x, int y);static void write_frame(LED_SCREEN_PARA *screen, int frame);static int LEDScreen_starttimer(void);static struct file_operations device_fops = {	owner:		THIS_MODULE,	ioctl:		LEDScreen_ioctl,
	mmap:		LEDScreen_mmap,	open:		LEDScreen_open,	release:	        LEDScreen_release,};/*******************************//* Memory management functions *//*******************************/#define MDEBUG(x)	do { } while(0)		/* Debug memory management *//* [DaveM] I've recoded most of this so that: * 1) It's easier to tell what is happening * 2) It's more portable, especially for translating things *    out of vmalloc mapped areas in the kernel. * 3) Less unnecessary translations happen. * * The code used to assume that the kernel vmalloc mappings * existed in the page tables of every process, this is simply * not guaranteed.  We now use pgd_offset_k which is the * defined way to get at the kernel page tables. *//* Given PGD from the address space's page table, return the kernel * virtual mapping of the physical memory mapped at ADR. */static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr){        unsigned long ret = 0UL;	pmd_t *pmd;	pte_t *ptep, pte;  	if (!pgd_none(*pgd)) {                pmd = pmd_offset(pgd, adr);                if (!pmd_none(*pmd)) {                        ptep = pte_offset(pmd, adr);                        pte = *ptep;                        if(pte_present(pte)) {				ret = (unsigned long) 					page_address(pte_page(pte));                                ret |= (adr & (PAGE_SIZE - 1));			}                }        }        MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));	return ret;}static inline unsigned long uvirt_to_bus(unsigned long adr) {        unsigned long kva, ret;        kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);	ret = virt_to_bus((void *)kva);        MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));        return ret;}static inline unsigned long kvirt_to_bus(unsigned long adr) {        unsigned long va, kva, ret;        va = VMALLOC_VMADDR(adr);        kva = uvirt_to_kva(pgd_offset_k(va), va);	ret = virt_to_bus((void *)kva);        MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));        return ret;}/* Here we want the physical address of the memory. * This is used when initializing the contents of the * area and marking the pages as reserved. */static inline unsigned long kvirt_to_pa(unsigned long adr) {        unsigned long va, kva, ret;        va = VMALLOC_VMADDR(adr);        kva = uvirt_to_kva(pgd_offset_k(va), va);	ret = __pa(kva);        MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));        return ret;}static void * rvmalloc(unsigned long size){	void * mem;	unsigned long adr, page;        	mem=vmalloc_32(size);	if (mem) 	{		memset(mem, 0, size); /* Clear the ram out, 					 no junk to the user */	        adr=(unsigned long) mem;		while (size > 0)                 {	                page = kvirt_to_pa(adr);			mem_map_reserve(virt_to_page(__va(page)));			adr+=PAGE_SIZE;			size-=PAGE_SIZE;		}	}	return mem;}static void rvfree(void * mem, unsigned long size){        unsigned long adr, page;        	if (mem) 	{	        adr=(unsigned long) mem;		while (size > 0)                 {	                page = kvirt_to_pa(adr);			mem_map_unreserve(virt_to_page(__va(page)));			adr+=PAGE_SIZE;			size-=PAGE_SIZE;		}		vfree(mem);	}}/* End of code taken from bttv.c */static int SetScreenMemory(LED_SCREEN_PARA *screen){    int w, h, d;    int bpl, dataSize;    unsigned char *data;                        w = screen->screenwidth;    h = screen->screenheight;    d = screen->depth;         if ( d == 1 )	bpl = (w*d+7)/8;    else	bpl = ((w*d+31)/32)*4;    dataSize = bpl * h;    if (dataSize%PAGE_SIZE) 
       dataSize = dataSize + PAGE_SIZE - (dataSize%PAGE_SIZE);
        DPRINTK(KERN_INFO "LED driver:  width(%d),height(%d),depth(%d),datasize(%d)\n",w,h,d,dataSize);	    data = rvmalloc(dataSize);    if (data == NULL) {	DPRINTK(KERN_INFO "LED driver:  Failed to allocate dma buffer");        return 0;    }    memset(data, 0, dataSize);    screen->datasize = dataSize;    screen->vram = data;    screen->linestep = bpl;    DPRINTK(KERN_INFO "LED driver:  SetScreenMemory ok \n" );	    return 1;}static void LEDScreen_Enable(){   set_gpio_ctrl(GPIO_LED_EN);   set_gpio_ctrl(GPIO_LED_CK);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -