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

📄 cvdv.c

📁 linux TV 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*     cvdv.c    Copyright (C) Christian Wolff                   Marcus Metzler for convergence integrated media.    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.*/      /////////////////////////////////////////////////////////////////////     //                                                                 //    //   Driver for the Convergence Digital Video decoder card (pci)   //   //   with L64017, L64021, PCM1723, and Bt864/Bt865 chipset         //  //   (c) Christian Wolff 19990209 for convergence integrated media // //                                                                 ///////////////////////////////////////////////////////////////////////#define __NO_VERSION__#include <linux/module.h>#include "cvdv.h"#include <linux/dvb/osd.h>#include "i2c.h"  //////////////////////   // global variables ////////////////////////// my little random function for memory testuint16_t rnd_seed;uint16_t rnd(uint16_t range){				// returns random 0..(range-1) range<=872	uint32_t b = 75 * (rnd_seed + 1) - 1;	rnd_seed = (uint16_t) (b & 0xFFFF);	return ((b * range) / 0xFFFF) - ((b / 0xFFFF) * range);}void rnd_omize(void){	rnd_seed = (uint16_t) jiffies;}static char *cimlogo[] = {".............................................",".............................................","......................###....................",".....................#####...................",".....................######..................","..............#......#####...................","...........#####....######...................",".........########...######...................","........########....######...................",".......#########...######....................","......########.....######...####.............",".....#######.......#####...#####.............",".....######.......######...######............","....#######.......######....######...........","....######........######....######...........","....#####........######......#####...........","...######........######......#####...........","...#####.........######......######..........","...#####.........#####.......######..........","...#####........######........#####..........","...#####........######.......######..........","...#####........#####.........#####..........","...#####.......######........######..........","...#####.......######........#####...........","...######.......####.........#####...........","....#####........##.........######...........","....######..................######...........","....######.................######............",".....#######..............######.....#####...",".....########............#######....#######..","......#########........########.....#######..",".......#######################......########.","........#####################.......#######..","..........#################.........#######..","............#############............#####...","...............#.#####.................##....",".............................................","............................................."};    /////////////////////////////////////////////   //                                         //  //  Controlling the L64021 MPEG-2 Decoder  // //                                         ///////////////////////////////////////////////int OSDTest(struct cvdv_cards *card){	int i, j, col, x0, y0, x1, y1,aspx;	uint8_t b;	if (!card->OSD.open)		return -2;	OSDQuery(card, &x0, &y0, &x1, &y1, &aspx);	OSDShow(card);	OSDSetColor(card, 0, 0, 0, 0, 0, 0, 0);	OSDSetColor(card, 1, 128, 255, 255, 0, 0, 0);	for ( i = 0; i < cimlogo_width; i++){		for ( j = 0; j < cimlogo_height; j++){			b = cimlogo[j][i];			col = (b == '#') ? 1: 0;			OSDSetPixel(card, x0+i, y0+j, col);		}	}	return 0;}void SetVideoSystem(struct cvdv_cards *card){	uint8_t reg;	// set the hsync and vsync generators in the L64017 according to the video standard	reg = read_indexed_register(card, IIO_VIDEO_CONTROL1);	reg &= ~0x03;	switch (card->videomode) {	case PAL:		// 864*625*50Hz = 27MHz, 25fps		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x41 | 0x0a);		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);		reg |= VMS_PAL;		break;	case PALN:		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0xa1 | 0x0a);		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);		reg |= VMS_PAL;		break;	case PALNc:		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x81 | 0x0a);		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, 0x8c);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x28);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xed);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);		reg |= VMS_PAL;		break;	case NTSC:		// 858*525*59.94006Hz = 27MHz, 29.97fps		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a);		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);		reg |= VMS_NTSC;		break;	case PALM:		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a);		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, 0x4e);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);		reg |= VMS_PAL;		break;	case NTSC60:		// 857*525*60.010002Hz = 27MHz, 30fps		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x21 | 0x0a);		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);		reg |= VMS_NTSC;		break;	case PALM60:		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x61 | 0x0a);		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, 0x4e);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1);		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);		reg |= VMS_PAL;		break;	case PAL60:		break;	}	write_indexed_register(card, IIO_VIDEO_CONTROL1, reg);	// set the pixel generators according to the video standard	L64021Setup(card);}int SetVideoAttr(struct cvdv_cards *card, uint16_t vattr){	uint8_t video_compression_mode;	uint8_t tv_system;	uint8_t aspect_ratio;	uint8_t display_mode;	uint8_t line_21_switch_1;	uint8_t line_21_switch_2;	uint8_t source_picture_resolution;	uint8_t source_picture_letterboxed;	uint8_t reserved;	uint8_t film_camera_mode;	uint16_t hsize, vsize;	if (vattr != card->lastvattr) {		video_compression_mode = (vattr >> 14) & 0x03;		tv_system = (vattr >> 12) & 0x03;		aspect_ratio = (vattr >> 10) & 0x03;		display_mode = (vattr >> 8) & 0x03;		line_21_switch_1 = (vattr >> 7) & 0x01;		line_21_switch_2 = (vattr >> 6) & 0x01;		source_picture_resolution = (vattr >> 3) & 0x07;		source_picture_letterboxed = (vattr >> 2) & 0x01;		reserved = (vattr >> 1) & 0x01;		film_camera_mode = (vattr >> 0) & 0x01;		card->videomode =			((tv_system == 0) ? NTSC : ((tv_system == 1) ? 						    PAL : PAL));			SetVideoSystem(card);		hsize =			((source_picture_resolution == 0) ? 720			 : ((source_picture_resolution == 1) ? 702 : 352));		vsize = ((source_picture_resolution == 3)			 ? ((tv_system == 0) ? 240 : 288)			 : ((tv_system == 0) ? 480 : 576));		if (DecoderOpen		    (card, hsize, vsize, ((aspect_ratio) ? 3 : 2),		     ((video_compression_mode) ? 0 : 1),		     source_picture_letterboxed, tv_system)) {				MDEBUG(0,			       ": Video Decoder Open failed: On-card memory insufficient for frame stores\n");		}		card->lastvattr = vattr;	} else {		MDEBUG(0,		       ": Video attribute not set, equal to previous one.\n");	}	return 0;}int SetAudioAttr(struct cvdv_cards *card, uint16_t aattr){	uint8_t audio_coding_mode;	uint8_t multichannel_extension;	uint8_t audio_type;	uint8_t audio_application_mode;	uint8_t quantization_drc;	uint8_t fs;	uint8_t reserved;	uint8_t num_audio_ch;	if (aattr) {		if (aattr != card->lastaattr) {			audio_coding_mode = (aattr >> 13) & 0x07;			multichannel_extension = (aattr >> 12) & 0x01;			audio_type = (aattr >> 10) & 0x03;			audio_application_mode = (aattr >> 8) & 0x03;			quantization_drc = (aattr >> 6) & 0x03;			fs = (aattr >> 4) & 0x03;			reserved = (aattr >> 3) & 0x01;			num_audio_ch = (aattr >> 0) & 0x07;			switch (audio_coding_mode) {			case 0:	// AC-3				card->setup.audioselect = audio_AC3;				break;			case 2:	// MPEG Audio				card->setup.audioselect = audio_MPEG;				break;			case 3:	// MPEG Audio with ext.				card->setup.audioselect = audio_MPEG_EXT;				break;			case 4:	// Linear Pulse Code fe_modulation_t LPCM				card->setup.audioselect = audio_LPCM;				break;			case 6:	// DTS				card->setup.audioselect = audio_DTS;				break;			case 7:	// SDDS				card->setup.audioselect = audio_SDDS;				break;			}			DecoderPrepareAudio(card);			AudioInit(card, ((fs) ? 96 : 48),				  ((audio_application_mode == 2) ? 1 : 0));		} else {			MDEBUG(0,			       ": Audio attribute not set, equal to previous one.\n");		}	} else {		card->setup.audioselect = audio_none;		DecoderPrepareAudio(card);	}	card->lastaattr = aattr;	return 0;}int Prepare(struct cvdv_cards *card){	int err, h;	struct StreamSetup *setup = &card->setup;	if (!card->ChannelBuffersAllocated) {					DecoderStreamReset(card);		if (setup->streamtype == stream_none) {			setup->streamtype = stream_PS; 		}				if (setup->audioselect == audio_none) {			setup->audioselect = audio_MPEG;		}		DecoderPrepareAudio(card);		AudioMute(card, 1);		DecoderPrepareVideo(card);		VideoSetBackground(card, 1, 0, 0, 0);	// black		switch (setup->streamtype) {		default:		case stream_none:	// unknown stream!			MDEBUG(0,			       ": Video Decoder Prepare failed: unknown stream type\n");			return -ENODEV;	// not an MPEG stream!		case stream_ES:	// Elementary Stream			err = DecoderPrepareES(card);			break;		case stream_PES:	// Packetized Elementary Stream			err = DecoderPreparePES(card);			break;		case stream_PS:	// MPEG-1 System Stream / MPEG-2 Program Stream			err = DecoderPreparePS(card, -1, 0, 0, 0, 0, 0);			break;		case stream_DVD:	// DVD Stream			err = DecoderPreparePS(card, 0, 0, 0, 0, 3, 1);			break;		}		if (err) {	// insufficient memory			MDEBUG(0,			       ": Video Decoder Prepare failed: no kernel memory, please reboot if possible\n");			CloseCard(card);			return -ENODEV;		}	}	// Set up the Video Decoder as we have the stream information	if ((!card->FrameBuffersAllocated)	    && (card->ChannelBuffersAllocated) && (card->stream.sh.valid)) {		//  Automatic PAL/NTSC-switch according to MPEG-Source		h = card->stream.vsize;		if (h < 480)			h *= 2;	// catch quarter sized images		printk(KERN_INFO LOGNAME ": Video mode: %s\n",		       ((h == 480) ? "NTSC" : "PAL"));		card->videomode = ((h == 480) ? NTSC : PAL);		SetVideoSystem(card);		// Open the Video Decoder with the parameters retreived from the stream		if (		    (err =		     DecoderOpen(card, card->stream.hsize,				 card->stream.vsize,				 card->stream.sh.aspectratio,				 !card->stream.MPEG2, 0,				 (card->stream.hsize > 480)))) {	// TODO: include vbvbuffersize			MDEBUG(0,			       ": Video Decoder Open failed: %s\n",			       ((err == 1) ?				"Picture size too big (>1440 pixel wide)" :				"On-card memory insufficient for frame stores"));			CloseCard(card);			return -ENODEV;	// picture too big or insufficient memory		}		MDEBUG(1, ": Ready to go\n");		card->startingV = 1;	// tell the card to start playing as soon as ES-buffers are sufficiently full		card->startingA = 1;	// tell the card to start playing as soon as ES-buffers are sufficiently full	}		return 0;}int SetSCRstart(struct cvdv_cards *card, uint32_t SCR_base){	uint32_t SCR_compare;	uint32_t SCR_compareA;	uint32_t SCR_compareV;	if (card->startingV) {		MDEBUG(0, ": SCR in DVD Pack: 0x%08X\n",		       SCR_base);		card->startingV = 0;		card->startingA = 0;		DecoderMaskByte(card, 0x007, 0xD2, 0xD2);	// Set 0x010, halt SCR counter		SCR_compare = SCR_base + 000;		if (SCR_base < 900)			SCR_base = 0;		else			SCR_base -= 900;		//DecoderWriteDWord(card,0x009,SCR_base);  // Set SCR counter		DecoderWriteByte(card, 0x009, SCR_base & 0xFF);	// Set SCR counter		DecoderWriteByte(card, 0x00A, (SCR_base >> 8) & 0xFF);		DecoderWriteByte(card, 0x00B, (SCR_base >> 16) & 0xFF);		DecoderWriteByte(card, 0x00C, (SCR_base >> 24) & 0xFF);		DecoderMaskByte(card, 0x011, 0x03, 0x02);	// compare, not capture		MDEBUG(0, ": SCR compare value: 0x%08X\n",		       SCR_compare);		//DecoderWriteDWord(card,0x00D,SCR_compare);  // Set Compare register		DecoderWriteByte(card, 0x00D, SCR_compare & 0xFF);	// Set Compare register		DecoderWriteByte(card, 0x00E, (SCR_compare >> 8) & 0xFF);		DecoderWriteByte(card, 0x00F, (SCR_compare >> 16) & 0xFF);		DecoderWriteByte(card, 0x010, (SCR_compare >> 24) & 0xFF);		//DecoderWriteDWord(card,0x014,SCR_compare);  // Set audio compare reg.		DecoderWriteByte(card, 0x014, SCR_compare & 0xFF);	// Set audio compare reg.		DecoderWriteByte(card, 0x015, (SCR_compare >> 8) & 0xFF);		DecoderWriteByte(card, 0x016, (SCR_compare >> 16) & 0xFF);		DecoderWriteByte(card, 0x017, (SCR_compare >> 24) & 0xFF);		DecoderSetByte(card, 0x013, 0x03);	// Video and Audio start on cmp.		//DecoderSetVideoPanic(card,0,DecoderGetVideoESSize(card)/4);  // video panic at 25 percent		VideoSetBackground(card, 1, 0, 0, 0);	// black		SCR_base = DecoderReadByte(card, 0x009);		SCR_base =		    SCR_base | ((uint32_t) DecoderReadByte(card, 0x00A) << 8);		SCR_base =		    SCR_base | ((uint32_t) DecoderReadByte(card, 0x00B) << 16);		SCR_base =		    SCR_base | ((uint32_t) DecoderReadByte(card, 0x00C) << 24);		SCR_compareA = DecoderReadByte(card, 0x014);		SCR_compareA =		    SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x015) <<				    8);		SCR_compareA =		    SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x016) <<				    16);		SCR_compareA =		    SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x017) <<				    24);		SCR_compareV = DecoderReadByte(card, 0x00D);		SCR_compareV =		    SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x00E) <<				    8);		SCR_compareV =		    SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x00F) <<				    16);		SCR_compareV =		    SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x010) <<				    24);		if (DecoderReadByte(card, 0x013) & 0x03)			MDEBUG(1,": SCR 0x%08X, videocmp=0x%08X, audiocmp=0x%08X %02X\n",			       SCR_base, SCR_compareV, SCR_compareA,			       DecoderReadByte(card, 0x013));		DecoderMaskByte(card, 0x007, 0xD2, 0xC2);	// Del 0x010, SCR counter run	}	return 0;}    //////////////////////////////   //                          //  //  Char Device Procedures  // //                          ////////////////////////////////static long margi_write(struct cvdv_cards *card, const char *data,                      unsigned long count, int nonblock){	int res;	long int out=0;	int free;	free = ring_write_rest(&(card->rbufA));	if (card != NULL) {		card->nonblock = nonblock;		if (count > 0) {	// Do we have data?			if ((res = Prepare(card)))				return res;			if (!card->use_ringA)				MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE,						0);			if (!nonblock && 			    !wait_event_interruptible(				    card->wqA, 				    ring_write_rest(&(card->rbufA)) >count )){								out = MargiPushA(card, count,						 data);			} else {				out = MargiPushA(card, count, data);			}		}		return out;	} else {		MDEBUG(0,

⌨️ 快捷键说明

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