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

📄 stradis.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * stradis.c - stradis 4:2:2 mpeg decoder driver * * Stradis 4:2:2 MPEG-2 Decoder Driver * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org> * * 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; without 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., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/module.h>#include <linux/version.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/init.h>#include <linux/poll.h>#include <linux/pci.h>#include <linux/signal.h>#include <asm/io.h>#include <linux/ioport.h>#include <asm/pgtable.h>#include <asm/page.h>#include <linux/sched.h>#include <asm/segment.h>#include <asm/types.h>#include <linux/types.h>#include <linux/wrapper.h>#include <linux/interrupt.h>#include <asm/uaccess.h>#include <linux/vmalloc.h>#include <linux/videodev.h>#include <linux/i2c-old.h>#include "saa7146.h"#include "saa7146reg.h"#include "ibmmpeg2.h"#include "saa7121.h"#include "cs8420.h"#define DEBUG(x) 		/* debug driver */#undef  IDEBUG	 		/* debug irq handler */#undef  MDEBUG	 		/* debug memory management */#define SAA7146_MAX 6static struct saa7146 saa7146s[SAA7146_MAX];static int saa_num = 0;		/* number of SAA7146s in use */static int video_nr = -1;MODULE_PARM(video_nr,"i");MODULE_LICENSE("GPL");#define nDebNormal	0x00480000#define nDebNoInc	0x00480000#define nDebVideo	0xd0480000#define nDebAudio	0xd0400000#define nDebDMA		0x02c80000#define oDebNormal	0x13c80000#define oDebNoInc	0x13c80000#define oDebVideo	0xd1080000#define oDebAudio	0xd1080000#define oDebDMA		0x03080000#define NewCard		(saa->boardcfg[3])#define ChipControl	(saa->boardcfg[1])#define NTSCFirstActive	(saa->boardcfg[4])#define PALFirstActive	(saa->boardcfg[5])#define NTSCLastActive	(saa->boardcfg[54])#define PALLastActive	(saa->boardcfg[55])#define Have2MB		(saa->boardcfg[18] & 0x40)#define HaveCS8420	(saa->boardcfg[18] & 0x04)#define IBMMPEGCD20	(saa->boardcfg[18] & 0x20)#define HaveCS3310	(saa->boardcfg[18] & 0x01)#define CS3310MaxLvl	((saa->boardcfg[30] << 8) | saa->boardcfg[31])#define HaveCS4341	(saa->boardcfg[40] == 2)#define SDIType		(saa->boardcfg[27])#define CurrentMode	(saa->boardcfg[2])#define debNormal	(NewCard ? nDebNormal : oDebNormal)#define debNoInc	(NewCard ? nDebNoInc : oDebNoInc)#define debVideo	(NewCard ? nDebVideo : oDebVideo)#define debAudio	(NewCard ? nDebAudio : oDebAudio)#define debDMA		(NewCard ? nDebDMA : oDebDMA)#ifdef DEBUGint stradis_driver(void)	/* for the benefit of ksymoops */{	return 1;}#endif#ifdef USE_RESCUE_EEPROM_SDM275static unsigned char rescue_eeprom[64] = {0x00,0x01,0x04,0x13,0x26,0x0f,0x10,0x00,0x00,0x00,0x43,0x63,0x22,0x01,0x29,0x15,0x73,0x00,0x1f, 'd', 'e', 'c', 'x', 'l', 'd', 'v', 'a',0x02,0x00,0x01,0x00,0xcc,0xa4,0x63,0x09,0xe2,0x10,0x00,0x0a,0x00,0x02,0x02, 'd', 'e', 'c', 'x', 'l', 'a',0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};#endif/* ----------------------------------------------------------------------- *//* Hardware I2C functions */static void I2CWipe(struct saa7146 *saa){	int i;	/* set i2c to ~=100kHz, abort transfer, clear busy */	saawrite(0x600 | SAA7146_I2C_ABORT, SAA7146_I2C_STATUS);	saawrite((SAA7146_MC2_UPLD_I2C << 16) |		 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);	/* wait for i2c registers to be programmed */	for (i = 0; i < 1000 &&	     !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)		schedule();	saawrite(0x600, SAA7146_I2C_STATUS);	saawrite((SAA7146_MC2_UPLD_I2C << 16) |		 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);	/* wait for i2c registers to be programmed */	for (i = 0; i < 1000 &&	     !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)		schedule();	saawrite(0x600, SAA7146_I2C_STATUS);	saawrite((SAA7146_MC2_UPLD_I2C << 16) |		 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);	/* wait for i2c registers to be programmed */	for (i = 0; i < 1000 &&	     !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)		schedule();}/* read I2C */static int I2CRead(struct i2c_bus *bus, unsigned char addr,		   unsigned char subaddr, int dosub){	struct saa7146 *saa = (struct saa7146 *) bus->data;	int i;	if (saaread(SAA7146_I2C_STATUS) & 0x3c)		I2CWipe(saa);	for (i = 0; i < 1000 &&	     (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)		schedule();	if (i == 1000)		I2CWipe(saa);	if (dosub)		saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 8) |		  ((subaddr & 0xff) << 16) | 0xed, SAA7146_I2C_TRANSFER);	else		saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 16) |			 0xf1, SAA7146_I2C_TRANSFER);	saawrite((SAA7146_MC2_UPLD_I2C << 16) |		 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);	/* wait for i2c registers to be programmed */	for (i = 0; i < 1000 &&	     !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)		schedule();	/* wait for valid data */	for (i = 0; i < 1000 &&	     (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)		schedule();	if (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_ERR)		return -1;	if (i == 1000) 		printk("i2c setup read timeout\n");	saawrite(0x41, SAA7146_I2C_TRANSFER);	saawrite((SAA7146_MC2_UPLD_I2C << 16) |		 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);	/* wait for i2c registers to be programmed */	for (i = 0; i < 1000 &&	     !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)		schedule();	/* wait for valid data */	for (i = 0; i < 1000 &&	     (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_BUSY); i++)		schedule();	if (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_ERR)		return -1;	if (i == 1000) 		printk("i2c read timeout\n");	return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff);}static int I2CReadOld(struct i2c_bus *bus, unsigned char addr){	return I2CRead(bus, addr, 0, 0);}/* set both to write both bytes, reset it to write only b1 */static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,		    unsigned char b2, int both){	struct saa7146 *saa = (struct saa7146 *) bus->data;	int i;	u32 data;	if (saaread(SAA7146_I2C_STATUS) & 0x3c)		I2CWipe(saa);	for (i = 0; i < 1000 &&	     (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)		schedule();	if (i == 1000)		I2CWipe(saa);	data = ((addr & 0xfe) << 24) | ((b1 & 0xff) << 16);	if (both)		data |= ((b2 & 0xff) << 8) | 0xe5;	else		data |= 0xd1;	saawrite(data, SAA7146_I2C_TRANSFER);	saawrite((SAA7146_MC2_UPLD_I2C << 16) | SAA7146_MC2_UPLD_I2C,		 SAA7146_MC2);	return 0;}static void attach_inform(struct i2c_bus *bus, int id){	struct saa7146 *saa = (struct saa7146 *) bus->data;	int i;	DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr, id));	if (id == 0xa0)	{ /* we have rev2 or later board, fill in info */		for (i = 0; i < 64; i++)			saa->boardcfg[i] = I2CRead(bus, 0xa0, i, 1);#ifdef USE_RESCUE_EEPROM_SDM275		if (saa->boardcfg[0] != 0) {			printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE BEEN IGNORED\n", saa->nr);			for (i = 0; i < 64; i++)				saa->boardcfg[i] = rescue_eeprom[i];		}#endif		printk("stradis%d: config =", saa->nr);		for (i = 0; i < 51; i++) {			printk(" %02x",saa->boardcfg[i]);		}		printk("\n");	}}static void detach_inform(struct i2c_bus *bus, int id){	struct saa7146 *saa = (struct saa7146 *) bus->data;	int i;	i = saa->nr;}static void I2CBusScan(struct i2c_bus *bus){	int i;	for (i = 0; i < 0xff; i += 2)		if ((I2CRead(bus, i, 0, 0)) >= 0)			attach_inform(bus, i);}static struct i2c_bus saa7146_i2c_bus_template ={	"saa7146",	I2C_BUSID_BT848,	NULL,	SPIN_LOCK_UNLOCKED,	attach_inform,	detach_inform,	NULL,	NULL,	I2CReadOld,	I2CWrite,};static int debiwait_maxwait = 0;static int wait_for_debi_done(struct saa7146 *saa){	int i;	/* wait for registers to be programmed */	for (i = 0; i < 100000 &&	     !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_DEBI); i++)		saaread(SAA7146_MC2);	/* wait for transfer to complete */	for (i = 0; i < 500000 &&	     (saaread(SAA7146_PSR) & SAA7146_PSR_DEBI_S); i++)		saaread(SAA7146_MC2);	if (i > debiwait_maxwait)		printk("wait-for-debi-done maxwait: %d\n",			debiwait_maxwait = i);		if (i == 500000)		return -1;	return 0;}static int debiwrite(struct saa7146 *saa, u32 config, int addr,		      u32 val, int count){	u32 cmd;	if (count <= 0 || count > 32764)		return -1;	if (wait_for_debi_done(saa) < 0)		return -1;	saawrite(config, SAA7146_DEBI_CONFIG);	if (count <= 4)		/* immediate transfer */		saawrite(val, SAA7146_DEBI_AD);	else			/* block transfer */		saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);	saawrite((cmd = (count << 17) | (addr & 0xffff)), SAA7146_DEBI_COMMAND);	saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,		 SAA7146_MC2);	return 0;}static u32 debiread(struct saa7146 *saa, u32 config, int addr, int count){	u32 result = 0;	if (count > 32764 || count <= 0)		return 0;	if (wait_for_debi_done(saa) < 0)		return 0;	saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);	saawrite((count << 17) | 0x10000 | (addr & 0xffff),		 SAA7146_DEBI_COMMAND);	saawrite(config, SAA7146_DEBI_CONFIG);	saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,		 SAA7146_MC2);	if (count > 4)		/* not an immediate transfer */		return count;	wait_for_debi_done(saa);	result = saaread(SAA7146_DEBI_AD);	if (count == 1)		result &= 0xff;	if (count == 2)		result &= 0xffff;	if (count == 3)		result &= 0xffffff;	return result;}#if 0 /* unused *//* MUST be a multiple of 8 bytes and 8-byte aligned and < 32768 bytes *//* data copied into saa->dmadebi buffer, caller must re-enable interrupts */static void ibm_block_dram_read(struct saa7146 *saa, int address, int bytes){	int i, j;	u32 *buf;	buf = (u32 *) saa->dmadebi;	if (bytes > 0x7000)		bytes = 0x7000;	saawrite(0, SAA7146_IER);	/* disable interrupts */	for (i=0; i < 10000 &&		(debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2)		& 0x8000); i++)		saaread(SAA7146_MC2);	if (i == 10000)		printk(KERN_ERR "stradis%d: dram_busy never cleared\n",			saa->nr);	debiwrite(saa, debNormal, IBM_MP2_SRC_ADDR, (address<<16) |		(address>>16), 4);	debiwrite(saa, debNormal, IBM_MP2_BLOCK_SIZE, bytes, 2);	debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 0x8a10, 2);	for (j = 0; j < bytes/4; j++) {		for (i = 0; i < 10000 &&			(!(debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2)			& 0x4000)); i++)			saaread(SAA7146_MC2);		if (i == 10000)			printk(KERN_ERR "stradis%d: dram_ready never set\n",				saa->nr);		buf[j] = debiread(saa, debNormal, IBM_MP2_DRAM_DATA, 4);	}}#endif /* unused */static void do_irq_send_data(struct saa7146 *saa){	int split, audbytes, vidbytes;	saawrite(SAA7146_PSR_PIN1, SAA7146_IER);	/* if special feature mode in effect, disable audio sending */	if (saa->playmode != VID_PLAY_NORMAL)		saa->audtail = saa->audhead = 0;	if (saa->audhead <= saa->audtail)		audbytes = saa->audtail - saa->audhead;	else		audbytes = 65536 - (saa->audhead - saa->audtail);	if (saa->vidhead <= saa->vidtail)		vidbytes = saa->vidtail - saa->vidhead;	else		vidbytes = 524288 - (saa->vidhead - saa->vidtail);	if (audbytes == 0 && vidbytes == 0 && saa->osdtail == saa->osdhead) {		saawrite(0, SAA7146_IER);		return;	}	/* if at least 1 block audio waiting and audio fifo isn't full */	if (audbytes >= 2048 && (debiread(saa, debNormal,		IBM_MP2_AUD_FIFO, 2) & 0xff) < 60) {		if (saa->audhead > saa->audtail)			split = 65536 - saa->audhead;		else			split = 0;		audbytes = 2048;		if (split > 0 && split < 2048) {			memcpy(saa->dmadebi, saa->audbuf + saa->audhead,				split);			saa->audhead = 0;			audbytes -= split;		} else			split = 0;		memcpy(saa->dmadebi + split, saa->audbuf + saa->audhead,			audbytes);		saa->audhead += audbytes;		saa->audhead &= 0xffff;		debiwrite(saa, debAudio, (NewCard? IBM_MP2_AUD_FIFO :			  IBM_MP2_AUD_FIFOW), 0, 2048);		wake_up_interruptible(&saa->audq);	/* if at least 1 block video waiting and video fifo isn't full */	} else if (vidbytes >= 30720 && (debiread(saa, debNormal,		IBM_MP2_FIFO, 2)) < 16384) {		if (saa->vidhead > saa->vidtail)			split = 524288 - saa->vidhead;		else			split = 0;		vidbytes = 30720;		if (split > 0 && split < 30720) {

⌨️ 快捷键说明

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