Re: [PULL] http://kernellabs.com/hg/~stoth/saa7164-v4l

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Em 31-07-2010 17:42, Steven Toth escreveu:
> Mauro,
> 
> Analog Encoder and VBI support in the SAA7164 tree, for the HVR2200
> and HVR2250 cards.
> 
> Please pull from http://www.kernellabs.com/hg/~stoth/saa7164-v4l

It generates a few warnings:

drivers/media/video/saa7164/saa7164-buffer.c: In function ‘saa7164_buffer_display’:
drivers/media/video/saa7164/saa7164-buffer.c:76: warning: cast to pointer from integer of different size
drivers/media/video/saa7164/saa7164-buffer.c:78: warning: cast to pointer from integer of different size

But the most important things is that the driver uses BKL and have a problematic access
to proc_fs. Those are the details I noticed on your code:

> diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile
> index 4b329fd..6303a8e 100644
> --- a/drivers/media/video/saa7164/Makefile
> +++ b/drivers/media/video/saa7164/Makefile
> @@ -1,6 +1,6 @@
>  saa7164-objs	:= saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
>  			saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \
> -			saa7164-buffer.o
> +			saa7164-buffer.o saa7164-encoder.o saa7164-vbi.o
>  
>  obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
>  
> diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
> index 3f1262b..045d909 100644
> --- a/drivers/media/video/saa7164/saa7164-api.c
> +++ b/drivers/media/video/saa7164/saa7164-api.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>

This is a minor detail: it should be, instead 2009-2010

