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

📄 saa7146.c

📁 linux数字电视播放器,比先的版本高一些.
💻 C
📖 第 1 页 / 共 2 页
字号:
	if( saa->interlace != 0 && w_height*4 >= modes_constants[saa->mode].v_calc && w_height*2 <= modes_constants[saa->mode].v_calc) {		vdma1.base_odd = vdma1.prot_addr;		vdma1.pitch /= 2;	}			vdma1.base_page = 0;	vdma1.num_line_byte = (modes_constants[saa->mode].v_field<<16)+modes_constants[saa->mode].h_pixels;	saa7146_write(saa->mem, BASE_EVEN1,     vdma1.base_even);	saa7146_write(saa->mem, BASE_ODD1,      vdma1.base_odd);	saa7146_write(saa->mem, PROT_ADDR1,     vdma1.prot_addr);	saa7146_write(saa->mem, BASE_PAGE1,     vdma1.base_page);	saa7146_write(saa->mem, PITCH1,		vdma1.pitch);	saa7146_write(saa->mem, NUM_LINE_BYTE1,	vdma1.num_line_byte);	/* update the video dma 1 registers */      	saa7146_write(saa->mem, MC2, (MASK_02 | MASK_18));		return 0;}/* ---------------------------------------------*//* size of window (overlay)			*//* ---------------------------------------------*/int set_window(struct saa7146* saa, int width, int height, int flip_lr, int port_sel, int sync_sel){	u32 hps_v_scale = 0, hps_v_gain  = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0;	/* set vertical scale according to selected mode: 0 = PAL, 1 = NTSC */	hps_v_scale = 0; /* all bits get set by the function-call */	hps_v_gain  = 0; /* fixme: saa7146_read(saa->mem, HPS_V_GAIN);*/ 	calculate_v_scale_registers(saa, modes_constants[saa->mode].v_calc, height, &hps_v_scale, &hps_v_gain);	/* set horizontal scale according to selected mode: 0 = PAL, 1 = NTSC */	hps_ctrl 	= 0;	hps_h_prescale	= 0; /* all bits get set in the function */	hps_h_scale	= 0;	calculate_h_scale_registers(saa, modes_constants[saa->mode].h_calc, width, 0, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale);	/* set hyo and hxo */	calculate_hxo_hyo_and_sources(saa, port_sel, sync_sel, &hps_h_scale, &hps_ctrl);		/* write out new register contents */	saa7146_write(saa->mem, HPS_V_SCALE,	hps_v_scale);	saa7146_write(saa->mem, HPS_V_GAIN,	hps_v_gain);	saa7146_write(saa->mem, HPS_CTRL,	hps_ctrl);	saa7146_write(saa->mem, HPS_H_PRESCALE,hps_h_prescale);	saa7146_write(saa->mem, HPS_H_SCALE,	hps_h_scale);	/* upload shadow-ram registers */      	saa7146_write( saa->mem, MC2, (MASK_05 | MASK_06 | MASK_21 | MASK_22) );/*	printk("w:%d,h:%d\n",width,height);*/	return 0;}void set_output_format(struct saa7146* saa, u16 palette){	u32	clip_format = saa7146_read(saa->mem, CLIP_FORMAT_CTRL);		dprintk("saa7146: ==> set_output_format: pal:0x%03x\n",palette);		/* call helper function */	calculate_output_format_register(saa,palette,&clip_format);	dprintk("saa7146: ==> set_output_format: 0x%08x\n",clip_format);	/* update the hps registers */	saa7146_write(saa->mem, CLIP_FORMAT_CTRL, clip_format);      	saa7146_write(saa->mem, MC2, (MASK_05 | MASK_21));}void set_picture_prop(struct saa7146 *saa, u32 brightness, u32 contrast, u32 colour){	u32	bcs_ctrl = 0;		calculate_bcs_ctrl_register(saa, brightness, contrast, colour, &bcs_ctrl);	saa7146_write(saa->mem, BCS_CTRL, bcs_ctrl);		/* update the bcs register */      	saa7146_write(saa->mem, MC2, (MASK_06 | MASK_22));}/* ---------------------------------------------*//* overlay enable/disable			*//* ---------------------------------------------*//* enable(1) / disable(0) video */void video_setmode(struct saa7146* saa, int v){	hprintk("saa7146: ==> video_setmode; m:%d\n",v);		/* disable ? */	if(v==0) {		/* disable video dma1 */      		saa7146_write(saa->mem, MC1, MASK_22);	} else {/* or enable ? */		/* fixme: enable video */	        saa7146_write(saa->mem, MC1, (MASK_06 | MASK_22));	}}		/* -----------------------------------------------------   common grabbing-functions. if you have some simple   saa7146-based frame-grabber you can most likely call   these. they do all the revision-dependend stuff and   do rps/irq-based grabbing for you.   -----------------------------------------------------*//* this function initializes the rps for the next grab for any "old"   saa7146s (= revision 0). it assumes that the rps is *not* running   when it gets called. */int init_rps0_rev0(struct saa7146* saa, int frame, int irq_call){	struct	saa7146_video_dma	vdma1;	u32 hps_v_scale = 0, hps_v_gain  = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0;	u32 clip_format = 0; /* this can be 0, since we don't do clipping */	u32 bcs_ctrl = 0;		int count = 0;/* these static values are used to remember the last "programming" of the rps.   if the height, width and format of the grab has not changed (which is very likely   when some streaming capture is done) the reprogramming overhead can be minimized */static	int last_height = 0;static	int last_width = 0;static	int last_format = 0;static	int last_port = 0;static	int last_frame = -1;	/* write the address of the rps-program */	saa7146_write(saa->mem, RPS_ADDR0, virt_to_bus(&saa->rps0[ 0]));	/* let's check if we can re-use something of the last grabbing process */	if (	   saa->grab_height[frame] != last_height		|| saa->grab_width[frame] != last_width		|| saa->grab_port[frame] != last_port		|| saa->grab_format[frame] != last_format ) {		/* nope, we have to start from the beginning */		calculate_video_dma1_grab(saa, frame, &vdma1);		calculate_v_scale_registers(saa, modes_constants[saa->mode].v_calc, saa->grab_height[frame], &hps_v_scale, &hps_v_gain);		calculate_h_scale_registers(saa, modes_constants[saa->mode].h_calc, saa->grab_width[frame], 0, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale);		calculate_hxo_hyo_and_sources(saa, saa->grab_port[frame], saa->grab_port[frame], &hps_h_scale, &hps_ctrl);		calculate_output_format_register(saa,saa->grab_format[frame],&clip_format);		calculate_bcs_ctrl_register(saa, 0x80, 0x40, 0x40, &bcs_ctrl);		count = 0;		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4));		/* turn off video-dma1 and dma2 (clipping)*/		saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22 | MASK_05 | MASK_21);	/* => mask */		saa->rps0[ count++ ] = cpu_to_le32(MASK_22 | MASK_21);			/* => values */		saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[frame] == 0 ? MASK_12 : MASK_14));	/* wait for o_fid_a/b */		saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[frame] == 0 ? MASK_11 : MASK_13));	/* wait for e_fid_a/b */		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (6 << 8) | HPS_CTRL/4);	/* upload hps-registers for next grab */		saa->rps0[ count++ ] = cpu_to_le32(hps_ctrl);		saa->rps0[ count++ ] = cpu_to_le32(hps_v_scale);		saa->rps0[ count++ ] = cpu_to_le32(hps_v_gain);		saa->rps0[ count++ ] = cpu_to_le32(hps_h_prescale);		saa->rps0[ count++ ] = cpu_to_le32(hps_h_scale);		saa->rps0[ count++ ] = cpu_to_le32(bcs_ctrl);		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (1 << 8) | CLIP_FORMAT_CTRL/4);/* upload hps-registers for next grab */		saa->rps0[ count++ ] = cpu_to_le32(clip_format);		saa->rps0[ count++ ] = cpu_to_le32(CMD_UPLOAD | MASK_05 | MASK_06);		/* upload hps1/2 */		/* upload video-dma1 registers for next grab */		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (6 << 8) | BASE_ODD1/4);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_odd);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_even);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.prot_addr);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.pitch);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_page);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.num_line_byte);		saa->rps0[ count++ ] = cpu_to_le32(CMD_UPLOAD | MASK_02);		/* upload video-dma1 */		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4));		/* turn on video-dma1 */		saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22);	    		/* => mask */		saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22);			/* => values */		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (1 << 8) | (MC2/4)); 	/* Write MC2 */		saa->rps0[ count++ ] = cpu_to_le32((1 << (27+frame)) | (1 << (11+frame)));		saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[frame] == 0 ? MASK_12 : MASK_14));	/* wait for o_fid_a/b */		saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[frame] == 0 ? MASK_11 : MASK_13));	/* wait for e_fid_a/b */		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4));     		/* turn off video-dma1 */		saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22);	    		/* => mask */		saa->rps0[ count++ ] = cpu_to_le32(MASK_22);					/* => values */		saa->rps0[ count++ ] = cpu_to_le32(CMD_INTERRUPT);				/* generate interrupt */		saa->rps0[ count++ ] = cpu_to_le32(CMD_STOP);				/* stop processing */		} else {			/* the height, width, ... have not changed. check if the user wants to grab to		   another *buffer* */		if( frame != last_frame ) {			/* ok, we want to grab to another buffer, but with the same programming.			   it is sufficient to adjust the video_dma1-registers and the rps-signal stuff. */			saa->rps0[ 20 ] = cpu_to_le32(virt_to_bus(saa->page_table[frame]) | ME1);			saa->rps0[ 27 ] = cpu_to_le32((1 << (27+frame)) | (1 << (11+frame)));			}	 }	 	/* if we are called from within the irq-handler, the hps is at the beginning of a	   new frame. the rps does not need to wait the new frame, and so we tweak the	   starting address a little bit and so we can directly start grabbing again.	   note: for large video-sizes and slow computers this can cause jaggy pictures	   because the whole process is not in sync. perhaps one should be able to	   disable this. (please remember that this whole stuff only belongs to 	   "old" saa7146s (= revision 0), newer saa7146s don磘 have any hardware-bugs	   and capture works fine. (see below) */   	if( 1 == irq_call ) {		saa7146_write(saa->mem, RPS_ADDR0, virt_to_bus(&saa->rps0[15]));	}			/* turn on rps */	saa7146_write(saa->mem, MC1, (MASK_12 | MASK_28));		/* store the values for the last grab */	last_height = saa->grab_height[frame];	last_width = saa->grab_width[frame];	last_format = saa->grab_format[frame];	last_port = saa->grab_port[frame];	last_frame = frame;	return 0;}int init_rps0_rev1(struct saa7146* saa, int frame) {static	int old_width[SAA7146_MAX_BUF];		/* pixel width of grabs */static	int old_height[SAA7146_MAX_BUF];	/* pixel height of grabs */static	int old_format[SAA7146_MAX_BUF];	/* video format of grabs */static	int old_port[SAA7146_MAX_BUF];		/* video port for grab */	static	int buf_stat[SAA7146_MAX_BUF];	struct	saa7146_video_dma	vdma1;	u32 hps_v_scale = 0, hps_v_gain  = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0;	u32 clip_format = 0; /* this can be 0, since we don't do clipping */	u32 bcs_ctrl = 0;	int i = 0, count = 0;	/* check if something has changed since the last grab for this buffer */	if ( 	   saa->grab_height[frame]	== old_height[frame]		&& saa->grab_width[frame]	== old_width[frame]		&& saa->grab_port[frame] 	== old_port[frame]		&& saa->grab_format[frame]	== old_format[frame] ) {		/* nope, nothing to be done here */		return 0;	}	/* re-program the rps0 completely */	/* indicate that the user has requested re-programming of the 'frame'-buffer */	buf_stat[frame] = 1;	/* turn off rps */	saa7146_write(saa->mem, MC1, MASK_28);		/* write beginning of rps-program */	count = 0;	saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | MASK_12);				/* wait for o_fid_a */	saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | MASK_11);				/* wait for e_fid_a */	for(i = 0; i < saa->buffers; i++) {				saa->rps0[ count++ ] = cpu_to_le32(CMD_JUMP  | (1 << (21+i)));		/* check signal x, jump if set */		saa->rps0[ count++ ] = cpu_to_le32(virt_to_bus(&saa->rps0[40*(i+1)]));	}	saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | MASK_12);				/* wait for o_fid_a */	saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | MASK_11);				/* wait for e_fid_a */	saa->rps0[ count++ ] = cpu_to_le32(CMD_JUMP);					/* jump to the beginning */	saa->rps0[ count++ ] = cpu_to_le32(virt_to_bus(&saa->rps0[2]));			for(i = 0; i < saa->buffers; i++) {		/* we only re-program the i-th buffer if the user had set some values for it earlier.		   otherwise the calculation-functions may fail. */		if( buf_stat[i] == 0)			continue;		count = 40*(i+1);		calculate_video_dma1_grab(saa, i, &vdma1);		calculate_v_scale_registers(saa, modes_constants[saa->mode].v_calc, saa->grab_height[i], &hps_v_scale, &hps_v_gain);		calculate_h_scale_registers(saa, modes_constants[saa->mode].h_calc, saa->grab_width[i], 0, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale);		calculate_hxo_hyo_and_sources(saa, saa->grab_port[i], saa->grab_port[i], &hps_h_scale, &hps_ctrl);		calculate_output_format_register(saa,saa->grab_format[i],&clip_format);		calculate_bcs_ctrl_register(saa, 0x80, 0x40, 0x40, &bcs_ctrl);			saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (6 << 8) | HPS_CTRL/4);	/* upload hps-registers for next grab */		saa->rps0[ count++ ] = cpu_to_le32(hps_ctrl);		saa->rps0[ count++ ] = cpu_to_le32(hps_v_scale);		saa->rps0[ count++ ] = cpu_to_le32(hps_v_gain);		saa->rps0[ count++ ] = cpu_to_le32(hps_h_prescale);		saa->rps0[ count++ ] = cpu_to_le32(hps_h_scale);		saa->rps0[ count++ ] = cpu_to_le32(bcs_ctrl);		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (1 << 8) | CLIP_FORMAT_CTRL/4);/* upload hps-registers for next grab */		saa->rps0[ count++ ] = cpu_to_le32(clip_format);			saa->rps0[ count++ ] = cpu_to_le32(CMD_UPLOAD | MASK_05 | MASK_06);		/* upload hps1/2 */			saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (6 << 8) | BASE_ODD1/4);	/* upload video-dma1 registers for next grab */		saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_odd);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_even);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.prot_addr);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.pitch);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_page);		saa->rps0[ count++ ] = cpu_to_le32(vdma1.num_line_byte);		saa->rps0[ count++ ] = cpu_to_le32(CMD_UPLOAD | MASK_02);		/* upload video-dma1 */		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4));		/* turn on video-dma1 */		saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22);	    		/* => mask */		saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22);			/* => values */		saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[i] == 0 ? MASK_12 : MASK_14));	/* wait for o_fid_a/b */		saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[i] == 0 ? MASK_11 : MASK_13));	/* wait for e_fid_a/b */		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4));		/* turn off video-dma1 and dma2 (clipping)*/		saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22 | MASK_05 | MASK_21);	/* => mask */		saa->rps0[ count++ ] = cpu_to_le32(MASK_22 | MASK_21);			/* => values */		saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (1 << 8) | (MC2/4)); 	/* Write MC2 */		saa->rps0[ count++ ] = cpu_to_le32((1 << (27+i)));		saa->rps0[ count++ ] = cpu_to_le32(CMD_INTERRUPT);				/* generate interrupt */		saa->rps0[ count++ ] = cpu_to_le32(CMD_JUMP);	/* jump to the beginning */		saa->rps0[ count++ ] = cpu_to_le32(virt_to_bus(&saa->rps0[2]));		old_height[frame] = saa->grab_height[frame];		old_width[frame]  = saa->grab_width[frame];		old_port[frame]	  = saa->grab_port[frame];		old_format[frame] = saa->grab_format[frame];	}	/* write the address of the rps-program */	saa7146_write(saa->mem, RPS_ADDR0, virt_to_bus(&saa->rps0[ 0]));	/* turn on rps again */	saa7146_write(saa->mem, MC1, (MASK_12 | MASK_28));		return 0;}/* this funtion is called whenever a new grab is requested. if possible (that   means: if the rps is not running) it re-programs the rps, otherwise it relys on   the irq-handler to do that */int set_up_grabbing(struct saa7146* saa, int frame){	u32 mc1 = 0;	if( 0 == saa->revision ) {		/* check if the rps is currently in use */		mc1   = saa7146_read(saa->mem, MC1);		/* the rps is not running ... */		if( 0 == ( mc1 & MASK_12) ) {			/* we can completly re-program the rps now */			dprintk("saa7146_v4l.o: ==> set_up_grabbing: start new rps.\n");			init_rps0_rev0(saa,frame,0);		} else {				/* the rps is running. in this case, the irq-handler is responsible for			   re-programming the rps and nothing can be done right now */			dprintk("saa7146_v4l.o: ==> set_up_grabbing: no new rps started.\n");		}	} else {			/* check if something has changed, reprogram if necessary */			init_rps0_rev1(saa,frame);			/* set rps-signal-bit to start grabbing */			saa7146_write(saa->mem, MC2, (1 << (27+frame)) |  (1 << (11+frame)));	}		return 0;	}void saa7146_std_grab_irq_callback_rps0(struct saa7146* saa, u32 isr, void* data){	u32 mc2 = 0;	int i = 0;			hprintk("saa7146_v4l.o: ==> saa7146_v4l_irq_callback_rps0\n");	/* check for revision: old revision */	if( 0 == saa->revision ) {		/* look what buffer has been grabbed, set the 磀one

⌨️ 快捷键说明

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