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

📄 ncplus_mjpeg.c

📁 MJPEG Driver 3.0.1
💻 C
📖 第 1 页 / 共 2 页
字号:
	int ret = 0;	int arg_temp;	strt_mjpeg_copy *arg_temp_strt;	int thread_num;	/*	* extract the type and number bitfields, and don't decode	* wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()	*/	if (_IOC_TYPE(cmd) != MJPEG_IOC_MAGIC) return -ENOTTY;	if (_IOC_NR(cmd) > MJPEG_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) {#ifdef MJPEG_DEBUG	case MJPEG_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;	/* don't break: fall through and reset things */#endif /* MJPEG_DEBUG */	case MJPEG_IOCRESET:		if (mjpeg_reset(dev) < 0)			printk("mjpeg: reset failed\n");	break;        	case MJPEG_IOCQFRAMEAVAIL: /* Query: frame available? */		return (dev->rbuf->valid);	case MJPEG_IOCQFRAMESIZE: /* Query: return the size of frame available */		return (dev->rbuf->count);	case MJPEG_IOCTALPHA: /* Tell: set the alpha coefficient value */		arg_temp = (int)arg;			// Dojip		if (arg_temp < 0 || arg_temp > 2048) {			printk("invalid alpha_coeff value : %d\n", arg_temp);			return -ENOTTY;		}		mjpeg_alphacoeff = arg_temp;			mjpeg_reset(dev);		break;	case MJPEG_IOCQALPHA: // Query: return it 		return mjpeg_alphacoeff;	case MJPEG_IOCTRESOL: /* Tell: set the resolution mode */		arg_temp = (int)arg;		if(arg_temp<0 || arg_temp>5) {			printk("invalid resol value : %d\n", arg_temp);			return -ENOTTY;		}		mjpeg_default = arg_temp;		mjpeg_reset(dev);		break;	case MJPEG_IOCQRESOL: // Query: return it		return mjpeg_default;	case MJPEG_IOCGREAD:		arg_temp_strt = (strt_mjpeg_copy *)arg;		thread_num = arg_temp_strt->thread_no;		if (mjpeg_debug_ioctl)			printk("ioc_get_read\n");		if(gs_thread_no & (1<<thread_num))			return 0;		ret = mjpeg_read(filp, arg_temp_strt->copy2user, 0, NULL);		if(ret)			gs_thread_no |= (1<<thread_num);		return ret;			case MJPEG_IOCTROTATE:		if (arg >= 4) {			printk("mjpeg: invalid rotate value %d\n", (int)arg);			return -ENOTTY;		}		dev->jpg_rotate = (int)arg;		break;	case MJPEG_IOCQROTATE:		return (dev->jpg_rotate);	default:  /* redundant, as cmd was checked against MAXNR */		if (mjpeg_debug_ioctl)			printk("-enotty\n");		return -ENOTTY;	}	return ret;}// Default Setting!!!/* * setup_mjpeg_default * 160x120, 422, alpha 50%, 10x15 (mcu) */static void setup_mjpeg(struct mjpeg_device *dev){	int i;	//mjpeg_buff_init(dev);	gs_new_frame = 0;	for(i=0; i<QUANTS_COUNT; i++)		mjpeg_writel((unsigned long)yquant[i], Y_QUANT_COEFF+(i*4));	for(i=0; i<QUANTS_COUNT; i++)		mjpeg_writel((unsigned long)uvquant[i], UV_QUANT_COEFF+(i*4));	setting_by_ioctl(dev);	/* common setting */	mjpeg_writel(YSTART_ADD_VAL_140, YSTART_ADD); // always 0x0 at the YSTART_ADD	mjpeg_writel(mjpeg_alphacoeff, ALPHA_COEFF);	/*	 * JPEG headeer setting 	 */	mjpeg_hdr_qt(dev);	mjpeg_writel(SDRAM_MODE_COM_VAL, SDRAM_MODE_COM);	// interrupt mode	mjpeg_writel(FIFO_ENABLE|FIFO_SET_HALF, DMA_MODE_COMMAND); // interrupt mode	mjpeg_writel(DMA_START_ADD_VAL, DMA_START_ADD);	mjpeg_writel(DMA_COUNT_NUM_VAL, DMA_COUNT_NUM); // questionable	mjpeg_writel(DMA_DESTINATION_VAL, DMA_DESTINATION);	mjpeg_writel(0x2, 0x22c);	mjpeg_buff_init(dev);} /* setup_mjpeg() */static void setting_by_ioctl(struct mjpeg_device *dev) {	int resolution = mjpeg_default;	/*	 * mjpg header setting	 */	mjpeg_hdr_res(dev);	if(resolution == 0) {	/* mjpeg core register setting */		mjpeg_writel(USTART_ADD_VAL_140, USTART_ADD);		mjpeg_writel(VSTART_ADD_VAL_140, VSTART_ADD);		mjpeg_writel(IMAGE_MCUWIDE_VAL_140, IMAGE_MCUWIDE);		mjpeg_writel(IMAGE_MCUHIGH_VAL_140, IMAGE_MCUHIGH);		mjpeg_writel(RSTINTERVAL_VAL_140, RSTINTERVAL);	/* mjpeg interface register setting */		mjpeg_writel(PREPRO_HLENGTH_VAL_140, PREPRO_HLENGTH);		mjpeg_writel(PREPRO_VLENGTH_VAL_140, PREPRO_VLENGTH);		mjpeg_writel(PREPRO_FORMAT_VAL_140, PREPRO_FORMAT);		mjpeg_writel(mjpeg_perform, 0x23c);	}	else if(resolution == 1) {	/* mjpeg core register setting */		mjpeg_writel(USTART_ADD_VAL_142, USTART_ADD);		mjpeg_writel(VSTART_ADD_VAL_142, VSTART_ADD);		mjpeg_writel(IMAGE_MCUWIDE_VAL_142, IMAGE_MCUWIDE);		mjpeg_writel(IMAGE_MCUHIGH_VAL_142, IMAGE_MCUHIGH);		mjpeg_writel(RSTINTERVAL_VAL_142, RSTINTERVAL);	/* mjpeg interface register setting */		mjpeg_writel(PREPRO_HLENGTH_VAL_142, PREPRO_HLENGTH);		mjpeg_writel(PREPRO_VLENGTH_VAL_142, PREPRO_VLENGTH);		mjpeg_writel(PREPRO_FORMAT_VAL_142, PREPRO_FORMAT);		mjpeg_writel(mjpeg_perform, 0x23c);	}	else if(resolution == 2) {	/* mjpeg core register setting */		mjpeg_writel(USTART_ADD_VAL_340, USTART_ADD);		mjpeg_writel(VSTART_ADD_VAL_340, VSTART_ADD);		mjpeg_writel(IMAGE_MCUWIDE_VAL_340, IMAGE_MCUWIDE);		mjpeg_writel(IMAGE_MCUHIGH_VAL_340, IMAGE_MCUHIGH);		mjpeg_writel(RSTINTERVAL_VAL_340, RSTINTERVAL);	/* mjpeg interface register setting */		mjpeg_writel(PREPRO_HLENGTH_VAL_340, PREPRO_HLENGTH);		mjpeg_writel(PREPRO_VLENGTH_VAL_340, PREPRO_VLENGTH);		mjpeg_writel(PREPRO_FORMAT_VAL_340, PREPRO_FORMAT);		mjpeg_writel(mjpeg_perform, 0x23c);	}	else if(resolution == 3) {	/* mjpeg core register setting */		mjpeg_writel(USTART_ADD_VAL_342, USTART_ADD);		mjpeg_writel(VSTART_ADD_VAL_342, VSTART_ADD);		mjpeg_writel(IMAGE_MCUWIDE_VAL_342, IMAGE_MCUWIDE);		mjpeg_writel(IMAGE_MCUHIGH_VAL_342, IMAGE_MCUHIGH);		mjpeg_writel(RSTINTERVAL_VAL_342, RSTINTERVAL);	/* mjpeg interface register setting */		mjpeg_writel(PREPRO_HLENGTH_VAL_342, PREPRO_HLENGTH);		mjpeg_writel(PREPRO_VLENGTH_VAL_342, PREPRO_VLENGTH);		mjpeg_writel(PREPRO_FORMAT_VAL_342, PREPRO_FORMAT);		mjpeg_writel(mjpeg_perform, 0x23c);		//mjpeg_writel(0x2301, 0x23c); // CIF 15 frames/sec	}	else if(resolution == 4) {	/* mjpeg core register setting */		mjpeg_writel(USTART_ADD_VAL_640, USTART_ADD);		mjpeg_writel(VSTART_ADD_VAL_640, VSTART_ADD);		mjpeg_writel(IMAGE_MCUWIDE_VAL_640, IMAGE_MCUWIDE);		mjpeg_writel(IMAGE_MCUHIGH_VAL_640, IMAGE_MCUHIGH);		mjpeg_writel(RSTINTERVAL_VAL_640, RSTINTERVAL);	/* mjpeg interface register setting */		mjpeg_writel(PREPRO_HLENGTH_VAL_640, PREPRO_HLENGTH);		mjpeg_writel(PREPRO_VLENGTH_VAL_640, PREPRO_VLENGTH);		mjpeg_writel(PREPRO_FORMAT_VAL_640, PREPRO_FORMAT);		mjpeg_writel(mjpeg_perform, 0x23c);	}	else if(resolution == 5) {	/* mjpeg core register setting */		mjpeg_writel(USTART_ADD_VAL_642, USTART_ADD);		mjpeg_writel(VSTART_ADD_VAL_642, VSTART_ADD);		mjpeg_writel(IMAGE_MCUWIDE_VAL_642, IMAGE_MCUWIDE);		mjpeg_writel(IMAGE_MCUHIGH_VAL_642, IMAGE_MCUHIGH);		mjpeg_writel(RSTINTERVAL_VAL_642, RSTINTERVAL);	/* mjpeg interface register setting */		mjpeg_writel(PREPRO_HLENGTH_VAL_642, PREPRO_HLENGTH);		mjpeg_writel(PREPRO_VLENGTH_VAL_642, PREPRO_VLENGTH);		mjpeg_writel(PREPRO_FORMAT_VAL_642, PREPRO_FORMAT);		mjpeg_writel(mjpeg_perform, 0x23c);	}}/* * success: return 0 * fail   : return -1 */static int mjpeg_raw_reset(void){	//unsigned long status;	unsigned long timeout;	mjpeg_writel(MODULE_FUNC_SET_STOP, MODULE_FUNC_SET); // stop operation	mjpeg_writel(MODULE_FUNC_SET_STOP|MODULE_FUNC_SET_RESET, MODULE_FUNC_SET);  // module reset		//status = mjpeg_readl(MODULE_FUNC_SET) & 0x0000000f;	timeout = jiffies + (1 * HZ); // 1secs	while (mjpeg_readl(MODULE_FUNC_SET) & MODULE_FUNC_SET_RESET) {		if (jiffies > timeout)			return -1;	}	return 0;}static int mjpeg_reset(struct mjpeg_device *dev){	disable_irq(IRQ_MJPEG); // disable interrupt	if (mjpeg_raw_reset() < 0) { 		enable_irq(IRQ_MJPEG);		return -1;	}	enable_irq(IRQ_MJPEG); // enable interrupt	setup_mjpeg(dev); // set the registers for mjpeg 	mjpeg_writel(MODULE_FUNC_SET_NORMAL, MODULE_FUNC_SET); // start mjpeg	return 0;}/* * mjpeg watchdog timer init */static void mjpeg_watchdog_init(void) {	mjpeg_watchdog_timeout = jiffies + (HZ * 2 * MJPEG_WATCHDOG_TIMEOUT);	init_timer(&mjpeg_watchdog_timer);	mjpeg_watchdog_timer.function = mjpeg_watchdog;	mjpeg_watchdog_timer.data = 0;	mjpeg_watchdog_timer.expires = mjpeg_watchdog_timeout;	add_timer(&mjpeg_watchdog_timer);}static void mjpeg_watchdog(unsigned long data){	mjpeg_reset(mjpeg_dev);	mjpeg_watchdog_timeout = jiffies + (HZ * MJPEG_WATCHDOG_TIMEOUT);	mod_timer(&mjpeg_watchdog_timer, mjpeg_watchdog_timeout);	//printk("mjpeg: watchdog timeout\n");}/* * mjpeg data buffer allocation  */static int mjpeg_buff_alloc(struct mjpeg_device *dev){	int i;	for (i = 0; i < 2; i++) {		dev->buf[i].valid = 0;		dev->buf[i].count = 0;		dev->buf[i].data = vmalloc(COMPRESSED_SIZE);		if (!dev->buf[i].data) {			printk("buffer allocation failed (%d)\n", i);			mjpeg_buff_free(dev);			return -1;		}		memset(dev->buf[i].data, 0, COMPRESSED_SIZE);	}	return 0;}/* * mjpeg data buffer free */static void mjpeg_buff_free(struct mjpeg_device *dev){	int i;	for (i = 0; i < 2; i++) {		if (dev->buf[i].data != NULL) {			vfree(dev->buf[i].data);			dev->buf[i].data = NULL;		}	}}/* * mjpeg init_module */int mjpeg_init_module(void){	int result = 0;	struct mjpeg_device *dev = NULL;	int i;	SET_MODULE_OWNER(&mjpeg_fops);    	printk("%s", version);	mjpeg_dev = kmalloc(sizeof(struct mjpeg_device), GFP_KERNEL);	if (!mjpeg_dev) {		return -ENOMEM;	}	dev = mjpeg_dev;	memset(dev, 0, sizeof(struct mjpeg_device));	// mjpeg data buffer initialization	if (mjpeg_buff_alloc(dev) < 0) {		kfree(dev);		return -ENOMEM;	}		// mjpeg watchdog init	mjpeg_watchdog_init();	dev->wbuf = &(dev->buf[0]);	dev->rbuf = &(dev->buf[1]);	dev->max_size = -1;	dev->jpg_rotate = 0;	// Normal	// jpeg header copy	for (i = 0; i < JPEG_HDR_SIZE; i++) {		dev->jpg_hdr[i] = _jpg_hdr[i];	}    	gs_new_frame = 0;    	/* spin_lock initailizing */	dev->lock = SPIN_LOCK_UNLOCKED;#ifdef MJPEG_PROC	proc_mjpeg = create_proc_entry("mjpeg",			S_IFREG | S_IWUSR,			&proc_root);	proc_mjpeg->read_proc = mjpeg_read_proc;#endif    	// Installing an interrupt handler	result = request_irq(IRQ_MJPEG, ncplus_mjpeg_interrupt, 0, DEVICE_NAME, dev);	if (result < 0) {		printk("mjpeg: can't install an interrupt handler\n");		result = -EBUSY;		goto irq_fail;	}    /*     * Register your major, and accept a dynamic number.      * This is the first thing to do,     * in order to avoid releasing other module's fops in mjpeg_cleanup_module()     */    if ((result = register_chrdev(mjpeg_major, DEVICE_NAME, &mjpeg_fops)) < 0) {        printk(KERN_WARNING "mjpeg: can't get major (%d)\n", mjpeg_major);	goto dev_fail;        //return result;    }    if (mjpeg_major == 0) mjpeg_major = result; /* dynamic */    printk(DEVICE_NAME " : device registered with major number = %d\n", mjpeg_major);#ifndef MJPEG_DEBUG    EXPORT_NO_SYMBOLS; /* otherwise, leave global symbols visible */#endif    mjpeg_reset(dev); // start mjpeg     return 0;dev_fail:#ifdef MJPEG_PROC    remove_proc_entry("mjpeg", &proc_root);#endif    free_irq(IRQ_MJPEG, dev);irq_fail:    /*     * mjpeg buffer free     */    mjpeg_buff_free(dev);    /*     * watchdog timer deletion     */    del_timer_sync(&mjpeg_watchdog_timer);    /*     * mjpeg device structure free     */    if (dev != NULL) {    	kfree(dev);	dev = NULL;    }    return result;}void mjpeg_cleanup_module(void){    int nRetCode;    // del watchdog timer    del_timer_sync(&mjpeg_watchdog_timer);    //if(mjpeg_debug_stop)    mjpeg_writel(MODULE_FUNC_SET_RESET, MODULE_FUNC_SET); // stop operation    free_irq(IRQ_MJPEG, mjpeg_dev);    mjpeg_buff_free(mjpeg_dev);    printk("Unloading MJPEG Module\n");    /* cleanup_module is never called if registering failed */    if ((nRetCode = unregister_chrdev(mjpeg_major, DEVICE_NAME)) < 0)        printk(DEVICE_NAME " : Device unregistration failed (%d)\n", nRetCode);    if (mjpeg_dev != NULL)	    kfree(mjpeg_dev);    mjpeg_dev = NULL; /* pedantic -.-; */#ifdef MJPEG_PROC    remove_proc_entry("mjpeg", &proc_root);#endif    return;}module_init(mjpeg_init_module);module_exit(mjpeg_cleanup_module);

⌨️ 快捷键说明

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