>   *
>   *  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
> @@ -24,14 +24,750 @@
>  
>  #include "saa7164.h"
>  
> -int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode)
> +int saa7164_api_get_load_info(struct saa7164_dev *dev, tmFwInfoStruct_t *i)
>  {
>  	int ret;
>  
> +	if (!(saa_debug & DBGLVL_CPU))
> +		return 0;
> +
> +	dprintk(DBGLVL_API, "%s()\n", __func__);
> +
> +	i->deviceinst = 0;
> +	i->devicespec = 0;
> +	i->mode = 0;
> +	i->status = 0;
> +
> +	ret = saa7164_cmd_send(dev, 0, GET_CUR,
> +		GET_FW_STATUS_CONTROL, sizeof(tmFwInfoStruct_t), i);
> +	if (ret != SAA_OK) {
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +	}
> +
> +	printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_collect_debug(struct saa7164_dev *dev)
> +{
> +	tmComResDebugGetData_t d;
> +	u8 more = 255;
> +	int ret;
> +
> +	dprintk(DBGLVL_API, "%s()\n", __func__);
> +
> +	while (more--) {
> +
> +		memset(&d, 0, sizeof(d));
> +
> +		ret = saa7164_cmd_send(dev, 0, GET_CUR,
> +			GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
> +		if (ret != SAA_OK) {
> +			printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +		}
> +
> +		if (d.dwResult != SAA_OK)
> +			break;
> +
> +		printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, d.ucDebugData);
> +	}
> +
> +	return 0;
> +}
> +
> +int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
> +{
> +	tmComResDebugSetLevel_t lvl;
> +	int ret;
> +
> +	dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level);
> +
> +	/* Retrieve current state */
> +	ret = saa7164_cmd_send(dev, 0, GET_CUR,
> +		SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
> +	if (ret != SAA_OK) {
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +	}
> +	dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
> +
> +	lvl.dwDebugLevel = level;
> +
> +	/* set new state */
> +	ret = saa7164_cmd_send(dev, 0, SET_CUR,
> +		SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
> +	if (ret != SAA_OK) {
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +	}
> +
> +	return ret;
> +}
> +
> +int saa7164_api_set_vbi_format(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	tmComResProbeCommit_t fmt, rsp;
> +	int ret;
> +
> +	dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__,
> +		port->nr, port->hwcfg.unitid);
> +
> +	fmt.bmHint = 0;
> +	fmt.bFormatIndex = 1;
> +	fmt.bFrameIndex = 1;
> +
> +	/* Probe, see if it can support this format */
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
> +		SET_CUR, SAA_PROBE_CONTROL, sizeof(fmt), &fmt);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() set error, ret = 0x%x\n", __func__, ret);
> +
> +	/* See of the format change was successful */
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
> +		GET_CUR, SAA_PROBE_CONTROL, sizeof(rsp), &rsp);
> +	if (ret != SAA_OK) {
> +		printk(KERN_ERR "%s() get error, ret = 0x%x\n", __func__, ret);
> +	} else {
> +		/* Compare requested vs received, should be same */
> +		if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
> +			dprintk(DBGLVL_API, "SET/PROBE Verified\n");
> +
> +			/* Ask the device to select the negotiated format */
> +			ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
> +				SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
> +			if (ret != SAA_OK)
> +				printk(KERN_ERR "%s() commit error, ret = 0x%x\n",
> +					__func__, ret);
> +
> +			ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
> +				GET_CUR, SAA_COMMIT_CONTROL, sizeof(rsp), &rsp);
> +			if (ret != SAA_OK)
> +				printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
> +					__func__, ret);
> +
> +			if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) {
> +				printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
> +					__func__, ret);
> +			} else
> +				dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
> +
> +			dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
> +			dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex);
> +			dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", rsp.bFrameIndex);
> +		} else
> +			printk(KERN_ERR "%s() compare failed\n", __func__);
> +	}
> +
> +	if (ret == SAA_OK)
> +		dprintk(DBGLVL_API, "%s(nr=%d) Success\n", __func__, port->nr);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_set_gop_size(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	tmComResEncVideoGopStructure_t gs;
> +	int ret;
> +
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	gs.ucRefFrameDist = port->encoder_params.refdist;
> +	gs.ucGOPSize = port->encoder_params.gop_size;
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
> +		EU_VIDEO_GOP_STRUCTURE_CONTROL,
> +		sizeof(gs), &gs);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_set_encoder(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	tmComResEncVideoBitRate_t vb;
> +	tmComResEncAudioBitRate_t ab;
> +	int ret;
> +
> +	dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
> +		port->hwcfg.sourceid);
> +
> +	if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
> +		port->encoder_profile = EU_PROFILE_PS_DVD;
> +	else
> +		port->encoder_profile = EU_PROFILE_TS_HQ;
> +
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
> +		EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Resolution */
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
> +		EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Establish video bitrates */
> +	if (port->encoder_params.bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
> +		vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT;
> +	else
> +		vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK;
> +	vb.dwVideoBitRate = port->encoder_params.bitrate;
> +	vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak;
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
> +		EU_VIDEO_BIT_RATE_CONTROL, sizeof(tmComResEncVideoBitRate_t), &vb);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Establish audio bitrates */
> +	ab.ucAudioBitRateMode = 0;
> +	ab.dwAudioBitRate = 384000;
> +	ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
> +		EU_AUDIO_BIT_RATE_CONTROL, sizeof(tmComResEncAudioBitRate_t), &ab);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	saa7164_api_set_aspect_ratio(port);
> +	saa7164_api_set_gop_size(port);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_get_encoder(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	tmComResEncVideoBitRate_t v;
> +	tmComResEncAudioBitRate_t a;
> +	tmComResEncVideoInputAspectRatio_t ar;
> +	int ret;
> +
> +	dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, port->hwcfg.sourceid);
> +
> +	port->encoder_profile = 0;
> +	port->video_format = 0;
> +	port->video_resolution = 0;
> +	port->audio_format = 0;
> +
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
> +		EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
> +		EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), &port->video_resolution);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
> +		EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
> +		EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
> +		EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
> +		EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Aspect Ratio */
> +	ar.width = 0;
> +	ar.height = 0;
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
> +		EU_VIDEO_INPUT_ASPECT_CONTROL,
> +		sizeof(tmComResEncVideoInputAspectRatio_t), &ar);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile);
> +	dprintk(DBGLVL_ENC, "video_format    = %d\n", port->video_format);
> +	dprintk(DBGLVL_ENC, "audio_format    = %d\n", port->audio_format);
> +	dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
> +	dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", v.ucVideoBitRateMode);
> +	dprintk(DBGLVL_ENC, "v.dwVideoBitRate     = %d\n", v.dwVideoBitRate);
> +	dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", v.dwVideoBitRatePeak);
> +	dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", a.ucAudioBitRateMode);
> +	dprintk(DBGLVL_ENC, "a.dwVideoBitRate     = %d\n", a.dwAudioBitRate);
> +	dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", a.dwAudioBitRatePeak);
> +	dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", ar.width, ar.height);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_set_aspect_ratio(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	tmComResEncVideoInputAspectRatio_t ar;
> +	int ret;
> +
> +	dprintk(DBGLVL_ENC, "%s(%d)\n", __func__,
> +		port->encoder_params.ctl_aspect);
> +
> +	switch (port->encoder_params.ctl_aspect) {
> +	case V4L2_MPEG_VIDEO_ASPECT_1x1:
> +		ar.width = 1;
> +		ar.height = 1;
> +		break;
> +	case V4L2_MPEG_VIDEO_ASPECT_4x3:
> +		ar.width = 4;
> +		ar.height = 3;
> +		break;
> +	case V4L2_MPEG_VIDEO_ASPECT_16x9:
> +		ar.width = 16;
> +		ar.height = 9;
> +		break;
> +	case V4L2_MPEG_VIDEO_ASPECT_221x100:
> +		ar.width = 221;
> +		ar.height = 100;
> +		break;
> +	default:
> +		BUG();
> +	}
> +
> +	dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__,
> +		port->encoder_params.ctl_aspect,
> +		ar.width, ar.height);
> +
> +	/* Aspect Ratio */
> +	ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
> +		EU_VIDEO_INPUT_ASPECT_CONTROL,
> +		sizeof(tmComResEncVideoInputAspectRatio_t), &ar);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +	u16 val;
> +
> +	if (ctl == PU_BRIGHTNESS_CONTROL)
> +		val = port->ctl_brightness;
> +	else
> +	if (ctl == PU_CONTRAST_CONTROL)
> +		val = port->ctl_contrast;
> +	else
> +	if (ctl == PU_HUE_CONTROL)
> +		val = port->ctl_hue;
> +	else
> +	if (ctl == PU_SATURATION_CONTROL)
> +		val = port->ctl_saturation;
> +	else
> +	if (ctl == PU_SHARPNESS_CONTROL)
> +		val = port->ctl_sharpness;
> +	else
> +		return -EINVAL;
> +
> +	dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n",
> +		__func__, port->encunit.vsourceid, ctl, val);
> +
> +	ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR,
> +		ctl, sizeof(u16), &val);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +	u16 val;
> +
> +	ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR,
> +		ctl, sizeof(u16), &val);
> +	if (ret != SAA_OK) {
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n",
> +		__func__, ctl, val);
> +
> +	if (ctl == PU_BRIGHTNESS_CONTROL)
> +		port->ctl_brightness = val;
> +	else
> +	if (ctl == PU_CONTRAST_CONTROL)
> +		port->ctl_contrast = val;
> +	else
> +	if (ctl == PU_HUE_CONTROL)
> +		port->ctl_hue = val;
> +	else
> +	if (ctl == PU_SATURATION_CONTROL)
> +		port->ctl_saturation = val;
> +	else
> +	if (ctl == PU_SHARPNESS_CONTROL)
> +		port->ctl_sharpness = val;
> +
> +	return ret;
> +}
> +
> +int saa7164_api_set_videomux(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 };
> +	int ret;
> +
> +	dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n",
> +		__func__, port->mux_input, inputs[ port->mux_input - 1 ]);
> +
> +	/* Audio Mute */
> +	ret = saa7164_api_audio_mute(port, 1);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Video Mux */
> +	ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR,
> +		SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Audio Mux */
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
> +		SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[ port->mux_input - 1 ]);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Audio UnMute */
> +	ret = saa7164_api_audio_mute(port, 0);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_audio_mute(struct saa7164_port *port, int mute)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	u8 v = mute;
> +	int ret;
> +
> +	dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute);
> +
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
> +		MUTE_CONTROL, sizeof(u8), &v);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	return ret;
> +}
> +
> +/* 0 = silence, 0xff = full */
> +int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	s16 v, min, max;
> +	int ret;
> +
> +	dprintk(DBGLVL_API, "%s(%d)\n", __func__, level);
> +
> +	/* Obtain the min/max ranges */
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN,
> +		VOLUME_CONTROL, sizeof(u16), &min);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX,
> +		VOLUME_CONTROL, sizeof(u16), &max);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
> +		( 0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
> +
> +	v = level;
> +	if (v < min)
> +		v = min;
> +	if (v > max)
> +		v = max;
> +
> +	/* Left */
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
> +		( 0x01 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Right */
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
> +		( 0x02 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
> +		( 0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_set_audio_std(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	tmComResAudioDefaults_t lvl;
> +	tmComResTunerStandard_t tvaudio;
> +	int ret;
> +
> +	dprintk(DBGLVL_API, "%s()\n", __func__);
> +
> +	/* Establish default levels */
> +	lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT;
> +	lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT;
> +	lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT;
> +	lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT;
> +	lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
> +	lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
> +	ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
> +		AUDIO_DEFAULT_CONTROL, sizeof(tmComResAudioDefaults_t), &lvl);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	/* Manually select the appropriate TV audio standard */
> +	if (port->encodernorm.id & V4L2_STD_NTSC) {
> +		tvaudio.std = TU_STANDARD_NTSC_M;
> +		tvaudio.country = 1;
> +	} else {
> +		tvaudio.std = TU_STANDARD_PAL_I;
> +		tvaudio.country = 44;
> +	}

Hmm... Just two audio formats? If not, please add a TODO here or (even better)
add the code for the other formats.

> +
> +	ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
> +		TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", __func__, ret);
> +	return ret;
> +}
> +
> +int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	tmComResTunerStandardAuto_t p;
> +	int ret;
> +
> +	dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect);
> +
> +	/* Disable TV Audio autodetect if not already set (buggy) */
> +	if (autodetect)
> +		p.mode = TU_STANDARD_AUTO;
> +	else
> +		p.mode = TU_STANDARD_MANUAL;
> +	ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
> +		TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", __func__, ret);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_get_videomux(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +
> +	ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR,
> +		SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +
> +	dprintk(DBGLVL_ENC, "%s() v_mux=%d\n",
> +		__func__, port->mux_input);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +
> +	u16 len = 0;
> +	u8 buf[256];
> +	int ret;
> +	u8 mas;
> +
> +	dprintk(DBGLVL_API, "%s(nr=%d type=%d val=%x)\n", __func__,
> +		port->nr, port->type, val);
> +
> +	if (port->nr == 0)
> +		mas = 0xd0;
> +	else
> +		mas = 0xe0;
> +
> +	memset(buf, 0, sizeof(buf));
> +
> +	buf[0x00] = 0x04;
> +	buf[0x01] = 0x00;
> +	buf[0x02] = 0x00;
> +	buf[0x03] = 0x00;
> +
> +	buf[0x04] = 0x04;
> +	buf[0x05] = 0x00;
> +	buf[0x06] = 0x00;
> +	buf[0x07] = 0x00;
> +
> +	buf[0x08] = reg;
> +	buf[0x09] = 0x26;
> +	buf[0x0a] = mas;
> +	buf[0x0b] = 0xb0;
> +
> +	buf[0x0c] = val;
> +	buf[0x0d] = 0x00;
> +	buf[0x0e] = 0x00;
> +	buf[0x0f] = 0x00;
> +
> +	ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN,
> +		EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
> +	if (ret != SAA_OK) {
> +		printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
> +		return -EIO;
> +	}
> +
> +	ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR,
> +		EXU_REGISTER_ACCESS_CONTROL, len, &buf);
> +	if (ret != SAA_OK)
> +		printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
> +
> +	//saa7164_dumphex16(dev, buf, 16);
> +
> +	return ret == SAA_OK ? 0 : -EIO;
> +}
> +
> +/* Disable the IF block AGC controls */
> +int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret = 0;
> +	u8 agc_disable;
> +
> +	dprintk(DBGLVL_API, "%s(nr=%d, 0x%x)\n", __func__, port->nr, std);
> +
> +	if (std & V4L2_STD_NTSC) {
> +		dprintk(DBGLVL_API, " NTSC\n");
> +		saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
> +		agc_disable = 0;
> +	} else if (std & V4L2_STD_PAL_I) {
> +		dprintk(DBGLVL_API, " PAL-I\n");
> +		saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */
> +		agc_disable = 0;
> +	} else if (std & V4L2_STD_PAL_M) {
> +		dprintk(DBGLVL_API, " PAL-M\n");
> +		saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
> +		agc_disable = 0;
> +	} else if (std & V4L2_STD_PAL_N) {
> +		dprintk(DBGLVL_API, " PAL-N\n");
> +		saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
> +		agc_disable = 0;
> +	} else if (std & V4L2_STD_PAL_Nc) {
> +		dprintk(DBGLVL_API, " PAL-Nc\n");
> +		saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
> +		agc_disable = 0;
> +	} else if (std & V4L2_STD_PAL_B) {
> +		dprintk(DBGLVL_API, " PAL-B\n");
> +		saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */
> +		agc_disable = 0;
> +	} else if (std & V4L2_STD_PAL_DK) {
> +		dprintk(DBGLVL_API, " PAL-DK\n");
> +		saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */
> +		agc_disable = 0;
> +	} else if (std & V4L2_STD_SECAM_L) {
> +		dprintk(DBGLVL_API, " SECAM-L\n");
> +		saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */
> +		agc_disable = 0;
> +	} else {

Hmm... Other formats might match this condition, like some SECAM variants.
There's currently two video standards for DTV:

/* ATSC/HDTV */
#define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
#define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)

Another option that won't match any existing formats would be to check for:

#define V4L2_STD_UNKNOWN        0

Yet, I'm not what should used in this case. The V4L API is not meant to be
used by a ATSC/DVB/ISDB video input. What's happen when with saa7164 when
the "digital TV" format is selected? 

> +		/* Unknown standard, assume DTV */
> +		dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
> +		saa7164_api_set_dif(port, 0x00, 0x80); /* Undefined Video Standard */
> +		agc_disable = 1;
> +	}
> +
> +	saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */
> +	saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */
> +	saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */
> +	saa7164_api_set_dif(port, 0x04, 0x01); /* Active */
> +	msleep(100);
> +	saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */
> +	msleep(100);
> +
> +	return ret;
> +}
> +
> +/* Ensure the dif is in the correct state for the operating mode
> + * (analog / dtv). We only configure the diff through the analog encoder
> + * so when we're in digital mode we need to find the appropriate encoder
> + * and use it to configure the DIF.
> + */
> +int saa7164_api_initialize_dif(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_port *p = 0;
> +	int ret = -EINVAL;
> +	u32 std = 0;
> +
> +	dprintk(DBGLVL_API, "%s(nr=%d type=%d)\n", __func__,
> +		port->nr, port->type);
> +
> +	if (port->type == SAA7164_MPEG_ENCODER) {
> +		/* Pick any analog standard to init the diff.
> +		 * we'll come back during encoder_init'
> +		 * and set the correct standard if requried.
> +		 */
> +		std = V4L2_STD_NTSC;
> +	} else
> +	if (port->type == SAA7164_MPEG_DVB) {
> +		if (port->nr == SAA7164_PORT_TS1)
> +			p = &dev->ports[ SAA7164_PORT_ENC1 ];
> +		else
> +			p = &dev->ports[ SAA7164_PORT_ENC2 ];
> +	} else
> +	if (port->type == SAA7164_MPEG_VBI) {
> +		std = V4L2_STD_NTSC;
> +		if (port->nr == SAA7164_PORT_VBI1)
> +			p = &dev->ports[ SAA7164_PORT_ENC1 ];
> +		else
> +			p = &dev->ports[ SAA7164_PORT_ENC2 ];
> +	} else
> +		BUG();
> +
> +	if (p)
> +		ret = saa7164_api_configure_dif(p, std);
> +
> +	return ret;
> +}
> +
> +int saa7164_api_transition_port(struct saa7164_port *port, u8 mode)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +
> +	int ret;
> +
> +	dprintk(DBGLVL_API, "%s(nr=%d unitid=0x%x,%d)\n",
> +		__func__, port->nr, port->hwcfg.unitid, mode);
> +
>  	ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
>  		SAA_STATE_CONTROL, sizeof(mode), &mode);
>  	if (ret != SAA_OK)
> -		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
> +		printk(KERN_ERR "%s(portnr %d unitid 0x%x) error, ret = 0x%x\n",
> +			__func__, port->nr, port->hwcfg.unitid, ret);
>  
>  	return ret;
>  }
> @@ -61,9 +797,44 @@ int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
>  		&reg[0], 128, buf);
>  }
>  
> +int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
> +	struct saa7164_port *port)
> +{
> +	tmComResVBIFormatDescrHeader_t *fmt = &port->vbi_fmt_ntsc;
> +
> +	dprintk(DBGLVL_API, "    bFormatIndex  = 0x%x\n", fmt->bFormatIndex);
> +	dprintk(DBGLVL_API, "    VideoStandard = 0x%x\n", fmt->VideoStandard);
> +	dprintk(DBGLVL_API, "    StartLine     = %d\n", fmt->StartLine);
> +	dprintk(DBGLVL_API, "    EndLine       = %d\n", fmt->EndLine);
> +	dprintk(DBGLVL_API, "    FieldRate     = %d\n", fmt->FieldRate);
> +	dprintk(DBGLVL_API, "    bNumLines     = %d\n", fmt->bNumLines);
> +
> +	/* Cache the hardware configuration in the port */
> +
> +	port->bufcounter = port->hwcfg.BARLocation;
> +	port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
> +	port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
> +	port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
> +	port->bufptr32l = port->hwcfg.BARLocation +
> +		(4 * sizeof(u32)) +
> +		(sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
> +	port->bufptr32h = port->hwcfg.BARLocation +
> +		(4 * sizeof(u32)) +
> +		(sizeof(u32) * port->hwcfg.buffercount);
> +	port->bufptr64 = port->hwcfg.BARLocation +
> +		(4 * sizeof(u32)) +
> +		(sizeof(u32) * port->hwcfg.buffercount);
> +	dprintk(DBGLVL_API, "   = port->hwcfg.BARLocation = 0x%x\n",
> +		port->hwcfg.BARLocation);
> +
> +	dprintk(DBGLVL_API, "   = VS_FORMAT_VBI (becomes dev->en[%d])\n",
> +		port->nr);
> +
> +	return 0;
> +}
>  
>  int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
> -	struct saa7164_tsport *port,
> +	struct saa7164_port *port,
>  	tmComResTSFormatDescrHeader_t *tsfmt)
>  {
>  	dprintk(DBGLVL_API, "    bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
> @@ -96,9 +867,44 @@ int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
>  	return 0;
>  }
>  
> +int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
> +	struct saa7164_port *port,
> +	tmComResPSFormatDescrHeader_t *fmt)
> +{
> +	dprintk(DBGLVL_API, "    bFormatIndex = 0x%x\n", fmt->bFormatIndex);
> +	dprintk(DBGLVL_API, "    wPacketLength= 0x%x\n", fmt->wPacketLength);
> +	dprintk(DBGLVL_API, "    wPackLength=   0x%x\n", fmt->wPackLength);
> +	dprintk(DBGLVL_API, "    bPackDataType= 0x%x\n", fmt->bPackDataType);
> +
> +	/* Cache the hardware configuration in the port */
> +	/* TODO: CHECK THIS in the port config */
> +	port->bufcounter = port->hwcfg.BARLocation;
> +	port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
> +	port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
> +	port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
> +	port->bufptr32l = port->hwcfg.BARLocation +
> +		(4 * sizeof(u32)) +
> +		(sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
> +	port->bufptr32h = port->hwcfg.BARLocation +
> +		(4 * sizeof(u32)) +
> +		(sizeof(u32) * port->hwcfg.buffercount);
> +	port->bufptr64 = port->hwcfg.BARLocation +
> +		(4 * sizeof(u32)) +
> +		(sizeof(u32) * port->hwcfg.buffercount);
> +	dprintk(DBGLVL_API, "   = port->hwcfg.BARLocation = 0x%x\n",
> +		port->hwcfg.BARLocation);
> +
> +	dprintk(DBGLVL_API, "   = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n",
> +		port->nr);
> +
> +	return 0;
> +}
> +
>  int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
>  {
> -	struct saa7164_tsport *port = 0;
> +	struct saa7164_port *tsport = 0;
> +	struct saa7164_port *encport = 0;
> +	struct saa7164_port *vbiport = 0;
>  	u32 idx, next_offset;
>  	int i;
>  	tmComResDescrHeader_t *hdr, *t;
> @@ -108,6 +914,12 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
>  	tmComResTunerDescrHeader_t *tunerunithdr;
>  	tmComResDMATermDescrHeader_t *vcoutputtermhdr;
>  	tmComResTSFormatDescrHeader_t *tsfmt;
> +	tmComResPSFormatDescrHeader_t *psfmt;
> +	tmComResSelDescrHeader_t *psel;
> +	tmComResProcDescrHeader_t *pdh;
> +	tmComResAFeatureDescrHeader_t *afd;
> +	tmComResEncoderDescrHeader_t *edh;
> +	tmComResVBIFormatDescrHeader_t *vbifmt;
>  	u32 currpath = 0;
>  
>  	dprintk(DBGLVL_API,
> @@ -244,21 +1056,38 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
>  					tsfmt =
>  					(tmComResTSFormatDescrHeader_t *)t;
>  					if (currpath == 1)
> -						port = &dev->ts1;
> +						tsport = &dev->ports[ SAA7164_PORT_TS1 ];
>  					else
> -						port = &dev->ts2;
> -					memcpy(&port->hwcfg, vcoutputtermhdr,
> +						tsport = &dev->ports[ SAA7164_PORT_TS2 ];
> +					memcpy(&tsport->hwcfg, vcoutputtermhdr,
>  						sizeof(*vcoutputtermhdr));
>  					saa7164_api_configure_port_mpeg2ts(dev,
> -						port, tsfmt);
> +						tsport, tsfmt);
>  					break;
>  				case VS_FORMAT_MPEG2PS:
> -					dprintk(DBGLVL_API,
> -						"   = VS_FORMAT_MPEG2PS\n");
> +					psfmt =
> +					(tmComResPSFormatDescrHeader_t *)t;
> +					if (currpath == 1)
> +						encport = &dev->ports[ SAA7164_PORT_ENC1 ];
> +					else
> +						encport = &dev->ports[ SAA7164_PORT_ENC2 ];
> +					memcpy(&encport->hwcfg, vcoutputtermhdr,
> +						sizeof(*vcoutputtermhdr));
> +					saa7164_api_configure_port_mpeg2ps(dev,
> +						encport, psfmt);
>  					break;
>  				case VS_FORMAT_VBI:
> -					dprintk(DBGLVL_API,
> -						"   = VS_FORMAT_VBI\n");
> +					vbifmt =
> +					(tmComResVBIFormatDescrHeader_t *)t;
> +					if (currpath == 1)
> +						vbiport = &dev->ports[ SAA7164_PORT_VBI1 ];
> +					else
> +						vbiport = &dev->ports[ SAA7164_PORT_VBI2 ];
> +					memcpy(&vbiport->hwcfg, vcoutputtermhdr,
> +						sizeof(*vcoutputtermhdr));
> +					memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, sizeof(*vbifmt));
> +					saa7164_api_configure_port_vbi(dev,
> +						vbiport);
>  					break;
>  				case VS_FORMAT_RDS:
>  					dprintk(DBGLVL_API,
> @@ -297,18 +1126,80 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
>  				tunerunithdr->controlsize);
>  			dprintk(DBGLVL_API, "  controls = 0x%x\n",
>  				tunerunithdr->controls);
> +
> +			if (tunerunithdr->unitid == tunerunithdr->iunit) {
> +				if (currpath == 1)
> +					encport = &dev->ports[ SAA7164_PORT_ENC1 ];
> +				else
> +					encport = &dev->ports[ SAA7164_PORT_ENC2 ];
> +				memcpy(&encport->tunerunit, tunerunithdr,
> +					sizeof(tmComResTunerDescrHeader_t));
> +				dprintk(DBGLVL_API, "  (becomes dev->enc[%d] tuner)\n", encport->nr);
> +			}
>  			break;
>  		case VC_SELECTOR_UNIT:
> +			psel = (tmComResSelDescrHeader_t *)(buf + idx);
>  			dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
> +			dprintk(DBGLVL_API, "  unitid = 0x%x\n",
> +				psel->unitid);
> +			dprintk(DBGLVL_API, "  nrinpins = 0x%x\n",
> +				psel->nrinpins);
> +			dprintk(DBGLVL_API, "  sourceid = 0x%x\n",
> +				psel->sourceid);
>  			break;
>  		case VC_PROCESSING_UNIT:
> +			pdh = (tmComResProcDescrHeader_t *)(buf + idx);
>  			dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
> +			dprintk(DBGLVL_API, "  unitid = 0x%x\n",
> +				pdh->unitid);
> +			dprintk(DBGLVL_API, "  sourceid = 0x%x\n",
> +				pdh->sourceid);
> +			dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
> +				pdh->controlsize);
> +			if (pdh->controlsize == 0x04) {
> +				if (currpath == 1)
> +					encport = &dev->ports[ SAA7164_PORT_ENC1 ];
> +				else
> +					encport = &dev->ports[ SAA7164_PORT_ENC2 ];
> +				memcpy(&encport->vidproc, pdh,
> +					sizeof(tmComResProcDescrHeader_t));
> +				dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n", encport->nr);
> +			}
>  			break;
>  		case FEATURE_UNIT:
> +			afd = (tmComResAFeatureDescrHeader_t *)(buf + idx);
>  			dprintk(DBGLVL_API, " FEATURE_UNIT\n");
> +			dprintk(DBGLVL_API, "  unitid = 0x%x\n",
> +				afd->unitid);
> +			dprintk(DBGLVL_API, "  sourceid = 0x%x\n",
> +				afd->sourceid);
> +			dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
> +				afd->controlsize);
> +			if (currpath == 1)
> +				encport = &dev->ports[ SAA7164_PORT_ENC1 ];
> +			else
> +				encport = &dev->ports[ SAA7164_PORT_ENC2 ];
> +			memcpy(&encport->audfeat, afd,
> +				sizeof(tmComResAFeatureDescrHeader_t));
> +			dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n", encport->nr);
>  			break;
>  		case ENCODER_UNIT:
> +			edh = (tmComResEncoderDescrHeader_t *)(buf + idx);
>  			dprintk(DBGLVL_API, " ENCODER_UNIT\n");
> +			dprintk(DBGLVL_API, "  subtype = 0x%x\n", edh->subtype);
> +			dprintk(DBGLVL_API, "  unitid = 0x%x\n", edh->unitid);
> +			dprintk(DBGLVL_API, "  vsourceid = 0x%x\n", edh->vsourceid);
> +			dprintk(DBGLVL_API, "  asourceid = 0x%x\n", edh->asourceid);
> +			dprintk(DBGLVL_API, "  iunit = 0x%x\n", edh->iunit);
> +			if (edh->iunit == edh->unitid) {
> +				if (currpath == 1)
> +					encport = &dev->ports[ SAA7164_PORT_ENC1 ];
> +				else
> +					encport = &dev->ports[ SAA7164_PORT_ENC2 ];
> +				memcpy(&encport->encunit, edh,
> +					sizeof(tmComResEncoderDescrHeader_t));
> +				dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n", encport->nr);
> +			}
>  			break;
>  		case EXTENSION_UNIT:
>  			dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
> @@ -364,6 +1255,15 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
>  				exthdr->numgpiogroups);
>  			dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
>  				exthdr->controlsize);
> +			if (exthdr->devicetype & 0x80) {
> +				if (currpath == 1)
> +					encport = &dev->ports[ SAA7164_PORT_ENC1 ];
> +				else
> +					encport = &dev->ports[ SAA7164_PORT_ENC2 ];
> +				memcpy(&encport->ifunit, exthdr,
> +					sizeof(tmComResExtDevDescrHeader_t));
> +				dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n", encport->nr);
> +			}
>  			break;
>  		case PVC_INFRARED_UNIT:
>  			dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
> @@ -560,7 +1460,6 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
>  	return ret == SAA_OK ? 0 : -EIO;
>  }
>  
> -
>  int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
>  	u8 pin, u8 state)
>  {
> @@ -597,5 +1496,3 @@ int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
>  	return saa7164_api_modify_gpio(dev, unitid, pin, 0);
>  }
>  
> -
> -
> diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
> index 5713f3a..61df8ef 100644
> --- a/drivers/media/video/saa7164/saa7164-buffer.c
> +++ b/drivers/media/video/saa7164/saa7164-buffer.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -66,12 +66,33 @@
>  						    | etc
>   */
>  
> +void saa7164_buffer_display(struct saa7164_buffer *buf)
> +{
> +	struct saa7164_dev *dev = buf->port->dev;
> +	int i;
> +
> +	dprintk(DBGLVL_BUF, "%s()   buffer @ 0x%p nr=%d\n",
> +		__func__, buf, buf->idx);
> +	dprintk(DBGLVL_BUF, "  pci_cpu @ 0x%p    dma @ 0x%p len = 0x%x\n",
> +		buf->cpu, (void *)buf->dma, buf->pci_size);
> +	dprintk(DBGLVL_BUF, "   pt_cpu @ 0x%p pt_dma @ 0x%p len = 0x%x\n",
> +		buf->pt_cpu, (void *)buf->pt_dma, buf->pt_size);
> +
> +	/* Format the Page Table Entries to point into the data buffer */
> +	for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
> +
> +		dprintk(DBGLVL_BUF, "    pt[%02d] = 0x%p -> 0x%llx\n",
> +			i, buf->pt_cpu, (u64)*(buf->pt_cpu));
> +
> +	}
> +}
>  /* Allocate a new buffer structure and associated PCI space in bytes.
>   * len must be a multiple of sizeof(u64)
>   */
> -struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
> +struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
>  	u32 len)
>  {
> +	tmHWStreamParameters_t *params = &port->hw_streamingparams;
>  	struct saa7164_buffer *buf = 0;
>  	struct saa7164_dev *dev = port->dev;
>  	int i;
> @@ -87,8 +108,12 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
>  		goto ret;
>  	}
>  
> +	buf->idx = -1;
>  	buf->port = port;
>  	buf->flags = SAA7164_BUFFER_FREE;
> +	buf->pos = 0;
> +	buf->actual_size = params->pitch * params->numberoflines;
> +	buf->crc = 0;
>  	/* TODO: arg len is being ignored */
>  	buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
>  	buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
> @@ -105,19 +130,23 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
>  		goto fail2;
>  
>  	/* init the buffers to a known pattern, easier during debugging */
> -	memset(buf->cpu, 0xff, buf->pci_size);
> -	memset(buf->pt_cpu, 0xff, buf->pt_size);
> +	memset_io(buf->cpu, 0xff, buf->pci_size);
> +	buf->crc = crc32(0, buf->cpu, buf->actual_size);
> +	memset_io(buf->pt_cpu, 0xff, buf->pt_size);
>  
> -	dprintk(DBGLVL_BUF, "%s()   allocated buffer @ 0x%p\n", __func__, buf);
> +	dprintk(DBGLVL_BUF, "%s()   allocated buffer @ 0x%p (%d pageptrs)\n",
> +		__func__, buf, params->numpagetables);
>  	dprintk(DBGLVL_BUF, "  pci_cpu @ 0x%p    dma @ 0x%08lx len = 0x%x\n",
>  		buf->cpu, (long)buf->dma, buf->pci_size);
>  	dprintk(DBGLVL_BUF, "   pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
>  		buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
>  
>  	/* Format the Page Table Entries to point into the data buffer */
> -	for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
> +	for (i = 0 ; i < params->numpagetables; i++) {
>  
>  		*(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
> +		dprintk(DBGLVL_BUF, "    pt[%02d] = 0x%p -> 0x%llx\n",
> +			i, buf->pt_cpu, (u64)*(buf->pt_cpu));
>  
>  	}
>  
> @@ -133,25 +162,162 @@ ret:
>  	return buf;
>  }
>  
> -int saa7164_buffer_dealloc(struct saa7164_tsport *port,
> -	struct saa7164_buffer *buf)
> +int saa7164_buffer_dealloc(struct saa7164_buffer *buf)
>  {
> -	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_dev *dev = buf->port->dev;
>  
> -	if ((buf == 0) || (port == 0))
> +	if (buf == 0)
>  		return SAA_ERR_BAD_PARAMETER;
>  
> -	dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
> +	dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n",
> +		__func__, buf);
>  
>  	if (buf->flags != SAA7164_BUFFER_FREE)
>  		log_warn(" freeing a non-free buffer\n");
>  
> -	pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
> -	pci_free_consistent(port->dev->pci, buf->pt_size, buf->pt_cpu,
> -		buf->pt_dma);
> +	pci_free_consistent(dev->pci, buf->pci_size, buf->cpu, buf->dma);
> +	pci_free_consistent(dev->pci, buf->pt_size, buf->pt_cpu, buf->pt_dma);
>  
>  	kfree(buf);
>  
>  	return SAA_OK;
>  }
>  
> +int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +
> +	if ((i < 0) || (i >= port->hwcfg.buffercount))
> +		return -EINVAL;
> +
> +	dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
> +
> +	saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
> +
> +	return 0;
> +}
> +
> +/* Write a buffer into the hardware */
> +int saa7164_buffer_activate(struct saa7164_buffer *buf, int i)
> +{
> +	struct saa7164_port *port = buf->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	if ((i < 0) || (i >= port->hwcfg.buffercount))
> +		return -EINVAL;
> +
> +	dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
> +
> +	buf->idx = i; /* Note of which buffer list index position we occupy */
> +	buf->flags = SAA7164_BUFFER_BUSY;
> +	buf->pos = 0;
> +
> +	/* TODO: Review this in light of 32v64 assignments */
> +	saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
> +	saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma);
> +	saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
> +
> +	dprintk(DBGLVL_BUF, "   buf[%d] offset 0x%llx (0x%x) "
> +		"buf 0x%llx/%llx (0x%x/%x) nr=%d\n",
> +		buf->idx,
> +		(u64)port->bufoffset + (i * sizeof(u32)),
> +		saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
> +		(u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
> +		(u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
> +		saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) * 2)),
> +		saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) * 2)),
> +		buf->idx);
> +
> +	return 0;
> +}
> +
> +int saa7164_buffer_cfg_port(struct saa7164_port *port)
> +{
> +	tmHWStreamParameters_t *params = &port->hw_streamingparams;
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_buffer *buf;
> +	struct list_head *c, *n;
> +	int i = 0;
> +
> +	dprintk(DBGLVL_BUF, "%s(port=%d)\n", __func__, port->nr);
> +
> +	saa7164_writel(port->bufcounter, 0);
> +	saa7164_writel(port->pitch, params->pitch);
> +	saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
> +
> +	dprintk(DBGLVL_BUF, " configured:\n");
> +	dprintk(DBGLVL_BUF, "   lmmio       0x%p\n", dev->lmmio);
> +	dprintk(DBGLVL_BUF, "   bufcounter  0x%x = 0x%x\n", port->bufcounter,
> +		saa7164_readl(port->bufcounter));
> +
> +	dprintk(DBGLVL_BUF, "   pitch       0x%x = %d\n", port->pitch,
> +		saa7164_readl(port->pitch));
> +
> +	dprintk(DBGLVL_BUF, "   bufsize     0x%x = %d\n", port->bufsize,
> +		saa7164_readl(port->bufsize));
> +
> +	dprintk(DBGLVL_BUF, "   buffercount = %d\n", port->hwcfg.buffercount);
> +	dprintk(DBGLVL_BUF, "   bufoffset = 0x%x\n", port->bufoffset);
> +	dprintk(DBGLVL_BUF, "   bufptr32h = 0x%x\n", port->bufptr32h);
> +	dprintk(DBGLVL_BUF, "   bufptr32l = 0x%x\n", port->bufptr32l);
> +
> +	/* Poke the buffers and offsets into PCI space */
> +	mutex_lock(&port->dmaqueue_lock);
> +	list_for_each_safe(c, n, &port->dmaqueue.list) {
> +		buf = list_entry(c, struct saa7164_buffer, list);
> +
> +		if (buf->flags != SAA7164_BUFFER_FREE)
> +			BUG();
> +
> +		/* Place the buffer in the h/w queue */
> +		saa7164_buffer_activate(buf, i);
> +
> +		/* Don't exceed the device maximum # bufs */
> +		if (i++ > port->hwcfg.buffercount)
> +			BUG();
> +
> +	}
> +	mutex_unlock(&port->dmaqueue_lock);
> +
> +	return 0;
> +}
> +
> +struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, u32 len)
> +{
> +	struct saa7164_user_buffer *buf;
> +
> +	buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL);
> +	if (buf == 0)
> +		return 0;
> +
> +	buf->data = kzalloc(len, GFP_KERNEL);
> +
> +	if (buf->data == 0) {

This is a small issue: don't use 0 to mean NULL. You should use
	if (!buf->data)
		or
	if (buf->data == NULL)

> +		kfree(buf);
> +		return 0;
> +	}
> +
> +	buf->actual_size = len;
> +	buf->pos = 0;
> +	buf->crc = 0;
> +
> +	dprintk(DBGLVL_BUF, "%s()   allocated user buffer @ 0x%p\n",
> +		__func__, buf);
> +
> +	return buf;
> +}
> +
> +void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
> +{
> +	if (!buf)
> +		return;
> +
> +	if (buf->data) {
> +		kfree(buf->data);
> +		buf->data = 0;
> +	}
> +
> +	if (buf)
> +		kfree(buf);

kfree(NULL) is valid.

> +}
> +
> diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
> index 83a0464..78ccf1a 100644
> --- a/drivers/media/video/saa7164/saa7164-bus.c
> +++ b/drivers/media/video/saa7164/saa7164-bus.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -43,17 +43,11 @@ int saa7164_bus_setup(struct saa7164_dev *dev)
>  
>  	b->m_dwSizeGetRing	= SAA_DEVICE_BUFFERBLOCKSIZE;
>  
> -	b->m_pdwSetWritePos	= (u32 *)((u8 *)(dev->bmmio +
> -		((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64))));
> +	b->m_dwSetWritePos	= ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64));
> +	b->m_dwSetReadPos	= b->m_dwSetWritePos + (1 * sizeof(u32));
>  
> -	b->m_pdwSetReadPos	= (u32 *)((u8 *)b->m_pdwSetWritePos +
> -		1 * sizeof(u32));
> -
> -	b->m_pdwGetWritePos	= (u32 *)((u8 *)b->m_pdwSetWritePos +
> -		2 * sizeof(u32));
> -
> -	b->m_pdwGetReadPos	= (u32 *)((u8 *)b->m_pdwSetWritePos +
> -		3 * sizeof(u32));
> +	b->m_dwGetWritePos	= b->m_dwSetWritePos + (2 * sizeof(u32));
> +	b->m_dwGetReadPos	= b->m_dwSetWritePos + (3 * sizeof(u32));
>  
>  	return 0;
>  }
> @@ -71,17 +65,44 @@ void saa7164_bus_dump(struct saa7164_dev *dev)
>  	dprintk(DBGLVL_BUS, " .m_pdwGetRing     = 0x%p\n", b->m_pdwGetRing);
>  	dprintk(DBGLVL_BUS, " .m_dwSizeGetRing  = 0x%x\n", b->m_dwSizeGetRing);
>  
> -	dprintk(DBGLVL_BUS, " .m_pdwSetWritePos = 0x%p (0x%08x)\n",
> -		b->m_pdwSetWritePos, *b->m_pdwSetWritePos);
> +	dprintk(DBGLVL_BUS, " .m_dwSetReadPos   = 0x%x (0x%08x)\n",
> +		b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
>  
> -	dprintk(DBGLVL_BUS, " .m_pdwSetReadPos  = 0x%p (0x%08x)\n",
> -		b->m_pdwSetReadPos, *b->m_pdwSetReadPos);
> +	dprintk(DBGLVL_BUS, " .m_dwSetWritePos  = 0x%x (0x%08x)\n",
> +		b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
>  
> -	dprintk(DBGLVL_BUS, " .m_pdwGetWritePos = 0x%p (0x%08x)\n",
> -		b->m_pdwGetWritePos, *b->m_pdwGetWritePos);
> +	dprintk(DBGLVL_BUS, " .m_dwGetReadPos   = 0x%x (0x%08x)\n",
> +		b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
>  
> -	dprintk(DBGLVL_BUS, " .m_pdwGetReadPos  = 0x%p (0x%08x)\n",
> -		b->m_pdwGetReadPos, *b->m_pdwGetReadPos);
> +	dprintk(DBGLVL_BUS, " .m_dwGetWritePos  = 0x%x (0x%08x)\n",
> +		b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
> +
> +}
> +
> +/* Intensionally throw a BUG() if the state of the message bus looks corrupt */
> +void saa7164_bus_verify(struct saa7164_dev *dev)
> +{
> +	tmComResBusInfo_t *b = &dev->bus;
> +	int bug = 0;
> +
> +	if (saa7164_readl(b->m_dwSetReadPos) > b->m_dwSizeSetRing)
> +		bug++;
> +
> +	if (saa7164_readl(b->m_dwSetWritePos) > b->m_dwSizeSetRing)
> +		bug++;
> +
> +	if (saa7164_readl(b->m_dwGetReadPos) > b->m_dwSizeGetRing)
> +		bug++;
> +
> +	if (saa7164_readl(b->m_dwGetWritePos) > b->m_dwSizeGetRing)
> +		bug++;
> +
> +	if (bug) {
> +		saa_debug = 0xffff; /* Ensure we get the bus dump */
> +		saa7164_bus_dump(dev);
> +		saa_debug = 1024; /* Ensure we get the bus dump */
> +		BUG();
> +	}
>  }

Hmm... this doesn't seem wise. Wouldn't be better to stop IRQ and streaming in this
case, instead of OOP'sing?

>  
>  void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf)
> @@ -111,7 +132,7 @@ void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf)
>  int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
>  {
>  	tmComResBusInfo_t *bus = &dev->bus;
> -	u32 bytes_to_write, read_distance, timeout, curr_srp, curr_swp;
> +	u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp;
>  	u32 new_swp, space_rem;
>  	int ret = SAA_ERR_BAD_PARAMETER;
>  
> @@ -122,6 +143,8 @@ int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
>  
>  	dprintk(DBGLVL_BUS, "%s()\n", __func__);
>  
> +	saa7164_bus_verify(dev);
> +
>  	msg->size = cpu_to_le16(msg->size);
>  	msg->command = cpu_to_le16(msg->command);
>  	msg->controlselector = cpu_to_le16(msg->controlselector);
> @@ -141,30 +164,30 @@ int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
>  	mutex_lock(&bus->lock);
>  
>  	bytes_to_write = sizeof(*msg) + msg->size;
> -	read_distance = 0;
> +	free_write_space = 0;
>  	timeout = SAA_BUS_TIMEOUT;
> -	curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
> -	curr_swp = le32_to_cpu(*bus->m_pdwSetWritePos);
> +	curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos));
> +	curr_swp = le32_to_cpu(saa7164_readl(bus->m_dwSetWritePos));
>  
>  	/* Deal with ring wrapping issues */
>  	if (curr_srp > curr_swp)
> -		/* The ring has not wrapped yet */
> -		read_distance = curr_srp - curr_swp;
> -	else
>  		/* Deal with the wrapped ring */
> -		read_distance = (curr_srp + bus->m_dwSizeSetRing) - curr_swp;
> +		free_write_space = curr_srp - curr_swp;
> +	else
> +		/* The ring has not wrapped yet */
> +		free_write_space = (curr_srp + bus->m_dwSizeSetRing) - curr_swp;
>  
>  	dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__,
>  		bytes_to_write);
>  
> -	dprintk(DBGLVL_BUS, "%s() read_distance = %d\n", __func__,
> -		read_distance);
> +	dprintk(DBGLVL_BUS, "%s() free_write_space = %d\n", __func__,
> +		free_write_space);
>  
>  	dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp);
>  	dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp);
>  
>  	/* Process the msg and write the content onto the bus */
> -	while (bytes_to_write >= read_distance) {
> +	while (bytes_to_write >= free_write_space) {
>  
>  		if (timeout-- == 0) {
>  			printk(KERN_ERR "%s() bus timeout\n", __func__);
> @@ -177,15 +200,15 @@ int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
>  		mdelay(1);
>  
>  		/* Check the space usage again */
> -		curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
> +		curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos));
>  
>  		/* Deal with ring wrapping issues */
>  		if (curr_srp > curr_swp)
> -			/* Read didn't wrap around the buffer */
> -			read_distance = curr_srp - curr_swp;
> -		else
>  			/* Deal with the wrapped ring */
> -			read_distance = (curr_srp + bus->m_dwSizeSetRing) -
> +			free_write_space = curr_srp - curr_swp;
> +		else
> +			/* Read didn't wrap around the buffer */
> +			free_write_space = (curr_srp + bus->m_dwSizeSetRing) -
>  				curr_swp;
>  
>  	}
> @@ -257,16 +280,14 @@ int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
>  
>  	dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
>  
> -	/* TODO: Convert all of the direct PCI writes into
> -	 * saa7164_writel/b calls for consistency.
> -	 */
> -
>  	/* Update the bus write position */
> -	*bus->m_pdwSetWritePos = cpu_to_le32(new_swp);
> +	saa7164_writel(bus->m_dwSetWritePos, cpu_to_le32(new_swp));
>  	ret = SAA_OK;
>  
>  out:
> +	saa7164_bus_dump(dev);
>  	mutex_unlock(&bus->lock);
> +	saa7164_bus_verify(dev);
>  	return ret;
>  }
>  
> @@ -288,6 +309,8 @@ int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf,
>  	tmComResInfo_t msg_tmp;
>  	int ret = SAA_ERR_BAD_PARAMETER;
>  
> +	saa7164_bus_verify(dev);
> +
>  	if (msg == 0)
>  		return ret;
>  
> @@ -309,11 +332,10 @@ int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf,
>  	/* Peek the bus to see if a msg exists, if it's not what we're expecting
>  	 * then return cleanly else read the message from the bus.
>  	 */
> -	curr_gwp = le32_to_cpu(*bus->m_pdwGetWritePos);
> -	curr_grp = le32_to_cpu(*bus->m_pdwGetReadPos);
> +	curr_gwp = le32_to_cpu(saa7164_readl(bus->m_dwGetWritePos));
> +	curr_grp = le32_to_cpu(saa7164_readl(bus->m_dwGetReadPos));
>  
>  	if (curr_gwp == curr_grp) {
> -		dprintk(DBGLVL_BUS, "%s() No message on the bus\n", __func__);
>  		ret = SAA_ERR_EMPTY;
>  		goto out;
>  	}
> @@ -434,7 +456,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf,
>  	}
>  
>  	/* Update the read positions, adjusting the ring */
> -	*bus->m_pdwGetReadPos = cpu_to_le32(new_grp);
> +	saa7164_writel(bus->m_dwGetReadPos, cpu_to_le32(new_grp));
>  
>  peekout:
>  	msg->size = le16_to_cpu(msg->size);
> @@ -443,6 +465,7 @@ peekout:
>  	ret = SAA_OK;
>  out:
>  	mutex_unlock(&bus->lock);
> +	saa7164_bus_verify(dev);
>  	return ret;
>  }
>  
> diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c
> index a3c2994..4cb634e 100644
> --- a/drivers/media/video/saa7164/saa7164-cards.c
> +++ b/drivers/media/video/saa7164/saa7164-cards.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -55,6 +55,10 @@ struct saa7164_board saa7164_boards[] = {
>  		.name		= "Hauppauge WinTV-HVR2200",
>  		.porta		= SAA7164_MPEG_DVB,
>  		.portb		= SAA7164_MPEG_DVB,
> +		.portc		= SAA7164_MPEG_ENCODER,
> +		.portd		= SAA7164_MPEG_ENCODER,
> +		.porte		= SAA7164_MPEG_VBI,
> +		.portf		= SAA7164_MPEG_VBI,
>  		.chiprev	= SAA7164_CHIP_REV3,
>  		.unit		= {{
>  			.id		= 0x1d,
> @@ -97,6 +101,10 @@ struct saa7164_board saa7164_boards[] = {
>  		.name		= "Hauppauge WinTV-HVR2200",
>  		.porta		= SAA7164_MPEG_DVB,
>  		.portb		= SAA7164_MPEG_DVB,
> +		.portc		= SAA7164_MPEG_ENCODER,
> +		.portd		= SAA7164_MPEG_ENCODER,
> +		.porte		= SAA7164_MPEG_VBI,
> +		.portf		= SAA7164_MPEG_VBI,
>  		.chiprev	= SAA7164_CHIP_REV2,
>  		.unit		= {{
>  			.id		= 0x06,
> @@ -139,6 +147,10 @@ struct saa7164_board saa7164_boards[] = {
>  		.name		= "Hauppauge WinTV-HVR2200",
>  		.porta		= SAA7164_MPEG_DVB,
>  		.portb		= SAA7164_MPEG_DVB,
> +		.portc		= SAA7164_MPEG_ENCODER,
> +		.portd		= SAA7164_MPEG_ENCODER,
> +		.porte		= SAA7164_MPEG_VBI,
> +		.portf		= SAA7164_MPEG_VBI,
>  		.chiprev	= SAA7164_CHIP_REV2,
>  		.unit		= {{
>  			.id		= 0x1d,
> @@ -195,6 +207,12 @@ struct saa7164_board saa7164_boards[] = {
>  		.name		= "Hauppauge WinTV-HVR2250",
>  		.porta		= SAA7164_MPEG_DVB,
>  		.portb		= SAA7164_MPEG_DVB,
> +		.portc		= SAA7164_MPEG_ENCODER,
> +		.portd		= SAA7164_MPEG_ENCODER,
> +		.portc		= SAA7164_MPEG_ENCODER,
> +		.portd		= SAA7164_MPEG_ENCODER,
> +		.porte		= SAA7164_MPEG_VBI,
> +		.portf		= SAA7164_MPEG_VBI,
>  		.chiprev	= SAA7164_CHIP_REV3,
>  		.unit		= {{
>  			.id		= 0x22,
> @@ -251,6 +269,12 @@ struct saa7164_board saa7164_boards[] = {
>  		.name		= "Hauppauge WinTV-HVR2250",
>  		.porta		= SAA7164_MPEG_DVB,
>  		.portb		= SAA7164_MPEG_DVB,
> +		.portc		= SAA7164_MPEG_ENCODER,
> +		.portd		= SAA7164_MPEG_ENCODER,
> +		.porte		= SAA7164_MPEG_VBI,
> +		.portf		= SAA7164_MPEG_VBI,
> +		.porte		= SAA7164_MPEG_VBI,
> +		.portf		= SAA7164_MPEG_VBI,
>  		.chiprev	= SAA7164_CHIP_REV3,
>  		.unit		= {{
>  			.id		= 0x28,
> @@ -307,6 +331,10 @@ struct saa7164_board saa7164_boards[] = {
>  		.name		= "Hauppauge WinTV-HVR2250",
>  		.porta		= SAA7164_MPEG_DVB,
>  		.portb		= SAA7164_MPEG_DVB,
> +		.portc		= SAA7164_MPEG_ENCODER,
> +		.portd		= SAA7164_MPEG_ENCODER,
> +		.porte		= SAA7164_MPEG_VBI,
> +		.portf		= SAA7164_MPEG_VBI,
>  		.chiprev	= SAA7164_CHIP_REV3,
>  		.unit		= {{
>  			.id		= 0x26,
> @@ -437,8 +465,6 @@ void saa7164_card_list(struct saa7164_dev *dev)
>  
>  void saa7164_gpio_setup(struct saa7164_dev *dev)
>  {
> -
> -
>  	switch (dev->board) {
>  	case SAA7164_BOARD_HAUPPAUGE_HVR2200:
>  	case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
> @@ -462,7 +488,6 @@ void saa7164_gpio_setup(struct saa7164_dev *dev)
>  		saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
>  		break;
>  	}
> -
>  }
>  
>  static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
> diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
> index 9c1d3ac..e4ec44f 100644
> --- a/drivers/media/video/saa7164/saa7164-cmd.c
> +++ b/drivers/media/video/saa7164/saa7164-cmd.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -82,9 +82,10 @@ u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
>   * -bus/c running buffer. */
>  int saa7164_irq_dequeue(struct saa7164_dev *dev)
>  {
> -	int ret = SAA_OK;
> +	int ret = SAA_OK, i = 0;
>  	u32 timeout;
>  	wait_queue_head_t *q = 0;
> +	u8 tmp[512];
>  	dprintk(DBGLVL_CMD, "%s()\n", __func__);
>  
>  	/* While any outstand message on the bus exists... */
> @@ -109,8 +110,22 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev)
>  			printk(KERN_ERR
>  				"%s() found timed out command on the bus\n",
>  					__func__);
> +
> +			/* Clean the bus */
> +			ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
> +			printk(KERN_ERR "%s() ret = %x\n", __func__, ret);
> +			if (ret == SAA_ERR_EMPTY)
> +				/* Someone else already fetched the response */
> +				return SAA_OK;
> +
> +			if (ret != SAA_OK)
> +				return ret;
>  		}
> -	} while (0);
> +
> +		/* It's unlikely to have more than 4 or 5 pending messages, ensure we exit
> +		 * at some point regardles.
> +		 */
> +	} while (i++ < 32);
>  
>  	return ret;
>  }
> diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
> index e6aa0fb..222fbda 100644
> --- a/drivers/media/video/saa7164/saa7164-core.c
> +++ b/drivers/media/video/saa7164/saa7164-core.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -30,6 +30,9 @@
>  #include <linux/delay.h>
>  #include <asm/div64.h>
>  
> +#ifdef CONFIG_PROC_FS
> +#include <linux/proc_fs.h>
> +#endif
>  #include "saa7164.h"
>  
>  MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
> @@ -49,14 +52,38 @@ unsigned int saa_debug;
>  module_param_named(debug, saa_debug, int, 0644);
>  MODULE_PARM_DESC(debug, "enable debug messages");
>  
> +unsigned int fw_debug = 2;
> +module_param(fw_debug, int, 0644);
> +MODULE_PARM_DESC(fw_debug, "Firware debug level def:2");
> +
> +unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS;
> +module_param(encoder_buffers, int, 0644);
> +MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64");
> +
> +unsigned int vbi_buffers = SAA7164_MAX_VBI_BUFFERS;
> +module_param(vbi_buffers, int, 0644);
> +MODULE_PARM_DESC(vbi_buffers, "Total buffers in read queue 16-512 def:64");
> +
>  unsigned int waitsecs = 10;
>  module_param(waitsecs, int, 0644);
> -MODULE_PARM_DESC(debug, "timeout on firmware messages");
> +MODULE_PARM_DESC(waitsecs, "timeout on firmware messages");
>  
>  static unsigned int card[]  = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
>  module_param_array(card,  int, NULL, 0444);
>  MODULE_PARM_DESC(card, "card type");
>  
> +unsigned int print_histogram = 64;
> +module_param(print_histogram, int, 0644);
> +MODULE_PARM_DESC(print_histogram, "print histogram values once");
> +
> +unsigned int crc_checking = 1;
> +module_param(crc_checking, int, 0644);
> +MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers");
> +
> +unsigned int guard_checking = 1;
> +module_param(guard_checking, int, 0644);
> +MODULE_PARM_DESC(guard_checking, "enable dma sanity checking for buffer overruns");
> +
>  static unsigned int saa7164_devcount;
>  
>  static DEFINE_MUTEX(devlist);
> @@ -64,6 +91,444 @@ LIST_HEAD(saa7164_devlist);
>  
>  #define INT_SIZE 16
>  
> +void saa7164_dumphex16FF(struct saa7164_dev *dev, u8 *buf, int len)
> +{
> +	int i;
> +	u8 tmp[16];
> +	memset(&tmp[0], 0xff, sizeof(tmp));
> +
> +	printk(KERN_INFO "--------------------> "
> +		"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
> +
> +	for (i = 0; i < len; i += 16) {
> +		if (memcmp(&tmp, buf + i, sizeof(tmp)) != 0) {
> +			printk(KERN_INFO "         [0x%08x] "
> +				"%02x %02x %02x %02x %02x %02x %02x %02x "
> +				"%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
> +			*(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
> +			*(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
> +			*(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
> +			*(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
> +		}
> +	}
> +}
> +
> +static void saa7164_pack_verifier(struct saa7164_buffer *buf)
> +{
> +	u8 *p = (u8 *)buf->cpu;
> +	int i;
> +
> +	for (i = 0; i < buf->actual_size; i += 2048) {
> +
> +		if ( (*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) ||
> +			(*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA) ) {
> +			printk(KERN_ERR "No pack at 0x%x\n", i);
> +//			saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
> +		}
> +	}
> +}
> +
> +#define FIXED_VIDEO_PID 0xf1
> +#define FIXED_AUDIO_PID 0xf2
> +
> +static void saa7164_ts_verifier(struct saa7164_buffer *buf)
> +{
> +	struct saa7164_port *port = buf->port;
> +	u32 i;
> +	u8 cc, a;
> +	u16 pid;
> +	u8 __iomem *bufcpu = (u8 *)buf->cpu;
> +
> +	port->sync_errors = 0;
> +	port->v_cc_errors = 0;
> +	port->a_cc_errors = 0;
> +
> +	for (i = 0; i < buf->actual_size; i += 188) {
> +		if (*(bufcpu + i) != 0x47)
> +			port->sync_errors++;
> +
> +		/* TODO: Query pid lower 8 bits, ignoring upper bits intensionally */
> +		pid = ((*(bufcpu + i + 1) & 0x1f) << 8) | *(bufcpu + i + 2);
> +		cc = *(bufcpu + i + 3) & 0x0f;
> +
> +		if (pid == FIXED_VIDEO_PID) {
> +			a = ((port->last_v_cc + 1) & 0x0f);
> +			if (a != cc) {
> +				printk(KERN_ERR "video cc last = %x current = %x i = %d\n",
> +					port->last_v_cc, cc, i);
> +				port->v_cc_errors++;
> +			}
> +
> +			port->last_v_cc = cc;
> +		} else
> +		if (pid == FIXED_AUDIO_PID) {
> +			a = ((port->last_a_cc + 1) & 0x0f);
> +			if (a != cc) {
> +				printk(KERN_ERR "audio cc last = %x current = %x i = %d\n",
> +					port->last_a_cc, cc, i);
> +				port->a_cc_errors++;
> +			}
> +
> +			port->last_a_cc = cc;
> +		}
> +
> +	}
> +
> +	/* Only report errors if we've been through this function atleast
> +	 * once already and the cached cc values are primed. First time through
> +	 * always generates errors.
> +	 */
> +	if (port->v_cc_errors && (port->done_first_interrupt > 1))
> +		printk(KERN_ERR "video pid cc, %d errors\n", port->v_cc_errors);
> +
> +	if (port->a_cc_errors && (port->done_first_interrupt > 1))
> +		printk(KERN_ERR "audio pid cc, %d errors\n", port->a_cc_errors);
> +
> +	if (port->sync_errors && (port->done_first_interrupt > 1))
> +		printk(KERN_ERR "sync_errors = %d\n", port->sync_errors);
> +
> +	if (port->done_first_interrupt == 1)
> +		port->done_first_interrupt++;
> +}
> +
> +static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name)
> +{
> +	int i;
> +
> +	memset(hg, 0, sizeof(struct saa7164_histogram));
> +	strcpy(hg->name, name);
> +
> +	/* First 30ms x 1ms */
> +	for (i = 0; i < 30; i++) {
> +		hg->counter1[0 + i].val = i;
> +	}
> +
> +	/* 30 - 200ms x 10ms  */
> +	for (i = 0; i < 18; i++) {
> +		hg->counter1[30 + i].val = 30 + (i * 10);
> +	}
> +
> +	/* 200 - 2000ms x 100ms  */
> +	for (i = 0; i < 15; i++) {
> +		hg->counter1[48 + i].val = 200 + (i * 200);
> +	}
> +
> +	/* Catch all massive value (2secs) */
> +	hg->counter1[55].val = 2000;
> +
> +	/* Catch all massive value (4secs) */
> +	hg->counter1[56].val = 4000;
> +
> +	/* Catch all massive value (8secs) */
> +	hg->counter1[57].val = 8000;
> +
> +	/* Catch all massive value (15secs) */
> +	hg->counter1[58].val = 15000;
> +
> +	/* Catch all massive value (30secs) */
> +	hg->counter1[59].val = 30000;
> +
> +	/* Catch all massive value (60secs) */
> +	hg->counter1[60].val = 60000;
> +
> +	/* Catch all massive value (5mins) */
> +	hg->counter1[61].val = 300000;
> +
> +	/* Catch all massive value (15mins) */
> +	hg->counter1[62].val = 900000;
> +
> +	/* Catch all massive values (1hr) */
> +	hg->counter1[63].val = 3600000;
> +}
> +
> +void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val)
> +{
> +	int i;
> +	for (i = 0; i < 64; i++ ) {
> +		if (val <= hg->counter1[i].val) {
> +			hg->counter1[i].count++;
> +			hg->counter1[i].update_time = jiffies;
> +			break;
> +		}
> +	}
> +}
> +
> +static void saa7164_histogram_print(struct saa7164_port *port,
> +	struct saa7164_histogram *hg)
> +{
> +	u32 entries = 0;
> +	int i;
> +
> +	printk(KERN_ERR "Histogram named %s (ms, count, last_update_jiffy)\n", hg->name);
> +	for (i = 0; i < 64; i++ ) {
> +		if (hg->counter1[i].count == 0)
> +			continue;
> +
> +		printk(KERN_ERR " %4d %12d %Ld\n",
> +			hg->counter1[i].val,
> +			hg->counter1[i].count,
> +			hg->counter1[i].update_time);
> +
> +		entries++;
> +	}
> +	printk(KERN_ERR "Total: %d\n", entries);
> +}
> +
> +static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_buffer *buf = 0;
> +	struct saa7164_user_buffer *ubuf = 0;
> +	struct list_head *c, *n;
> +	int i = 0;
> +	u8 __iomem *p;
> +
> +	mutex_lock(&port->dmaqueue_lock);
> +	list_for_each_safe(c, n, &port->dmaqueue.list) {
> +
> +		buf = list_entry(c, struct saa7164_buffer, list);
> +		if (i++ > port->hwcfg.buffercount) {
> +			printk(KERN_ERR "%s() illegal i count %d\n",
> +				__func__, i);
> +			break;
> +		}
> +
> +		if (buf->idx == bufnr) {
> +
> +			/* Found the buffer, deal with it */
> +			dprintk(DBGLVL_IRQ, "%s() bufnr: %d\n", __func__, bufnr);
> +
> +			if (crc_checking) {
> +				/* Throw a new checksum on the dma buffer */
> +				buf->crc = crc32(0, buf->cpu, buf->actual_size);
> +			}
> +
> +			if (guard_checking) {
> +				p = (u8 *)buf->cpu;
> +				if ( (*(p + buf->actual_size + 0) != 0xff) ||
> +					(*(p + buf->actual_size + 1) != 0xff) ||
> +					(*(p + buf->actual_size + 2) != 0xff) ||
> +					(*(p + buf->actual_size + 3) != 0xff) ||
> +					(*(p + buf->actual_size + 0x10) != 0xff) ||
> +					(*(p + buf->actual_size + 0x11) != 0xff) ||
> +					(*(p + buf->actual_size + 0x12) != 0xff) ||
> +					(*(p + buf->actual_size + 0x13) != 0xff) ) {
> +						printk(KERN_ERR "%s() buf %p guard buffer breach\n",
> +							__func__, buf);
> +//						saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
> +				}
> +			}
> +
> +			if ((port->nr != SAA7164_PORT_VBI1) && (port->nr != SAA7164_PORT_VBI2)) {
> +				/* Validate the incoming buffer content */
> +				if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
> +					saa7164_ts_verifier(buf);
> +				else if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)
> +					saa7164_pack_verifier(buf);
> +			}
> +
> +			/* find a free user buffer and clone to it */
> +			if (!list_empty(&port->list_buf_free.list)) {
> +
> +				/* Pull the first buffer from the used list */
> +				ubuf = list_first_entry(&port->list_buf_free.list,
> +					struct saa7164_user_buffer, list);
> +
> +				if (buf->actual_size <= ubuf->actual_size) {
> +
> +					memcpy_fromio(ubuf->data, buf->cpu,
> +						ubuf->actual_size);
> +
> +					if (crc_checking) {
> +						/* Throw a new checksum on the read buffer */
> +						ubuf->crc = crc32(0, ubuf->data, ubuf->actual_size);
> +					}
> +
> +					/* Requeue the buffer on the free list */
> +					ubuf->pos = 0;
> +
> +					list_move_tail(&ubuf->list,
> +						&port->list_buf_used.list);
> +
> +					/* Flag any userland waiters */
> +					wake_up_interruptible(&port->wait_read);
> +
> +				} else {
> +					printk(KERN_ERR "buf %p bufsize fails match\n", buf);
> +				}
> +
> +			} else
> +				printk(KERN_ERR "encirq no free buffers, increase param encoder_buffers\n");
> +
> +			/* Ensure offset into buffer remains 0, fill buffer
> +			 * with known bad data. We check for this data at a later point
> +			 * in time. */
> +			saa7164_buffer_zero_offsets(port, bufnr);
> +			memset_io(buf->cpu, 0xff, buf->pci_size);
> +			if (crc_checking) {
> +				/* Throw yet aanother new checksum on the dma buffer */
> +				buf->crc = crc32(0, buf->cpu, buf->actual_size);
> +			}
> +
> +			break;
> +		}
> +	}
> +	mutex_unlock(&port->dmaqueue_lock);
> +}
> +
> +static void saa7164_work_enchandler(struct work_struct *w)
> +{
> +	struct saa7164_port *port =
> +		container_of(w, struct saa7164_port, workenc);
> +	struct saa7164_dev *dev = port->dev;
> +
> +	u32 wp, mcb, rp, cnt = 0;
> +
> +	port->last_svc_msecs_diff = port->last_svc_msecs;
> +	port->last_svc_msecs = jiffies_to_msecs(jiffies);
> +
> +	port->last_svc_msecs_diff = port->last_svc_msecs -
> +		port->last_svc_msecs_diff;
> +
> +	saa7164_histogram_update(&port->svc_interval,
> +		port->last_svc_msecs_diff);
> +
> +	port->last_irq_svc_msecs_diff = port->last_svc_msecs -
> +		port->last_irq_msecs;
> +
> +	saa7164_histogram_update(&port->irq_svc_interval,
> +		port->last_irq_svc_msecs_diff);
> +
> +	dprintk(DBGLVL_IRQ,
> +		"%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
> +		__func__,
> +		port->last_svc_msecs_diff,
> +		port->last_irq_svc_msecs_diff,
> +		port->last_svc_wp,
> +		port->last_svc_rp
> +		);
> +
> +	/* Current write position */
> +	wp = saa7164_readl(port->bufcounter);
> +	if (wp > (port->hwcfg.buffercount - 1)) {
> +		printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
> +		return;
> +	}
> +
> +	/* Most current complete buffer */
> +	if (wp == 0)
> +		mcb = (port->hwcfg.buffercount - 1);
> +	else
> +		mcb = wp - 1;
> +
> +	while (1) {
> +		if (port->done_first_interrupt == 0) {
> +			port->done_first_interrupt++;
> +			rp = mcb;
> +		} else
> +			rp = (port->last_svc_rp + 1) % 8;
> +
> +		if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
> +			printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
> +			break;
> +		}
> +
> +		saa7164_work_enchandler_helper(port, rp);
> +		port->last_svc_rp = rp;
> +		cnt++;
> +
> +		if (rp == mcb)
> +			break;
> +	}
> +
> +	/* TODO: Convert this into a /proc/saa7164 style readable file */
> +	if (print_histogram == port->nr) {
> +		saa7164_histogram_print(port, &port->irq_interval);
> +		saa7164_histogram_print(port, &port->svc_interval);
> +		saa7164_histogram_print(port, &port->irq_svc_interval);
> +		saa7164_histogram_print(port, &port->read_interval);
> +		saa7164_histogram_print(port, &port->poll_interval);
> +		/* TODO: fix this to preserve any previous state */
> +		print_histogram = 64 + port->nr;
> +	}
> +}
> +
> +static void saa7164_work_vbihandler(struct work_struct *w)
> +{
> +	struct saa7164_port *port =
> +		container_of(w, struct saa7164_port, workenc);
> +	struct saa7164_dev *dev = port->dev;
> +
> +	u32 wp, mcb, rp, cnt = 0;
> +
> +	port->last_svc_msecs_diff = port->last_svc_msecs;
> +	port->last_svc_msecs = jiffies_to_msecs(jiffies);
> +	port->last_svc_msecs_diff = port->last_svc_msecs -
> +		port->last_svc_msecs_diff;
> +
> +	saa7164_histogram_update(&port->svc_interval,
> +		port->last_svc_msecs_diff);
> +
> +	port->last_irq_svc_msecs_diff = port->last_svc_msecs -
> +		port->last_irq_msecs;
> +
> +	saa7164_histogram_update(&port->irq_svc_interval,
> +		port->last_irq_svc_msecs_diff);
> +
> +	dprintk(DBGLVL_IRQ,
> +		"%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",
> +		__func__,
> +		port->last_svc_msecs_diff,
> +		port->last_irq_svc_msecs_diff,
> +		port->last_svc_wp,
> +		port->last_svc_rp
> +		);
> +
> +	/* Current write position */
> +	wp = saa7164_readl(port->bufcounter);
> +	if (wp > (port->hwcfg.buffercount - 1)) {
> +		printk(KERN_ERR "%s() illegal buf count %d\n", __func__, wp);
> +		return;
> +	}
> +
> +	/* Most current complete buffer */
> +	if (wp == 0)
> +		mcb = (port->hwcfg.buffercount - 1);
> +	else
> +		mcb = wp - 1;
> +
> +	while (1) {
> +		if (port->done_first_interrupt == 0) {
> +			port->done_first_interrupt++;
> +			rp = mcb;
> +		} else
> +			rp = (port->last_svc_rp + 1) % 8;
> +
> +		if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
> +			printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
> +			break;
> +		}
> +
> +		saa7164_work_enchandler_helper(port, rp);
> +		port->last_svc_rp = rp;
> +		cnt++;
> +
> +		if (rp == mcb)
> +			break;
> +	}
> +
> +	/* TODO: Convert this into a /proc/saa7164 style readable file */
> +	if (print_histogram == port->nr) {
> +		saa7164_histogram_print(port, &port->irq_interval);
> +		saa7164_histogram_print(port, &port->svc_interval);
> +		saa7164_histogram_print(port, &port->irq_svc_interval);
> +		saa7164_histogram_print(port, &port->read_interval);
> +		saa7164_histogram_print(port, &port->poll_interval);
> +		/* TODO: fix this to preserve any previous state */
> +		print_histogram = 64 + port->nr;
> +	}
> +}
> +
>  static void saa7164_work_cmdhandler(struct work_struct *w)
>  {
>  	struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
> @@ -74,7 +539,7 @@ static void saa7164_work_cmdhandler(struct work_struct *w)
>  
>  static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
>  {
> -	struct saa7164_tsport *port = buf->port;
> +	struct saa7164_port *port = buf->port;
>  
>  	/* Feed the transport payload into the kernel demux */
>  	dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu,
> @@ -82,7 +547,56 @@ static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
>  
>  }
>  
> -static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
> +static irqreturn_t saa7164_irq_vbi(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +
> +	/* Store old time */
> +	port->last_irq_msecs_diff = port->last_irq_msecs;
> +
> +	/* Collect new stats */
> +	port->last_irq_msecs = jiffies_to_msecs(jiffies);
> +
> +	/* Calculate stats */
> +	port->last_irq_msecs_diff = port->last_irq_msecs -
> +		port->last_irq_msecs_diff;
> +
> +	saa7164_histogram_update(&port->irq_interval,
> +		port->last_irq_msecs_diff);
> +
> +	dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,
> +		port->last_irq_msecs_diff);
> +
> +	/* Tis calls the vbi irq handler */
> +	schedule_work(&port->workenc);
> +	return 0;
> +}
> +
> +static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +
> +	/* Store old time */
> +	port->last_irq_msecs_diff = port->last_irq_msecs;
> +
> +	/* Collect new stats */
> +	port->last_irq_msecs = jiffies_to_msecs(jiffies);
> +
> +	/* Calculate stats */
> +	port->last_irq_msecs_diff = port->last_irq_msecs -
> +		port->last_irq_msecs_diff;
> +
> +	saa7164_histogram_update(&port->irq_interval,
> +		port->last_irq_msecs_diff);
> +
> +	dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,
> +		port->last_irq_msecs_diff);
> +
> +	schedule_work(&port->workenc);
> +	return 0;
> +}
> +
> +static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
>  {
>  	struct saa7164_dev *dev = port->dev;
>  	struct saa7164_buffer *buf;
> @@ -96,7 +610,7 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
>  
>  	/* Find the previous buffer to the current write point */
>  	if (wp == 0)
> -		rp = 7;
> +		rp = (port->hwcfg.buffercount - 1);
>  	else
>  		rp = wp - 1;
>  
> @@ -107,7 +621,7 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
>  		if (i++ > port->hwcfg.buffercount)
>  			BUG();
>  
> -		if (buf->nr == rp) {
> +		if (buf->idx == rp) {
>  			/* Found the buffer, deal with it */
>  			dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
>  				__func__, wp, rp);
> @@ -123,6 +637,13 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
>  static irqreturn_t saa7164_irq(int irq, void *dev_id)
>  {
>  	struct saa7164_dev *dev = dev_id;
> +	struct saa7164_port *porta = &dev->ports[ SAA7164_PORT_TS1 ];
> +	struct saa7164_port *portb = &dev->ports[ SAA7164_PORT_TS2 ];
> +	struct saa7164_port *portc = &dev->ports[ SAA7164_PORT_ENC1 ];
> +	struct saa7164_port *portd = &dev->ports[ SAA7164_PORT_ENC2 ];
> +	struct saa7164_port *porte = &dev->ports[ SAA7164_PORT_VBI1 ];
> +	struct saa7164_port *portf = &dev->ports[ SAA7164_PORT_VBI2 ];
> +
>  	u32 intid, intstat[INT_SIZE/4];
>  	int i, handled = 0, bit;
>  
> @@ -168,17 +689,35 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id)
>  				if (intid == dev->intfdesc.bInterruptId) {
>  					/* A response to an cmd/api call */
>  					schedule_work(&dev->workcmd);
> -				} else if (intid ==
> -					dev->ts1.hwcfg.interruptid) {
> +				} else if (intid == porta->hwcfg.interruptid) {
>  
>  					/* Transport path 1 */
> -					saa7164_irq_ts(&dev->ts1);
> +					saa7164_irq_ts(porta);
>  
> -				} else if (intid ==
> -					dev->ts2.hwcfg.interruptid) {
> +				} else if (intid == portb->hwcfg.interruptid) {
>  
>  					/* Transport path 2 */
> -					saa7164_irq_ts(&dev->ts2);
> +					saa7164_irq_ts(portb);
> +
> +				} else if (intid == portc->hwcfg.interruptid) {
> +
> +					/* Encoder path 1 */
> +					saa7164_irq_encoder(portc);
> +
> +				} else if (intid == portd->hwcfg.interruptid) {
> +
> +					/* Encoder path 2 */
> +					saa7164_irq_encoder(portd);
> +
> +				} else if (intid == porte->hwcfg.interruptid) {
> +
> +					/* VBI path 1 */
> +					saa7164_irq_vbi(porte);
> +
> +				} else if (intid == portf->hwcfg.interruptid) {
> +
> +					/* VBI path 2 */
> +					saa7164_irq_vbi(portf);
>  
>  				} else {
>  					/* Find the function */
> @@ -356,10 +895,10 @@ static void saa7164_dump_busdesc(struct saa7164_dev *dev)
>   */
>  static void saa7164_get_descriptors(struct saa7164_dev *dev)
>  {
> -	memcpy(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t));
> -	memcpy(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t),
> +	memcpy_fromio(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t));
> +	memcpy_fromio(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t),
>  		sizeof(tmComResInterfaceDescr_t));
> -	memcpy(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
> +	memcpy_fromio(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
>  		sizeof(tmComResBusDescr_t));
>  
>  	if (dev->hwdesc.bLength != sizeof(tmComResHWDescr_t)) {
> @@ -402,6 +941,58 @@ static int get_resources(struct saa7164_dev *dev)
>  	return -EBUSY;
>  }
>  
> +static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
> +{
> +	struct saa7164_port *port = 0;
> +
> +	if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS))
> +		BUG();
> +
> +	port = &dev->ports[ portnr ];
> +
> +	port->dev = dev;
> +	port->nr = portnr;
> +
> +	if ((portnr == SAA7164_PORT_TS1) || (portnr == SAA7164_PORT_TS2))
> +		port->type = SAA7164_MPEG_DVB;
> +	else
> +	if ((portnr == SAA7164_PORT_ENC1) || (portnr == SAA7164_PORT_ENC2)) {
> +		port->type = SAA7164_MPEG_ENCODER;
> +
> +		/* We need a deferred interrupt handler for cmd handling */
> +		INIT_WORK(&port->workenc, saa7164_work_enchandler);
> +	}
> +	else
> +	if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) {
> +		port->type = SAA7164_MPEG_VBI;
> +
> +		/* We need a deferred interrupt handler for cmd handling */
> +		INIT_WORK(&port->workenc, saa7164_work_vbihandler);
> +	} else
> +		BUG();
> +
> +	/* Init all the critical resources */
> +	mutex_init(&port->dvb.lock);
> +	INIT_LIST_HEAD(&port->dmaqueue.list);
> +	mutex_init(&port->dmaqueue_lock);
> +
> +	INIT_LIST_HEAD(&port->list_buf_used.list);
> +	INIT_LIST_HEAD(&port->list_buf_free.list);
> +	init_waitqueue_head(&port->wait_read);
> +
> +
> +	saa7164_histogram_reset(&port->irq_interval, "irq intervals");
> +	saa7164_histogram_reset(&port->svc_interval, "deferred intervals");
> +	saa7164_histogram_reset(&port->irq_svc_interval,
> +		"irq to deferred intervals");
> +	saa7164_histogram_reset(&port->read_interval,
> +		"encoder/vbi read() intervals");
> +	saa7164_histogram_reset(&port->poll_interval,
> +		"encoder/vbi poll() intervals");
> +
> +	return 0;
> +}
> +
>  static int saa7164_dev_setup(struct saa7164_dev *dev)
>  {
>  	int i;
> @@ -443,23 +1034,13 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
>  	dev->i2c_bus[2].dev = dev;
>  	dev->i2c_bus[2].nr = 2;
>  
> -	/* Transport port A Defaults / setup */
> -	dev->ts1.dev = dev;
> -	dev->ts1.nr = 0;
> -	mutex_init(&dev->ts1.dvb.lock);
> -	INIT_LIST_HEAD(&dev->ts1.dmaqueue.list);
> -	INIT_LIST_HEAD(&dev->ts1.dummy_dmaqueue.list);
> -	mutex_init(&dev->ts1.dmaqueue_lock);
> -	mutex_init(&dev->ts1.dummy_dmaqueue_lock);
> -
> -	/* Transport port B Defaults / setup */
> -	dev->ts2.dev = dev;
> -	dev->ts2.nr = 1;
> -	mutex_init(&dev->ts2.dvb.lock);
> -	INIT_LIST_HEAD(&dev->ts2.dmaqueue.list);
> -	INIT_LIST_HEAD(&dev->ts2.dummy_dmaqueue.list);
> -	mutex_init(&dev->ts2.dmaqueue_lock);
> -	mutex_init(&dev->ts2.dummy_dmaqueue_lock);
> +	/* Transport + Encoder ports 1, 2, 3, 4 - Defaults / setup */
> +	saa7164_port_init(dev, SAA7164_PORT_TS1);
> +	saa7164_port_init(dev, SAA7164_PORT_TS2);
> +	saa7164_port_init(dev, SAA7164_PORT_ENC1);
> +	saa7164_port_init(dev, SAA7164_PORT_ENC2);
> +	saa7164_port_init(dev, SAA7164_PORT_VBI1);
> +	saa7164_port_init(dev, SAA7164_PORT_VBI2);
>  
>  	if (get_resources(dev) < 0) {
>  		printk(KERN_ERR "CORE %s No more PCIe resources for "
> @@ -516,6 +1097,132 @@ static void saa7164_dev_unregister(struct saa7164_dev *dev)
>  	return;
>  }
>  
> +#ifdef CONFIG_PROC_FS
> +static int saa7164_proc_show(struct seq_file *m, void *v)
> +{
> +	struct saa7164_dev *dev;
> +	tmComResBusInfo_t *b;
> +	struct list_head *list;
> +	int i, c;
> +
> +	if (saa7164_devcount == 0)
> +		return 0;
> +
> +	list_for_each(list, &saa7164_devlist) {
> +		dev = list_entry(list, struct saa7164_dev, devlist);
> +		seq_printf(m, "%s = %p\n", dev->name, dev);
> +
> +		/* Lock the bus from any other access */
> +		b = &dev->bus;
> +		mutex_lock(&b->lock);
> +
> +		seq_printf(m, " .m_pdwSetWritePos = 0x%x (0x%08x)\n",
> +			b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
> +
> +		seq_printf(m, " .m_pdwSetReadPos  = 0x%x (0x%08x)\n",
> +			b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
> +
> +		seq_printf(m, " .m_pdwGetWritePos = 0x%x (0x%08x)\n",
> +			b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
> +
> +		seq_printf(m, " .m_pdwGetReadPos  = 0x%x (0x%08x)\n",
> +			b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
> +		c = 0;
> +		seq_printf(m, "\n  Set Ring:\n");
> +		seq_printf(m, "\n addr  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
> +		for (i = 0; i < b->m_dwSizeSetRing; i++) {
> +			if (c == 0)
> +				seq_printf(m, " %04x:", i);
> +
> +			seq_printf(m, " %02x", *(b->m_pdwSetRing + i));
> +
> +			if (++c == 16) {
> +				seq_printf(m, "\n");
> +				c = 0;
> +			}
> +		}
> +
> +		c = 0;
> +		seq_printf(m, "\n  Get Ring:\n");
> +		seq_printf(m, "\n addr  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
> +		for (i = 0; i < b->m_dwSizeGetRing; i++) {
> +			if (c == 0)
> +				seq_printf(m, " %04x:", i);
> +
> +			seq_printf(m, " %02x", *(b->m_pdwGetRing + i));
> +
> +			if (++c == 16) {
> +				seq_printf(m, "\n");
> +				c = 0;
> +			}
> +		}
> +
> +		mutex_unlock(&b->lock);
> +
> +	}
> +
> +	return 0;
> +}


This piece of code can cause serious trouble. A procfs I/O is none on a page of
PAGE_SIZE (generally 4 Kb). There's nothing on the above logic preventing to write
past the 4 Kb size. To be worse, the size of information depends on the amount of
devices. Such code can cause random troubles, as the driver will write on some
random data outside the procfs space.

Also, procfs should not be used for debuging purposes. Instead, please use
debugfs, where you don't have a PAGE_SIZE limit, and it is more adequate for
debugging.

> +
> +static int saa7164_proc_open(struct inode *inode, struct file *filp)
> +{
> +	return single_open(filp, saa7164_proc_show, NULL);
> +}
> +
> +static struct file_operations saa7164_proc_fops = {
> +	.open		= saa7164_proc_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= single_release,
> +};
> +
> +static int saa7164_proc_create(void)
> +{
> +	struct proc_dir_entry *pe;
> +
> +	pe = proc_create("saa7164", S_IRUGO, NULL, &saa7164_proc_fops);
> +	if (!pe)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +#endif
> +
> +static int saa7164_thread_function(void *data)
> +{
> +	struct saa7164_dev *dev = data;
> +	tmFwInfoStruct_t fwinfo;
> +	u64 last_poll_time = 0;
> +
> +	dprintk(DBGLVL_THR, "thread started\n");
> +
> +	set_freezable();
> +
> +	while (1) {
> +		msleep_interruptible(100);
> +		if (kthread_should_stop())
> +			break;
> +		try_to_freeze();
> +
> +		dprintk(DBGLVL_THR, "thread running\n");
> +
> +		/* Dump the firmware debug message to console */
> +		/* Polling this costs us 1-2% of the arm CPU */
> +		/* convert this into a respnde to interrupt 0x7a */
> +		saa7164_api_collect_debug(dev);
> +
> +		/* Monitor CPU load every 1 second */
> +		if ((last_poll_time + 1000 /* ms */) < jiffies_to_msecs(jiffies)) {
> +			saa7164_api_get_load_info(dev, &fwinfo);
> +			last_poll_time = jiffies_to_msecs(jiffies);
> +		}
> +
> +	}
> +
> +	dprintk(DBGLVL_THR, "thread exiting\n");
> +	return 0;
> +}
> +
>  static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
>  				     const struct pci_device_id *pci_id)
>  {
> @@ -622,7 +1329,6 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
>  		saa7164_gpio_setup(dev);
>  		saa7164_card_setup(dev);
>  
> -
>  		/* Parse the dynamic device configuration, find various
>  		 * media endpoints (MPEG, WMV, PS, TS) and cache their
>  		 * configuration details into the driver, so we can
> @@ -633,7 +1339,7 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
>  
>  		/* Begin to create the video sub-systems and register funcs */
>  		if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
> -			if (saa7164_dvb_register(&dev->ts1) < 0) {
> +			if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS1 ]) < 0) {
>  				printk(KERN_ERR "%s() Failed to register "
>  					"dvb adapters on porta\n",
>  					__func__);
> @@ -641,13 +1347,50 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
>  		}
>  
>  		if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
> -			if (saa7164_dvb_register(&dev->ts2) < 0) {
> +			if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS2 ]) < 0) {
>  				printk(KERN_ERR"%s() Failed to register "
>  					"dvb adapters on portb\n",
>  					__func__);
>  			}
>  		}
>  
> +		if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) {
> +			if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC1 ]) < 0) {
> +				printk(KERN_ERR"%s() Failed to register "
> +					"mpeg encoder\n", __func__);
> +			}
> +		}
> +
> +		if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) {
> +			if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC2 ]) < 0) {
> +				printk(KERN_ERR"%s() Failed to register "
> +					"mpeg encoder\n", __func__);
> +			}
> +		}
> +
> +		if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) {
> +			if (saa7164_vbi_register(&dev->ports[ SAA7164_PORT_VBI1 ]) < 0) {
> +				printk(KERN_ERR"%s() Failed to register "
> +					"vbi device\n", __func__);
> +			}
> +		}
> +
> +		if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) {
> +			if (saa7164_vbi_register(&dev->ports[ SAA7164_PORT_VBI2 ]) < 0) {
> +				printk(KERN_ERR"%s() Failed to register "
> +					"vbi device\n", __func__);
> +			}
> +		}
> +		saa7164_api_set_debug(dev, fw_debug);
> +
> +		if (fw_debug) {
> +			dev->kthread = kthread_run(saa7164_thread_function, dev,
> +				"saa7164 debug");
> +			if (!dev->kthread)
> +				printk(KERN_ERR "%s() Failed to create "
> +					"debug kernel thread\n", __func__);
> +		}
> +
>  	} /* != BOARD_UNKNOWN */
>  	else
>  		printk(KERN_ERR "%s() Unsupported board detected, "
> @@ -675,13 +1418,48 @@ static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
>  {
>  	struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
>  
> +	if (dev->board != SAA7164_BOARD_UNKNOWN) {
> +		if (fw_debug && dev->kthread) {
> +			kthread_stop(dev->kthread);
> +			dev->kthread = NULL;
> +		}
> +		saa7164_api_set_debug(dev, 0x00);
> +	}
> +
> +	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
> +		&dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);
> +	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
> +		&dev->ports[ SAA7164_PORT_ENC1 ].svc_interval);
> +	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
> +		&dev->ports[ SAA7164_PORT_ENC1 ].irq_svc_interval);
> +	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
> +		&dev->ports[ SAA7164_PORT_ENC1 ].read_interval);
> +	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
> +		&dev->ports[ SAA7164_PORT_ENC1 ].poll_interval);
> +	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_VBI1 ],
> +		&dev->ports[ SAA7164_PORT_VBI1 ].read_interval);
> +	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_VBI2 ],
> +		&dev->ports[ SAA7164_PORT_VBI2 ].poll_interval);
> +
>  	saa7164_shutdown(dev);
>  
>  	if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
> -		saa7164_dvb_unregister(&dev->ts1);
> +		saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS1 ]);
>  
>  	if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
> -		saa7164_dvb_unregister(&dev->ts2);
> +		saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS2 ]);
> +
> +	if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER)
> +		saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC1 ]);
> +
> +	if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER)
> +		saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC2 ]);
> +
> +	if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI)
> +		saa7164_vbi_unregister(&dev->ports[ SAA7164_PORT_VBI1 ]);
> +
> +	if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI)
> +		saa7164_vbi_unregister(&dev->ports[ SAA7164_PORT_VBI2 ]);
>  
>  	saa7164_i2c_unregister(&dev->i2c_bus[0]);
>  	saa7164_i2c_unregister(&dev->i2c_bus[1]);
> @@ -727,11 +1505,18 @@ static struct pci_driver saa7164_pci_driver = {
>  static int __init saa7164_init(void)
>  {
>  	printk(KERN_INFO "saa7164 driver loaded\n");
> +
> +#ifdef CONFIG_PROC_FS
> +	saa7164_proc_create();
> +#endif
>  	return pci_register_driver(&saa7164_pci_driver);
>  }
>  
>  static void __exit saa7164_fini(void)
>  {
> +#ifdef CONFIG_PROC_FS
> +	remove_proc_entry("saa7164", NULL);
> +#endif
>  	pci_unregister_driver(&saa7164_pci_driver);
>  }
>  
> diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
> index cf099c5..2d21c01 100644
> --- a/drivers/media/video/saa7164/saa7164-dvb.c
> +++ b/drivers/media/video/saa7164/saa7164-dvb.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -82,7 +82,7 @@ static struct s5h1411_config hauppauge_s5h1411_config = {
>  	.mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
>  };
>  
> -static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port)
> +static int saa7164_dvb_stop_port(struct saa7164_port *port)
>  {
>  	struct saa7164_dev *dev = port->dev;
>  	int ret;
> @@ -100,7 +100,7 @@ static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port)
>  	return ret;
>  }
>  
> -static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port)
> +static int saa7164_dvb_acquire_port(struct saa7164_port *port)
>  {
>  	struct saa7164_dev *dev = port->dev;
>  	int ret;
> @@ -118,7 +118,7 @@ static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port)
>  	return ret;
>  }
>  
> -static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port)
> +static int saa7164_dvb_pause_port(struct saa7164_port *port)
>  {
>  	struct saa7164_dev *dev = port->dev;
>  	int ret;
> @@ -140,90 +140,28 @@ static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port)
>   * the part through AVStream / KS Windows stages, forwards or backwards.
>   * States are: stopped, acquired (h/w), paused, started.
>   */
> -static int saa7164_dvb_stop_streaming(struct saa7164_tsport *port)
> +static int saa7164_dvb_stop_streaming(struct saa7164_port *port)
>  {
>  	struct saa7164_dev *dev = port->dev;
>  	int ret;
>  
>  	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
>  
> -	ret = saa7164_dvb_pause_tsport(port);
> -	ret = saa7164_dvb_acquire_tsport(port);
> -	ret = saa7164_dvb_stop_tsport(port);
> +	ret = saa7164_dvb_pause_port(port);
> +	ret = saa7164_dvb_acquire_port(port);
> +	ret = saa7164_dvb_stop_port(port);
>  
>  	return ret;
>  }
>  
> -static int saa7164_dvb_cfg_tsport(struct saa7164_tsport *port)
> -{
> -	tmHWStreamParameters_t *params = &port->hw_streamingparams;
> -	struct saa7164_dev *dev = port->dev;
> -	struct saa7164_buffer *buf;
> -	struct list_head *c, *n;
> -	int i = 0;
> -
> -	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
> -
> -	saa7164_writel(port->pitch, params->pitch);
> -	saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
> -
> -	dprintk(DBGLVL_DVB, " configured:\n");
> -	dprintk(DBGLVL_DVB, "   lmmio       0x%p\n", dev->lmmio);
> -	dprintk(DBGLVL_DVB, "   bufcounter  0x%x = 0x%x\n", port->bufcounter,
> -		saa7164_readl(port->bufcounter));
> -
> -	dprintk(DBGLVL_DVB, "   pitch       0x%x = %d\n", port->pitch,
> -		saa7164_readl(port->pitch));
> -
> -	dprintk(DBGLVL_DVB, "   bufsize     0x%x = %d\n", port->bufsize,
> -		saa7164_readl(port->bufsize));
> -
> -	dprintk(DBGLVL_DVB, "   buffercount = %d\n", port->hwcfg.buffercount);
> -	dprintk(DBGLVL_DVB, "   bufoffset = 0x%x\n", port->bufoffset);
> -	dprintk(DBGLVL_DVB, "   bufptr32h = 0x%x\n", port->bufptr32h);
> -	dprintk(DBGLVL_DVB, "   bufptr32l = 0x%x\n", port->bufptr32l);
> -
> -	/* Poke the buffers and offsets into PCI space */
> -	mutex_lock(&port->dmaqueue_lock);
> -	list_for_each_safe(c, n, &port->dmaqueue.list) {
> -		buf = list_entry(c, struct saa7164_buffer, list);
> -
> -		/* TODO: Review this in light of 32v64 assignments */
> -		saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
> -		saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i),
> -			buf->pt_dma);
> -		saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
> -
> -		dprintk(DBGLVL_DVB,
> -			"   buf[%d] offset 0x%llx (0x%x) "
> -			"buf 0x%llx/%llx (0x%x/%x)\n",
> -			i,
> -			(u64)port->bufoffset + (i * sizeof(u32)),
> -			saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
> -			(u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
> -			(u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
> -			saa7164_readl(port->bufptr32h + ((sizeof(u32) * i)
> -				* 2)),
> -			saa7164_readl(port->bufptr32l + ((sizeof(u32) * i)
> -				* 2)));
> -
> -		if (i++ > port->hwcfg.buffercount)
> -			BUG();
> -
> -	}
> -	mutex_unlock(&port->dmaqueue_lock);
> -
> -	return 0;
> -}
> -
> -static int saa7164_dvb_start_tsport(struct saa7164_tsport *port)
> +static int saa7164_dvb_start_port(struct saa7164_port *port)
>  {
>  	struct saa7164_dev *dev = port->dev;
>  	int ret = 0, result;
>  
>  	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
>  
> -	saa7164_dvb_cfg_tsport(port);
> +	saa7164_buffer_cfg_port(port);
>  
>  	/* Acquire the hardware */
>  	result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
> @@ -284,7 +222,7 @@ out:
>  static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
>  {
>  	struct dvb_demux *demux = feed->demux;
> -	struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
> +	struct saa7164_port *port = (struct saa7164_port *) demux->priv;
>  	struct saa7164_dvb *dvb = &port->dvb;
>  	struct saa7164_dev *dev = port->dev;
>  	int ret = 0;
> @@ -298,7 +236,7 @@ static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
>  		mutex_lock(&dvb->lock);
>  		if (dvb->feeding++ == 0) {
>  			/* Start transport */
> -			ret = saa7164_dvb_start_tsport(port);
> +			ret = saa7164_dvb_start_port(port);
>  		}
>  		mutex_unlock(&dvb->lock);
>  		dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
> @@ -311,7 +249,7 @@ static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
>  static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
>  {
>  	struct dvb_demux *demux = feed->demux;
> -	struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
> +	struct saa7164_port *port = (struct saa7164_port *) demux->priv;
>  	struct saa7164_dvb *dvb = &port->dvb;
>  	struct saa7164_dev *dev = port->dev;
>  	int ret = 0;
> @@ -332,7 +270,7 @@ static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
>  	return ret;
>  }
>  
> -static int dvb_register(struct saa7164_tsport *port)
> +static int dvb_register(struct saa7164_port *port)
>  {
>  	struct saa7164_dvb *dvb = &port->dvb;
>  	struct saa7164_dev *dev = port->dev;
> @@ -341,6 +279,9 @@ static int dvb_register(struct saa7164_tsport *port)
>  
>  	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
>  
> +	if (port->type != SAA7164_MPEG_DVB)
> +		BUG();
> +
>  	/* Sanity check that the PCI configuration space is active */
>  	if (port->hwcfg.BARLocation == 0) {
>  		result = -ENOMEM;
> @@ -378,7 +319,6 @@ static int dvb_register(struct saa7164_tsport *port)
>  				DRIVER_NAME, result);
>  			goto fail_adapter;
>  		}
> -		buf->nr = i;
>  
>  		mutex_lock(&port->dmaqueue_lock);
>  		list_add_tail(&buf->list, &port->dmaqueue.list);
> @@ -473,7 +413,7 @@ fail_adapter:
>  	return result;
>  }
>  
> -int saa7164_dvb_unregister(struct saa7164_tsport *port)
> +int saa7164_dvb_unregister(struct saa7164_port *port)
>  {
>  	struct saa7164_dvb *dvb = &port->dvb;
>  	struct saa7164_dev *dev = port->dev;
> @@ -482,12 +422,15 @@ int saa7164_dvb_unregister(struct saa7164_tsport *port)
>  
>  	dprintk(DBGLVL_DVB, "%s()\n", __func__);
>  
> +	if (port->type != SAA7164_MPEG_DVB)
> +		BUG();
> +
>  	/* Remove any allocated buffers */
>  	mutex_lock(&port->dmaqueue_lock);
>  	list_for_each_safe(c, n, &port->dmaqueue.list) {
>  		b = list_entry(c, struct saa7164_buffer, list);
>  		list_del(c);
> -		saa7164_buffer_dealloc(port, b);
> +		saa7164_buffer_dealloc(b);
>  	}
>  	mutex_unlock(&port->dmaqueue_lock);
>  
> @@ -508,7 +451,7 @@ int saa7164_dvb_unregister(struct saa7164_tsport *port)
>  /* All the DVB attach calls go here, this function get's modified
>   * for each new card.
>   */
> -int saa7164_dvb_register(struct saa7164_tsport *port)
> +int saa7164_dvb_register(struct saa7164_port *port)
>  {
>  	struct saa7164_dev *dev = port->dev;
>  	struct saa7164_dvb *dvb = &port->dvb;
> @@ -588,8 +531,6 @@ int saa7164_dvb_register(struct saa7164_tsport *port)
>  		return -1;
>  	}
>  
> -	/* Put the analog decoder in standby to keep it quiet */
> -
>  	/* register everything */
>  	ret = dvb_register(port);
>  	if (ret < 0) {
> diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
> new file mode 100644
> index 0000000..0d317ae
> --- /dev/null
> +++ b/drivers/media/video/saa7164/saa7164-encoder.c
> @@ -0,0 +1,1535 @@
> +/*
> + *  Driver for the NXP SAA7164 PCIe bridge
> + *
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *
> + *  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 "saa7164.h"
> +
> +#define ENCODER_MAX_BITRATE 6500000
> +#define ENCODER_MIN_BITRATE 1000000
> +#define ENCODER_DEF_BITRATE 5000000
> +
> +static struct saa7164_tvnorm saa7164_tvnorms[] = {
> +	{
> +		.name      = "NTSC-M",
> +		.id        = V4L2_STD_NTSC_M,
> +	}, {
> +		.name      = "NTSC-JP",
> +		.id        = V4L2_STD_NTSC_M_JP,
> +	}
> +};
> +
> +static const u32 saa7164_v4l2_ctrls[] = {
> +	V4L2_CID_BRIGHTNESS,
> +	V4L2_CID_CONTRAST,
> +	V4L2_CID_SATURATION,
> +	V4L2_CID_HUE,
> +	V4L2_CID_AUDIO_VOLUME,
> +	V4L2_CID_SHARPNESS,
> +	V4L2_CID_MPEG_STREAM_TYPE,
> +	V4L2_CID_MPEG_VIDEO_ASPECT,
> +	V4L2_CID_MPEG_VIDEO_B_FRAMES,
> +	V4L2_CID_MPEG_VIDEO_GOP_SIZE,
> +	V4L2_CID_MPEG_AUDIO_MUTE,
> +	V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
> +	V4L2_CID_MPEG_VIDEO_BITRATE,
> +	V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
> +	0
> +};
> +
> +/* Take the encoder configuration form the port struct and
> + * flush it to the hardware.
> + */
> +static void saa7164_encoder_configure(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	port->encoder_params.width = port->width;
> +	port->encoder_params.height = port->height;
> +	port->encoder_params.is_50hz =
> +		(port->encodernorm.id & V4L2_STD_625_50) != 0;
> +
> +	/* Set up the DIF (enable it) for analog mode by default */
> +	saa7164_api_initialize_dif(port);
> +
> +	/* Configure the correct video standard */
> +	saa7164_api_configure_dif(port, port->encodernorm.id);
> +
> +	/* Ensure the audio decoder is correct configured */
> +	saa7164_api_set_audio_std(port);
> +}
> +
> +static int saa7164_encoder_buffers_dealloc(struct saa7164_port *port)
> +{
> +	struct list_head *c, *n, *p, *q, *l, *v;
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_buffer *buf;
> +	struct saa7164_user_buffer *ubuf;
> +
> +	/* Remove any allocated buffers */
> +	mutex_lock(&port->dmaqueue_lock);
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d) dmaqueue\n", __func__, port->nr);
> +	list_for_each_safe(c, n, &port->dmaqueue.list) {
> +		buf = list_entry(c, struct saa7164_buffer, list);
> +		list_del(c);
> +		saa7164_buffer_dealloc(buf);
> +	}
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d) used\n", __func__, port->nr);
> +	list_for_each_safe(p, q, &port->list_buf_used.list) {
> +		ubuf = list_entry(p, struct saa7164_user_buffer, list);
> +		list_del(p);
> +		saa7164_buffer_dealloc_user(ubuf);
> +	}
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d) free\n", __func__, port->nr);
> +	list_for_each_safe(l, v, &port->list_buf_free.list) {
> +		ubuf = list_entry(l, struct saa7164_user_buffer, list);
> +		list_del(l);
> +		saa7164_buffer_dealloc_user(ubuf);
> +	}
> +
> +	mutex_unlock(&port->dmaqueue_lock);
> +	dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
> +
> +	return 0;
> +}
> +
> +/* Dynamic buffer switch at encoder start time */
> +static int saa7164_encoder_buffers_alloc(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_buffer *buf;
> +	struct saa7164_user_buffer *ubuf;
> +	tmHWStreamParameters_t *params = &port->hw_streamingparams;
> +	int result = -ENODEV, i;
> +	int len = 0;
> +
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
> +		dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", __func__);
> +		params->samplesperline = 128;
> +		params->numberoflines = 256;
> +		params->pitch = 128;
> +		params->numpagetables = 2 +
> +			((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE);
> +	} else
> +	if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
> +		dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", __func__);
> +		params->samplesperline = 188;
> +		params->numberoflines = 312;
> +		params->pitch = 188;
> +		params->numpagetables = 2 +
> +			((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
> +	} else
> +		BUG();
> +
> +	/* Init and establish defaults */
> +	params->bitspersample = 8;
> +	params->linethreshold = 0;
> +	params->pagetablelistvirt = 0;
> +	params->pagetablelistphys = 0;
> +	params->numpagetableentries = port->hwcfg.buffercount;
> +
> +	/* Allocate the PCI resources, buffers (hard) */
> +	for (i = 0; i < port->hwcfg.buffercount; i++) {
> +		buf = saa7164_buffer_alloc(port,
> +			params->numberoflines *
> +			params->pitch);
> +
> +		if (!buf) {
> +			printk(KERN_ERR "%s() failed "
> +			       "(errno = %d), unable to allocate buffer\n",
> +				__func__, result);
> +			result = -ENOMEM;
> +			goto failed;
> +		} else {
> +
> +			mutex_lock(&port->dmaqueue_lock);
> +			list_add_tail(&buf->list, &port->dmaqueue.list);
> +			mutex_unlock(&port->dmaqueue_lock);
> +
> +		}
> +	}
> +
> +	/* Allocate some kenrel kernel buffers for copying
> +	 * to userpsace.
> +	 */
> +	len = params->numberoflines * params->pitch;
> +
> +	if (encoder_buffers < 16)
> +		encoder_buffers = 16;
> +	if (encoder_buffers > 512)
> +		encoder_buffers = 512;
> +
> +	for (i = 0; i < encoder_buffers; i++) {
> +
> +		ubuf = saa7164_buffer_alloc_user(dev, len);
> +		if (ubuf) {
> +			mutex_lock(&port->dmaqueue_lock);
> +			list_add_tail(&ubuf->list, &port->list_buf_free.list);
> +			mutex_unlock(&port->dmaqueue_lock);
> +		}
> +
> +	}
> +
> +	result = 0;
> +
> +failed:
> +	return result;
> +}
> +
> +static int saa7164_encoder_initialize(struct saa7164_port *port)
> +{
> +	saa7164_encoder_configure(port);
> +	return 0;
> +}
> +
> +/* -- V4L2 --------------------------------------------------------- */
> +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +	unsigned int i;
> +
> +	dprintk(DBGLVL_ENC, "%s(id=0x%x)\n", __func__, (u32)*id);
> +
> +	for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
> +		if (*id & saa7164_tvnorms[i].id)
> +			break;
> +	}
> +	if (i == ARRAY_SIZE(saa7164_tvnorms))
> +		return -EINVAL;
> +
> +	port->encodernorm = saa7164_tvnorms[i];
> +
> +	/* Update the audio decoder while is not running in
> +	 * auto detect mode.
> +	 */
> +	saa7164_api_set_audio_std(port);
> +
> +	dprintk(DBGLVL_ENC, "%s(id=0x%x) OK\n", __func__, (u32)*id);
> +
> +	return 0;
> +}
> +
> +static int vidioc_enum_input(struct file *file, void *priv,
> +	struct v4l2_input *i)
> +{
> +	int n;
> +
> +	char *inputs[] = { "tuner", "composite", "svideo", "aux",
> +		"composite", "svideo", "aux" };
> +
> +	if (i->index >= 7)
> +		return -EINVAL;
> +
> +	strcpy(i->name, inputs[ i->index ]);
> +
> +	if (i->index == 0)
> +		i->type = V4L2_INPUT_TYPE_TUNER;
> +	else
> +		i->type  = V4L2_INPUT_TYPE_CAMERA;
> +
> +	for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
> +		i->std |= saa7164_tvnorms[n].id;
> +
> +	return 0;
> +}
> +
> +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	if (saa7164_api_get_videomux(port) != SAA_OK)
> +		return -EIO;
> +
> +	*i = (port->mux_input - 1);
> +
> +	dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, *i);
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, i);
> +
> +	if (i >= 7)
> +		return -EINVAL;
> +
> +	port->mux_input = i + 1;
> +
> +	if (saa7164_api_set_videomux(port) != SAA_OK)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int vidioc_g_tuner(struct file *file, void *priv,
> +	struct v4l2_tuner *t)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	if (0 != t->index)
> +		return -EINVAL;
> +
> +	strcpy(t->name, "tuner");
> +	t->type = V4L2_TUNER_ANALOG_TV;
> +	t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
> +
> +	dprintk(DBGLVL_ENC, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_tuner(struct file *file, void *priv,
> +	struct v4l2_tuner *t)
> +{
> +	/* Update the A/V core */
> +	return 0;
> +}
> +
> +static int vidioc_g_frequency(struct file *file, void *priv,
> +	struct v4l2_frequency *f)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +
> +	f->type = V4L2_TUNER_ANALOG_TV;
> +	f->frequency = port->freq;
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_frequency(struct file *file, void *priv,
> +	struct v4l2_frequency *f)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_port *tsport;
> +	struct dvb_frontend *fe;
> +
> +	/* TODO: Pull this for the std */
> +	struct analog_parameters params = {
> +		.mode      = V4L2_TUNER_ANALOG_TV,
> +		.audmode   = V4L2_TUNER_MODE_STEREO,
> +		.std       = port->encodernorm.id,
> +		.frequency = f->frequency
> +	};
> +
> +	/* Stop the encoder */
> +	dprintk(DBGLVL_ENC, "%s() frequency=%d tuner=%d\n", __func__,
> +		f->frequency, f->tuner);
> +
> +	if (f->tuner != 0)
> +		return -EINVAL;
> +
> +	if (f->type != V4L2_TUNER_ANALOG_TV)
> +		return -EINVAL;
> +
> +	port->freq = f->frequency;
> +
> +	/* Update the hardware */
> +	if (port->nr == SAA7164_PORT_ENC1)
> +		tsport = &dev->ports[ SAA7164_PORT_TS1 ];
> +	else
> +	if (port->nr == SAA7164_PORT_ENC2)
> +		tsport = &dev->ports[ SAA7164_PORT_TS2 ];
> +	else
> +		BUG();
> +
> +	fe = tsport->dvb.frontend;
> +
> +	if (fe && fe->ops.tuner_ops.set_analog_params)
> +		fe->ops.tuner_ops.set_analog_params(fe, &params);
> +	else
> +		printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
> +
> +	saa7164_encoder_initialize(port);
> +
> +	return 0;
> +}
> +
> +static int vidioc_g_ctrl(struct file *file, void *priv,
> +	struct v4l2_control *ctl)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
> +		ctl->id, ctl->value);
> +
> +	switch (ctl->id) {
> +	case V4L2_CID_BRIGHTNESS:
> +		ctl->value = port->ctl_brightness;
> +		break;
> +	case V4L2_CID_CONTRAST:
> +		ctl->value = port->ctl_contrast;
> +		break;
> +	case V4L2_CID_SATURATION:
> +		ctl->value = port->ctl_saturation;
> +		break;
> +	case V4L2_CID_HUE:
> +		ctl->value = port->ctl_hue;
> +		break;
> +	case V4L2_CID_SHARPNESS:
> +		ctl->value = port->ctl_sharpness;
> +		break;
> +	case V4L2_CID_AUDIO_VOLUME:
> +		ctl->value = port->ctl_volume;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_ctrl(struct file *file, void *priv,
> +	struct v4l2_control *ctl)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +	int ret = 0;
> +
> +	dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__,
> +		ctl->id, ctl->value);
> +
> +	switch (ctl->id) {
> +	case V4L2_CID_BRIGHTNESS:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_brightness = ctl->value;
> +			saa7164_api_set_usercontrol(port,
> +				PU_BRIGHTNESS_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_CONTRAST:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_contrast = ctl->value;
> +			saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_SATURATION:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_saturation = ctl->value;
> +			saa7164_api_set_usercontrol(port,
> +				PU_SATURATION_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_HUE:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_hue = ctl->value;
> +			saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_SHARPNESS:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_sharpness = ctl->value;
> +			saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_AUDIO_VOLUME:
> +		if ((ctl->value >= -83) && (ctl->value <= 24)) {
> +			port->ctl_volume = ctl->value;
> +			saa7164_api_set_audio_volume(port, port->ctl_volume);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int saa7164_get_ctrl(struct saa7164_port *port,
> +	struct v4l2_ext_control *ctrl)
> +{
> +	struct saa7164_encoder_params *params = &port->encoder_params;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_MPEG_VIDEO_BITRATE:
> +		ctrl->value = params->bitrate;
> +		break;
> +	case V4L2_CID_MPEG_STREAM_TYPE:
> +		ctrl->value = params->stream_type;
> +		break;
> +	case V4L2_CID_MPEG_AUDIO_MUTE:
> +		ctrl->value = params->ctl_mute;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_ASPECT:
> +		ctrl->value = params->ctl_aspect;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
> +		ctrl->value = params->bitrate_mode;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		ctrl->value = params->refdist;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
> +		ctrl->value = params->bitrate_peak;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		ctrl->value = params->gop_size;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	return 0;
> +}
> +
> +static int vidioc_g_ext_ctrls(struct file *file, void *priv,
> +	struct v4l2_ext_controls *ctrls)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	int i, err = 0;
> +
> +	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
> +		for (i = 0; i < ctrls->count; i++) {
> +			struct v4l2_ext_control *ctrl = ctrls->controls + i;
> +
> +			err = saa7164_get_ctrl(port, ctrl);
> +			if (err) {
> +				ctrls->error_idx = i;
> +				break;
> +			}
> +		}
> +		return err;
> +
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
> +{
> +	int ret = -EINVAL;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_MPEG_VIDEO_BITRATE:
> +		if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
> +			(ctrl->value <= ENCODER_MAX_BITRATE))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_STREAM_TYPE:
> +		if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
> +			(ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_AUDIO_MUTE:
> +		if ((ctrl->value >= 0) &&
> +			(ctrl->value <= 1))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_ASPECT:
> +		if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
> +			(ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		if ((ctrl->value >= 0) &&
> +			(ctrl->value <= 255))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
> +		if ((ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ||
> +			(ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		if ((ctrl->value >= 1) &&
> +			(ctrl->value <= 3))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
> +		if ((ctrl->value >= ENCODER_MIN_BITRATE) &&
> +			(ctrl->value <= ENCODER_MAX_BITRATE))
> +			ret = 0;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int vidioc_try_ext_ctrls(struct file *file, void *priv,
> +	struct v4l2_ext_controls *ctrls)
> +{
> +	int i, err = 0;
> +
> +	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
> +		for (i = 0; i < ctrls->count; i++) {
> +			struct v4l2_ext_control *ctrl = ctrls->controls + i;
> +
> +			err = saa7164_try_ctrl(ctrl, 0);
> +			if (err) {
> +				ctrls->error_idx = i;
> +				break;
> +			}
> +		}
> +		return err;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int saa7164_set_ctrl(struct saa7164_port *port,
> +	struct v4l2_ext_control *ctrl)
> +{
> +	struct saa7164_encoder_params *params = &port->encoder_params;
> +	int ret = 0;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_MPEG_VIDEO_BITRATE:
> +		params->bitrate = ctrl->value;
> +		break;
> +	case V4L2_CID_MPEG_STREAM_TYPE:
> +		params->stream_type = ctrl->value;
> +		break;
> +	case V4L2_CID_MPEG_AUDIO_MUTE:
> +		params->ctl_mute = ctrl->value;
> +		ret = saa7164_api_audio_mute(port, params->ctl_mute);
> +		if (ret != SAA_OK) {
> +			printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
> +				ret);
> +			ret = -EIO;
> +		}
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_ASPECT:
> +		params->ctl_aspect = ctrl->value;
> +		ret = saa7164_api_set_aspect_ratio(port);
> +		if (ret != SAA_OK) {
> +			printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
> +				ret);
> +			ret = -EIO;
> +		}
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
> +		params->bitrate_mode = ctrl->value;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		params->refdist = ctrl->value;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
> +		params->bitrate_peak = ctrl->value;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		params->gop_size = ctrl->value;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	/* TODO: Update the hardware */
> +
> +	return ret;
> +}
> +
> +static int vidioc_s_ext_ctrls(struct file *file, void *priv,
> +	struct v4l2_ext_controls *ctrls)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	int i, err = 0;
> +
> +	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
> +		for (i = 0; i < ctrls->count; i++) {
> +			struct v4l2_ext_control *ctrl = ctrls->controls + i;
> +
> +			err = saa7164_try_ctrl(ctrl, 0);
> +			if (err) {
> +				ctrls->error_idx = i;
> +				break;
> +			}
> +			err = saa7164_set_ctrl(port, ctrl);
> +			if (err) {
> +				ctrls->error_idx = i;
> +				break;
> +			}
> +		}
> +		return err;
> +
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int vidioc_querycap(struct file *file, void  *priv,
> +	struct v4l2_capability *cap)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	strcpy(cap->driver, dev->name);
> +	strlcpy(cap->card, saa7164_boards[dev->board].name,
> +		sizeof(cap->card));
> +	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
> +
> +	cap->capabilities =
> +		V4L2_CAP_VIDEO_CAPTURE |
> +		V4L2_CAP_READWRITE     |
> +		V4L2_CAP_STREAMING     |
> +		0;
> +
> +	cap->capabilities |= V4L2_CAP_TUNER;
> +	cap->version = 0;
> +
> +	return 0;
> +}
> +
> +static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
> +	struct v4l2_fmtdesc *f)
> +{
> +	if (f->index != 0)
> +		return -EINVAL;
> +
> +	strlcpy(f->description, "MPEG", sizeof(f->description));
> +	f->pixelformat = V4L2_PIX_FMT_MPEG;
> +
> +	return 0;
> +}
> +
> +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
> +				struct v4l2_format *f)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
> +	f->fmt.pix.bytesperline = 0;
> +	f->fmt.pix.sizeimage    =
> +		port->ts_packet_size * port->ts_packet_count;
> +	f->fmt.pix.colorspace   = 0;
> +	f->fmt.pix.width        = port->width;
> +	f->fmt.pix.height       = port->height;
> +
> +	dprintk(DBGLVL_ENC, "VIDIOC_G_FMT: w: %d, h: %d\n",
> +		port->width, port->height);
> +
> +	return 0;
> +}
> +
> +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
> +				struct v4l2_format *f)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
> +	f->fmt.pix.bytesperline = 0;
> +	f->fmt.pix.sizeimage    =
> +		port->ts_packet_size * port->ts_packet_count;
> +	f->fmt.pix.colorspace   = 0;
> +	dprintk(DBGLVL_ENC, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
> +		port->width, port->height);
> +	return 0;
> +}
> +
> +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
> +				struct v4l2_format *f)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
> +	f->fmt.pix.bytesperline = 0;
> +	f->fmt.pix.sizeimage    =
> +		port->ts_packet_size * port->ts_packet_count;
> +	f->fmt.pix.colorspace   = 0;
> +
> +	dprintk(DBGLVL_ENC, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
> +		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
> +
> +	return 0;
> +}
> +
> +static int vidioc_log_status(struct file *file, void *priv)
> +{
> +	return 0;
> +}
> +
> +static int fill_queryctrl(struct saa7164_encoder_params *params,
> +	struct v4l2_queryctrl *c)
> +{
> +	switch (c->id) {
> +	case V4L2_CID_BRIGHTNESS:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
> +	case V4L2_CID_CONTRAST:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
> +	case V4L2_CID_SATURATION:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
> +	case V4L2_CID_HUE:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
> +	case V4L2_CID_SHARPNESS:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
> +	case V4L2_CID_MPEG_AUDIO_MUTE:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
> +	case V4L2_CID_AUDIO_VOLUME:
> +		return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
> +	case V4L2_CID_MPEG_VIDEO_BITRATE:
> +		return v4l2_ctrl_query_fill(c,
> +			ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
> +			100000, ENCODER_DEF_BITRATE);
> +	case V4L2_CID_MPEG_STREAM_TYPE:
> +		return v4l2_ctrl_query_fill(c,
> +			V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
> +			V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
> +			1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
> +	case V4L2_CID_MPEG_VIDEO_ASPECT:
> +		return v4l2_ctrl_query_fill(c,
> +			V4L2_MPEG_VIDEO_ASPECT_1x1,
> +			V4L2_MPEG_VIDEO_ASPECT_221x100,
> +			1, V4L2_MPEG_VIDEO_ASPECT_4x3);
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
> +		return v4l2_ctrl_query_fill(c,
> +			V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
> +			1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		return v4l2_ctrl_query_fill(c,
> +			1, 3, 1, 1);
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
> +		return v4l2_ctrl_query_fill(c,
> +			ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE,
> +			100000, ENCODER_DEF_BITRATE);
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int vidioc_queryctrl(struct file *file, void *priv,
> +	struct v4l2_queryctrl *c)
> +{
> +	struct saa7164_encoder_fh *fh = priv;
> +	struct saa7164_port *port = fh->port;
> +	int i, next;
> +	u32 id = c->id;
> +
> +	memset(c, 0, sizeof(*c));
> +
> +	next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
> +	c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
> +
> +	for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
> +		if (next) {
> +			if (c->id < saa7164_v4l2_ctrls[i])
> +				c->id = saa7164_v4l2_ctrls[i];
> +			else
> +				continue;
> +		}
> +
> +		if (c->id == saa7164_v4l2_ctrls[i])
> +			return fill_queryctrl(&port->encoder_params, c);
> +
> +		if (c->id < saa7164_v4l2_ctrls[i])
> +			break;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int saa7164_encoder_stop_port(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +
> +	ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
> +	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
> +			__func__, ret);
> +		ret = -EIO;
> +	} else {
> +		dprintk(DBGLVL_ENC, "%s()    Stopped\n", __func__);
> +		ret = 0;
> +	}
> +
> +	return ret;
> +}
> +
> +static int saa7164_encoder_acquire_port(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +
> +	ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
> +	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
> +			__func__, ret);
> +		ret = -EIO;
> +	} else {
> +		dprintk(DBGLVL_ENC, "%s() Acquired\n", __func__);
> +		ret = 0;
> +	}
> +
> +	return ret;
> +}
> +
> +static int saa7164_encoder_pause_port(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +
> +	ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
> +	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
> +			__func__, ret);
> +		ret = -EIO;
> +	} else {
> +		dprintk(DBGLVL_ENC, "%s()   Paused\n", __func__);
> +		ret = 0;
> +	}
> +
> +	return ret;
> +}
> +
> +/* Firmware is very windows centric, meaning you have to transition
> + * the part through AVStream / KS Windows stages, forwards or backwards.
> + * States are: stopped, acquired (h/w), paused, started.
> + * We have to leave here will all of the soft buffers on the free list,
> + * else the cfg_post() func won't have soft buffers to correctly configure.
> + */
> +static int saa7164_encoder_stop_streaming(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_buffer *buf;
> +	struct saa7164_user_buffer *ubuf;
> +	struct list_head *c, *n;
> +	int ret;
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
> +
> +	ret = saa7164_encoder_pause_port(port);
> +	ret = saa7164_encoder_acquire_port(port);
> +	ret = saa7164_encoder_stop_port(port);
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d) Hardware stopped\n", __func__,
> +		port->nr);
> +
> +	/* Reset the state of any allocated buffer resources */
> +	mutex_lock(&port->dmaqueue_lock);
> +
> +	/* Reset the hard and soft buffer state */
> +	list_for_each_safe(c, n, &port->dmaqueue.list) {
> +		buf = list_entry(c, struct saa7164_buffer, list);
> +		buf->flags = SAA7164_BUFFER_FREE;
> +		buf->pos = 0;
> +	}
> +
> +	list_for_each_safe(c, n, &port->list_buf_used.list) {
> +		ubuf = list_entry(c, struct saa7164_user_buffer, list);
> +		ubuf->pos = 0;
> +		list_move_tail(&ubuf->list, &port->list_buf_free.list);
> +	}
> +
> +	mutex_unlock(&port->dmaqueue_lock);
> +
> +	/* Free any allocated resources */
> +	saa7164_encoder_buffers_dealloc(port);
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d) Released\n", __func__, port->nr);
> +
> +	return ret;
> +}
> +
> +static int saa7164_encoder_start_streaming(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int result, ret = 0;
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
> +
> +	port->done_first_interrupt = 0;
> +
> +	/* allocate all of the PCIe DMA buffer resources on the fly,
> +	 * allowing switching between TS and PS payloads without
> +	 * requiring a complete driver reload.
> +	 */
> +	saa7164_encoder_buffers_alloc(port);
> +
> +	/* Configure the encoder with any cache values */
> +	saa7164_api_set_encoder(port);
> +	saa7164_api_get_encoder(port);
> +
> +	/* Place the empty buffers on the hardware */
> +	saa7164_buffer_cfg_port(port);
> +
> +	/* Acquire the hardware */
> +	result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
> +	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
> +			__func__, result);
> +
> +		/* Stop the hardware, regardless */
> +		result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
> +		if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +			printk(KERN_ERR "%s() acquire/forced stop transition "
> +				"failed, res = 0x%x\n", __func__, result);
> +		}
> +		ret = -EIO;
> +		goto out;
> +	} else
> +		dprintk(DBGLVL_ENC, "%s()   Acquired\n", __func__);
> +
> +	/* Pause the hardware */
> +	result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
> +	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
> +				__func__, result);
> +
> +		/* Stop the hardware, regardless */
> +		result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
> +		if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +			printk(KERN_ERR "%s() pause/forced stop transition "
> +				"failed, res = 0x%x\n", __func__, result);
> +		}
> +
> +		ret = -EIO;
> +		goto out;
> +	} else
> +		dprintk(DBGLVL_ENC, "%s()   Paused\n", __func__);
> +
> +	/* Start the hardware */
> +	result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
> +	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
> +				__func__, result);
> +
> +		/* Stop the hardware, regardless */
> +		result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
> +		if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +			printk(KERN_ERR "%s() run/forced stop transition "
> +				"failed, res = 0x%x\n", __func__, result);
> +		}
> +
> +		ret = -EIO;
> +	} else
> +		dprintk(DBGLVL_ENC, "%s()   Running\n", __func__);
> +
> +out:
> +	return ret;
> +}
> +
> +static int fops_open(struct file *file)
> +{
> +	struct saa7164_dev *h, *dev = NULL;
> +	struct saa7164_port *port = NULL;
> +	struct saa7164_port *portc = NULL;
> +	struct saa7164_port *portd = NULL;
> +	struct saa7164_encoder_fh *fh;
> +	struct list_head *list;
> +	int minor = video_devdata(file)->minor;
> +
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	/* TODO: Really, the BKL? - remove this */
> +	lock_kernel();

We're removing BKL upstream. We should not add BKL'd drivers anymore.

> +	list_for_each(list, &saa7164_devlist) {
> +		h = list_entry(list, struct saa7164_dev, devlist);
> +
> +		portc = &h->ports[ SAA7164_PORT_ENC1 ];
> +		portd = &h->ports[ SAA7164_PORT_ENC2 ];
> +
> +		if (portc->v4l_device &&
> +		    portc->v4l_device->minor == minor) {
> +			dev = h;
> +			port = portc;
> +			break;
> +		}
> +
> +		if (portd->v4l_device &&
> +		    portd->v4l_device->minor == minor) {
> +			dev = h;
> +			port = portd;
> +			break;
> +		}
> +
> +	}
> +
> +	if (port == NULL) {
> +		unlock_kernel();
> +		return -ENODEV;
> +	}
> +
> +	/* allocate + initialize per filehandle data */
> +	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
> +	if (NULL == fh) {
> +		unlock_kernel();
> +		return -ENOMEM;
> +	}
> +
> +	file->private_data = fh;
> +	fh->port = port;
> +
> +	unlock_kernel();
> +
> +	return 0;
> +}
> +
> +static int fops_release(struct file *file)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	/* Shut device down on last close */
> +	if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
> +		if (atomic_dec_return(&port->v4l_reader_count) == 0) {
> +			/* stop mpeg capture then cancel buffers */
> +			saa7164_encoder_stop_streaming(port);
> +		}
> +	}
> +
> +	file->private_data = NULL;
> +	kfree(fh);
> +
> +	return 0;
> +}
> +
> +struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
> +{
> +	struct saa7164_user_buffer *ubuf = 0;
> +	struct saa7164_dev *dev = port->dev;
> +	u32 crc;
> +
> +	mutex_lock(&port->dmaqueue_lock);
> +	if (!list_empty(&port->list_buf_used.list)) {
> +		ubuf = list_first_entry(&port->list_buf_used.list,
> +			struct saa7164_user_buffer, list);
> +
> +		if (crc_checking) {
> +			crc = crc32(0, ubuf->data, ubuf->actual_size);
> +			if (crc != ubuf->crc) {
> +				printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
> +					ubuf, ubuf->crc, crc);
> +			}
> +		}
> +
> +	}
> +	mutex_unlock(&port->dmaqueue_lock);
> +
> +	dprintk(DBGLVL_ENC, "%s() returns %p\n", __func__, ubuf);
> +
> +	return ubuf;
> +}
> +
> +static ssize_t fops_read(struct file *file, char __user *buffer,
> +	size_t count, loff_t *pos)
> +{
> +	struct saa7164_encoder_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_user_buffer *ubuf = NULL;
> +	struct saa7164_dev *dev = port->dev;
> +	unsigned int ret = 0;
> +	int rem, cnt;
> +	u8 *p;
> +
> +	port->last_read_msecs_diff = port->last_read_msecs;
> +	port->last_read_msecs = jiffies_to_msecs(jiffies);
> +	port->last_read_msecs_diff = port->last_read_msecs -
> +		port->last_read_msecs_diff;
> +
> +	saa7164_histogram_update(&port->read_interval,
> +		port->last_read_msecs_diff);
> +
> +	if (*pos) {
> +		printk(KERN_ERR "%s() ESPIPE\n", __func__);
> +		return -ESPIPE;
> +	}
> +
> +	if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
> +		if (atomic_inc_return(&port->v4l_reader_count) == 1) {
> +
> +			if (saa7164_encoder_initialize(port) < 0) {
> +				printk(KERN_ERR "%s() EINVAL\n", __func__);
> +				return -EINVAL;
> +			}
> +
> +			saa7164_encoder_start_streaming(port);
> +			msleep(200);
> +		}
> +	}
> +
> +	/* blocking wait for buffer */
> +	if ((file->f_flags & O_NONBLOCK) == 0) {
> +		if (wait_event_interruptible(port->wait_read,
> +			saa7164_enc_next_buf(port))) {
> +				printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
> +				return -ERESTARTSYS;
> +		}
> +	}
> +
> +	/* Pull the first buffer from the used list */
> +	ubuf = saa7164_enc_next_buf(port);
> +
> +	while ((count > 0) && ubuf) {
> +
> +		/* set remaining bytes to copy */
> +		rem = ubuf->actual_size - ubuf->pos;
> +		cnt = rem > count ? count : rem;
> +
> +		p = ubuf->data + ubuf->pos;
> +
> +		dprintk(DBGLVL_ENC,
> +			"%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
> +			__func__, (int)count, cnt, rem, ubuf, ubuf->pos);
> +
> +		if (copy_to_user(buffer, p, cnt)) {
> +			printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
> +			if (!ret) {
> +				printk(KERN_ERR "%s() EFAULT\n", __func__);
> +				ret = -EFAULT;
> +			}
> +			goto err;
> +		}
> +
> +		ubuf->pos += cnt;
> +		count -= cnt;
> +		buffer += cnt;
> +		ret += cnt;
> +
> +		if (ubuf->pos > ubuf->actual_size) {
> +			printk(KERN_ERR "read() pos > actual, huh?\n");
> +		}
> +
> +		if (ubuf->pos == ubuf->actual_size) {
> +
> +			/* finished with current buffer, take next buffer */
> +
> +			/* Requeue the buffer on the free list */
> +			ubuf->pos = 0;
> +
> +			mutex_lock(&port->dmaqueue_lock);
> +			list_move_tail(&ubuf->list, &port->list_buf_free.list);
> +			mutex_unlock(&port->dmaqueue_lock);
> +
> +			/* Dequeue next */
> +			if ((file->f_flags & O_NONBLOCK) == 0) {
> +				if (wait_event_interruptible(port->wait_read,
> +					saa7164_enc_next_buf(port))) {
> +						break;
> +				}
> +			}
> +			ubuf = saa7164_enc_next_buf(port);
> +		}
> +	}
> +err:
> +	if (!ret && !ubuf) {
> +		printk(KERN_ERR "%s() EAGAIN\n", __func__);
> +		ret = -EAGAIN;
> +	}
> +
> +	return ret;
> +}
> +
> +static unsigned int fops_poll(struct file *file, poll_table *wait)
> +{
> +	struct saa7164_encoder_fh *fh = (struct saa7164_encoder_fh *)file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_user_buffer *ubuf;
> +	unsigned int mask = 0;
> +
> +	port->last_poll_msecs_diff = port->last_poll_msecs;
> +	port->last_poll_msecs = jiffies_to_msecs(jiffies);
> +	port->last_poll_msecs_diff = port->last_poll_msecs -
> +		port->last_poll_msecs_diff;
> +
> +	saa7164_histogram_update(&port->poll_interval,
> +		port->last_poll_msecs_diff);
> +
> +	if (!video_is_registered(port->v4l_device)) {
> +		return -EIO;
> +	}
> +
> +	if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
> +		if (atomic_inc_return(&port->v4l_reader_count) == 1) {
> +			if (saa7164_encoder_initialize(port) < 0)
> +				return -EINVAL;
> +			saa7164_encoder_start_streaming(port);
> +			msleep(200);
> +		}
> +	}
> +
> +	/* blocking wait for buffer */
> +	if ((file->f_flags & O_NONBLOCK) == 0) {
> +		if (wait_event_interruptible(port->wait_read,
> +			saa7164_enc_next_buf(port))) {
> +				return -ERESTARTSYS;
> +		}
> +	}
> +
> +	/* Pull the first buffer from the used list */
> +	ubuf = list_first_entry(&port->list_buf_used.list,
> +		struct saa7164_user_buffer, list);
> +
> +	if (ubuf)
> +		mask |= POLLIN | POLLRDNORM;
> +
> +	return mask;
> +}
> +
> +static const struct v4l2_file_operations mpeg_fops = {
> +	.owner		= THIS_MODULE,
> +	.open		= fops_open,
> +	.release	= fops_release,
> +	.read		= fops_read,
> +	.poll		= fops_poll,
> +	.unlocked_ioctl	= video_ioctl2,
> +};
> +
> +int saa7164_g_chip_ident(struct file *file, void *fh,
> +	struct v4l2_dbg_chip_ident *chip)
> +{
> +	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
> +	struct saa7164_dev *dev = port->dev;
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	return 0;
> +}
> +
> +int saa7164_g_register(struct file *file, void *fh,
> +	struct v4l2_dbg_register *reg)
> +{
> +	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
> +	struct saa7164_dev *dev = port->dev;
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	if (!capable(CAP_SYS_ADMIN))
> +		return -EPERM;
> +
> +	return 0;
> +}
> +
> +int saa7164_s_register(struct file *file, void *fh,
> +	struct v4l2_dbg_register *reg)
> +{
> +	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
> +	struct saa7164_dev *dev = port->dev;
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	if (!capable(CAP_SYS_ADMIN))
> +		return -EPERM;
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
> +	.vidioc_s_std		 = vidioc_s_std,
> +	.vidioc_enum_input	 = vidioc_enum_input,
> +	.vidioc_g_input		 = vidioc_g_input,
> +	.vidioc_s_input		 = vidioc_s_input,
> +	.vidioc_g_tuner		 = vidioc_g_tuner,
> +	.vidioc_s_tuner		 = vidioc_s_tuner,
> +	.vidioc_g_frequency	 = vidioc_g_frequency,
> +	.vidioc_s_frequency	 = vidioc_s_frequency,
> +	.vidioc_s_ctrl		 = vidioc_s_ctrl,
> +	.vidioc_g_ctrl		 = vidioc_g_ctrl,
> +	.vidioc_querycap	 = vidioc_querycap,
> +	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
> +	.vidioc_g_fmt_vid_cap	 = vidioc_g_fmt_vid_cap,
> +	.vidioc_try_fmt_vid_cap	 = vidioc_try_fmt_vid_cap,
> +	.vidioc_s_fmt_vid_cap	 = vidioc_s_fmt_vid_cap,
> +	.vidioc_g_ext_ctrls	 = vidioc_g_ext_ctrls,
> +	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
> +	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
> +	.vidioc_log_status	 = vidioc_log_status,
> +	.vidioc_queryctrl	 = vidioc_queryctrl,
> +	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,
> +#ifdef CONFIG_VIDEO_ADV_DEBUG
> +	.vidioc_g_register	 = saa7164_g_register,
> +	.vidioc_s_register	 = saa7164_s_register,
> +#endif
> +};
> +
> +static struct video_device saa7164_mpeg_template = {
> +	.name          = "saa7164",
> +	.fops          = &mpeg_fops,
> +	.ioctl_ops     = &mpeg_ioctl_ops,
> +	.minor         = -1,
> +	.tvnorms       = SAA7164_NORMS,
> +	.current_norm  = V4L2_STD_NTSC_M,
> +};
> +
> +static struct video_device *saa7164_encoder_alloc(
> +	struct saa7164_port *port,
> +	struct pci_dev *pci,
> +	struct video_device *template,
> +	char *type)
> +{
> +	struct video_device *vfd;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	vfd = video_device_alloc();
> +	if (NULL == vfd)
> +		return NULL;
> +
> +	*vfd = *template;
> +	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
> +		type, saa7164_boards[dev->board].name);
> +
> +	vfd->parent  = &pci->dev;
> +	vfd->release = video_device_release;
> +	return vfd;
> +}
> +
> +int saa7164_encoder_register(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int result = -ENODEV;
> +
> +	dprintk(DBGLVL_ENC, "%s()\n", __func__);
> +
> +	if (port->type != SAA7164_MPEG_ENCODER)
> +		BUG();
> +
> +	/* Sanity check that the PCI configuration space is active */
> +	if (port->hwcfg.BARLocation == 0) {
> +		printk(KERN_ERR "%s() failed "
> +		       "(errno = %d), NO PCI configuration\n",
> +			__func__, result);
> +		result = -ENOMEM;
> +		goto failed;
> +	}
> +
> +	/* Establish encoder defaults here */
> +	/* Set default TV standard */
> +	port->encodernorm = saa7164_tvnorms[0];
> +	port->width = 720;
> +	port->mux_input = 1; /* Composite */
> +	port->video_format = EU_VIDEO_FORMAT_MPEG_2;
> +	port->audio_format = 0;
> +	port->video_resolution = 0;
> +	port->ctl_brightness = 127;
> +	port->ctl_contrast = 66;
> +	port->ctl_hue = 128;
> +	port->ctl_saturation = 62;
> +	port->ctl_sharpness = 8;
> +	port->encoder_params.bitrate = ENCODER_DEF_BITRATE;
> +	port->encoder_params.bitrate_peak = ENCODER_DEF_BITRATE;
> +	port->encoder_params.bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
> +	port->encoder_params.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
> +	port->encoder_params.ctl_mute = 0;
> +	port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
> +	port->encoder_params.refdist = 1;
> +	port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE;
> +
> +	if (port->encodernorm.id & V4L2_STD_525_60)
> +		port->height = 480;
> +	else
> +		port->height = 576;
> +
> +	/* Allocate and register the video device node */
> +	port->v4l_device = saa7164_encoder_alloc(port,
> +		dev->pci, &saa7164_mpeg_template, "mpeg");
> +
> +	if (port->v4l_device == NULL) {
> +		printk(KERN_INFO "%s: can't allocate mpeg device\n",
> +			dev->name);
> +		result = -ENOMEM;
> +		goto failed;
> +	}
> +
> +	result = video_register_device(port->v4l_device,
> +		VFL_TYPE_GRABBER, -1);
> +	if (result < 0) {
> +		printk(KERN_INFO "%s: can't register mpeg device\n",
> +			dev->name);
> +		/* TODO: We're going to leak here if we don't dealloc
> +		 The buffers above. The unreg function can't deal wit it.
> +		*/
> +		goto failed;
> +	}
> +
> +	printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
> +		dev->name, port->v4l_device->num);
> +
> +	/* Configure the hardware defaults */
> +	saa7164_api_set_videomux(port);
> +	saa7164_api_set_usercontrol(port, PU_BRIGHTNESS_CONTROL);
> +	saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
> +	saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
> +	saa7164_api_set_usercontrol(port, PU_SATURATION_CONTROL);
> +	saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
> +	saa7164_api_audio_mute(port, 0);
> +	saa7164_api_set_audio_volume(port, 20);
> +	saa7164_api_set_aspect_ratio(port);
> +
> +	/* Disable audio standard detection, it's buggy */
> +	saa7164_api_set_audio_detection(port, 0);
> +
> +	saa7164_api_set_encoder(port);
> +	saa7164_api_get_encoder(port);
> +
> +	result = 0;
> +failed:
> +	return result;
> +}
> +
> +void saa7164_encoder_unregister(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d)\n", __func__, port->nr);
> +
> +	if (port->type != SAA7164_MPEG_ENCODER)
> +		BUG();
> +
> +	if (port->v4l_device) {
> +		if (port->v4l_device->minor != -1)
> +			video_unregister_device(port->v4l_device);
> +		else
> +			video_device_release(port->v4l_device);
> +
> +		port->v4l_device = NULL;
> +	}
> +
> +	dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr);
> +}
> +
> diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
> index 270245d..e48e2b4 100644
> --- a/drivers/media/video/saa7164/saa7164-fw.c
> +++ b/drivers/media/video/saa7164/saa7164-fw.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -24,11 +24,11 @@
>  
>  #include "saa7164.h"
>  
> -#define SAA7164_REV2_FIRMWARE		"v4l-saa7164-1.0.2.fw"
> -#define SAA7164_REV2_FIRMWARE_SIZE	3978608
> +#define SAA7164_REV2_FIRMWARE		"NXP7164-2010-03-10.1.fw"
> +#define SAA7164_REV2_FIRMWARE_SIZE	4019072
>  
> -#define SAA7164_REV3_FIRMWARE		"v4l-saa7164-1.0.3.fw"
> -#define SAA7164_REV3_FIRMWARE_SIZE	3978608
> +#define SAA7164_REV3_FIRMWARE		"NXP7164-2010-03-10.1.fw"
> +#define SAA7164_REV3_FIRMWARE_SIZE	4019072

