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

📄 margi.c

📁 linux TV 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	spin_unlock(&card->timelock);}void WriteByte(struct cvdv_cards *card, int addr, u_char data){	dev_link_t *link = &(((margi_info_t *) card->margi)->link);	spin_lock(&card->timelock);	outb((u_char) (addr & 255),	     link->io.BasePort1 + DIO_LSI_INDEX_LOW);	outb(((addr & 256) ? 1 : 0),	     link->io.BasePort1 + DIO_LSI_INDEX_HIGH);	outb(data, link->io.BasePort1 + DIO_LSI_DATA);	spin_unlock(&card->timelock);}u_char ReadByte(struct cvdv_cards *card, int addr){	dev_link_t *link = &(((margi_info_t *) card->margi)->link);	u_char data;	spin_lock(&card->timelock);	outb((u_char) (addr & 255),	     link->io.BasePort1 + DIO_LSI_INDEX_LOW);	outb(((addr & 256) ? 1 : 0),	     link->io.BasePort1 + DIO_LSI_INDEX_HIGH);	data = inb(link->io.BasePort1 + DIO_LSI_DATA);	spin_unlock(&card->timelock);	return data;}void MaskByte(struct cvdv_cards *card, int addr, u_char mask, u_char bits){	WriteByte(card, addr, (ReadByte(card, addr) & ~(mask)) | (bits));}#define MAXWRITE CHANNELBUFFERSIZE/2#define MAX_COUNT 400#ifdef USE_BHstruct cvdv_cards *bh_card;static void do_margi_bh(void){	struct cvdv_cards *card = bh_card;#elsestatic void do_margi(struct cvdv_cards *card){#endif	int countA;	int try;	int stype = card->setup.streamtype;	countA = 0;	card->currentType = 0;	for ( try = 0; try < MAX_COUNT ;try++)		if (countA < MAXWRITE){			int count = 0;			switch (stype){			case stream_PES:			case stream_ES:				count = ringDMA(card);				countA += count;				if (!count) 					try=MAX_COUNT;							break;			case stream_PS:			case stream_DVD:				count = ringDMA(card);				countA += count;				if (!count) 					try=MAX_COUNT;				break;			}		} else break;}void L64014Intr_function(struct cvdv_cards *card){	uint8_t control,mask,stat;	int try;	control= read_indexed_register(card, IIO_IRQ_CONTROL);	if (control & IRQ_EN){		mask = 0;		if ( control & DEC_EN ) mask |= DEC_INT;		if ( control & VSYNC_EN ) mask |= VSYNC_INT;		stat = read_indexed_register(card, IIO_IRQ_STATUS);		try = 0;		while ( (try++ < 100) && (stat & mask) ){		      				  if (stat & VSYNC_INT) {					write_indexed_register(card,IIO_IRQ_CONTROL,						       control & (~VSYNC_EN));				write_indexed_register(card,IIO_IRQ_CONTROL,						       control);				if (card->DMAABusy || card->DMABBusy){#ifdef USE_BH					bh_card = card;					mark_bh(MARGI_BH);#else 					do_margi(card);#endif					if(card->use_ringA || card->use_ringB){					  L64021Intr(card);					}				} 			}			if (stat & DEC_INT) {				write_indexed_register(card,IIO_IRQ_CONTROL,						       control & (~DEC_EN));				write_indexed_register(card,IIO_IRQ_CONTROL,						       control);								if(card->use_ringA || card->use_ringB){					L64021Intr(card);				}			}			stat = read_indexed_register(card, IIO_IRQ_STATUS);		}	}}void Timerfunction(unsigned long data){	struct cvdv_cards *card = (struct cvdv_cards *) data;	L64014Intr_function(card);	card->timer.function = Timerfunction;	card->timer.data=(unsigned long) card;	card->timer.expires=jiffies+10;	if ( card->open)		add_timer(&card->timer);}void L64014Intr(int irq, void *dev_id, struct pt_regs *regs){	margi_info_t *margi = dev_id;	struct cvdv_cards *card = &(margi->card);	u_char dio_index, lsi_index_low, lsi_index_high;	spin_lock(&card->timelock);	//save registers	dio_index = inb(margi->link.io.BasePort1 + DIO_CONTROL_INDEX);	lsi_index_low = inb(margi->link.io.BasePort1 + DIO_LSI_INDEX_LOW);	lsi_index_high = inb(margi->link.io.BasePort1 + DIO_LSI_INDEX_HIGH);		L64014Intr_function(card);	//load registers	outb(dio_index, margi->link.io.BasePort1 + DIO_CONTROL_INDEX);	outb(lsi_index_low, margi->link.io.BasePort1 + DIO_LSI_INDEX_LOW);	outb(lsi_index_high,margi->link.io.BasePort1 + DIO_LSI_INDEX_HIGH);	spin_unlock(&card->timelock);}int L64014RemoveIntr(struct cvdv_cards *card){	MDEBUG(1, ": -- L64014RemoveIntr\n");	// Disable the IRQ's	write_indexed_register(card, IIO_IRQ_CONTROL, 0x00);	if (!card->IntInstalled)		return 1;	L64021RemoveIntr(card);	return 0;}void l64020Reset(struct cvdv_cards *card){	uint8_t data;			data = read_indexed_register(card, IIO_LSI_CONTROL);	data &= ~(RR | DR);	write_indexed_register(card, IIO_LSI_CONTROL, data);	mdelay(100);	data = read_indexed_register(card, IIO_LSI_CONTROL);	data |= DR;	write_indexed_register(card, IIO_LSI_CONTROL, data);	data = read_indexed_register(card,IIO_GPIO_PINS);	data &= ~0x01;	write_indexed_register(card,IIO_GPIO_PINS,data);	data |= 0x01;	write_indexed_register(card,IIO_GPIO_PINS,data);		//write_indexed_register(card, IIO_LSI_CONTROL, DR);		data = read_indexed_register(card, IIO_LSI_CONTROL);	data &= ~DSVC;	write_indexed_register(card, IIO_LSI_CONTROL, data);}void ZV_init(struct cvdv_cards *card){	uint32_t delay, activel;	uint8_t reg;	delay = 235;	activel = delay + 1448;		// init delay and active lines	write_indexed_register(card, IIO_VIDEO_HOR_DELAY, 			       (uint8_t)(delay & 0x00FF));	write_indexed_register(card, IIO_VIDEO_HOR_ACTIVE, 			       (uint8_t)(activel & 0x00FF));      	reg = ((uint8_t)((activel >> 4) & 0x0070))|((uint8_t)((delay >> 8) & 0x0007));	write_indexed_register(card, IIO_VIDEO_HOR_HIGH, reg);	//init video	reg = read_indexed_register(card, IIO_VIDEO_CONTROL0);	reg |= (ZVCLK13 | ZV16BIT | ZVCLKINV);	write_indexed_register(card, IIO_VIDEO_CONTROL0, reg);	reg = read_indexed_register(card, IIO_VIDEO_CONTROL1);	reg |= (ZV_OVERRIDE | ZV_ENABLE);	write_indexed_register(card, IIO_VIDEO_CONTROL1, reg);}void set_svhs(struct cvdv_cards *card, int onoff){	uint8_t val;	val =  I2CRead(card, card->i2c_addr, CS_DAC)&0x0f;	MDEBUG(1, ": --svhs val 0x%02x\n",val);	if (onoff){		if (!card->svhs){			I2CWrite(card, card->i2c_addr, CS_DAC, val|0x03);			card->svhs = 1;		}	} else {		if (!card->svhs){			I2CWrite(card, card->i2c_addr, CS_DAC, val|0x30);			card->svhs = 1;		}	}}void set_composite(struct cvdv_cards *card, int onoff){	uint8_t val;	val =  I2CRead(card, card->i2c_addr, CS_DAC)&0x0f;	MDEBUG(1, ": --composite val 0x%02x\n",val);		if (onoff){		if (!card->composite){			I2CWrite(card, card->i2c_addr, CS_DAC, val|0x84);			card->composite = 1;		}	} else {		if (!card->svhs){			I2CWrite(card, card->i2c_addr, CS_DAC, val|0xE0);			card->composite = 1;		}	}}int L64014Init(struct cvdv_cards *card){	uint16_t testram[16];	int i, err;	MDEBUG(1, ": -- L64014Init\n");	card->videomode = VIDEO_MODE;	/* Reset 64020 */	write_indexed_register(card, IIO_GPIO_CONTROL, 0x01);	l64020Reset(card);	/* init GPIO */	write_indexed_register(card, IIO_GPIO_CONTROL, 0x01);	write_indexed_register(card, IIO_GPIO_PINS, 0xff);	/* Set to PAL */	write_indexed_register(card, IIO_VIDEO_CONTROL0, 0);	write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL);	/* Set Audio freq */	write_indexed_register(card, IIO_OSC_AUD, 0x12);	write_indexed_register(card, CSS_COMMAND, 0x01);	MDEBUG(0, "CSID: %02x\n", I2CRead(card, 0, 0x3d));	card->i2c_addr = I2CRead(card, 0, 0x0f);	MDEBUG(0, "I2CADDR: %02x\n", card->i2c_addr);	I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x4a);	I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);	I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);	I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);	I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);	I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);	I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);//	I2CWrite(card, card->i2c_addr, CS_DAC, 0x87);	if (svhs) set_svhs(card, 1);	if (composite) set_composite(card, 1);	I2CWrite(card, card->i2c_addr, CS_BKG_COL, 0x03);	MDEBUG(0,"Decoder Status: %d\n", read_lsi_status(card));	MDEBUG(0,"lsi stat %d\n", DecoderReadByte(card, 0x005));	if (use_zv) ZV_init(card);	L64021Init(card);	// Find out how much DRAM we have	card->DRAMSize = 0x00100000;	// maximum size	do {		MDEBUG(0,		       ": Probing DRAM Size: 0x%08X (%d kByte) ... ",		       card->DRAMSize, card->DRAMSize / 512);		for (i = 0; i < 8; i++)			testram[i] = rnd(0x100) | (rnd(0x100) << 8);		if (DRAMWriteWord(card, 0, 4, &testram[0], 0))			MDEBUG(0, ": DRAM Write error.\n");		if (DRAMWriteWord		    (card, card->DRAMSize - 4, 4, &testram[4],		     0)) MDEBUG(0,				": DRAM Write error.\n");		if (DRAMReadWord(card, 0, 4, &testram[8], 0))			MDEBUG(0, ": DRAM Read error.\n");		if (DRAMReadWord		    (card, card->DRAMSize - 4, 4, &testram[12],		     0)) MDEBUG(0, ": DRAM Read error.\n");		err = 0;		for (i = 0; (!err) && (i < 8); i++)			if (testram[i] != testram[i + 8])				err = i + 1;		if (err) {			MDEBUG(0," failed\n");		} else {			MDEBUG(0," ok\n");		}		if (err)			MDEBUG(2,": DRAM compare error at cell %d: 0x%04X %04X %04X %04X->0x%04X %04X %04X %04X / 0x%04X %04X %04X %04X->0x%04X %04X %04X %04X\n",			       err, testram[0], testram[1], testram[2],			       testram[3], testram[8], testram[9],			       testram[10], testram[11], testram[4],			       testram[5], testram[6], testram[7],			       testram[12], testram[13], testram[14],			       testram[15]);		if (err)			card->DRAMSize >>= 1;	} while (err && (card->DRAMSize >= 0x00100000));	printk(KERN_INFO LOGNAME ": DRAM Size: 0x%08X (%d kByte)\n",	       card->DRAMSize, card->DRAMSize / 512);	if (card->DRAMSize < 0x00100000) {	// minimum size		printk(KERN_INFO LOGNAME		       ": DRAM ERROR: Not enough memory on card!\n");		return 1;	}	return 0;}void CardDeInit(struct cvdv_cards *card){	CloseCard(card);	MargiFlush(card);	MargiFreeBuffers(card);	L64014RemoveIntr(card);	card_init(card);}static u_char read_lsi_status(struct cvdv_cards *card){	margi_info_t *margi = (margi_info_t *) card->margi;	return (inb(margi->link.io.BasePort1 + DIO_LSI_STATUS) & 15);}/*====================================================================*/static void cs_error(client_handle_t handle, int func, int ret){	error_info_t err = { func, ret };	CardServices(ReportError, handle, &err);}/*======================================================================    margi_attach() creates an "instance" of the driver, allocating    local data structures for one device.  The device is registered    with Card Services.    The dev_link structure is initialized, but we don't actually    configure the card at this point -- we wait until we receive a    card insertion event.    ======================================================================*/static dev_link_t *margi_attach(void){	margi_info_t *local;	dev_link_t *link;	client_reg_t client_reg;	int ret, i;	MDEBUG(0, "margi_attach()\n");	for (i = 0; i < MAX_DEV; i++)		if (dev_table[i] == NULL)			break;	if (i == MAX_DEV) {		printk(KERN_NOTICE "margi_cs: no devices available\n");		return NULL;	}	/* Allocate space for private device-specific data */	local = kmalloc(sizeof(margi_info_t), GFP_KERNEL);	if (!local)		return NULL;	memset(local, 0, sizeof(margi_info_t));	link = &local->link;	link->priv = local;	local->card.margi = (void *) local;	dev_table[i] = link;	/* Initialize the dev_link_t structure */	link->release.function = &margi_release;	link->release.data = (u_long) link;	/* Interrupt setup */	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;	if (irq_list[0] == -1)		link->irq.IRQInfo2 = irq_mask;	else		for (i = 0; i < 4; i++)			link->irq.IRQInfo2 |= 1 << irq_list[i];	link->irq.Handler = NULL;	/*	   General socket configuration defaults can go here.  In this	   client, we assume very little, and rely on the CIS for almost	   everything.  In most clients, many details (i.e., number, sizes,	   and attributes of IO windows) are fixed by the nature of the	   device, and can be hard-wired here.	 */	link->conf.Attributes = 0;	link->conf.Vcc = 50;		if (!use_zv)		link->conf.IntType = INT_MEMORY_AND_IO;	else		link->conf.IntType = INT_ZOOMED_VIDEO;	/* Register with Card Services */	link->next = dev_list;

⌨️ 快捷键说明

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