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

📄 hmp4d.c.svn-base

📁 linux2.6.18下支持sd2.0的驱动程序源码,支持最大32G的SD卡
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************                                                                              **        This software is confidential and proprietary and may be used         **          only as expressly authorized by a licensing agreement from          **                                                                              **                             Hantro Products Oy.                              **                                                                              **       In the event of publication, the following notice is applicable:       **                                                                              **                    (C) COPYRIGHT 2002 HANTRO PRODUCTS OY                     **                             ALL RIGHTS RESERVED                              **                                                                              **           The entire notice above must be reproduced on all copies.          **                                                                              ***********************************************************************************   Project  : 1200s**   Abstract : Decoder Driver Module***********************************************************************************   Version control information, please leave untouched.**   $RCSfile$*   $Author$*   $Date$*   $Revision$********************************************************************************/#include <linux/kernel.h>#include <linux/module.h>/* needed for __init,__exit directives */#include <linux/init.h>/* needed for remap_page_range */#include <linux/mm.h>/* obviously, for kmalloc */#include <linux/slab.h>/* for struct file_operations, register_chrdev() */#include <linux/fs.h>#include <linux/interrupt.h>/* standard error codes */#include <linux/errno.h>/* this header files wraps some common module-space operations ...    here we use mem_map_reserve() macro *///#include <linux/wrapper.h>#define mem_map_reserve(p)	set_bit(PG_reserved, &((p)->flags))#define mem_map_unreserve(p)	clear_bit(PG_reserved, &((p)->flags))/* needed for virt_to_phys() */#include <asm/io.h>#include <asm/uaccess.h>#include <linux/ioport.h>#define NON_PAGE_ALIGNED	1 /* non page aligned     */#define CONS_ALLOC		0	  /* use consistent alloc */#if CONS_ALLOCu32	hmp4d_phys;#endif/* our own includes */#include "hmp4d.h"/* module description */MODULE_AUTHOR("Hantro Products Oy");MODULE_LICENSE("GPL");MODULE_DESCRIPTION("Device driver for Hantro's MPEG4 decoder HW");MODULE_SUPPORTED_DEVICE("1200s MPEG4 Decoder");/* this is ARM Integrator specific */#define INTEGRATOR_LOGIC_MODULE0_BASE   0x20000000#define INT_EXPINT1                    28 /* these could be module params in the future */#define DEC_IO_BASE                 INTEGRATOR_LOGIC_MODULE0_BASE#define DEC_IO_SIZE                 (22*4)  /*(35*4)*/   #define DEC_IRQ                     INT_EXPINT1#define HMP4D_BUF_SIZE              (1048576)/* bytes */#define DEC_HW_ID                   0x5150unsigned long base_port = DEC_IO_BASE;unsigned int irq = DEC_IRQ;MODULE_PARM(base_port, "l");MODULE_PARM(irq, "i");/* and this is our MAJOR; use 0 for dynamic allocation (recommended)*/static int hmp4d_major = 0;/* here's all the must remember stuff */typedef struct{    char *buffer;    unsigned int buffsize;    unsigned long iobaseaddr;    unsigned int iosize;    volatile u8 *hwregs;    unsigned int irq;    struct fasync_struct *async_queue;}hmp4d_t;void dump_regs(unsigned long data);static hmp4d_t hmp4d_data;  /* dynamic allocation? */static int AllocMemory(void);static void FreeMemory(void);static int ReserveIO(void);static void ReleaseIO(void);static int MapBuffers(struct file *filp, struct vm_area_struct *vma);static int MapHwRegs(struct file *filp, struct vm_area_struct *vma);static void ResetAsic(hmp4d_t * dev);int hmp4d_isr(int irq, void *dev_id, struct pt_regs *regs);/* VM operations */static struct page *hmp4d_vm_nopage(struct vm_area_struct *vma,                                    unsigned long address, int *type){    PDEBUG("hmp4d_vm_nopage: problem with mem access\n");    return NOPAGE_SIGBUS;   /* send a SIGBUS */}static void hmp4d_vm_open(struct vm_area_struct *vma){    //MOD_INC_USE_COUNT;    PDEBUG("hmp4d_vm_open:\n");}static void hmp4d_vm_close(struct vm_area_struct *vma){    //MOD_DEC_USE_COUNT;    PDEBUG("hmp4d_vm_close:\n");}static struct vm_operations_struct hmp4d_vm_ops = {    open:hmp4d_vm_open,    close:hmp4d_vm_close,    nopage:hmp4d_vm_nopage,};/* the device's mmap method. The VFS has kindly prepared the process's * vm_area_struct for us, so we examine this to see what was requested. */static int hmp4d_mmap(struct file *filp, struct vm_area_struct *vma){    int result;    unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;#if NON_PAGE_ALIGNED	int	ofs;	ofs  = hmp4d_data.iobaseaddr & (PAGE_SIZE - 1);#endif    PDEBUG("hmp4d_mmap: size = %lu off = 0x%08lx\n",           vma->vm_end - vma->vm_start, offset);    if(offset == 0)        result = MapBuffers(filp, vma);#if NON_PAGE_ALIGNED    else if(offset == hmp4d_data.iobaseaddr - ofs)#else    else if(offset == hmp4d_data.iobaseaddr)#endif        result = MapHwRegs(filp, vma);    else        result = -EINVAL;    if(result == 0)    {        vma->vm_ops = &hmp4d_vm_ops;        /* open is not implicitly called when mmap is called */        hmp4d_vm_open(vma);    }    return result;}static int hmp4d_ioctl(struct inode *inode, struct file *filp,                       unsigned int cmd, unsigned long arg){    int err = 0;    PDEBUG("ioctl cmd 0x%08ux\n", cmd);    /*     * extract the type and number bitfields, and don't decode     * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()     */    if(_IOC_TYPE(cmd) != HMP4D_IOC_MAGIC)        return -ENOTTY;    if(_IOC_NR(cmd) > HMP4D_IOC_MAXNR)        return -ENOTTY;    /*     * the direction is a bitmask, and VERIFY_WRITE catches R/W     * transfers. `Type' is user-oriented, while     * access_ok is kernel-oriented, so the concept of "read" and     * "write" is reversed     */    if(_IOC_DIR(cmd) & _IOC_READ)        err = !access_ok(VERIFY_WRITE, (void *) arg, _IOC_SIZE(cmd));    else if(_IOC_DIR(cmd) & _IOC_WRITE)        err = !access_ok(VERIFY_READ, (void *) arg, _IOC_SIZE(cmd));    if(err)        return -EFAULT;    switch (cmd)    {    case HMP4D_IOCHARDRESET:        /*         * reset the counter to 1, to allow unloading in case         * of problems. Use 1, not 0, because the invoking         * process has the device open.         */			/*        while(MOD_IN_USE)            MOD_DEC_USE_COUNT;        MOD_INC_USE_COUNT;		*/        break;    case HMP4D_IOCGBUFBUSADDR:#if !CONS_ALLOC        __put_user(virt_to_phys(hmp4d_data.buffer), (unsigned long *) arg);#else        __put_user(hmp4d_phys, (unsigned long *) arg);#endif        break;     case HMP4D_IOCXVIRT2BUS:        {            unsigned long base;            __get_user(base, (unsigned int *) arg);            base = virt_to_phys((void *)base);            __put_user(base, (unsigned int *) arg);        }    	break;            case HMP4D_IOCGBUFSIZE:        __put_user(hmp4d_data.buffsize, (unsigned int *) arg);        break;    case HMP4D_IOCGHWOFFSET:        __put_user(hmp4d_data.iobaseaddr, (unsigned long *) arg);        break;    case HMP4D_IOCGHWIOSIZE:        __put_user(hmp4d_data.iosize, (unsigned int *) arg);        break;    }    return 0;}#define IRQTEST1static int hmp4d_open(struct inode *inode, struct file *filp){    int result;    hmp4d_t *dev = &hmp4d_data;	    printk("trying to open dev\n");        filp->private_data = (void *) dev;#if 0    if(MOD_IN_USE)  /* just single access */        return -EBUSY;#endif#if 0    writel(0, dev->hwregs); /* disable first */#if 0	/*no-word write to any reg & write to reg7 causes AHB error*/    memset_io(dev->hwregs, 0, hmp4d_data.iosize);   /* reset the HW interface */#else{	int	i;	for (i = 0; i < hmp4d_data.iosize / 4 - 1; i++)	{		writel(0, dev->hwregs + i);	}}#endif#endif#ifndef IRQTEST1    result = request_irq(dev->irq, hmp4d_isr,                         SA_SHIRQ, "hmp4d", (void *) dev);    if(result == -EINVAL)    {        printk(KERN_ERR "hmp4d: Bad irq number or handler\n");        return result;    }    else if(result == -EBUSY)    {        printk(KERN_ERR "hmp4d: IRQ %d busy, change your config\n", dev->irq);        return result;    }#endif//	hantro_request_fb();    //MOD_INC_USE_COUNT;    PDEBUG("dev opened\n");    return 0;}static int hmp4d_fasync(int fd, struct file *filp, int mode){    hmp4d_t *dev = (hmp4d_t *) filp->private_data;    PDEBUG("fasync called\n");    return fasync_helper(fd, filp, mode, &dev->async_queue);}static int hmp4d_release(struct inode *inode, struct file *filp){    hmp4d_t *dev = (hmp4d_t *) filp->private_data;    printk("trying to release dev\n");//	hantro_free_fb();    /* free the encoder IRQ */// sasi{#include <asm/irq.h>//	disable_irq(dev->irq);}#ifndef IRQTEST1    free_irq(dev->irq, (void *) dev);#endif    ResetAsic(dev);    /* remove this filp from the asynchronusly notified filp's */    hmp4d_fasync(-1, filp, 0);    //MOD_DEC_USE_COUNT;    PDEBUG("dev closed\n");    return 0;}/* VFS methods */static struct file_operations hmp4d_fops = {    mmap:hmp4d_mmap,    open:hmp4d_open,    release:hmp4d_release,    ioctl:hmp4d_ioctl,    fasync:hmp4d_fasync,};static int use_hmp4d=1;static int __init setup_hmp4d(char *str){	if(str[0] == '0') use_hmp4d=0;	return 1;}__setup("hmp4d=", setup_hmp4d);int __init hmp4d_init(void){    int result;

⌨️ 快捷键说明

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