We need a patch also for linux-firmware with those firmwares (of if we can't really get any
permissions to redistribute, at least we need some script to extract it from somewhere.

>  
>  struct fw_header {
>  	u32	firmwaresize;
> diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c
> index e1ae9b0..b5167d3 100644
> --- a/drivers/media/video/saa7164/saa7164-i2c.c
> +++ b/drivers/media/video/saa7164/saa7164-i2c.c
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/video/saa7164/saa7164-reg.h
> index 06be4c1..2bbf815 100644
> --- a/drivers/media/video/saa7164/saa7164-reg.h
> +++ b/drivers/media/video/saa7164/saa7164-reg.h
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -60,6 +60,7 @@
>  #define GET_STRING_CONTROL		0x03
>  #define GET_LANGUAGE_CONTROL		0x05
>  #define SET_POWER_CONTROL		0x07
> +#define GET_FW_STATUS_CONTROL		0x08
>  #define GET_FW_VERSION_CONTROL		0x09
>  #define SET_DEBUG_LEVEL_CONTROL		0x0B
>  #define GET_DEBUG_DATA_CONTROL		0x0C
> @@ -156,11 +157,63 @@
>  #define EXU_INTERRUPT_CONTROL		0x03
>  
>  /* State Transition and args */
> +#define SAA_PROBE_CONTROL	0x01
> +#define SAA_COMMIT_CONTROL	0x02
>  #define SAA_STATE_CONTROL	0x03
>  #define SAA_DMASTATE_STOP	0x00
>  #define SAA_DMASTATE_ACQUIRE	0x01
>  #define SAA_DMASTATE_PAUSE	0x02
>  #define SAA_DMASTATE_RUN	0x03
>  
> -/* Hardware registers */
> -
> +/* A/V Mux Input Selector */
> +#define SU_INPUT_SELECT_CONTROL 0x01
> +
> +/* Encoder Profiles */
> +#define EU_PROFILE_PS_DVD	0x06
> +#define EU_PROFILE_TS_HQ	0x09
> +#define EU_VIDEO_FORMAT_MPEG_2	0x02
> +
> +/* Tuner */
> +#define TU_AUDIO_MODE_CONTROL  0x17
> +
> +/* Video Formats */
> +#define TU_STANDARD_CONTROL		0x00
> +#define TU_STANDARD_AUTO_CONTROL	0x01
> +#define TU_STANDARD_NONE		0x00
> +#define TU_STANDARD_NTSC_M		0x01
> +#define TU_STANDARD_PAL_I		0x08
> +#define TU_STANDARD_MANUAL		0x00
> +#define TU_STANDARD_AUTO		0x01
> +
> +/* Video Controls */
> +#define PU_BRIGHTNESS_CONTROL	0x02
> +#define PU_CONTRAST_CONTROL	0x03
> +#define PU_HUE_CONTROL		0x06
> +#define PU_SATURATION_CONTROL	0x07
> +#define PU_SHARPNESS_CONTROL	0x08
> +
> +/* Audio Controls */
> +#define MUTE_CONTROL		0x01
> +#define VOLUME_CONTROL		0x02
> +#define AUDIO_DEFAULT_CONTROL	0x0D
> +
> +/* Default Volume Levels */
> +#define TMHW_LEV_ADJ_DECLEV_DEFAULT     0x00
> +#define TMHW_LEV_ADJ_MONOLEV_DEFAULT    0x00
> +#define TMHW_LEV_ADJ_NICLEV_DEFAULT     0x00
> +#define TMHW_LEV_ADJ_SAPLEV_DEFAULT     0x00
> +#define TMHW_LEV_ADJ_ADCLEV_DEFAULT     0x00
> +
> +/* Encoder Related Commands */
> +#define EU_PROFILE_CONTROL		0x00
> +#define EU_VIDEO_FORMAT_CONTROL		0x01
> +#define EU_VIDEO_BIT_RATE_CONTROL	0x02
> +#define EU_VIDEO_RESOLUTION_CONTROL	0x03
> +#define EU_VIDEO_GOP_STRUCTURE_CONTROL	0x04
> +#define EU_VIDEO_INPUT_ASPECT_CONTROL	0x0A
> +#define EU_AUDIO_FORMAT_CONTROL		0x0C
> +#define EU_AUDIO_BIT_RATE_CONTROL	0x0D
> +
> +/* Firmware Debugging */
> +#define SET_DEBUG_LEVEL_CONTROL	0x0B
> +#define GET_DEBUG_DATA_CONTROL	0x0C
> diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h
> index 99093f2..e66c29d 100644
> --- a/drivers/media/video/saa7164/saa7164-types.h
> +++ b/drivers/media/video/saa7164/saa7164-types.h
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -82,10 +82,10 @@ typedef struct {
>  	u32	m_dwSizeSetRing;
>  	u8	*m_pdwGetRing;
>  	u32	m_dwSizeGetRing;
> -	u32	*m_pdwSetWritePos;
> -	u32	*m_pdwSetReadPos;
> -	u32	*m_pdwGetWritePos;
> -	u32	*m_pdwGetReadPos;
> +	u32	m_dwSetWritePos;
> +	u32	m_dwSetReadPos;
> +	u32	m_dwGetWritePos;
> +	u32	m_dwGetReadPos;
>  
>  	/* All access is protected */
>  	struct mutex lock;
> @@ -285,3 +285,176 @@ typedef struct {
>  	u8	guidStrideFormat[16];
>  } __attribute__((packed)) tmComResTSFormatDescrHeader_t;
>  
> +/* Encoder related structures */
> +
> +/* A/V Mux Selector */
> +typedef struct
> +{
> +	u8	len;
> +	u8	type;
> +	u8	subtype;
> +	u8	unitid;
> +	u8	nrinpins;
> +	u8	sourceid;
> +} __attribute__((packed)) tmComResSelDescrHeader_t;
> +
> +/* A/V Audio processor definitions */
> +typedef struct
> +{
> +	u8	len;
> +	u8	type;
> +	u8	subtype;
> +	u8	unitid;
> +	u8	sourceid;
> +	u16	wreserved;
> +	u8	controlsize;
> +} __attribute__((packed)) tmComResProcDescrHeader_t;
> +
> +/* Video bitrate control message */
> +#define EU_VIDEO_BIT_RATE_MODE_CONSTANT		(0)
> +#define EU_VIDEO_BIT_RATE_MODE_VARIABLE_AVERAGE (1)
> +#define EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK	(2)
> +typedef struct
> +{
> +	u8	ucVideoBitRateMode;
> +	u32	dwVideoBitRate;
> +	u32	dwVideoBitRatePeak;
> +} __attribute__((packed)) tmComResEncVideoBitRate_t;
> +
> +/* Video Encoder Aspect Ratio message */
> +typedef struct
> +{
> +	u8	width;
> +	u8	height;
> +} __attribute__((packed)) tmComResEncVideoInputAspectRatio_t;
> +
> +/* Video Encoder GOP IBP message */
> +/* 1. IPPPPPPPPPPPPPP */
> +/* 2. IBPBPBPBPBPBPBP */
> +/* 3. IBBPBBPBBPBBP   */
> +#define SAA7164_ENCODER_DEFAULT_GOP_DIST ( 1)
> +#define SAA7164_ENCODER_DEFAULT_GOP_SIZE (15)
> +typedef struct
> +{
> +	u8	ucGOPSize;	/* GOP Size 12, 15 */
> +	u8	ucRefFrameDist; /* Reference Frame Distance */
> +} __attribute__((packed)) tmComResEncVideoGopStructure_t;
> +
> +/* Encoder processor definition */
> +typedef struct
> +{
> +	u8	len;
> +	u8	type;
> +	u8	subtype;
> +	u8	unitid;
> +	u8	vsourceid;
> +	u8	asourceid;
> +	u8	iunit;
> +	u32	dwmControlCap;
> +	u32	dwmProfileCap;
> +	u32	dwmVidFormatCap;
> +	u8	bmVidBitrateCap;
> +	u16	wmVidResolutionsCap;
> +	u16	wmVidFrmRateCap;
> +	u32	dwmAudFormatCap;
> +	u8	bmAudBitrateCap;
> +} __attribute__((packed)) tmComResEncoderDescrHeader_t;
> +
> +/* Audio processor definition */
> +typedef struct
> +{
> +	u8	len;
> +	u8	type;
> +	u8	subtype;
> +	u8	unitid;
> +	u8	sourceid;
> +	u8	controlsize;
> +} __attribute__((packed)) tmComResAFeatureDescrHeader_t;
> +
> +/* Audio control messages */
> +typedef struct
> +{
> +	u8	ucDecoderLevel;
> +	u8	ucDecoderFM_Level;
> +	u8	ucMonoLevel;
> +	u8	ucNICAM_Level;
> +	u8	ucSAP_Level;
> +	u8	ucADC_Level;
> +} __attribute__((packed)) tmComResAudioDefaults_t;
> +
> +/* Audio bitrate control message */
> +typedef struct
> +{
> +	u8	ucAudioBitRateMode;
> +	u32	dwAudioBitRate;
> +	u32	dwAudioBitRatePeak;
> +} __attribute__((packed)) tmComResEncAudioBitRate_t;
> +
> +/* Tuner / AV Decoder messages */
> +typedef struct
> +{
> +	u8	std;
> +	u32	country;
> +} __attribute__((packed)) tmComResTunerStandard_t;
> +
> +typedef struct
> +{
> +	u8	mode;
> +} __attribute__((packed)) tmComResTunerStandardAuto_t;
> +
> +/* EEPROM definition for PS stream types */
> +typedef struct
> +{
> +	u8	len;
> +	u8	type;
> +	u8	subtype;
> +	u8	bFormatIndex;
> +	u16	wPacketLength;
> +	u16	wPackLength;
> +	u8	bPackDataType;
> +} __attribute__((packed)) tmComResPSFormatDescrHeader_t;
> +
> +/* VBI control structure */
> +typedef struct
> +{
> +	u8	len;
> +	u8	type;
> +	u8	subtype; /* VS_FORMAT_VBI */
> +	u8	bFormatIndex;
> +	u32	VideoStandard; /* See KS_AnalogVideoStandard, NTSC = 1 */
> +	u8	StartLine; /* NTSC Start = 10 */
> +	u8	EndLine; /* NTSC = 21 */
> +	u8	FieldRate; /* 60 for NTSC */
> +	u8	bNumLines; /* Unsed - scheduled for removal */
> +} __attribute__((packed)) tmComResVBIFormatDescrHeader_t;
> +
> +typedef struct
> +{
> +	u16	bmHint;
> +	u8	bFormatIndex;
> +	u8	bFrameIndex;
> +} __attribute__((packed)) tmComResProbeCommit_t;
> +
> +typedef struct
> +{
> +	u32	dwDebugLevel;
> +} __attribute__((packed)) tmComResDebugSetLevel_t;
> +
> +typedef struct
> +{
> +	u32	dwResult;
> +	u8	ucDebugData[256];
> +} __attribute__((packed)) tmComResDebugGetData_t;
> +
> +typedef struct
> +{
> +	u32	status;
> +	u32	mode;
> +	u32	devicespec;
> +	u32	deviceinst;
> +	u32	CPULoad;
> +	u32	RemainHeap;
> +	u32	CPUClock;
> +	u32	RAMSpeed;
> +} __attribute__((packed)) tmFwInfoStruct_t;
> +
> diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
> new file mode 100644
> index 0000000..f6211c9
> --- /dev/null
> +++ b/drivers/media/video/saa7164/saa7164-vbi.c
> @@ -0,0 +1,1406 @@
> +/*
> + *  Driver for the NXP SAA7164 PCIe bridge
> + *
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *
> + *  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 "saa7164.h"
> +
> +static struct saa7164_tvnorm saa7164_tvnorms[] = {
> +	{
> +		.name      = "NTSC-M",
> +		.id        = V4L2_STD_NTSC_M,
> +	}, {
> +		.name      = "NTSC-JP",
> +		.id        = V4L2_STD_NTSC_M_JP,
> +	}
> +};
> +
> +static const u32 saa7164_v4l2_ctrls[] = {
> +	0
> +};
> +
> +/* Take the encoder configuration from the port struct and
> + * flush it to the hardware.
> + */
> +static void saa7164_vbi_configure(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	dprintk(DBGLVL_VBI, "%s()\n", __func__);
> +
> +	port->vbi_params.width = port->width;
> +	port->vbi_params.height = port->height;
> +	port->vbi_params.is_50hz =
> +		(port->encodernorm.id & V4L2_STD_625_50) != 0;
> +
> +	/* Set up the DIF (enable it) for analog mode by default */
> +	saa7164_api_initialize_dif(port);
> +
> +//	/* Configure the correct video standard */
> +//	saa7164_api_configure_dif(port, port->encodernorm.id);
> +
> +//	/* Ensure the audio decoder is correct configured */
> +//	saa7164_api_set_audio_std(port);
> +	dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
> +}
> +
> +static int saa7164_vbi_buffers_dealloc(struct saa7164_port *port)
> +{
> +	struct list_head *c, *n, *p, *q, *l, *v;
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_buffer *buf;
> +	struct saa7164_user_buffer *ubuf;
> +
> +	/* Remove any allocated buffers */
> +	mutex_lock(&port->dmaqueue_lock);
> +
> +	dprintk(DBGLVL_VBI, "%s(port=%d) dmaqueue\n", __func__, port->nr);
> +	list_for_each_safe(c, n, &port->dmaqueue.list) {
> +		buf = list_entry(c, struct saa7164_buffer, list);
> +		list_del(c);
> +		saa7164_buffer_dealloc(buf);
> +	}
> +
> +	dprintk(DBGLVL_VBI, "%s(port=%d) used\n", __func__, port->nr);
> +	list_for_each_safe(p, q, &port->list_buf_used.list) {
> +		ubuf = list_entry(p, struct saa7164_user_buffer, list);
> +		list_del(p);
> +		saa7164_buffer_dealloc_user(ubuf);
> +	}
> +
> +	dprintk(DBGLVL_VBI, "%s(port=%d) free\n", __func__, port->nr);
> +	list_for_each_safe(l, v, &port->list_buf_free.list) {
> +		ubuf = list_entry(l, struct saa7164_user_buffer, list);
> +		list_del(l);
> +		saa7164_buffer_dealloc_user(ubuf);
> +	}
> +
> +	mutex_unlock(&port->dmaqueue_lock);
> +	dprintk(DBGLVL_VBI, "%s(port=%d) done\n", __func__, port->nr);
> +
> +	return 0;
> +}
> +
> +/* Dynamic buffer switch at vbi start time */
> +static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_buffer *buf;
> +	struct saa7164_user_buffer *ubuf;
> +	tmHWStreamParameters_t *params = &port->hw_streamingparams;
> +	int result = -ENODEV, i;
> +	int len = 0;
> +
> +	dprintk(DBGLVL_VBI, "%s()\n", __func__);
> +
> +	/* TODO: NTSC SPECIFIC */
> +	/* Init and establish defaults */
> +	params->samplesperline = 1440;
> +	params->numberoflines = 12;
> +	params->numberoflines = 18;
> +	params->pitch = 1600;
> +	params->pitch = 1440;
> +	params->numpagetables = 2 +
> +		((params->numberoflines * params->pitch) / PAGE_SIZE);
> +	params->bitspersample = 8;
> +	params->linethreshold = 0;
> +	params->pagetablelistvirt = 0;
> +	params->pagetablelistphys = 0;
> +	params->numpagetableentries = port->hwcfg.buffercount;
> +
> +	/* Allocate the PCI resources, buffers (hard) */
> +	for (i = 0; i < port->hwcfg.buffercount; i++) {
> +		buf = saa7164_buffer_alloc(port,
> +			params->numberoflines *
> +			params->pitch);
> +
> +		if (!buf) {
> +			printk(KERN_ERR "%s() failed "
> +			       "(errno = %d), unable to allocate buffer\n",
> +				__func__, result);
> +			result = -ENOMEM;
> +			goto failed;
> +		} else {
> +
> +			mutex_lock(&port->dmaqueue_lock);
> +			list_add_tail(&buf->list, &port->dmaqueue.list);
> +			mutex_unlock(&port->dmaqueue_lock);
> +
> +		}
> +	}
> +
> +	/* Allocate some kenrel kernel buffers for copying
> +	 * to userpsace.
> +	 */
> +	len = params->numberoflines * params->pitch;
> +
> +	if (vbi_buffers < 16)
> +		vbi_buffers = 16;
> +	if (vbi_buffers > 512)
> +		vbi_buffers = 512;
> +
> +	for (i = 0; i < vbi_buffers; i++) {
> +
> +		ubuf = saa7164_buffer_alloc_user(dev, len);
> +		if (ubuf) {
> +			mutex_lock(&port->dmaqueue_lock);
> +			list_add_tail(&ubuf->list, &port->list_buf_free.list);
> +			mutex_unlock(&port->dmaqueue_lock);
> +		}
> +
> +	}
> +
> +	result = 0;
> +
> +failed:
> +	return result;
> +}
> +
> +
> +static int saa7164_vbi_initialize(struct saa7164_port *port)
> +{
> +	saa7164_vbi_configure(port);
> +	return 0;
> +}
> +
> +/* -- V4L2 --------------------------------------------------------- */
> +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +	unsigned int i;
> +
> +	dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)*id);
> +
> +	for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
> +		if (*id & saa7164_tvnorms[i].id)
> +			break;
> +	}
> +	if (i == ARRAY_SIZE(saa7164_tvnorms))
> +		return -EINVAL;
> +
> +	port->encodernorm = saa7164_tvnorms[i];
> +
> +	/* Update the audio decoder while is not running in
> +	 * auto detect mode.
> +	 */
> +	saa7164_api_set_audio_std(port);
> +
> +	dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)*id);
> +
> +	return 0;
> +}
> +
> +static int vidioc_enum_input(struct file *file, void *priv,
> +	struct v4l2_input *i)
> +{
> +	int n;
> +
> +	char *inputs[] = { "tuner", "composite", "svideo", "aux",
> +		"composite", "svideo", "aux" };
> +
> +	if (i->index >= 7)
> +		return -EINVAL;
> +
> +	strcpy(i->name, inputs[ i->index ]);
> +
> +	if (i->index == 0)
> +		i->type = V4L2_INPUT_TYPE_TUNER;
> +	else
> +		i->type  = V4L2_INPUT_TYPE_CAMERA;
> +
> +	for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
> +		i->std |= saa7164_tvnorms[n].id;
> +
> +	return 0;
> +}
> +
> +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	if (saa7164_api_get_videomux(port) != SAA_OK)
> +		return -EIO;
> +
> +	*i = (port->mux_input - 1);
> +
> +	dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i);
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i);
> +
> +	if (i >= 7)
> +		return -EINVAL;
> +
> +	port->mux_input = i + 1;
> +
> +	if (saa7164_api_set_videomux(port) != SAA_OK)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int vidioc_g_tuner(struct file *file, void *priv,
> +	struct v4l2_tuner *t)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	if (0 != t->index)
> +		return -EINVAL;
> +
> +	strcpy(t->name, "tuner");
> +	t->type = V4L2_TUNER_ANALOG_TV;
> +	t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
> +
> +	dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_tuner(struct file *file, void *priv,
> +	struct v4l2_tuner *t)
> +{
> +	/* Update the A/V core */
> +	return 0;
> +}
> +
> +static int vidioc_g_frequency(struct file *file, void *priv,
> +	struct v4l2_frequency *f)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +
> +	f->type = V4L2_TUNER_ANALOG_TV;
> +	f->frequency = port->freq;
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_frequency(struct file *file, void *priv,
> +	struct v4l2_frequency *f)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_port *tsport;
> +	struct dvb_frontend *fe;
> +
> +	/* TODO: Pull this for the std */
> +	struct analog_parameters params = {
> +		.mode      = V4L2_TUNER_ANALOG_TV,
> +		.audmode   = V4L2_TUNER_MODE_STEREO,
> +		.std       = port->encodernorm.id,
> +		.frequency = f->frequency
> +	};
> +
> +	/* Stop the encoder */
> +	dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__,
> +		f->frequency, f->tuner);
> +
> +	if (f->tuner != 0)
> +		return -EINVAL;
> +
> +	if (f->type != V4L2_TUNER_ANALOG_TV)
> +		return -EINVAL;
> +
> +	port->freq = f->frequency;
> +
> +	/* Update the hardware */
> +	if (port->nr == SAA7164_PORT_VBI1)
> +		tsport = &dev->ports[ SAA7164_PORT_TS1 ];
> +	else
> +	if (port->nr == SAA7164_PORT_VBI2)
> +		tsport = &dev->ports[ SAA7164_PORT_TS2 ];
> +	else
> +		BUG();
> +
> +	fe = tsport->dvb.frontend;
> +
> +	if (fe && fe->ops.tuner_ops.set_analog_params)
> +		fe->ops.tuner_ops.set_analog_params(fe, &params);
> +	else
> +		printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
> +
> +	saa7164_vbi_initialize(port);
> +
> +	return 0;
> +}
> +
> +static int vidioc_g_ctrl(struct file *file, void *priv,
> +	struct v4l2_control *ctl)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
> +		ctl->id, ctl->value);
> +
> +	switch (ctl->id) {
> +	case V4L2_CID_BRIGHTNESS:
> +		ctl->value = port->ctl_brightness;
> +		break;
> +	case V4L2_CID_CONTRAST:
> +		ctl->value = port->ctl_contrast;
> +		break;
> +	case V4L2_CID_SATURATION:
> +		ctl->value = port->ctl_saturation;
> +		break;
> +	case V4L2_CID_HUE:
> +		ctl->value = port->ctl_hue;
> +		break;
> +	case V4L2_CID_SHARPNESS:
> +		ctl->value = port->ctl_sharpness;
> +		break;
> +	case V4L2_CID_AUDIO_VOLUME:
> +		ctl->value = port->ctl_volume;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_ctrl(struct file *file, void *priv,
> +	struct v4l2_control *ctl)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +	int ret = 0;
> +
> +	dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
> +		ctl->id, ctl->value);
> +
> +	switch (ctl->id) {
> +	case V4L2_CID_BRIGHTNESS:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_brightness = ctl->value;
> +			saa7164_api_set_usercontrol(port,
> +				PU_BRIGHTNESS_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_CONTRAST:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_contrast = ctl->value;
> +			saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_SATURATION:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_saturation = ctl->value;
> +			saa7164_api_set_usercontrol(port,
> +				PU_SATURATION_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_HUE:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_hue = ctl->value;
> +			saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_SHARPNESS:
> +		if ((ctl->value >= 0) && (ctl->value <= 255)) {
> +			port->ctl_sharpness = ctl->value;
> +			saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	case V4L2_CID_AUDIO_VOLUME:
> +		if ((ctl->value >= -83) && (ctl->value <= 24)) {
> +			port->ctl_volume = ctl->value;
> +			saa7164_api_set_audio_volume(port, port->ctl_volume);
> +		} else
> +			ret = -EINVAL;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int saa7164_get_ctrl(struct saa7164_port *port,
> +	struct v4l2_ext_control *ctrl)
> +{
> +	struct saa7164_vbi_params *params = &port->vbi_params;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_MPEG_STREAM_TYPE:
> +		ctrl->value = params->stream_type;
> +		break;
> +	case V4L2_CID_MPEG_AUDIO_MUTE:
> +		ctrl->value = params->ctl_mute;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_ASPECT:
> +		ctrl->value = params->ctl_aspect;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		ctrl->value = params->refdist;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		ctrl->value = params->gop_size;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	return 0;
> +}
> +
> +static int vidioc_g_ext_ctrls(struct file *file, void *priv,
> +	struct v4l2_ext_controls *ctrls)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	int i, err = 0;
> +
> +	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
> +		for (i = 0; i < ctrls->count; i++) {
> +			struct v4l2_ext_control *ctrl = ctrls->controls + i;
> +
> +			err = saa7164_get_ctrl(port, ctrl);
> +			if (err) {
> +				ctrls->error_idx = i;
> +				break;
> +			}
> +		}
> +		return err;
> +
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
> +{
> +	int ret = -EINVAL;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_MPEG_STREAM_TYPE:
> +		if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
> +			(ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_AUDIO_MUTE:
> +		if ((ctrl->value >= 0) &&
> +			(ctrl->value <= 1))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_ASPECT:
> +		if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
> +			(ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		if ((ctrl->value >= 0) &&
> +			(ctrl->value <= 255))
> +			ret = 0;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		if ((ctrl->value >= 1) &&
> +			(ctrl->value <= 3))
> +			ret = 0;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int vidioc_try_ext_ctrls(struct file *file, void *priv,
> +	struct v4l2_ext_controls *ctrls)
> +{
> +	int i, err = 0;
> +
> +	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
> +		for (i = 0; i < ctrls->count; i++) {
> +			struct v4l2_ext_control *ctrl = ctrls->controls + i;
> +
> +			err = saa7164_try_ctrl(ctrl, 0);
> +			if (err) {
> +				ctrls->error_idx = i;
> +				break;
> +			}
> +		}
> +		return err;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int saa7164_set_ctrl(struct saa7164_port *port,
> +	struct v4l2_ext_control *ctrl)
> +{
> +	struct saa7164_vbi_params *params = &port->vbi_params;
> +	int ret = 0;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_MPEG_STREAM_TYPE:
> +		params->stream_type = ctrl->value;
> +		break;
> +	case V4L2_CID_MPEG_AUDIO_MUTE:
> +		params->ctl_mute = ctrl->value;
> +		ret = saa7164_api_audio_mute(port, params->ctl_mute);
> +		if (ret != SAA_OK) {
> +			printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
> +				ret);
> +			ret = -EIO;
> +		}
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_ASPECT:
> +		params->ctl_aspect = ctrl->value;
> +		ret = saa7164_api_set_aspect_ratio(port);
> +		if (ret != SAA_OK) {
> +			printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
> +				ret);
> +			ret = -EIO;
> +		}
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		params->refdist = ctrl->value;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		params->gop_size = ctrl->value;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	/* TODO: Update the hardware */
> +
> +	return ret;
> +}
> +
> +static int vidioc_s_ext_ctrls(struct file *file, void *priv,
> +	struct v4l2_ext_controls *ctrls)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	int i, err = 0;
> +
> +	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
> +		for (i = 0; i < ctrls->count; i++) {
> +			struct v4l2_ext_control *ctrl = ctrls->controls + i;
> +
> +			err = saa7164_try_ctrl(ctrl, 0);
> +			if (err) {
> +				ctrls->error_idx = i;
> +				break;
> +			}
> +			err = saa7164_set_ctrl(port, ctrl);
> +			if (err) {
> +				ctrls->error_idx = i;
> +				break;
> +			}
> +		}
> +		return err;
> +
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int vidioc_querycap(struct file *file, void  *priv,
> +	struct v4l2_capability *cap)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	strcpy(cap->driver, dev->name);
> +	strlcpy(cap->card, saa7164_boards[dev->board].name,
> +		sizeof(cap->card));
> +	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
> +
> +	cap->capabilities =
> +		V4L2_CAP_VBI_CAPTURE |
> +		V4L2_CAP_READWRITE     |
> +		V4L2_CAP_STREAMING     |
> +		0;
> +
> +	cap->capabilities |= V4L2_CAP_TUNER;
> +	cap->version = 0;
> +
> +	return 0;
> +}
> +
> +static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
> +	struct v4l2_fmtdesc *f)
> +{
> +	if (f->index != 0)
> +		return -EINVAL;
> +
> +	strlcpy(f->description, "VBI", sizeof(f->description));
> +	f->pixelformat = V4L2_PIX_FMT_MPEG;
> +
> +	return 0;
> +}
> +
> +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
> +				struct v4l2_format *f)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
> +	f->fmt.pix.bytesperline = 0;
> +	f->fmt.pix.sizeimage    =
> +		port->ts_packet_size * port->ts_packet_count;
> +	f->fmt.pix.colorspace   = 0;
> +	f->fmt.pix.width        = port->width;
> +	f->fmt.pix.height       = port->height;
> +
> +	dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n",
> +		port->width, port->height);
> +
> +	return 0;
> +}
> +
> +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
> +				struct v4l2_format *f)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
> +	f->fmt.pix.bytesperline = 0;
> +	f->fmt.pix.sizeimage    =
> +		port->ts_packet_size * port->ts_packet_count;
> +	f->fmt.pix.colorspace   = 0;
> +	dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
> +		port->width, port->height);
> +	return 0;
> +}
> +
> +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
> +				struct v4l2_format *f)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
> +	f->fmt.pix.bytesperline = 0;
> +	f->fmt.pix.sizeimage    =
> +		port->ts_packet_size * port->ts_packet_count;
> +	f->fmt.pix.colorspace   = 0;
> +
> +	dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
> +		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
> +
> +	return 0;
> +}
> +
> +static int vidioc_log_status(struct file *file, void *priv)
> +{
> +	return 0;
> +}
> +
> +static int fill_queryctrl(struct saa7164_vbi_params *params,
> +	struct v4l2_queryctrl *c)
> +{
> +	switch (c->id) {
> +	case V4L2_CID_BRIGHTNESS:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
> +	case V4L2_CID_CONTRAST:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
> +	case V4L2_CID_SATURATION:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
> +	case V4L2_CID_HUE:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
> +	case V4L2_CID_SHARPNESS:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
> +	case V4L2_CID_MPEG_AUDIO_MUTE:
> +		return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
> +	case V4L2_CID_AUDIO_VOLUME:
> +		return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
> +	case V4L2_CID_MPEG_STREAM_TYPE:
> +		return v4l2_ctrl_query_fill(c,
> +			V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
> +			V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
> +			1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
> +	case V4L2_CID_MPEG_VIDEO_ASPECT:
> +		return v4l2_ctrl_query_fill(c,
> +			V4L2_MPEG_VIDEO_ASPECT_1x1,
> +			V4L2_MPEG_VIDEO_ASPECT_221x100,
> +			1, V4L2_MPEG_VIDEO_ASPECT_4x3);
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		return v4l2_ctrl_query_fill(c,
> +			1, 3, 1, 1);
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int vidioc_queryctrl(struct file *file, void *priv,
> +	struct v4l2_queryctrl *c)
> +{
> +	struct saa7164_vbi_fh *fh = priv;
> +	struct saa7164_port *port = fh->port;
> +	int i, next;
> +	u32 id = c->id;
> +
> +	memset(c, 0, sizeof(*c));
> +
> +	next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
> +	c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
> +
> +	for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
> +		if (next) {
> +			if (c->id < saa7164_v4l2_ctrls[i])
> +				c->id = saa7164_v4l2_ctrls[i];
> +			else
> +				continue;
> +		}
> +
> +		if (c->id == saa7164_v4l2_ctrls[i])
> +			return fill_queryctrl(&port->vbi_params, c);
> +
> +		if (c->id < saa7164_v4l2_ctrls[i])
> +			break;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int saa7164_vbi_stop_port(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +
> +	ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
> +	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
> +			__func__, ret);
> +		ret = -EIO;
> +	} else {
> +		dprintk(DBGLVL_VBI, "%s()    Stopped\n", __func__);
> +		ret = 0;
> +	}
> +
> +	return ret;
> +}
> +
> +static int saa7164_vbi_acquire_port(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +
> +	ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
> +	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
> +			__func__, ret);
> +		ret = -EIO;
> +	} else {
> +		dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
> +		ret = 0;
> +	}
> +
> +	return ret;
> +}
> +
> +static int saa7164_vbi_pause_port(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int ret;
> +
> +	ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
> +	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
> +			__func__, ret);
> +		ret = -EIO;
> +	} else {
> +		dprintk(DBGLVL_VBI, "%s()   Paused\n", __func__);
> +		ret = 0;
> +	}
> +
> +	return ret;
> +}
> +
> +/* Firmware is very windows centric, meaning you have to transition
> + * the part through AVStream / KS Windows stages, forwards or backwards.
> + * States are: stopped, acquired (h/w), paused, started.
> + * We have to leave here will all of the soft buffers on the free list,
> + * else the cfg_post() func won't have soft buffers to correctly configure.
> + */
> +static int saa7164_vbi_stop_streaming(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	struct saa7164_buffer *buf;
> +	struct saa7164_user_buffer *ubuf;
> +	struct list_head *c, *n;
> +	int ret;
> +
> +	dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
> +
> +	ret = saa7164_vbi_pause_port(port);
> +	ret = saa7164_vbi_acquire_port(port);
> +	ret = saa7164_vbi_stop_port(port);
> +
> +	dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__,
> +		port->nr);
> +
> +	/* Reset the state of any allocated buffer resources */
> +	mutex_lock(&port->dmaqueue_lock);
> +
> +	/* Reset the hard and soft buffer state */
> +	list_for_each_safe(c, n, &port->dmaqueue.list) {
> +		buf = list_entry(c, struct saa7164_buffer, list);
> +		buf->flags = SAA7164_BUFFER_FREE;
> +		buf->pos = 0;
> +	}
> +
> +	list_for_each_safe(c, n, &port->list_buf_used.list) {
> +		ubuf = list_entry(c, struct saa7164_user_buffer, list);
> +		ubuf->pos = 0;
> +		list_move_tail(&ubuf->list, &port->list_buf_free.list);
> +	}
> +
> +	mutex_unlock(&port->dmaqueue_lock);
> +
> +	/* Free any allocated resources */
> +	saa7164_vbi_buffers_dealloc(port);
> +
> +	dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr);
> +
> +	return ret;
> +}
> +
> +static int saa7164_vbi_start_streaming(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int result, ret = 0;
> +
> +	dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
> +
> +	port->done_first_interrupt = 0;
> +
> +	/* allocate all of the PCIe DMA buffer resources on the fly,
> +	 * allowing switching between TS and PS payloads without
> +	 * requiring a complete driver reload.
> +	 */
> +	saa7164_vbi_buffers_alloc(port);
> +
> +	/* Configure the encoder with any cache values */
> +//	saa7164_api_set_encoder(port);
> +//	saa7164_api_get_encoder(port);
> +
> +	/* Place the empty buffers on the hardware */
> +	saa7164_buffer_cfg_port(port);
> +
> +	/* Negotiate format */
> +	if (saa7164_api_set_vbi_format(port) != SAA_OK) {
> +		printk(KERN_ERR "%s() No supported VBI format\n", __func__);
> +		ret = -EIO;
> +		goto out;
> +	}
> +
> +	/* Acquire the hardware */
> +	result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
> +	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
> +			__func__, result);
> +
> +		ret = -EIO;
> +		goto out;
> +	} else
> +		dprintk(DBGLVL_VBI, "%s()   Acquired\n", __func__);
> +
> +	/* Pause the hardware */
> +	result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
> +	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
> +				__func__, result);
> +
> +		/* Stop the hardware, regardless */
> +		result = saa7164_vbi_stop_port(port);
> +		if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +			printk(KERN_ERR "%s() pause/forced stop transition "
> +				"failed, res = 0x%x\n", __func__, result);
> +		}
> +
> +		ret = -EIO;
> +		goto out;
> +	} else
> +		dprintk(DBGLVL_VBI, "%s()   Paused\n", __func__);
> +
> +	/* Start the hardware */
> +	result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
> +	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +		printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
> +				__func__, result);
> +
> +		/* Stop the hardware, regardless */
> +		result = saa7164_vbi_acquire_port(port);
> +		result = saa7164_vbi_stop_port(port);
> +		if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
> +			printk(KERN_ERR "%s() run/forced stop transition "
> +				"failed, res = 0x%x\n", __func__, result);
> +		}
> +
> +		ret = -EIO;
> +	} else
> +		dprintk(DBGLVL_VBI, "%s()   Running\n", __func__);
> +
> +out:
> +	return ret;
> +}
> +
> +int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f)
> +{
> +	/* ntsc */
> +	f->fmt.vbi.samples_per_line = 1600;
> +	f->fmt.vbi.samples_per_line = 1440;
> +	f->fmt.vbi.sampling_rate = 27000000;
> +	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
> +	f->fmt.vbi.offset = 0;
> +	f->fmt.vbi.flags = 0;
> +	f->fmt.vbi.start[0] = 10;
> +	f->fmt.vbi.count[0] = 18;
> +	f->fmt.vbi.start[1] = 263 + 10 + 1;
> +	f->fmt.vbi.count[1] = 18;
> +	return 0;
> +}
> +
> +static int fops_open(struct file *file)
> +{
> +	struct saa7164_dev *h, *dev = NULL;
> +	struct saa7164_port *port = NULL;
> +	struct saa7164_port *porte = NULL;
> +	struct saa7164_port *portf = NULL;
> +	struct saa7164_vbi_fh *fh;
> +	struct list_head *list;
> +	int minor = video_devdata(file)->minor;
> +
> +	dprintk(DBGLVL_VBI, "%s()\n", __func__);
> +
> +	/* TODO: Really, the BKL? - remove this */
> +	lock_kernel();
> +	list_for_each(list, &saa7164_devlist) {
> +		h = list_entry(list, struct saa7164_dev, devlist);
> +
> +		porte = &h->ports[ SAA7164_PORT_VBI1 ];
> +		portf = &h->ports[ SAA7164_PORT_VBI2 ];
> +
> +		if (porte->v4l_device &&
> +		    porte->v4l_device->minor == minor) {
> +			dev = h;
> +			port = porte;
> +			break;
> +		}
> +
> +		if (portf->v4l_device &&
> +		    portf->v4l_device->minor == minor) {
> +			dev = h;
> +			port = portf;
> +			break;
> +		}
> +
> +	}
> +
> +	if (port == NULL) {
> +		unlock_kernel();
> +		return -ENODEV;
> +	}
> +
> +	/* allocate + initialize per filehandle data */
> +	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
> +	if (NULL == fh) {
> +		unlock_kernel();
> +		return -ENOMEM;
> +	}
> +
> +	file->private_data = fh;
> +	fh->port = port;
> +
> +	unlock_kernel();
> +
> +	return 0;
> +}
> +
> +static int fops_release(struct file *file)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_VBI, "%s()\n", __func__);
> +
> +	/* Shut device down on last close */
> +	if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
> +		if (atomic_dec_return(&port->v4l_reader_count) == 0) {
> +			/* stop vbi capture then cancel buffers */
> +			saa7164_vbi_stop_streaming(port);
> +		}
> +	}
> +
> +	file->private_data = NULL;
> +	kfree(fh);
> +
> +	return 0;
> +}
> +
> +struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
> +{
> +	struct saa7164_user_buffer *ubuf = 0;
> +	struct saa7164_dev *dev = port->dev;
> +	u32 crc;
> +
> +	mutex_lock(&port->dmaqueue_lock);
> +	if (!list_empty(&port->list_buf_used.list)) {
> +		ubuf = list_first_entry(&port->list_buf_used.list,
> +			struct saa7164_user_buffer, list);
> +
> +		if (crc_checking) {
> +			crc = crc32(0, ubuf->data, ubuf->actual_size);
> +			if (crc != ubuf->crc) {
> +				printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
> +					ubuf, ubuf->crc, crc);
> +			}
> +		}
> +
> +	}
> +	mutex_unlock(&port->dmaqueue_lock);
> +
> +	dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf);
> +
> +	return ubuf;
> +}
> +
> +static ssize_t fops_read(struct file *file, char __user *buffer,
> +	size_t count, loff_t *pos)
> +{
> +	struct saa7164_vbi_fh *fh = file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_user_buffer *ubuf = NULL;
> +	struct saa7164_dev *dev = port->dev;
> +	unsigned int ret = 0;
> +	int rem, cnt;
> +	u8 *p;
> +
> +	port->last_read_msecs_diff = port->last_read_msecs;
> +	port->last_read_msecs = jiffies_to_msecs(jiffies);
> +	port->last_read_msecs_diff = port->last_read_msecs -
> +		port->last_read_msecs_diff;
> +
> +	saa7164_histogram_update(&port->read_interval,
> +		port->last_read_msecs_diff);
> +
> +	if (*pos) {
> +		printk(KERN_ERR "%s() ESPIPE\n", __func__);
> +		return -ESPIPE;
> +	}
> +
> +	if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
> +		if (atomic_inc_return(&port->v4l_reader_count) == 1) {
> +
> +			if (saa7164_vbi_initialize(port) < 0) {
> +				printk(KERN_ERR "%s() EINVAL\n", __func__);
> +				return -EINVAL;
> +			}
> +
> +			saa7164_vbi_start_streaming(port);
> +			msleep(200);
> +		}
> +	}
> +
> +	/* blocking wait for buffer */
> +	if ((file->f_flags & O_NONBLOCK) == 0) {
> +		if (wait_event_interruptible(port->wait_read,
> +			saa7164_vbi_next_buf(port))) {
> +				printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
> +				return -ERESTARTSYS;
> +		}
> +	}
> +
> +	/* Pull the first buffer from the used list */
> +	ubuf = saa7164_vbi_next_buf(port);
> +
> +	while ((count > 0) && ubuf) {
> +
> +		/* set remaining bytes to copy */
> +		rem = ubuf->actual_size - ubuf->pos;
> +		cnt = rem > count ? count : rem;
> +
> +		p = ubuf->data + ubuf->pos;
> +
> +		dprintk(DBGLVL_VBI,
> +			"%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
> +			__func__, (int)count, cnt, rem, ubuf, ubuf->pos);
> +
> +		if (copy_to_user(buffer, p, cnt)) {
> +			printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
> +			if (!ret) {
> +				printk(KERN_ERR "%s() EFAULT\n", __func__);
> +				ret = -EFAULT;
> +			}
> +			goto err;
> +		}
> +
> +		ubuf->pos += cnt;
> +		count -= cnt;
> +		buffer += cnt;
> +		ret += cnt;
> +
> +		if (ubuf->pos > ubuf->actual_size) {
> +			printk(KERN_ERR "read() pos > actual, huh?\n");
> +		}
> +
> +		if (ubuf->pos == ubuf->actual_size) {
> +
> +			/* finished with current buffer, take next buffer */
> +
> +			/* Requeue the buffer on the free list */
> +			ubuf->pos = 0;
> +
> +			mutex_lock(&port->dmaqueue_lock);
> +			list_move_tail(&ubuf->list, &port->list_buf_free.list);
> +			mutex_unlock(&port->dmaqueue_lock);
> +
> +			/* Dequeue next */
> +			if ((file->f_flags & O_NONBLOCK) == 0) {
> +				if (wait_event_interruptible(port->wait_read,
> +					saa7164_vbi_next_buf(port))) {
> +						break;
> +				}
> +			}
> +			ubuf = saa7164_vbi_next_buf(port);
> +		}
> +	}
> +err:
> +	if (!ret && !ubuf) {
> +		printk(KERN_ERR "%s() EAGAIN\n", __func__);
> +		ret = -EAGAIN;
> +	}
> +
> +	return ret;
> +}
> +
> +static unsigned int fops_poll(struct file *file, poll_table *wait)
> +{
> +	struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data;
> +	struct saa7164_port *port = fh->port;
> +	struct saa7164_user_buffer *ubuf;
> +	unsigned int mask = 0;
> +
> +	port->last_poll_msecs_diff = port->last_poll_msecs;
> +	port->last_poll_msecs = jiffies_to_msecs(jiffies);
> +	port->last_poll_msecs_diff = port->last_poll_msecs -
> +		port->last_poll_msecs_diff;
> +
> +	saa7164_histogram_update(&port->poll_interval,
> +		port->last_poll_msecs_diff);
> +
> +	if (!video_is_registered(port->v4l_device)) {
> +		return -EIO;
> +	}
> +
> +	if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
> +		if (atomic_inc_return(&port->v4l_reader_count) == 1) {
> +			if (saa7164_vbi_initialize(port) < 0)
> +				return -EINVAL;
> +			saa7164_vbi_start_streaming(port);
> +			msleep(200);
> +		}
> +	}
> +
> +	/* blocking wait for buffer */
> +	if ((file->f_flags & O_NONBLOCK) == 0) {
> +		if (wait_event_interruptible(port->wait_read,
> +			saa7164_vbi_next_buf(port))) {
> +				return -ERESTARTSYS;
> +		}
> +	}
> +
> +	/* Pull the first buffer from the used list */
> +	ubuf = list_first_entry(&port->list_buf_used.list,
> +		struct saa7164_user_buffer, list);
> +
> +	if (ubuf)
> +		mask |= POLLIN | POLLRDNORM;
> +
> +	return mask;
> +}
> +static const struct v4l2_file_operations vbi_fops = {
> +	.owner		= THIS_MODULE,
> +	.open		= fops_open,
> +	.release	= fops_release,
> +	.read		= fops_read,
> +	.poll		= fops_poll,
> +	.unlocked_ioctl	= video_ioctl2,
> +};
> +
> +static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
> +	.vidioc_s_std		 = vidioc_s_std,
> +	.vidioc_enum_input	 = vidioc_enum_input,
> +	.vidioc_g_input		 = vidioc_g_input,
> +	.vidioc_s_input		 = vidioc_s_input,
> +	.vidioc_g_tuner		 = vidioc_g_tuner,
> +	.vidioc_s_tuner		 = vidioc_s_tuner,
> +	.vidioc_g_frequency	 = vidioc_g_frequency,
> +	.vidioc_s_frequency	 = vidioc_s_frequency,
> +	.vidioc_s_ctrl		 = vidioc_s_ctrl,
> +	.vidioc_g_ctrl		 = vidioc_g_ctrl,
> +	.vidioc_querycap	 = vidioc_querycap,
> +	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
> +	.vidioc_g_fmt_vid_cap	 = vidioc_g_fmt_vid_cap,
> +	.vidioc_try_fmt_vid_cap	 = vidioc_try_fmt_vid_cap,
> +	.vidioc_s_fmt_vid_cap	 = vidioc_s_fmt_vid_cap,
> +	.vidioc_g_ext_ctrls	 = vidioc_g_ext_ctrls,
> +	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
> +	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
> +	.vidioc_log_status	 = vidioc_log_status,
> +	.vidioc_queryctrl	 = vidioc_queryctrl,
> +//	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,
> +#ifdef CONFIG_VIDEO_ADV_DEBUG
> +//	.vidioc_g_register	 = saa7164_g_register,
> +//	.vidioc_s_register	 = saa7164_s_register,
> +#endif
> +	.vidioc_g_fmt_vbi_cap	 = saa7164_vbi_fmt,
> +	.vidioc_try_fmt_vbi_cap	 = saa7164_vbi_fmt,
> +	.vidioc_s_fmt_vbi_cap	 = saa7164_vbi_fmt,
> +};
> +
> +static struct video_device saa7164_vbi_template = {
> +	.name          = "saa7164",
> +	.fops          = &vbi_fops,
> +	.ioctl_ops     = &vbi_ioctl_ops,
> +	.minor         = -1,
> +	.tvnorms       = SAA7164_NORMS,
> +	.current_norm  = V4L2_STD_NTSC_M,
> +};
> +
> +static struct video_device *saa7164_vbi_alloc(
> +	struct saa7164_port *port,
> +	struct pci_dev *pci,
> +	struct video_device *template,
> +	char *type)
> +{
> +	struct video_device *vfd;
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_VBI, "%s()\n", __func__);
> +
> +	vfd = video_device_alloc();
> +	if (NULL == vfd)
> +		return NULL;
> +
> +	*vfd = *template;
> +	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
> +		type, saa7164_boards[dev->board].name);
> +
> +	vfd->parent  = &pci->dev;
> +	vfd->release = video_device_release;
> +	return vfd;
> +}
> +
> +int saa7164_vbi_register(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +	int result = -ENODEV;
> +
> +	dprintk(DBGLVL_VBI, "%s()\n", __func__);
> +
> +	if (port->type != SAA7164_MPEG_VBI)
> +		BUG();
> +
> +	/* Sanity check that the PCI configuration space is active */
> +	if (port->hwcfg.BARLocation == 0) {
> +		printk(KERN_ERR "%s() failed "
> +		       "(errno = %d), NO PCI configuration\n",
> +			__func__, result);
> +		result = -ENOMEM;
> +		goto failed;
> +	}
> +
> +	/* Establish VBI defaults here */
> +
> +	/* Allocate and register the video device node */
> +	port->v4l_device = saa7164_vbi_alloc(port,
> +		dev->pci, &saa7164_vbi_template, "vbi");
> +
> +	if (port->v4l_device == NULL) {
> +		printk(KERN_INFO "%s: can't allocate vbi device\n",
> +			dev->name);
> +		result = -ENOMEM;
> +		goto failed;
> +	}
> +
> +	result = video_register_device(port->v4l_device,
> +		VFL_TYPE_VBI, -1);
> +	if (result < 0) {
> +		printk(KERN_INFO "%s: can't register vbi device\n",
> +			dev->name);
> +		/* TODO: We're going to leak here if we don't dealloc
> +		 The buffers above. The unreg function can't deal wit it.
> +		*/
> +		goto failed;
> +	}
> +
> +	printk(KERN_INFO "%s: registered device vbi%d [vbi]\n",
> +		dev->name, port->v4l_device->num);
> +
> +	/* Configure the hardware defaults */
> +
> +	result = 0;
> +failed:
> +	return result;
> +}
> +
> +void saa7164_vbi_unregister(struct saa7164_port *port)
> +{
> +	struct saa7164_dev *dev = port->dev;
> +
> +	dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
> +
> +	if (port->type != SAA7164_MPEG_VBI)
> +		BUG();
> +
> +	if (port->v4l_device) {
> +		if (port->v4l_device->minor != -1)
> +			video_unregister_device(port->v4l_device);
> +		else
> +			video_device_release(port->v4l_device);
> +
> +		port->v4l_device = NULL;
> +	}
> +
> +}
> diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
> index 42660b5..f16b3f9 100644
> --- a/drivers/media/video/saa7164/saa7164.h
> +++ b/drivers/media/video/saa7164/saa7164.h
> @@ -1,7 +1,7 @@
>  /*
>   *  Driver for the NXP SAA7164 PCIe bridge
>   *
> - *  Copyright (c) 2009 Steven Toth <stoth@xxxxxxxxxxxxxx>
> + *  Copyright (c) 2010 Steven Toth <stoth@xxxxxxxxxxxxxx>
>   *
>   *  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
> @@ -48,18 +48,29 @@
>  #include <linux/i2c.h>
>  #include <linux/i2c-algo-bit.h>
>  #include <linux/kdev_t.h>
> +#include <linux/version.h>
> +#include <linux/mutex.h>
> +#include <linux/crc32.h>
> +#include <linux/kthread.h>
> +#include <linux/freezer.h>
>  
>  #include <media/tuner.h>
>  #include <media/tveeprom.h>
>  #include <media/videobuf-dma-sg.h>
>  #include <media/videobuf-dvb.h>
> +#include <linux/smp_lock.h>
> +#include <dvb_demux.h>
> +#include <dvb_frontend.h>
> +#include <dvb_net.h>
> +#include <dvbdev.h>
> +#include <dmxdev.h>
> +#include <media/v4l2-common.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/v4l2-chip-ident.h>
>  
>  #include "saa7164-reg.h"
>  #include "saa7164-types.h"
>  
> -#include <linux/version.h>
> -#include <linux/mutex.h>
> -
>  #define SAA7164_MAXBOARDS 8
>  
>  #define UNSET (-1U)
> @@ -76,7 +87,19 @@
>  
>  #define SAA7164_MAX_UNITS		8
>  #define SAA7164_TS_NUMBER_OF_LINES	312
> +#define SAA7164_PS_NUMBER_OF_LINES	256
>  #define SAA7164_PT_ENTRIES		16 /* (312 * 188) / 4096 */
> +#define SAA7164_MAX_ENCODER_BUFFERS	64 /* max 5secs of latency at 6Mbps */
> +#define SAA7164_MAX_VBI_BUFFERS		64
> +
> +/* Port related defines */
> +#define SAA7164_PORT_TS1	(0)
> +#define SAA7164_PORT_TS2	(SAA7164_PORT_TS1 + 1)
> +#define SAA7164_PORT_ENC1	(SAA7164_PORT_TS2 + 1)
> +#define SAA7164_PORT_ENC2	(SAA7164_PORT_ENC1 + 1)
> +#define SAA7164_PORT_VBI1	(SAA7164_PORT_ENC2 + 1)
> +#define SAA7164_PORT_VBI2	(SAA7164_PORT_VBI1 + 1)
> +#define SAA7164_MAX_PORTS	(SAA7164_PORT_VBI2 + 1)
>  
>  #define DBGLVL_FW    4
>  #define DBGLVL_DVB   8
> @@ -86,10 +109,18 @@
>  #define DBGLVL_BUS 128
>  #define DBGLVL_IRQ 256
>  #define DBGLVL_BUF 512
> +#define DBGLVL_ENC 1024
> +#define DBGLVL_VBI 2048
> +#define DBGLVL_THR 4096
> +#define DBGLVL_CPU 8192
> +
> +#define SAA7164_NORMS ( V4L2_STD_NTSC_M |  V4L2_STD_NTSC_M_JP |  V4L2_STD_NTSC_443 )
>  
>  enum port_t {
>  	SAA7164_MPEG_UNDEFINED = 0,
>  	SAA7164_MPEG_DVB,
> +	SAA7164_MPEG_ENCODER,
> +	SAA7164_MPEG_VBI,
>  };
>  
>  enum saa7164_i2c_bus_nr {
> @@ -134,7 +165,8 @@ struct saa7164_unit {
>  
>  struct saa7164_board {
>  	char	*name;
> -	enum port_t porta, portb;
> +	enum port_t porta, portb, portc,
> +		portd, porte, portf;
>  	enum {
>  		SAA7164_CHIP_UNDEFINED = 0,
>  		SAA7164_CHIP_REV2,
> @@ -149,6 +181,42 @@ struct saa7164_subid {
>  	u32     card;
>  };
>  
> +struct saa7164_encoder_fh {
> +	struct saa7164_port *port;
> +//	u32 freq;
> +//	u32 tuner_type;
> +	atomic_t v4l_reading;
> +};
> +
> +struct saa7164_vbi_fh {
> +	struct saa7164_port *port;
> +//	u32 freq;
> +//	u32 tuner_type;
> +	atomic_t v4l_reading;
> +};
> +
> +struct saa7164_histogram_bucket {
> +	u32 val;
> +	u32 count;
> +	u64 update_time;
> +};
> +
> +struct saa7164_histogram {
> +	char name[32];
> +	struct saa7164_histogram_bucket counter1[64];
> +};
> +
> +struct saa7164_user_buffer {
> +	struct list_head list;
> +
> +	/* Attributes */
> +	u8  *data;
> +	u32 pos;
> +	u32 actual_size;
> +
> +	u32 crc;
> +};
> +
>  struct saa7164_fw_status {
>  
>  	/* RISC Core details */
> @@ -191,14 +259,60 @@ struct saa7164_i2c {
>  	u32				i2c_rc;
>  };
>  
> -struct saa7164_tsport;
> +struct saa7164_ctrl {
> +	struct v4l2_queryctrl v;
> +};
> +
> +struct saa7164_tvnorm {
> +	char		*name;
> +	v4l2_std_id	id;
> +//	u32		cxiformat;
> +//	u32		cxoformat;
> +};
> +
> +struct saa7164_encoder_params {
> +	struct saa7164_tvnorm encodernorm;
> +	u32 height;
> +	u32 width;
> +	u32 is_50hz;
> +	u32 bitrate; /* bps */
> +	u32 bitrate_peak; /* bps */
> +	u32 bitrate_mode;
> +	u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */
> +
> +	u32 audio_sampling_freq;
> +	u32 ctl_mute;
> +	u32 ctl_aspect;
> +	u32 refdist;
> +	u32 gop_size;
> +};
> +
> +struct saa7164_vbi_params {
> +	struct saa7164_tvnorm encodernorm;
> +	u32 height;
> +	u32 width;
> +	u32 is_50hz;
> +	u32 bitrate; /* bps */
> +	u32 bitrate_peak; /* bps */
> +	u32 bitrate_mode;
> +	u32 stream_type; /* V4L2_MPEG_STREAM_TYPE_MPEG2_TS */
> +
> +	u32 audio_sampling_freq;
> +	u32 ctl_mute;
> +	u32 ctl_aspect;
> +	u32 refdist;
> +	u32 gop_size;
> +};
> +
> +struct saa7164_port;
>  
>  struct saa7164_buffer {
>  	struct list_head list;
>  
> -	u32 nr;
> +	/* Note of which h/w buffer list index position we occupy */
> +	int idx;
>  
> -	struct saa7164_tsport *port;
> +	struct saa7164_port *port;
>  
>  	/* Hardware Specific */
>  	/* PCI Memory allocations */
> @@ -206,24 +320,29 @@ struct saa7164_buffer {
>  
>  	/* A block of page align PCI memory */
>  	u32 pci_size;	/* PCI allocation size in bytes */
> -	u64 *cpu;	/* Virtual address */
> +	u64 __iomem *cpu;	/* Virtual address */
>  	dma_addr_t dma;	/* Physical address */
> +	u32 crc;	/* Checksum for the entire buffer data */
>  
>  	/* A page table that splits the block into a number of entries */
>  	u32 pt_size;		/* PCI allocation size in bytes */
> -	u64 *pt_cpu;		/* Virtual address */
> +	u64 __iomem *pt_cpu;		/* Virtual address */
>  	dma_addr_t pt_dma;	/* Physical address */
> +
> +	/* Encoder fops */
> +	u32 pos;
> +	u32 actual_size;
>  };
>  
> -struct saa7164_tsport {
> +struct saa7164_port {
>  
>  	struct saa7164_dev *dev;
> -	int nr;
>  	enum port_t type;
> +	int nr;
>  
> -	struct saa7164_dvb dvb;
> +	/* --- Generic port attributes --- */
>  
> -	/* HW related stream parameters */
> +	/* HW stream parameters */
>  	tmHWStreamParameters_t hw_streamingparams;
>  
>  	/* DMA configuration values, is seeded during initialization */
> @@ -239,11 +358,76 @@ struct saa7164_tsport {
>  	u64 bufptr64;
>  
>  	u32 numpte;	/* Number of entries in array, only valid in head */
> +
>  	struct mutex dmaqueue_lock;
> -	struct mutex dummy_dmaqueue_lock;
>  	struct saa7164_buffer dmaqueue;
> -	struct saa7164_buffer dummy_dmaqueue;
>  
> +	u64 last_irq_msecs, last_svc_msecs;
> +	u64 last_irq_msecs_diff, last_svc_msecs_diff;
> +	u32 last_svc_wp;
> +	u32 last_svc_rp;
> +	u64 last_irq_svc_msecs_diff;
> +	u64 last_read_msecs, last_read_msecs_diff;
> +	u64 last_poll_msecs, last_poll_msecs_diff;
> +
> +	struct saa7164_histogram irq_interval;
> +	struct saa7164_histogram svc_interval;
> +	struct saa7164_histogram irq_svc_interval;
> +	struct saa7164_histogram read_interval;
> +	struct saa7164_histogram poll_interval;
> +
> +	/* --- DVB Transport Specific --- */
> +	struct saa7164_dvb dvb;
> +
> +	/* --- Encoder/V4L related attributes --- */
> +	/* Encoder */
> +	/* Defaults established in saa7164-encoder.c */
> +	struct saa7164_tvnorm encodernorm;
> +	u32 height;
> +	u32 width;
> +	u32 freq;
> +	u32 ts_packet_size;
> +	u32 ts_packet_count;
> +	u8 mux_input;
> +	u8 encoder_profile;
> +	u8 video_format;
> +	u8 audio_format;
> +	u8 video_resolution;
> +	u16 ctl_brightness;
> +	u16 ctl_contrast;
> +	u16 ctl_hue;
> +	u16 ctl_saturation;
> +	u16 ctl_sharpness;
> +	s8 ctl_volume;
> +
> +	tmComResAFeatureDescrHeader_t audfeat;
> +	tmComResEncoderDescrHeader_t encunit;
> +	tmComResProcDescrHeader_t vidproc;
> +	tmComResExtDevDescrHeader_t ifunit;
> +	tmComResTunerDescrHeader_t tunerunit;
> +
> +	struct work_struct workenc;
> +
> +	/* V4L Encoder Video */
> +	struct saa7164_encoder_params encoder_params;
> +	struct video_device *v4l_device;
> +	atomic_t v4l_reader_count;
> +
> +	struct saa7164_buffer list_buf_used;
> +	struct saa7164_buffer list_buf_free;
> +	wait_queue_head_t wait_read;
> +
> +	/* V4L VBI */
> +	tmComResVBIFormatDescrHeader_t vbi_fmt_ntsc;
> +	struct saa7164_vbi_params vbi_params;
> +
> +	/* Debug */
> +	u32 sync_errors;
> +	u32 v_cc_errors;
> +	u32 a_cc_errors;
> +	u8 last_v_cc;
> +	u8 last_a_cc;
> +	u32 done_first_interrupt;
>  };
>  
>  struct saa7164_dev {
> @@ -286,15 +470,22 @@ struct saa7164_dev {
>  	struct saa7164_i2c i2c_bus[3];
>  
>  	/* Transport related */
> -	struct saa7164_tsport ts1, ts2;
> +	struct saa7164_port ports[ SAA7164_MAX_PORTS ];
>  
>  	/* Deferred command/api interrupts handling */
>  	struct work_struct workcmd;
>  
> +	/* A kernel thread to monitor the firmware log, used
> +	 * only in debug mode.
> +	 */
> +	struct task_struct *kthread;
> +
>  };
>  
>  extern struct list_head saa7164_devlist;
>  extern unsigned int waitsecs;
> +extern unsigned int encoder_buffers;
> +extern unsigned int vbi_buffers;
>  
>  /* ----------------------------------------------------------- */
>  /* saa7164-core.c                                              */
> @@ -302,6 +493,7 @@ void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr);
>  void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len);
>  void saa7164_getfirmwarestatus(struct saa7164_dev *dev);
>  u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev);
> +void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val);
>  
>  /* ----------------------------------------------------------- */
>  /* saa7164-fw.c                                                */
> @@ -343,7 +535,24 @@ int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr,
>  int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen);
>  int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
>  int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
> -int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode);
> +int saa7164_api_transition_port(struct saa7164_port *port, u8 mode);
> +int saa7164_api_initialize_dif(struct saa7164_port *port);
> +int saa7164_api_configure_dif(struct saa7164_port *port, u32 std);
> +int saa7164_api_set_encoder(struct saa7164_port *port);
> +int saa7164_api_get_encoder(struct saa7164_port *port);
> +int saa7164_api_set_aspect_ratio(struct saa7164_port *port);
> +int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl);
> +int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl);
> +int saa7164_api_set_videomux(struct saa7164_port *port);
> +int saa7164_api_audio_mute(struct saa7164_port *port, int mute);
> +int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level);
> +int saa7164_api_set_audio_std(struct saa7164_port *port);
> +int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect);
> +int saa7164_api_get_videomux(struct saa7164_port *port);
> +int saa7164_api_set_vbi_format(struct saa7164_port *port);
> +int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level);
> +int saa7164_api_collect_debug(struct saa7164_dev *dev);
> +int saa7164_api_get_load_info(struct saa7164_dev *dev, tmFwInfoStruct_t *i);
>  
>  /* ----------------------------------------------------------- */
>  /* saa7164-cards.c                                             */
> @@ -363,18 +572,36 @@ extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid);
>  
>  /* ----------------------------------------------------------- */
>  /* saa7164-dvb.c                                               */
> -extern int saa7164_dvb_register(struct saa7164_tsport *port);
> -extern int saa7164_dvb_unregister(struct saa7164_tsport *port);
> +extern int saa7164_dvb_register(struct saa7164_port *port);
> +extern int saa7164_dvb_unregister(struct saa7164_port *port);
>  
>  /* ----------------------------------------------------------- */
>  /* saa7164-buffer.c                                            */
> -extern struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
> -	u32 len);
> -extern int saa7164_buffer_dealloc(struct saa7164_tsport *port,
> -	struct saa7164_buffer *buf);
> +extern struct saa7164_buffer *saa7164_buffer_alloc(
> +	struct saa7164_port *port, u32 len);
> +extern int saa7164_buffer_dealloc(struct saa7164_buffer *buf);
> +extern void saa7164_buffer_display(struct saa7164_buffer *buf);
> +extern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i);
> +extern int saa7164_buffer_cfg_port(struct saa7164_port *port);
> +extern struct saa7164_user_buffer *saa7164_buffer_alloc_user(
> +	struct saa7164_dev *dev, u32 len);
> +extern void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf);
> +extern int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i);
> +
> +/* ----------------------------------------------------------- */
> +/* saa7164-encoder.c                                            */
> +int saa7164_encoder_register(struct saa7164_port *port);
> +void saa7164_encoder_unregister(struct saa7164_port *port);
> +
> +/* ----------------------------------------------------------- */
> +/* saa7164-vbi.c                                            */
> +int saa7164_vbi_register(struct saa7164_port *port);
> +void saa7164_vbi_unregister(struct saa7164_port *port);
>  
>  /* ----------------------------------------------------------- */
>  
> +extern unsigned int crc_checking;
> +
>  extern unsigned int saa_debug;
>  #define dprintk(level, fmt, arg...)\
>  	do { if (saa_debug & level)\
> @@ -394,7 +621,6 @@ extern unsigned int saa_debug;
>  #define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2))
>  #define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
>  
> -
>  #define saa7164_readb(reg)             readl(dev->bmmio + (reg))
>  #define saa7164_writeb(reg, value)     writel((value), dev->bmmio + (reg))
>  


There are some checkpatch issues (I did a diff over the entire series, to 
discard any troubles that could be fixed by a latter patch). This is 
somewhat polluted by the 80 lines warning, but yet there are some other reports there:


WARNING: braces {} are not necessary for single statement blocks
#47: FILE: drivers/media/video/saa7164/saa7164-api.c:43:
+	if (ret != SAA_OK) {
+		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+	}

WARNING: braces {} are not necessary for single statement blocks
#70: FILE: drivers/media/video/saa7164/saa7164-api.c:66:
+		if (ret != SAA_OK) {
+			printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+		}

WARNING: line over 80 characters
#71: FILE: drivers/media/video/saa7164/saa7164-api.c:67:
+			printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);

