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

📄 ncplus_mjpeg.c

📁 MJPEG Driver 3.0.1
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ncplus_mjpeg.c * * Copyright(C) 2005 Chipsbrain Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; with out even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * modified by Chipsbrain Engineer <support@chipsbrain.com> */static const char version[] = "ncplus_mjpeg.c:v3.0.1 (C) 2005 Chipsbrain Co., Ltd.\n";#ifndef __KERNEL__#  define __KERNEL__#endif#ifndef MODULE#  define MODULE#endif#define MJPEG_PROC#define __NO_VERSION__#include <linux/module.h>#include <linux/version.h>#include <linux/config.h>#include <linux/init.h>#include <linux/kernel.h>	/* printk() */#include <linux/slab.h>		/* kmalloc() */#include <linux/vmalloc.h>	/* vmalloc() */#include <linux/fs.h>		/* everything... */#include <linux/errno.h>	/* error codes */#include <linux/types.h>	/* size_t */#include <linux/fcntl.h>	/* O_ACCMODE */#include <linux/kdev_t.h>#include <linux/timer.h>	#include <asm/system.h>		/* cli(), *_flags */#include <linux/interrupt.h>#include <linux/sched.h>#include <asm/uaccess.h>#include <asm/irq.h>#include <asm/io.h>//#include <asm-arm/spinlock.h>	#ifdef MJPEG_PROC#include <linux/proc_fs.h>#endif#include "ncplus_mjpeg.h"		/* local definitions and sysdep.h */#include "ncplus_jpghdr.h"		/* jpeg header *//*#define MJPEG_RESOL_160		0x00#define MJPEG_RESOL_320		0x01#define MJPEG_RESOL_640		0x02#define MJPEG_YUV_420		0x03#define MJPEG_YUV_422		0x04*/struct mjpeg_buffer {	char	valid;			/* is valid */	int	count;			/* buffer count */	char	*data;			/* buffer data */};#if 0struct mjpeg_info {	char	res;			/* resolution */	char	yuv;			/* YUV format */	int	alpha;			/* alpha coefficient */};#endifstruct mjpeg_device {	spinlock_t	lock;		/* buffer lock */	struct mjpeg_buffer buf[2];	/* buffer */	struct mjpeg_buffer *wbuf;	/* write buffer pointer */	struct mjpeg_buffer *rbuf;	/* read buffer pointer */	int max_size;			/* status: mjpeg data max size */	unsigned char jpg_hdr[JPEG_HDR_SIZE];//	struct mjpeg_info *info;	/* mjpeg infomation */	int jpg_rotate;};static struct mjpeg_device *mjpeg_dev = NULL;// mjpeg watchdog #define MJPEG_WATCHDOG_TIMEOUT		1 // 1 secstatic unsigned long mjpeg_watchdog_timeout;struct timer_list mjpeg_watchdog_timer;#define DEVICE_NAME	"mjpeg"#define BUF1	0#define BUF2	1/* * I don't use static symbols here, because we export no symbols */static int mjpeg_major = MJPEG_MAJOR;static int gs_new_frame = 0;static int mjpeg_default = 2; // 0(q0), 1(q2), 2(c0), 3(c2), 4(v0), 5(v2)static int mjpeg_debug_ioctl = 0;static int mjpeg_perform = 9256; // 9256(c0, c2), 9216(q0, q2)static int mjpeg_alphacoeff = 64;	/* 50%(64), 32(best), 128(worst) */static int mjpeg_bDeviceReadOpen = 0;static int mjpeg_bDeviceWriteOpen = 0;static int gs_thread_no=0;MODULE_PARM(mjpeg_default,"i");MODULE_PARM(mjpeg_alphacoeff,"i");MODULE_PARM(mjpeg_debug,"i");MODULE_PARM(mjpeg_debug_owner,"i");MODULE_PARM(mjpeg_debug_interrupt,"i");MODULE_PARM(mjpeg_debug_ioctl,"i");MODULE_PARM(mjpeg_debug_stop,"i");MODULE_PARM(mjpeg_perform,"i");MODULE_PARM(mjpeg_frmeasure,"i");//MODULE_AUTHOR("donald kim");//MODULE_LICENSE("GPL");/* * Functions Prototypes */int mjpeg_init_module(void);void mjpeg_cleanup_module(void);int mjpeg_open(struct inode *inode, struct file *filp);ssize_t mjpeg_read(struct file *filp, char *buffer, size_t length, loff_t *offset);int mjpeg_release(struct inode *inode, struct file *filp);int mjpeg_ioctl(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg);static int mjpeg_raw_reset(void);static int mjpeg_reset(struct mjpeg_device *dev);static void setup_mjpeg(struct mjpeg_device *dev);void ncplus_mjpeg_interrupt(int, void *, struct pt_regs *);static void setting_by_ioctl(struct mjpeg_device *dev);static void mjpeg_watchdog_init(void);static void mjpeg_watchdog(unsigned long data);static int mjpeg_buff_alloc(struct mjpeg_device *dev);static void mjpeg_buff_free(struct mjpeg_device *dev);static inline void mjpeg_buff_change(struct mjpeg_device *dev);static inline void mjpeg_buff_init(struct mjpeg_device *dev);static int mjpeg_hdr_res(struct mjpeg_device *dev);static int mjpeg_hdr_qt(struct mjpeg_device *dev);#ifdef MJPEG_PROCstruct proc_dir_entry *proc_mjpeg;#endif/* * Device Operations */struct file_operations mjpeg_fops = {    read : mjpeg_read,    ioctl : mjpeg_ioctl,            open : mjpeg_open,    release : mjpeg_release,};/* * JPEG Header *      Resolution *      YUV */static int mjpeg_hdr_res(struct mjpeg_device *dev){	switch (mjpeg_default) {		case 0: /* 160x120 YUV 420 */			dev->jpg_hdr[0x245] = 0x00; /* width */			dev->jpg_hdr[0x246] = 0xA0; 			dev->jpg_hdr[0x243] = 0x00; /* height */			dev->jpg_hdr[0x244] = 0x78;			dev->jpg_hdr[0x249] = 0x22; /* YUV 420 */			dev->jpg_hdr[0x23C] = 0x07; /* q0 */			dev->jpg_hdr[0x23D] = 0xD0; 			break;		case 1: /* 160x120 YUV 422 */			dev->jpg_hdr[0x245] = 0x00; /* width */			dev->jpg_hdr[0x246] = 0xA0; 			dev->jpg_hdr[0x243] = 0x00; /* height */			dev->jpg_hdr[0x244] = 0x78;			dev->jpg_hdr[0x249] = 0x21; /* YUV 422 */			dev->jpg_hdr[0x23C] = 0x03; /* q2 */			dev->jpg_hdr[0x23D] = 0xE8;			break;		case 2: /* 320x240 YUV 420 */			dev->jpg_hdr[0x245] = 0x01; /* width */			dev->jpg_hdr[0x246] = 0x40; 			dev->jpg_hdr[0x243] = 0x00; /* height */			dev->jpg_hdr[0x244] = 0xF0;			dev->jpg_hdr[0x249] = 0x22; /* YUV 420 */			dev->jpg_hdr[0x23C] = 0x03; /* c0 */			dev->jpg_hdr[0x23D] = 0xE8;			break;		case 3: /* 320x240 YUV 422 */			dev->jpg_hdr[0x245] = 0x01; /* width */			dev->jpg_hdr[0x246] = 0x40; 			dev->jpg_hdr[0x243] = 0x00; /* height */			dev->jpg_hdr[0x244] = 0xF0;			dev->jpg_hdr[0x249] = 0x21; /* YUV 422 */			dev->jpg_hdr[0x23C] = 0x07; /* c2 */			dev->jpg_hdr[0x23D] = 0xD0;			break;		case 4: /* 640x480 YUV 420 */			dev->jpg_hdr[0x245] = 0x02; /* width */			dev->jpg_hdr[0x246] = 0x80; 			dev->jpg_hdr[0x243] = 0x01; /* height */			dev->jpg_hdr[0x244] = 0xE0;			dev->jpg_hdr[0x249] = 0x22; /* YUV 420 */			dev->jpg_hdr[0x23C] = 0x07; /* v0 */			dev->jpg_hdr[0x23D] = 0xD0;			break;		case 5: /* 640x480 YUV 422 */			dev->jpg_hdr[0x245] = 0x02; /* width */			dev->jpg_hdr[0x246] = 0x80; 			dev->jpg_hdr[0x243] = 0x01; /* height */			dev->jpg_hdr[0x244] = 0xE0;			dev->jpg_hdr[0x249] = 0x21; /* YUV 422 */			dev->jpg_hdr[0x23C] = 0x07; /* v2 */			dev->jpg_hdr[0x23D] = 0xD0;			break;		default:			printk("mjpeg: header error\n");			return -1;	}	return 0;}	/* * JPEG Header *      Quantization table */static int mjpeg_hdr_qt(struct mjpeg_device *dev){	int r;	int i;	unsigned long tmp;	switch (mjpeg_alphacoeff) {		case 32:			for (i = 0; i < 64; i++) {				dev->jpg_hdr[0x07+i] = yquant[i] / 2;				dev->jpg_hdr[0x48+i] = uvquant[i] / 2;			}			goto final;		case 64:			r = 1;			break;		case 128:			r = 2;			break;		case 256:			r = 4;			break;		case 512:			r = 8;			break;		default:			printk("mjpg: header error\n");			return -1;	}	for (i = 0; i < 64; i++) {		tmp = (unsigned long)yquant[i];		tmp = tmp * r;		if (tmp > 0xff)			tmp = 0xff;		dev->jpg_hdr[0x07+i] = (unsigned char)tmp;		tmp = (unsigned long)uvquant[i];		tmp = tmp * r;		if (tmp > 0xff) 			tmp = 0xff;		dev->jpg_hdr[0x48+i] = (unsigned char)tmp;	}final:	return 0;}#ifdef MJPEG_PROCint mjpeg_read_proc(char *page, char **start, off_t off, int count,		int *eof, void *data){	struct mjpeg_device *dev = mjpeg_dev;	struct mjpeg_buffer *r = dev->rbuf;	int size = 0;	size += sprintf(page+size, "%20s : %7d bytes\n", 			"mjpeg data",			r->count);	size += sprintf(page+size, "%20s : %7d bytes\n",			"mjpeg max data",			dev->max_size);	return size;}#endifstatic inline void mjpeg_buff_init(struct mjpeg_device *dev) {	struct mjpeg_buffer *buf = dev->wbuf;	buf->valid = 0;	buf->count = 0;	/*	 * jpeg header copy	 */	memcpy(buf->data, dev->jpg_hdr, JPEG_HDR_SIZE);	buf->count += JPEG_HDR_SIZE;}static inline void mjpeg_buff_change(struct mjpeg_device *dev){	struct mjpeg_buffer *tmp;	tmp = dev->rbuf;	dev->rbuf = dev->wbuf;	dev->wbuf = tmp;}/* * mjpeg interrupt service routine */void ncplus_mjpeg_interrupt(int irq, void *dev_id, struct pt_regs *regs){	unsigned long dma_count, status;	struct mjpeg_device *dev = dev_id;	struct mjpeg_buffer *w = dev->wbuf;	unsigned long *buffer = NULL;		// mjpeg watchdog timeout renewal	mjpeg_watchdog_timeout = jiffies + (HZ * MJPEG_WATCHDOG_TIMEOUT);	mod_timer(&mjpeg_watchdog_timer, mjpeg_watchdog_timeout);	if(gs_new_frame) {		mjpeg_buff_init(dev);		gs_new_frame = 0;		gs_thread_no = 0;	}	buffer = (unsigned long *)(w->data + w->count);	status = mjpeg_readl(MODULE_FUNC_STS);	dma_count = (((unsigned long)mjpeg_readl(MCU_FIFO_STATUS)&0xffff0000)>>16);	if (w->count + (dma_count * 4) > COMPRESSED_SIZE) {		printk("mjpeg: buffer overflow\n");		mjpeg_reset(dev);		mjpeg_buff_init(dev);		return;	}	if ((status & FRAME_ENC_FINISHED)==0x60) {		mjpeg_writel((mjpeg_readl(JPEG_STATUS))&0xfffffffe, JPEG_STATUS);	}	insl(MJPEG_BASE+DMA_START_ADD_VAL, buffer, dma_count);	w->count += dma_count * 4;	if ((status & FRAME_ENC_FINISHED)==0x60) {		if (w->count > dev->max_size)			dev->max_size = w->count;		w->valid = 1;		mjpeg_buff_change(dev);		gs_new_frame = 1;	}	return;}/* * Device Operations */int mjpeg_open(struct inode *inode, struct file *filp){        if ((filp->f_flags & O_ACCMODE) & (O_WRONLY | O_RDWR)) {	/*        if (mjpeg_bDeviceWriteOpen) {            printk(DEVICE_NAME " : Device already open for writing\n");            return -EBUSY;        } else	*/            ++mjpeg_bDeviceWriteOpen;    } else {	/*        if (mjpeg_bDeviceReadOpen) {            printk(DEVICE_NAME " : Device already open for reading\n");            return -EBUSY;        } else	*/            ++mjpeg_bDeviceReadOpen;    }    /*    if (!filp->private_data) {	    //dev = mjpeg_dev;	    filp->private_data = dev;    } else {	    dev = filp->private_data;    }    */    //filp->private_data = dev;    //MOD_INC_USE_COUNT;    return 0;}int mjpeg_release(struct inode *inode, struct file *filp){    if ((filp->f_flags & O_ACCMODE) & (O_WRONLY | O_RDWR))        --mjpeg_bDeviceWriteOpen;    else        --mjpeg_bDeviceReadOpen;    //MOD_DEC_USE_COUNT;    return 0;}/* * return value * 0 : end of file * positive : read bytes count * negative(-1) : buffer empty */ssize_t mjpeg_read(struct file *filp, char *buffer, size_t length, loff_t *offset){    	struct mjpeg_device *dev = mjpeg_dev;	struct mjpeg_buffer *r = dev->rbuf;	int count = 0;	unsigned long flags;	// spin_lock flags	spin_lock_irqsave(dev->lock, flags);	if (r->valid) {		count = r->count;		if (copy_to_user(buffer, r->data, count) ) {			printk(DEVICE_NAME " : copy_to_user fault!\n");			return -EFAULT;		}	} else		count = 0;	spin_unlock_irqrestore(mjpeg_device, flags);	return count;}/* * The ioctl() implementation */int mjpeg_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){    	struct mjpeg_device *dev = mjpeg_dev;	int err = 0;

⌨️ 快捷键说明

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