static irqreturn_t venc_isr(int irq, void *arg)
{
	struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
	struct vpbe_layer *layer;
	static unsigned last_event;
	unsigned event = 0;
	int fid;
	int i;

	if ((NULL == arg) || (NULL == disp_dev->dev[0]))
		return IRQ_HANDLED;

	if (venc_is_second_field(disp_dev))
		event |= VENC_SECOND_FIELD;
	else
		event |= VENC_FIRST_FIELD;

	if (event == (last_event & ~VENC_END_OF_FRAME)) {
		event |= VENC_END_OF_FRAME;
	} else if (event == VENC_SECOND_FIELD) {
		
		event |= VENC_END_OF_FRAME;
	}
	last_event = event;

	for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
		layer = disp_dev->dev[i];
		
		if (!layer->started)
			continue;

		if (layer->layer_first_int) {
			layer->layer_first_int = 0;
			continue;
		}
		
		if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
			(event & VENC_END_OF_FRAME)) {
			

			vpbe_isr_even_field(disp_dev, layer);
			vpbe_isr_odd_field(disp_dev, layer);
		} else {
		

			layer->field_id ^= 1;
			if (event & VENC_FIRST_FIELD)
				fid = 0;
			else
				fid = 1;

			if (fid != layer->field_id) {
				
				layer->field_id = fid;
				continue;
			}
			if (0 == fid)
				vpbe_isr_even_field(disp_dev, layer);
			else  
				vpbe_isr_odd_field(disp_dev, layer);
		}
	}

	return IRQ_HANDLED;
}
Beispiel #2
0
/* interrupt service routine */
static irqreturn_t venc_isr(int irq, void *arg)
{
	struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
	struct vpbe_layer *layer;
	static unsigned last_event;
	unsigned event = 0;
	int fid;
	int i;

	if ((NULL == arg) || (NULL == disp_dev->dev[0]))
		return IRQ_HANDLED;

	if (venc_is_second_field(disp_dev))
		event |= VENC_SECOND_FIELD;
	else
		event |= VENC_FIRST_FIELD;

	if (event == (last_event & ~VENC_END_OF_FRAME)) {
		/*
		* If the display is non-interlaced, then we need to flag the
		* end-of-frame event at every interrupt regardless of the
		* value of the FIDST bit.  We can conclude that the display is
		* non-interlaced if the value of the FIDST bit is unchanged
		* from the previous interrupt.
		*/
		event |= VENC_END_OF_FRAME;
	} else if (event == VENC_SECOND_FIELD) {
		/* end-of-frame for interlaced display */
		event |= VENC_END_OF_FRAME;
	}
	last_event = event;

	for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
		layer = disp_dev->dev[i];
		/* If streaming is started in this layer */
		if (!layer->started)
			continue;

		if (layer->layer_first_int) {
			layer->layer_first_int = 0;
			continue;
		}
		/* Check the field format */
		if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
			(event & VENC_END_OF_FRAME)) {
			/* Progressive mode */

			vpbe_isr_even_field(disp_dev, layer);
			vpbe_isr_odd_field(disp_dev, layer);
		} else {
		/* Interlaced mode */

			layer->field_id ^= 1;
			if (event & VENC_FIRST_FIELD)
				fid = 0;
			else
				fid = 1;

			/*
			* If field id does not match with store
			* field id
			*/
			if (fid != layer->field_id) {
				/* Make them in sync */
				layer->field_id = fid;
				continue;
			}
			/*
			* device field id and local field id are
			* in sync. If this is even field
			*/
			if (0 == fid)
				vpbe_isr_even_field(disp_dev, layer);
			else  /* odd field */
				vpbe_isr_odd_field(disp_dev, layer);
		}
	}

	return IRQ_HANDLED;
}