WARNING: line over 80 characters
#77: FILE: drivers/media/video/saa7164/saa7164-api.c:73:
+		printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, d.ucDebugData);

WARNING: braces {} are not necessary for single statement blocks
#93: FILE: drivers/media/video/saa7164/saa7164-api.c:89:
+	if (ret != SAA_OK) {
+		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+	}

WARNING: braces {} are not necessary for single statement blocks
#103: FILE: drivers/media/video/saa7164/saa7164-api.c:99:
+	if (ret != SAA_OK) {
+		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+	}

WARNING: line over 80 characters
#159: FILE: drivers/media/video/saa7164/saa7164-api.c:155:
+			dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex);

WARNING: line over 80 characters
#160: FILE: drivers/media/video/saa7164/saa7164-api.c:156:
+			dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", rsp.bFrameIndex);

WARNING: line over 80 characters
#217: FILE: drivers/media/video/saa7164/saa7164-api.c:213:
+	if (port->encoder_params.bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)

WARNING: line over 80 characters
#224: FILE: drivers/media/video/saa7164/saa7164-api.c:220:
+		EU_VIDEO_BIT_RATE_CONTROL, sizeof(tmComResEncVideoBitRate_t), &vb);

WARNING: line over 80 characters
#233: FILE: drivers/media/video/saa7164/saa7164-api.c:229:
+		EU_AUDIO_BIT_RATE_CONTROL, sizeof(tmComResEncAudioBitRate_t), &ab);

