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

📄 ppcore.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
static unsigned intpp_poll(struct file *file, poll_table *table){	if (pp_suspended)		return -EPERM;        if (!frame_in_process)                return (POLLIN | POLLRDNORM);        	poll_wait (file, &frame_complete, table);	return 0;}static int	pp_open(struct inode *inode, struct file *file){	if (pp_suspended)		return -EPERM;	if (pp_busy)		return -EBUSY;	pp_busy = 1;        mx_module_clk_open(HCLK_MODULE_EMMA);        mx_module_clk_open(IPG_MODULE_EMMA);        EMMA_PP_CNTL |= PP_CNTL_SWRST;        mdelay(5);        if (EMMA_PP_CNTL & PP_CNTL_SWRST) {                err("PP Reset error\n");                return -EIO;        }        MOD_INC_USE_COUNT;	enable_irq(INT_EMMAPP);        return 0;}static intpp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,                 unsigned long arg){	if (pp_suspended)		return -EPERM;        if (frame_in_process)                return -EAGAIN;        switch (cmd) {                /* Set ouput format*/	        case VIDIOC_S_FMT:                 {                        struct v4l2_format *fmt = (void*)arg;                        struct v4l2_pix_format *pfmt = &(fmt->fmt.pix);                        if (!fmt) {                                return -EINVAL;                        }                        switch (pfmt->pixelformat) {                                case V4L2_PIX_FMT_YUYV:                                case V4L2_PIX_FMT_RGB565:                                        /*TODO additioanl format can be support                                         * (RGB555, RGB 888)*/                                        pfmt->depth = 16;                                        break;                                default:                        /*XXX Add adtitinal YUVdata types from book */                                        return -EINVAL;                        }                        this->out_format = *fmt;                        return set_frame_parameters(&(this->in_format.fmt.pix),                                         &(this->out_format.fmt.pix));                }                /* Get ouput format */	        case VIDIOC_G_FMT:                {                        struct v4l2_format *fmt = (void*)arg;                        if (!fmt) {                                return -EINVAL;                        }                        *fmt = this->out_format;                        return 0;                /* Set input format*/                }	        case VIDIOC_S_IN_FMT:                {                        struct v4l2_format *fmt = (void*)arg;                        struct v4l2_pix_format *pfmt = &(fmt->fmt.pix);                        int oldfrmsize, frmsize;                        if (!fmt) {                                return -EINVAL;                        }                        if (pfmt->pixelformat != V4L2_PIX_FMT_YUV420) {                                return -EINVAL;                        }                        frmsize = pfmt->width * pfmt->height * 2;                        oldfrmsize = this->in_format.fmt.pix.width *                                      this->in_format.fmt.pix.height * 2;                        if (frmsize > oldfrmsize) {                                if (frame_buf) {                                        consistent_free(frame_buf,                                                        oldfrmsize, frame_buf_phys);                                }                                frame_buf = consistent_alloc(GFP_KERNEL | GFP_DMA,                                                             frmsize, &frame_buf_phys);                                frame_size = frmsize;                                if (!frame_buf) {                                        return -ENOMEM;                                }                        }                        this->in_format = *fmt;                        return set_frame_parameters(&(this->in_format.fmt.pix),                                         &(this->out_format.fmt.pix));                }                /* Get input format */	        case VIDIOC_G_IN_FMT:                {                        struct v4l2_format *fmt = (void*)arg;                        if (!fmt) {                                return -EINVAL;                        }                        *fmt = this->in_format;                        if (this->Yptr) {                                set_in_pointers(this->Yptr);                        }                        return 0;                }                case VIDIOC_S_IN_PTR:                {                        if (!arg)                                return -EINVAL;                        this->Yptr = (unsigned int)arg;                        set_in_pointers(this->Yptr);                        return 0;                }                case VIDIOC_S_OUT_PTR:                {                        if (!arg)                                return -EINVAL;                        this->outptr = (void *)arg;                        return 0;                }                case VIDIOC_START:                {                        return pp_start();                }                case VIDIOC_POLL:                {                        return frame_in_process;                }                case VIDIOC_S_OUT_STRIDE:                {                        if (!((int)arg)) {                                return -EINVAL;                        }                        this->out_stride = (int)arg;                        return 0;                }                default:                {                        return -ENOIOCTLCMD;                }        }        return -ENOIOCTLCMD;}static ssize_tpp_write (struct file *file, const char *buf, size_t count, loff_t *ppos){        int ret;	if (pp_suspended)		return -EPERM;        if (frame_in_process)                return -EAGAIN;                        copy_from_user(frame_buf, buf, count);                set_in_pointers(frame_buf_phys);        	if ((ret = pp_start())) {                return ret;        }        return count;}static intpp_fasync(int fd, struct file *filp, int mode){        return 0;}static intpp_close(struct inode *inode, struct file *file){	disable_irq(INT_EMMAPP);        if (!check_mem_region(EMMA_PRP_BASE, EMMA_PRP_IO_SIZE)) {                /* If no PRP modules exists in same time stop clocks */                mx_module_clk_close(HCLK_MODULE_EMMA);                mx_module_clk_close(IPG_MODULE_EMMA);        }        MOD_DEC_USE_COUNT;	pp_busy = 0;        return 0;}static struct file_operations	pp_fops = {	open:		pp_open,        write:          pp_write,	ioctl:		pp_ioctl,	release: 	pp_close,	fasync:		pp_fasync,        poll:           pp_poll,};static void __initpp_exit(void){        if (irq_requested) {	        free_irq(INT_EMMAPP, NULL);                irq_requested = 0;#if 1   /* power management */		mx21_ldm_bus_unregister( &mx2ads_pp_device_ldm,        	        &mx2ads_pp_driver_ldm);#ifdef CONFIG_PM		if (mx2ads_pp_pmdev)			pm_unregister(mx2ads_pp_pmdev);#endif#endif /* power management */        }        if (frame_buf) {                consistent_free(frame_buf,                                frame_size, frame_buf_phys);        }   	if(major > 0) {		if(devfs_unregister_chrdev(major, "emma_pp") < 0) {			err("failed to unregister from devfs\n");			return;		}	}	if(devfs_handle != NULL) {		devfs_unregister(devfs_handle);	} else {                err("failed to unregister from devfs, devfs_handle = 0x%p\n",                                 devfs_handle);		return;	}        if (mem_region_reserved) {		release_mem_region(EMMA_PP_BASE, EMMA_PP_IO_SIZE);        }}#define PP_MIN_HCLK  33000int __initpp_init(void){#if 1 /*CEE LDM*/	if (PP_MIN_HCLK > mx_module_get_clk(HCLK) / 1000) {		err("cannot initialize - HCLK too slow\n");		return -EPERM;	}#endif        this = &pp_dev;         memset(&pp_dev, 0, sizeof(pp_dev));         	major = devfs_register_chrdev(0, "emma_pp", &pp_fops); 	if ( major < 0 ) {		err("unable to register character device\n");                pp_exit();		return -ENODEV;	}	devfs_handle = devfs_register(NULL, "emma_pp", DEVFS_FL_DEFAULT,				      major, 0,				      S_IFCHR | S_IRUSR | S_IWUSR,				      &pp_fops, NULL);	if(devfs_handle == NULL) {		err("unable to register devfs driver\n");                pp_exit();		return -ENODEV;	}        if (!request_mem_region(EMMA_PP_BASE, EMMA_PP_IO_SIZE,                                 "MX21.EMMA PP registers")) {                err("EMMA PP memory region is already in use\n");                dbg("Address=0x%08x, size=0x%x\n", EMMA_PP_BASE,                                EMMA_PP_IO_SIZE);                pp_exit();		return -1;	}        mem_region_reserved = 1;	if (request_irq(INT_EMMAPP, pp_isr, SA_INTERRUPT, "eMMa PP", NULL)) {                err("Error requesting IRQ\n");                pp_exit();		return -ENODEV;        }        irq_requested = 1;	disable_irq(INT_EMMAPP);	init_waitqueue_head (&frame_complete);#if 1   /* power management */#ifdef CONFIG_DPM	mx2ads_pp_constraints.param[0].min = PP_MIN_HCLK;	/*in KHz */	mx2ads_pp_constraints.param[0].max = mx_module_get_clk(MPLL) / 1000;	/* unlimited */#endif        mx21_ldm_bus_register(&mx2ads_pp_device_ldm,                &mx2ads_pp_driver_ldm);#ifdef CONFIG_PM	mx2ads_pp_pmdev = pm_register(PM_UNKNOWN_DEV, PM_SYS_UNKNOWN,					 mx2ads_pp_pm_callback);	if (!mx2ads_pp_pmdev)		warn("failed to initialize static power management\n");#endif /* CONFIG_PM */#endif /* power management */        return 0;}#ifdef MODULEmodule_init(pp_init);module_exit(pp_exit);#endif        MODULE_LICENSE ("GPL");

⌨️ 快捷键说明

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