WARNING: line over 80 characters
#251: FILE: drivers/media/video/saa7164/saa7164-api.c:247:
+	dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, port->hwcfg.sourceid);

WARNING: line over 80 characters
#264: FILE: drivers/media/video/saa7164/saa7164-api.c:260:
+		EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), &port->video_resolution);

WARNING: line over 80 characters
#301: FILE: drivers/media/video/saa7164/saa7164-api.c:297:
+	dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", v.ucVideoBitRateMode);

WARNING: line over 80 characters
#303: FILE: drivers/media/video/saa7164/saa7164-api.c:299:
+	dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", v.dwVideoBitRatePeak);

WARNING: line over 80 characters
#304: FILE: drivers/media/video/saa7164/saa7164-api.c:300:
+	dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", a.ucAudioBitRateMode);

WARNING: line over 80 characters
#306: FILE: drivers/media/video/saa7164/saa7164-api.c:302:
+	dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", a.dwAudioBitRatePeak);

WARNING: line over 80 characters
#307: FILE: drivers/media/video/saa7164/saa7164-api.c:303:
+	dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", ar.width, ar.height);

ERROR: space prohibited after that open square bracket '['
#431: FILE: drivers/media/video/saa7164/saa7164-api.c:427:
+		__func__, port->mux_input, inputs[ port->mux_input - 1 ]);

ERROR: space prohibited before that close square bracket ']'
#431: FILE: drivers/media/video/saa7164/saa7164-api.c:427:
+		__func__, port->mux_input, inputs[ port->mux_input - 1 ]);

WARNING: line over 80 characters
#446: FILE: drivers/media/video/saa7164/saa7164-api.c:442:
+		SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[ port->mux_input - 1 ]);

ERROR: space prohibited after that open square bracket '['
#446: FILE: drivers/media/video/saa7164/saa7164-api.c:442:
+		SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[ port->mux_input - 1 ]);

ERROR: space prohibited before that close square bracket ']'
#446: FILE: drivers/media/video/saa7164/saa7164-api.c:442:
+		SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[ port->mux_input - 1 ]);

ERROR: space prohibited after that open parenthesis '('
#495: FILE: drivers/media/video/saa7164/saa7164-api.c:491:
+		( 0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);

WARNING: line over 80 characters
#499: FILE: drivers/media/video/saa7164/saa7164-api.c:495:
+	dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);

ERROR: space prohibited after that open parenthesis '('
#509: FILE: drivers/media/video/saa7164/saa7164-api.c:505:
+		( 0x01 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);

ERROR: space prohibited before that close parenthesis ')'
#509: FILE: drivers/media/video/saa7164/saa7164-api.c:505:
+		( 0x01 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);

ERROR: space prohibited after that open parenthesis '('
#515: FILE: drivers/media/video/saa7164/saa7164-api.c:511:
+		( 0x02 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);

ERROR: space prohibited before that close parenthesis ')'
#515: FILE: drivers/media/video/saa7164/saa7164-api.c:511:
+		( 0x02 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);

ERROR: space prohibited after that open parenthesis '('
#520: FILE: drivers/media/video/saa7164/saa7164-api.c:516:
+		( 0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);

WARNING: line over 80 characters
#524: FILE: drivers/media/video/saa7164/saa7164-api.c:520:
+	dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);

WARNING: line over 80 characters
#562: FILE: drivers/media/video/saa7164/saa7164-api.c:558:
+		printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", __func__, ret);

WARNING: line over 80 characters
#582: FILE: drivers/media/video/saa7164/saa7164-api.c:578:
+		printk(KERN_ERR "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", __func__, ret);

ERROR: do not use C99 // comments
#654: FILE: drivers/media/video/saa7164/saa7164-api.c:650:
+	//saa7164_dumphex16(dev, buf, 16);

WARNING: line over 80 characters
#703: FILE: drivers/media/video/saa7164/saa7164-api.c:699:
+		saa7164_api_set_dif(port, 0x00, 0x80); /* Undefined Video Standard */

ERROR: space prohibited after that open square bracket '['
#742: FILE: drivers/media/video/saa7164/saa7164-api.c:738:
+			p = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#742: FILE: drivers/media/video/saa7164/saa7164-api.c:738:
+			p = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#744: FILE: drivers/media/video/saa7164/saa7164-api.c:740:
+			p = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#744: FILE: drivers/media/video/saa7164/saa7164-api.c:740:
+			p = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited after that open square bracket '['
#749: FILE: drivers/media/video/saa7164/saa7164-api.c:745:
+			p = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#749: FILE: drivers/media/video/saa7164/saa7164-api.c:745:
+			p = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#751: FILE: drivers/media/video/saa7164/saa7164-api.c:747:
+			p = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#751: FILE: drivers/media/video/saa7164/saa7164-api.c:747:
+			p = &dev->ports[ SAA7164_PORT_ENC2 ];

WARNING: line over 80 characters
#889: FILE: drivers/media/video/saa7164/saa7164-api.c:1059:
+						tsport = &dev->ports[ SAA7164_PORT_TS1 ];

ERROR: space prohibited after that open square bracket '['
#889: FILE: drivers/media/video/saa7164/saa7164-api.c:1059:
+						tsport = &dev->ports[ SAA7164_PORT_TS1 ];

ERROR: space prohibited before that close square bracket ']'
#889: FILE: drivers/media/video/saa7164/saa7164-api.c:1059:
+						tsport = &dev->ports[ SAA7164_PORT_TS1 ];

WARNING: line over 80 characters
#893: FILE: drivers/media/video/saa7164/saa7164-api.c:1061:
+						tsport = &dev->ports[ SAA7164_PORT_TS2 ];

ERROR: space prohibited after that open square bracket '['
#893: FILE: drivers/media/video/saa7164/saa7164-api.c:1061:
+						tsport = &dev->ports[ SAA7164_PORT_TS2 ];

ERROR: space prohibited before that close square bracket ']'
#893: FILE: drivers/media/video/saa7164/saa7164-api.c:1061:
+						tsport = &dev->ports[ SAA7164_PORT_TS2 ];

WARNING: line over 80 characters
#906: FILE: drivers/media/video/saa7164/saa7164-api.c:1071:
+						encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#906: FILE: drivers/media/video/saa7164/saa7164-api.c:1071:
+						encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#906: FILE: drivers/media/video/saa7164/saa7164-api.c:1071:
+						encport = &dev->ports[ SAA7164_PORT_ENC1 ];

WARNING: line over 80 characters
#908: FILE: drivers/media/video/saa7164/saa7164-api.c:1073:
+						encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited after that open square bracket '['
#908: FILE: drivers/media/video/saa7164/saa7164-api.c:1073:
+						encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#908: FILE: drivers/media/video/saa7164/saa7164-api.c:1073:
+						encport = &dev->ports[ SAA7164_PORT_ENC2 ];

WARNING: line over 80 characters
#920: FILE: drivers/media/video/saa7164/saa7164-api.c:1083:
+						vbiport = &dev->ports[ SAA7164_PORT_VBI1 ];

ERROR: space prohibited after that open square bracket '['
#920: FILE: drivers/media/video/saa7164/saa7164-api.c:1083:
+						vbiport = &dev->ports[ SAA7164_PORT_VBI1 ];

ERROR: space prohibited before that close square bracket ']'
#920: FILE: drivers/media/video/saa7164/saa7164-api.c:1083:
+						vbiport = &dev->ports[ SAA7164_PORT_VBI1 ];

WARNING: line over 80 characters
#922: FILE: drivers/media/video/saa7164/saa7164-api.c:1085:
+						vbiport = &dev->ports[ SAA7164_PORT_VBI2 ];

ERROR: space prohibited after that open square bracket '['
#922: FILE: drivers/media/video/saa7164/saa7164-api.c:1085:
+						vbiport = &dev->ports[ SAA7164_PORT_VBI2 ];

ERROR: space prohibited before that close square bracket ']'
#922: FILE: drivers/media/video/saa7164/saa7164-api.c:1085:
+						vbiport = &dev->ports[ SAA7164_PORT_VBI2 ];

WARNING: line over 80 characters
#925: FILE: drivers/media/video/saa7164/saa7164-api.c:1088:
+					memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, sizeof(*vbifmt));

WARNING: line over 80 characters
#938: FILE: drivers/media/video/saa7164/saa7164-api.c:1132:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#938: FILE: drivers/media/video/saa7164/saa7164-api.c:1132:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#938: FILE: drivers/media/video/saa7164/saa7164-api.c:1132:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

WARNING: line over 80 characters
#940: FILE: drivers/media/video/saa7164/saa7164-api.c:1134:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited after that open square bracket '['
#940: FILE: drivers/media/video/saa7164/saa7164-api.c:1134:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#940: FILE: drivers/media/video/saa7164/saa7164-api.c:1134:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

WARNING: line over 80 characters
#943: FILE: drivers/media/video/saa7164/saa7164-api.c:1137:
+				dprintk(DBGLVL_API, "  (becomes dev->enc[%d] tuner)\n", encport->nr);

WARNING: line over 80 characters
#967: FILE: drivers/media/video/saa7164/saa7164-api.c:1161:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#967: FILE: drivers/media/video/saa7164/saa7164-api.c:1161:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#967: FILE: drivers/media/video/saa7164/saa7164-api.c:1161:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

WARNING: line over 80 characters
#969: FILE: drivers/media/video/saa7164/saa7164-api.c:1163:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited after that open square bracket '['
#969: FILE: drivers/media/video/saa7164/saa7164-api.c:1163:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#969: FILE: drivers/media/video/saa7164/saa7164-api.c:1163:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

WARNING: line over 80 characters
#972: FILE: drivers/media/video/saa7164/saa7164-api.c:1166:
+				dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n", encport->nr);

ERROR: space prohibited after that open square bracket '['
#985: FILE: drivers/media/video/saa7164/saa7164-api.c:1179:
+				encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#985: FILE: drivers/media/video/saa7164/saa7164-api.c:1179:
+				encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#987: FILE: drivers/media/video/saa7164/saa7164-api.c:1181:
+				encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#987: FILE: drivers/media/video/saa7164/saa7164-api.c:1181:
+				encport = &dev->ports[ SAA7164_PORT_ENC2 ];

WARNING: line over 80 characters
#990: FILE: drivers/media/video/saa7164/saa7164-api.c:1184:
+			dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n", encport->nr);

WARNING: line over 80 characters
#997: FILE: drivers/media/video/saa7164/saa7164-api.c:1191:
+			dprintk(DBGLVL_API, "  vsourceid = 0x%x\n", edh->vsourceid);

WARNING: line over 80 characters
#998: FILE: drivers/media/video/saa7164/saa7164-api.c:1192:
+			dprintk(DBGLVL_API, "  asourceid = 0x%x\n", edh->asourceid);

WARNING: line over 80 characters
#1002: FILE: drivers/media/video/saa7164/saa7164-api.c:1196:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#1002: FILE: drivers/media/video/saa7164/saa7164-api.c:1196:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#1002: FILE: drivers/media/video/saa7164/saa7164-api.c:1196:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

WARNING: line over 80 characters
#1004: FILE: drivers/media/video/saa7164/saa7164-api.c:1198:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited after that open square bracket '['
#1004: FILE: drivers/media/video/saa7164/saa7164-api.c:1198:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#1004: FILE: drivers/media/video/saa7164/saa7164-api.c:1198:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

WARNING: line over 80 characters
#1007: FILE: drivers/media/video/saa7164/saa7164-api.c:1201:
+				dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n", encport->nr);

WARNING: line over 80 characters
#1018: FILE: drivers/media/video/saa7164/saa7164-api.c:1260:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#1018: FILE: drivers/media/video/saa7164/saa7164-api.c:1260:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#1018: FILE: drivers/media/video/saa7164/saa7164-api.c:1260:
+					encport = &dev->ports[ SAA7164_PORT_ENC1 ];

WARNING: line over 80 characters
#1020: FILE: drivers/media/video/saa7164/saa7164-api.c:1262:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited after that open square bracket '['
#1020: FILE: drivers/media/video/saa7164/saa7164-api.c:1262:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#1020: FILE: drivers/media/video/saa7164/saa7164-api.c:1262:
+					encport = &dev->ports[ SAA7164_PORT_ENC2 ];

WARNING: line over 80 characters
#1023: FILE: drivers/media/video/saa7164/saa7164-api.c:1265:
+				dprintk(DBGLVL_API, "  (becomes dev->enc[%d])\n", encport->nr);

WARNING: line over 80 characters
#1263: FILE: drivers/media/video/saa7164/saa7164-buffer.c:285:
+struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, u32 len)

WARNING: kfree(NULL) is safe this check is probably not required
#1294: FILE: drivers/media/video/saa7164/saa7164-buffer.c:316:
+	if (buf->data) {
+		kfree(buf->data);

WARNING: kfree(NULL) is safe this check is probably not required
#1299: FILE: drivers/media/video/saa7164/saa7164-buffer.c:321:
+	if (buf)
+		kfree(buf);

WARNING: line over 80 characters
#1321: FILE: drivers/media/video/saa7164/saa7164-bus.c:46:
+	b->m_dwSetWritePos	= ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64));

WARNING: line over 80 characters
#1672: FILE: drivers/media/video/saa7164/saa7164-cmd.c:125:
+		/* It's unlikely to have more than 4 or 5 pending messages, ensure we exit

WARNING: line over 80 characters
#1737: FILE: drivers/media/video/saa7164/saa7164-core.c:85:
+MODULE_PARM_DESC(guard_checking, "enable dma sanity checking for buffer overruns");

ERROR: space prohibited after that open parenthesis '('
#1775: FILE: drivers/media/video/saa7164/saa7164-core.c:123:
+		if ( (*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) ||

ERROR: space prohibited before that close parenthesis ')'
#1776: FILE: drivers/media/video/saa7164/saa7164-core.c:124:
+			(*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA) ) {

ERROR: do not use C99 // comments
#1778: FILE: drivers/media/video/saa7164/saa7164-core.c:126:
+//			saa7164_dumphex16FF(buf->port->dev, (p + i), 32);

WARNING: line over 80 characters
#1802: FILE: drivers/media/video/saa7164/saa7164-core.c:150:
+		/* TODO: Query pid lower 8 bits, ignoring upper bits intensionally */

WARNING: braces {} are not necessary for single statement blocks
#1854: FILE: drivers/media/video/saa7164/saa7164-core.c:202:
+	for (i = 0; i < 30; i++) {
+		hg->counter1[0 + i].val = i;
+	}

WARNING: braces {} are not necessary for single statement blocks
#1859: FILE: drivers/media/video/saa7164/saa7164-core.c:207:
+	for (i = 0; i < 18; i++) {
+		hg->counter1[30 + i].val = 30 + (i * 10);
+	}

WARNING: braces {} are not necessary for single statement blocks
#1864: FILE: drivers/media/video/saa7164/saa7164-core.c:212:
+	for (i = 0; i < 15; i++) {
+		hg->counter1[48 + i].val = 200 + (i * 200);
+	}

ERROR: space prohibited before that close parenthesis ')'
#1899: FILE: drivers/media/video/saa7164/saa7164-core.c:247:
+	for (i = 0; i < 64; i++ ) {

WARNING: line over 80 characters
#1914: FILE: drivers/media/video/saa7164/saa7164-core.c:262:
+	printk(KERN_ERR "Histogram named %s (ms, count, last_update_jiffy)\n", hg->name);

ERROR: space prohibited before that close parenthesis ')'
#1915: FILE: drivers/media/video/saa7164/saa7164-core.c:263:
+	for (i = 0; i < 64; i++ ) {

WARNING: %Ld/%Lu are not-standard C, use %lld/%llu
#1919: FILE: drivers/media/video/saa7164/saa7164-core.c:267:
+		printk(KERN_ERR " %4d %12d %Ld\n",

WARNING: line over 80 characters
#1951: FILE: drivers/media/video/saa7164/saa7164-core.c:299:
+			dprintk(DBGLVL_IRQ, "%s() bufnr: %d\n", __func__, bufnr);

ERROR: space prohibited after that open parenthesis '('
#1960: FILE: drivers/media/video/saa7164/saa7164-core.c:308:
+				if ( (*(p + buf->actual_size + 0) != 0xff) ||

WARNING: line over 80 characters
#1964: FILE: drivers/media/video/saa7164/saa7164-core.c:312:
+					(*(p + buf->actual_size + 0x10) != 0xff) ||

WARNING: line over 80 characters
#1965: FILE: drivers/media/video/saa7164/saa7164-core.c:313:
+					(*(p + buf->actual_size + 0x11) != 0xff) ||

WARNING: line over 80 characters
#1966: FILE: drivers/media/video/saa7164/saa7164-core.c:314:
+					(*(p + buf->actual_size + 0x12) != 0xff) ||

WARNING: line over 80 characters
#1967: FILE: drivers/media/video/saa7164/saa7164-core.c:315:
+					(*(p + buf->actual_size + 0x13) != 0xff) ) {

ERROR: space prohibited before that close parenthesis ')'
#1967: FILE: drivers/media/video/saa7164/saa7164-core.c:315:
+					(*(p + buf->actual_size + 0x13) != 0xff) ) {

WARNING: line over 80 characters
#1970: FILE: drivers/media/video/saa7164/saa7164-core.c:318:
+//						saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);

ERROR: do not use C99 // comments
#1970: FILE: drivers/media/video/saa7164/saa7164-core.c:318:
+//						saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);

WARNING: line over 80 characters
#1974: FILE: drivers/media/video/saa7164/saa7164-core.c:322:
+			if ((port->nr != SAA7164_PORT_VBI1) && (port->nr != SAA7164_PORT_VBI2)) {

WARNING: line over 80 characters
#1976: FILE: drivers/media/video/saa7164/saa7164-core.c:324:
+				if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)

WARNING: line over 80 characters
#1978: FILE: drivers/media/video/saa7164/saa7164-core.c:326:
+				else if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS)

WARNING: line over 80 characters
#1986: FILE: drivers/media/video/saa7164/saa7164-core.c:334:
+				ubuf = list_first_entry(&port->list_buf_free.list,

WARNING: line over 80 characters
#1995: FILE: drivers/media/video/saa7164/saa7164-core.c:343:
+						/* Throw a new checksum on the read buffer */

WARNING: line over 80 characters
#1996: FILE: drivers/media/video/saa7164/saa7164-core.c:344:
+						ubuf->crc = crc32(0, ubuf->data, ubuf->actual_size);

WARNING: line over 80 characters
#1999: FILE: drivers/media/video/saa7164/saa7164-core.c:347:
+					/* Requeue the buffer on the free list */

WARNING: line over 80 characters
#2009: FILE: drivers/media/video/saa7164/saa7164-core.c:357:
+					printk(KERN_ERR "buf %p bufsize fails match\n", buf);

WARNING: line over 80 characters
#2016: FILE: drivers/media/video/saa7164/saa7164-core.c:364:
+			 * with known bad data. We check for this data at a later point

WARNING: line over 80 characters
#2021: FILE: drivers/media/video/saa7164/saa7164-core.c:369:
+				/* Throw yet aanother new checksum on the dma buffer */

WARNING: %Ld/%Lu are not-standard C, use %lld/%llu
#2055: FILE: drivers/media/video/saa7164/saa7164-core.c:403:
+		"%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",

WARNING: line over 80 characters
#2084: FILE: drivers/media/video/saa7164/saa7164-core.c:432:
+			printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);

WARNING: %Ld/%Lu are not-standard C, use %lld/%llu
#2131: FILE: drivers/media/video/saa7164/saa7164-core.c:479:
+		"%s() %Ldms elapsed irq->deferred %Ldms wp: %d rp: %d\n",

WARNING: line over 80 characters
#2160: FILE: drivers/media/video/saa7164/saa7164-core.c:508:
+			printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);

WARNING: %Ld/%Lu are not-standard C, use %lld/%llu
#2218: FILE: drivers/media/video/saa7164/saa7164-core.c:567:
+	dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,

WARNING: %Ld/%Lu are not-standard C, use %lld/%llu
#2243: FILE: drivers/media/video/saa7164/saa7164-core.c:592:
+	dprintk(DBGLVL_IRQ, "%s() %Ldms elapsed\n", __func__,

ERROR: space prohibited after that open square bracket '['
#2276: FILE: drivers/media/video/saa7164/saa7164-core.c:640:
+	struct saa7164_port *porta = &dev->ports[ SAA7164_PORT_TS1 ];

ERROR: space prohibited before that close square bracket ']'
#2276: FILE: drivers/media/video/saa7164/saa7164-core.c:640:
+	struct saa7164_port *porta = &dev->ports[ SAA7164_PORT_TS1 ];

ERROR: space prohibited after that open square bracket '['
#2277: FILE: drivers/media/video/saa7164/saa7164-core.c:641:
+	struct saa7164_port *portb = &dev->ports[ SAA7164_PORT_TS2 ];

ERROR: space prohibited before that close square bracket ']'
#2277: FILE: drivers/media/video/saa7164/saa7164-core.c:641:
+	struct saa7164_port *portb = &dev->ports[ SAA7164_PORT_TS2 ];

ERROR: space prohibited after that open square bracket '['
#2278: FILE: drivers/media/video/saa7164/saa7164-core.c:642:
+	struct saa7164_port *portc = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#2278: FILE: drivers/media/video/saa7164/saa7164-core.c:642:
+	struct saa7164_port *portc = &dev->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#2279: FILE: drivers/media/video/saa7164/saa7164-core.c:643:
+	struct saa7164_port *portd = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#2279: FILE: drivers/media/video/saa7164/saa7164-core.c:643:
+	struct saa7164_port *portd = &dev->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited after that open square bracket '['
#2280: FILE: drivers/media/video/saa7164/saa7164-core.c:644:
+	struct saa7164_port *porte = &dev->ports[ SAA7164_PORT_VBI1 ];

ERROR: space prohibited before that close square bracket ']'
#2280: FILE: drivers/media/video/saa7164/saa7164-core.c:644:
+	struct saa7164_port *porte = &dev->ports[ SAA7164_PORT_VBI1 ];

ERROR: space prohibited after that open square bracket '['
#2281: FILE: drivers/media/video/saa7164/saa7164-core.c:645:
+	struct saa7164_port *portf = &dev->ports[ SAA7164_PORT_VBI2 ];

ERROR: space prohibited before that close square bracket ']'
#2281: FILE: drivers/media/video/saa7164/saa7164-core.c:645:
+	struct saa7164_port *portf = &dev->ports[ SAA7164_PORT_VBI2 ];

ERROR: space prohibited after that open square bracket '['
#2353: FILE: drivers/media/video/saa7164/saa7164-core.c:951:
+	port = &dev->ports[ portnr ];

ERROR: space prohibited before that close square bracket ']'
#2353: FILE: drivers/media/video/saa7164/saa7164-core.c:951:
+	port = &dev->ports[ portnr ];

ERROR: else should follow close brace '}'
#2367: FILE: drivers/media/video/saa7164/saa7164-core.c:965:
+	}
+	else

WARNING: line over 80 characters
#2468: FILE: drivers/media/video/saa7164/saa7164-core.c:1132:
+		seq_printf(m, "\n addr  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");

WARNING: line over 80 characters
#2483: FILE: drivers/media/video/saa7164/saa7164-core.c:1147:
+		seq_printf(m, "\n addr  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");

WARNING: struct file_operations should normally be const
#2508: FILE: drivers/media/video/saa7164/saa7164-core.c:1172:
+static struct file_operations saa7164_proc_fops = {

WARNING: line over 80 characters
#2551: FILE: drivers/media/video/saa7164/saa7164-core.c:1215:
+		if ((last_poll_time + 1000 /* ms */) < jiffies_to_msecs(jiffies)) {

WARNING: line over 80 characters
#2578: FILE: drivers/media/video/saa7164/saa7164-core.c:1342:
+			if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS1 ]) < 0) {

ERROR: space prohibited after that open square bracket '['
#2578: FILE: drivers/media/video/saa7164/saa7164-core.c:1342:
+			if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS1 ]) < 0) {

ERROR: space prohibited before that close square bracket ']'
#2578: FILE: drivers/media/video/saa7164/saa7164-core.c:1342:
+			if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS1 ]) < 0) {

WARNING: line over 80 characters
#2587: FILE: drivers/media/video/saa7164/saa7164-core.c:1350:
+			if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS2 ]) < 0) {

ERROR: space prohibited after that open square bracket '['
#2587: FILE: drivers/media/video/saa7164/saa7164-core.c:1350:
+			if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS2 ]) < 0) {

ERROR: space prohibited before that close square bracket ']'
#2587: FILE: drivers/media/video/saa7164/saa7164-core.c:1350:
+			if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS2 ]) < 0) {

WARNING: line over 80 characters
#2595: FILE: drivers/media/video/saa7164/saa7164-core.c:1358:
+			if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC1 ]) < 0) {

ERROR: space prohibited after that open square bracket '['
#2595: FILE: drivers/media/video/saa7164/saa7164-core.c:1358:
+			if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC1 ]) < 0) {

ERROR: space prohibited before that close square bracket ']'
#2595: FILE: drivers/media/video/saa7164/saa7164-core.c:1358:
+			if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC1 ]) < 0) {

WARNING: line over 80 characters
#2602: FILE: drivers/media/video/saa7164/saa7164-core.c:1365:
+			if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC2 ]) < 0) {

ERROR: space prohibited after that open square bracket '['
#2602: FILE: drivers/media/video/saa7164/saa7164-core.c:1365:
+			if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC2 ]) < 0) {

ERROR: space prohibited before that close square bracket ']'
#2602: FILE: drivers/media/video/saa7164/saa7164-core.c:1365:
+			if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC2 ]) < 0) {

WARNING: line over 80 characters
#2609: FILE: drivers/media/video/saa7164/saa7164-core.c:1372:
+			if (saa7164_vbi_register(&dev->ports[ SAA7164_PORT_VBI1 ]) < 0) {

ERROR: space prohibited after that open square bracket '['
#2609: FILE: drivers/media/video/saa7164/saa7164-core.c:1372:
+			if (saa7164_vbi_register(&dev->ports[ SAA7164_PORT_VBI1 ]) < 0) {

ERROR: space prohibited before that close square bracket ']'
#2609: FILE: drivers/media/video/saa7164/saa7164-core.c:1372:
+			if (saa7164_vbi_register(&dev->ports[ SAA7164_PORT_VBI1 ]) < 0) {

WARNING: line over 80 characters
#2616: FILE: drivers/media/video/saa7164/saa7164-core.c:1379:
+			if (saa7164_vbi_register(&dev->ports[ SAA7164_PORT_VBI2 ]) < 0) {

ERROR: space prohibited after that open square bracket '['
#2616: FILE: drivers/media/video/saa7164/saa7164-core.c:1379:
+			if (saa7164_vbi_register(&dev->ports[ SAA7164_PORT_VBI2 ]) < 0) {

ERROR: space prohibited before that close square bracket ']'
#2616: FILE: drivers/media/video/saa7164/saa7164-core.c:1379:
+			if (saa7164_vbi_register(&dev->ports[ SAA7164_PORT_VBI2 ]) < 0) {

ERROR: space prohibited after that open square bracket '['
#2646: FILE: drivers/media/video/saa7164/saa7164-core.c:1429:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited before that close square bracket ']'
#2646: FILE: drivers/media/video/saa7164/saa7164-core.c:1429:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited after that open square bracket '['
#2647: FILE: drivers/media/video/saa7164/saa7164-core.c:1430:
+		&dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);

ERROR: space prohibited before that close square bracket ']'
#2647: FILE: drivers/media/video/saa7164/saa7164-core.c:1430:
+		&dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);

ERROR: space prohibited after that open square bracket '['
#2648: FILE: drivers/media/video/saa7164/saa7164-core.c:1431:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited before that close square bracket ']'
#2648: FILE: drivers/media/video/saa7164/saa7164-core.c:1431:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited after that open square bracket '['
#2649: FILE: drivers/media/video/saa7164/saa7164-core.c:1432:
+		&dev->ports[ SAA7164_PORT_ENC1 ].svc_interval);

ERROR: space prohibited before that close square bracket ']'
#2649: FILE: drivers/media/video/saa7164/saa7164-core.c:1432:
+		&dev->ports[ SAA7164_PORT_ENC1 ].svc_interval);

ERROR: space prohibited after that open square bracket '['
#2650: FILE: drivers/media/video/saa7164/saa7164-core.c:1433:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited before that close square bracket ']'
#2650: FILE: drivers/media/video/saa7164/saa7164-core.c:1433:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited after that open square bracket '['
#2651: FILE: drivers/media/video/saa7164/saa7164-core.c:1434:
+		&dev->ports[ SAA7164_PORT_ENC1 ].irq_svc_interval);

ERROR: space prohibited before that close square bracket ']'
#2651: FILE: drivers/media/video/saa7164/saa7164-core.c:1434:
+		&dev->ports[ SAA7164_PORT_ENC1 ].irq_svc_interval);

ERROR: space prohibited after that open square bracket '['
#2652: FILE: drivers/media/video/saa7164/saa7164-core.c:1435:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited before that close square bracket ']'
#2652: FILE: drivers/media/video/saa7164/saa7164-core.c:1435:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited after that open square bracket '['
#2653: FILE: drivers/media/video/saa7164/saa7164-core.c:1436:
+		&dev->ports[ SAA7164_PORT_ENC1 ].read_interval);

ERROR: space prohibited before that close square bracket ']'
#2653: FILE: drivers/media/video/saa7164/saa7164-core.c:1436:
+		&dev->ports[ SAA7164_PORT_ENC1 ].read_interval);

ERROR: space prohibited after that open square bracket '['
#2654: FILE: drivers/media/video/saa7164/saa7164-core.c:1437:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited before that close square bracket ']'
#2654: FILE: drivers/media/video/saa7164/saa7164-core.c:1437:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],

ERROR: space prohibited after that open square bracket '['
#2655: FILE: drivers/media/video/saa7164/saa7164-core.c:1438:
+		&dev->ports[ SAA7164_PORT_ENC1 ].poll_interval);

ERROR: space prohibited before that close square bracket ']'
#2655: FILE: drivers/media/video/saa7164/saa7164-core.c:1438:
+		&dev->ports[ SAA7164_PORT_ENC1 ].poll_interval);

ERROR: space prohibited after that open square bracket '['
#2656: FILE: drivers/media/video/saa7164/saa7164-core.c:1439:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_VBI1 ],

ERROR: space prohibited before that close square bracket ']'
#2656: FILE: drivers/media/video/saa7164/saa7164-core.c:1439:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_VBI1 ],

ERROR: space prohibited after that open square bracket '['
#2657: FILE: drivers/media/video/saa7164/saa7164-core.c:1440:
+		&dev->ports[ SAA7164_PORT_VBI1 ].read_interval);

ERROR: space prohibited before that close square bracket ']'
#2657: FILE: drivers/media/video/saa7164/saa7164-core.c:1440:
+		&dev->ports[ SAA7164_PORT_VBI1 ].read_interval);

ERROR: space prohibited after that open square bracket '['
#2658: FILE: drivers/media/video/saa7164/saa7164-core.c:1441:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_VBI2 ],

ERROR: space prohibited before that close square bracket ']'
#2658: FILE: drivers/media/video/saa7164/saa7164-core.c:1441:
+	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_VBI2 ],

ERROR: space prohibited after that open square bracket '['
#2659: FILE: drivers/media/video/saa7164/saa7164-core.c:1442:
+		&dev->ports[ SAA7164_PORT_VBI2 ].poll_interval);

ERROR: space prohibited before that close square bracket ']'
#2659: FILE: drivers/media/video/saa7164/saa7164-core.c:1442:
+		&dev->ports[ SAA7164_PORT_VBI2 ].poll_interval);

ERROR: space prohibited after that open square bracket '['
#2665: FILE: drivers/media/video/saa7164/saa7164-core.c:1447:
+		saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS1 ]);

ERROR: space prohibited before that close square bracket ']'
#2665: FILE: drivers/media/video/saa7164/saa7164-core.c:1447:
+		saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS1 ]);

ERROR: space prohibited after that open square bracket '['
#2669: FILE: drivers/media/video/saa7164/saa7164-core.c:1450:
+		saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS2 ]);

ERROR: space prohibited before that close square bracket ']'
#2669: FILE: drivers/media/video/saa7164/saa7164-core.c:1450:
+		saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS2 ]);

ERROR: space prohibited after that open square bracket '['
#2672: FILE: drivers/media/video/saa7164/saa7164-core.c:1453:
+		saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC1 ]);

ERROR: space prohibited before that close square bracket ']'
#2672: FILE: drivers/media/video/saa7164/saa7164-core.c:1453:
+		saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC1 ]);

ERROR: space prohibited after that open square bracket '['
#2675: FILE: drivers/media/video/saa7164/saa7164-core.c:1456:
+		saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC2 ]);

ERROR: space prohibited before that close square bracket ']'
#2675: FILE: drivers/media/video/saa7164/saa7164-core.c:1456:
+		saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC2 ]);

ERROR: space prohibited after that open square bracket '['
#2678: FILE: drivers/media/video/saa7164/saa7164-core.c:1459:
+		saa7164_vbi_unregister(&dev->ports[ SAA7164_PORT_VBI1 ]);

ERROR: space prohibited before that close square bracket ']'
#2678: FILE: drivers/media/video/saa7164/saa7164-core.c:1459:
+		saa7164_vbi_unregister(&dev->ports[ SAA7164_PORT_VBI1 ]);

ERROR: space prohibited after that open square bracket '['
#2681: FILE: drivers/media/video/saa7164/saa7164-core.c:1462:
+		saa7164_vbi_unregister(&dev->ports[ SAA7164_PORT_VBI2 ]);

ERROR: space prohibited before that close square bracket ']'
#2681: FILE: drivers/media/video/saa7164/saa7164-core.c:1462:
+		saa7164_vbi_unregister(&dev->ports[ SAA7164_PORT_VBI2 ]);

WARNING: line over 80 characters
#3072: FILE: drivers/media/video/saa7164/saa7164-encoder.c:128:
+	if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {

WARNING: line over 80 characters
#3073: FILE: drivers/media/video/saa7164/saa7164-encoder.c:129:
+		dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", __func__);

WARNING: line over 80 characters
#3080: FILE: drivers/media/video/saa7164/saa7164-encoder.c:136:
+	if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {

WARNING: line over 80 characters
#3081: FILE: drivers/media/video/saa7164/saa7164-encoder.c:137:
+		dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", __func__);

ERROR: space prohibited after that open square bracket '['
#3191: FILE: drivers/media/video/saa7164/saa7164-encoder.c:247:
+	strcpy(i->name, inputs[ i->index ]);

ERROR: space prohibited before that close square bracket ']'
#3191: FILE: drivers/media/video/saa7164/saa7164-encoder.c:247:
+	strcpy(i->name, inputs[ i->index ]);

ERROR: space prohibited after that open square bracket '['
#3308: FILE: drivers/media/video/saa7164/saa7164-encoder.c:364:
+		tsport = &dev->ports[ SAA7164_PORT_TS1 ];

ERROR: space prohibited before that close square bracket ']'
#3308: FILE: drivers/media/video/saa7164/saa7164-encoder.c:364:
+		tsport = &dev->ports[ SAA7164_PORT_TS1 ];

ERROR: space prohibited after that open square bracket '['
#3311: FILE: drivers/media/video/saa7164/saa7164-encoder.c:367:
+		tsport = &dev->ports[ SAA7164_PORT_TS2 ];

ERROR: space prohibited before that close square bracket ']'
#3311: FILE: drivers/media/video/saa7164/saa7164-encoder.c:367:
+		tsport = &dev->ports[ SAA7164_PORT_TS2 ];

WARNING: line over 80 characters
#3774: FILE: drivers/media/video/saa7164/saa7164-encoder.c:830:
+			V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,

ERROR: space prohibited after that open square bracket '['
#4017: FILE: drivers/media/video/saa7164/saa7164-encoder.c:1073:
+		portc = &h->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited before that close square bracket ']'
#4017: FILE: drivers/media/video/saa7164/saa7164-encoder.c:1073:
+		portc = &h->ports[ SAA7164_PORT_ENC1 ];

ERROR: space prohibited after that open square bracket '['
#4018: FILE: drivers/media/video/saa7164/saa7164-encoder.c:1074:
+		portd = &h->ports[ SAA7164_PORT_ENC2 ];

ERROR: space prohibited before that close square bracket ']'
#4018: FILE: drivers/media/video/saa7164/saa7164-encoder.c:1074:
+		portd = &h->ports[ SAA7164_PORT_ENC2 ];

WARNING: line over 80 characters
#4092: FILE: drivers/media/video/saa7164/saa7164-encoder.c:1148:
+				printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,

WARNING: braces {} are not necessary for single statement blocks
#4180: FILE: drivers/media/video/saa7164/saa7164-encoder.c:1236:
+		if (ubuf->pos > ubuf->actual_size) {
+			printk(KERN_ERR "read() pos > actual, huh?\n");
+		}

WARNING: line over 80 characters
#4216: FILE: drivers/media/video/saa7164/saa7164-encoder.c:1272:
+	struct saa7164_encoder_fh *fh = (struct saa7164_encoder_fh *)file->private_data;

WARNING: braces {} are not necessary for single statement blocks
#4229: FILE: drivers/media/video/saa7164/saa7164-encoder.c:1285:
+	if (!video_is_registered(port->v4l_device)) {
+		return -EIO;
+	}

WARNING: do not add new typedefs
#4644: FILE: drivers/media/video/saa7164/saa7164-types.h:291:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4645: FILE: drivers/media/video/saa7164/saa7164-types.h:292:
+typedef struct
+{

WARNING: do not add new typedefs
#4655: FILE: drivers/media/video/saa7164/saa7164-types.h:302:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4656: FILE: drivers/media/video/saa7164/saa7164-types.h:303:
+typedef struct
+{

WARNING: do not add new typedefs
#4670: FILE: drivers/media/video/saa7164/saa7164-types.h:317:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4671: FILE: drivers/media/video/saa7164/saa7164-types.h:318:
+typedef struct
+{

WARNING: do not add new typedefs
#4678: FILE: drivers/media/video/saa7164/saa7164-types.h:325:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4679: FILE: drivers/media/video/saa7164/saa7164-types.h:326:
+typedef struct
+{

ERROR: space prohibited after that open parenthesis '('
#4688: FILE: drivers/media/video/saa7164/saa7164-types.h:335:
+#define SAA7164_ENCODER_DEFAULT_GOP_DIST ( 1)

WARNING: do not add new typedefs
#4690: FILE: drivers/media/video/saa7164/saa7164-types.h:337:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4691: FILE: drivers/media/video/saa7164/saa7164-types.h:338:
+typedef struct
+{

WARNING: do not add new typedefs
#4697: FILE: drivers/media/video/saa7164/saa7164-types.h:344:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4698: FILE: drivers/media/video/saa7164/saa7164-types.h:345:
+typedef struct
+{

WARNING: do not add new typedefs
#4717: FILE: drivers/media/video/saa7164/saa7164-types.h:364:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4718: FILE: drivers/media/video/saa7164/saa7164-types.h:365:
+typedef struct
+{

WARNING: do not add new typedefs
#4728: FILE: drivers/media/video/saa7164/saa7164-types.h:375:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4729: FILE: drivers/media/video/saa7164/saa7164-types.h:376:
+typedef struct
+{

WARNING: do not add new typedefs
#4739: FILE: drivers/media/video/saa7164/saa7164-types.h:386:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4740: FILE: drivers/media/video/saa7164/saa7164-types.h:387:
+typedef struct
+{

WARNING: do not add new typedefs
#4747: FILE: drivers/media/video/saa7164/saa7164-types.h:394:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4748: FILE: drivers/media/video/saa7164/saa7164-types.h:395:
+typedef struct
+{

WARNING: do not add new typedefs
#4753: FILE: drivers/media/video/saa7164/saa7164-types.h:400:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4754: FILE: drivers/media/video/saa7164/saa7164-types.h:401:
+typedef struct
+{

WARNING: do not add new typedefs
#4759: FILE: drivers/media/video/saa7164/saa7164-types.h:406:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4760: FILE: drivers/media/video/saa7164/saa7164-types.h:407:
+typedef struct
+{

WARNING: do not add new typedefs
#4771: FILE: drivers/media/video/saa7164/saa7164-types.h:418:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4772: FILE: drivers/media/video/saa7164/saa7164-types.h:419:
+typedef struct
+{

WARNING: do not add new typedefs
#4784: FILE: drivers/media/video/saa7164/saa7164-types.h:431:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4785: FILE: drivers/media/video/saa7164/saa7164-types.h:432:
+typedef struct
+{

WARNING: do not add new typedefs
#4791: FILE: drivers/media/video/saa7164/saa7164-types.h:438:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4792: FILE: drivers/media/video/saa7164/saa7164-types.h:439:
+typedef struct
+{

WARNING: do not add new typedefs
#4796: FILE: drivers/media/video/saa7164/saa7164-types.h:443:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4797: FILE: drivers/media/video/saa7164/saa7164-types.h:444:
+typedef struct
+{

WARNING: do not add new typedefs
#4802: FILE: drivers/media/video/saa7164/saa7164-types.h:449:
+typedef struct

ERROR: open brace '{' following struct go on the same line
#4803: FILE: drivers/media/video/saa7164/saa7164-types.h:450:
+typedef struct
+{

ERROR: do not use C99 // comments
#4873: FILE: drivers/media/video/saa7164/saa7164-vbi.c:54:
+//	/* Configure the correct video standard */

ERROR: do not use C99 // comments
#4874: FILE: drivers/media/video/saa7164/saa7164-vbi.c:55:
+//	saa7164_api_configure_dif(port, port->encodernorm.id);

ERROR: do not use C99 // comments
#4876: FILE: drivers/media/video/saa7164/saa7164-vbi.c:57:
+//	/* Ensure the audio decoder is correct configured */

ERROR: do not use C99 // comments
#4877: FILE: drivers/media/video/saa7164/saa7164-vbi.c:58:
+//	saa7164_api_set_audio_std(port);

ERROR: space prohibited after that open square bracket '['
#5040: FILE: drivers/media/video/saa7164/saa7164-vbi.c:221:
+	strcpy(i->name, inputs[ i->index ]);

ERROR: space prohibited before that close square bracket ']'
#5040: FILE: drivers/media/video/saa7164/saa7164-vbi.c:221:
+	strcpy(i->name, inputs[ i->index ]);

ERROR: space prohibited after that open square bracket '['
#5157: FILE: drivers/media/video/saa7164/saa7164-vbi.c:338:
+		tsport = &dev->ports[ SAA7164_PORT_TS1 ];

ERROR: space prohibited before that close square bracket ']'
#5157: FILE: drivers/media/video/saa7164/saa7164-vbi.c:338:
+		tsport = &dev->ports[ SAA7164_PORT_TS1 ];

ERROR: space prohibited after that open square bracket '['
#5160: FILE: drivers/media/video/saa7164/saa7164-vbi.c:341:
+		tsport = &dev->ports[ SAA7164_PORT_TS2 ];

ERROR: space prohibited before that close square bracket ']'
#5160: FILE: drivers/media/video/saa7164/saa7164-vbi.c:341:
+		tsport = &dev->ports[ SAA7164_PORT_TS2 ];

ERROR: do not use C99 // comments
#5742: FILE: drivers/media/video/saa7164/saa7164-vbi.c:923:
+//	saa7164_api_set_encoder(port);

ERROR: do not use C99 // comments
#5743: FILE: drivers/media/video/saa7164/saa7164-vbi.c:924:
+//	saa7164_api_get_encoder(port);

ERROR: space prohibited after that open square bracket '['
#5839: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1020:
+		porte = &h->ports[ SAA7164_PORT_VBI1 ];

ERROR: space prohibited before that close square bracket ']'
#5839: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1020:
+		porte = &h->ports[ SAA7164_PORT_VBI1 ];

ERROR: space prohibited after that open square bracket '['
#5840: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1021:
+		portf = &h->ports[ SAA7164_PORT_VBI2 ];

ERROR: space prohibited before that close square bracket ']'
#5840: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1021:
+		portf = &h->ports[ SAA7164_PORT_VBI2 ];

WARNING: line over 80 characters
#5914: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1095:
+				printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,

WARNING: braces {} are not necessary for single statement blocks
#6002: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1183:
+		if (ubuf->pos > ubuf->actual_size) {
+			printk(KERN_ERR "read() pos > actual, huh?\n");
+		}

WARNING: braces {} are not necessary for single statement blocks
#6051: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1232:
+	if (!video_is_registered(port->v4l_device)) {
+		return -EIO;
+	}

ERROR: do not use C99 // comments
#6111: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1292:
+//	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,

ERROR: do not use C99 // comments
#6113: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1294:
+//	.vidioc_g_register	 = saa7164_g_register,

ERROR: do not use C99 // comments
#6114: FILE: drivers/media/video/saa7164/saa7164-vbi.c:1295:
+//	.vidioc_s_register	 = saa7164_s_register,

WARNING: line over 80 characters
#6301: FILE: drivers/media/video/saa7164/saa7164.h:117:
+#define SAA7164_NORMS ( V4L2_STD_NTSC_M |  V4L2_STD_NTSC_M_JP |  V4L2_STD_NTSC_443 )

ERROR: space prohibited after that open parenthesis '('
#6301: FILE: drivers/media/video/saa7164/saa7164.h:117:
+#define SAA7164_NORMS ( V4L2_STD_NTSC_M |  V4L2_STD_NTSC_M_JP |  V4L2_STD_NTSC_443 )

ERROR: space prohibited before that close parenthesis ')'
#6301: FILE: drivers/media/video/saa7164/saa7164.h:117:
+#define SAA7164_NORMS ( V4L2_STD_NTSC_M |  V4L2_STD_NTSC_M_JP |  V4L2_STD_NTSC_443 )

ERROR: do not use C99 // comments
#6327: FILE: drivers/media/video/saa7164/saa7164.h:186:
+//	u32 freq;

ERROR: do not use C99 // comments
#6328: FILE: drivers/media/video/saa7164/saa7164.h:187:
+//	u32 tuner_type;

ERROR: do not use C99 // comments
#6334: FILE: drivers/media/video/saa7164/saa7164.h:193:
+//	u32 freq;

ERROR: do not use C99 // comments
#6335: FILE: drivers/media/video/saa7164/saa7164.h:194:
+//	u32 tuner_type;

ERROR: do not use C99 // comments
#6376: FILE: drivers/media/video/saa7164/saa7164.h:269:
+//	u32		cxiformat;

ERROR: do not use C99 // comments
#6377: FILE: drivers/media/video/saa7164/saa7164.h:270:
+//	u32		cxoformat;

ERROR: space prohibited after that open square bracket '['
#6548: FILE: drivers/media/video/saa7164/saa7164.h:473:
+	struct saa7164_port ports[ SAA7164_MAX_PORTS ];

ERROR: space prohibited before that close square bracket ']'
#6548: FILE: drivers/media/video/saa7164/saa7164.h:473:
+	struct saa7164_port ports[ SAA7164_MAX_PORTS ];

ERROR: Missing Signed-off-by: line(s)

total: 184 errors, 120 warnings, 6488 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

> 
>  b/linux/drivers/media/video/saa7164/saa7164-encoder.c |   23
>  b/linux/drivers/media/video/saa7164/saa7164-vbi.c     | 1459 ++++++
>  linux/drivers/media/video/saa7164/Makefile            |    4
>  linux/drivers/media/video/saa7164/saa7164-api.c       | 1143 ++++-
>  linux/drivers/media/video/saa7164/saa7164-buffer.c    |  204
>  linux/drivers/media/video/saa7164/saa7164-bus.c       |  231 -
>  linux/drivers/media/video/saa7164/saa7164-cards.c     |   56
>  linux/drivers/media/video/saa7164/saa7164-cmd.c       |   21
>  linux/drivers/media/video/saa7164/saa7164-core.c      | 2103 ++++++----
>  linux/drivers/media/video/saa7164/saa7164-dvb.c       |  109
>  linux/drivers/media/video/saa7164/saa7164-encoder.c   | 1872 ++++++++
>  linux/drivers/media/video/saa7164/saa7164-fw.c        |   35
>  linux/drivers/media/video/saa7164/saa7164-i2c.c       |    2
>  linux/drivers/media/video/saa7164/saa7164-reg.h       |   70
>  linux/drivers/media/video/saa7164/saa7164-types.h     |  183
>  linux/drivers/media/video/saa7164/saa7164-vbi.c       |   53
>  linux/drivers/media/video/saa7164/saa7164.h           |  328 +
>  17 files changed, 6421 insertions(+), 1475 deletions(-)
> 
> Regards,
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux