diff options
Diffstat (limited to 'drivers/media/pci')
66 files changed, 1764 insertions, 4349 deletions
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index c4c59175e52..b7dc921e1b9 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -3547,6 +3547,16 @@ void bttv_init_card2(struct bttv *btv)  	if (btv->sd_msp34xx)  		return; +	/* Now see if we can find one of the tvaudio devices. */ +	btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, +		&btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); +	if (btv->sd_tvaudio) { +		/* There may be two tvaudio chips on the card, so try to +		   find another. */ +		v4l2_i2c_new_subdev(&btv->c.v4l2_dev, +			&btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); +	} +  	/* it might also be a tda7432. */  	if (!bttv_tvcards[btv->c.type].no_tda7432) {  		static const unsigned short addrs[] = { @@ -3554,14 +3564,11 @@ void bttv_init_card2(struct bttv *btv)  			I2C_CLIENT_END  		}; -		if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, -				&btv->c.i2c_adap, "tda7432", 0, addrs)) +		btv->sd_tda7432 = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, +				&btv->c.i2c_adap, "tda7432", 0, addrs); +		if (btv->sd_tda7432)  			return;  	} - -	/* Now see if we can find one of the tvaudio devices. */ -	btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, -		&btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());  	if (btv->sd_tvaudio)  		return; @@ -3940,7 +3947,7 @@ static void avermedia_eeprom(struct bttv *btv)  u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits)  { -	if (btv->audio == TVAUDIO_INPUT_TUNER) { +	if (btv->audio_input == TVAUDIO_INPUT_TUNER) {  		if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN)  			gpiobits |= 0x10000;  		else diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index ccd18e4ee78..e7d08841341 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -49,6 +49,8 @@  #include "bttvp.h"  #include <media/v4l2-common.h>  #include <media/v4l2-ioctl.h> +#include <media/v4l2-event.h> +#include <media/v4l2-chip-ident.h>  #include <media/tvaudio.h>  #include <media/msp3400.h> @@ -93,7 +95,7 @@ static unsigned int combfilter;  static unsigned int lumafilter;  static unsigned int automute    = 1;  static unsigned int chroma_agc; -static unsigned int adc_crush   = 1; +static unsigned int agc_crush   = 1;  static unsigned int whitecrush_upper = 0xCF;  static unsigned int whitecrush_lower = 0x7F;  static unsigned int vcr_hack; @@ -125,7 +127,7 @@ module_param(combfilter,        int, 0444);  module_param(lumafilter,        int, 0444);  module_param(automute,          int, 0444);  module_param(chroma_agc,        int, 0444); -module_param(adc_crush,         int, 0444); +module_param(agc_crush,         int, 0444);  module_param(whitecrush_upper,  int, 0444);  module_param(whitecrush_lower,  int, 0444);  module_param(vcr_hack,          int, 0444); @@ -138,27 +140,27 @@ module_param_array(video_nr,    int, NULL, 0444);  module_param_array(radio_nr,    int, NULL, 0444);  module_param_array(vbi_nr,      int, NULL, 0444); -MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)"); -MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian"); -MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)"); -MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)"); -MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)"); -MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)"); +MODULE_PARM_DESC(radio, "The TV card supports radio, default is 0 (no)"); +MODULE_PARM_DESC(bigendian, "byte order of the framebuffer, default is native endian"); +MODULE_PARM_DESC(bttv_verbose, "verbose startup messages, default is 1 (yes)"); +MODULE_PARM_DESC(bttv_gpio, "log gpio changes, default is 0 (no)"); +MODULE_PARM_DESC(bttv_debug, "debug messages, default is 0 (no)"); +MODULE_PARM_DESC(irq_debug, "irq handler debug messages, default is 0 (no)");  MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); -MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8"); -MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000"); -MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default " +MODULE_PARM_DESC(gbuffers, "number of capture buffers. range 2-32, default 8"); +MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 0x208000"); +MODULE_PARM_DESC(reset_crop, "reset cropping parameters at open(), default "  		 "is 1 (yes) for compatibility with older applications"); -MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)"); -MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)"); -MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)"); -MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207"); -MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127"); -MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); -MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); -MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50"); -MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)"); -MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)"); +MODULE_PARM_DESC(automute, "mute audio on bad/missing video signal, default is 1 (yes)"); +MODULE_PARM_DESC(chroma_agc, "enables the AGC of chroma signal, default is 0 (no)"); +MODULE_PARM_DESC(agc_crush, "enables the luminance AGC crush, default is 1 (yes)"); +MODULE_PARM_DESC(whitecrush_upper, "sets the white crush upper value, default is 207"); +MODULE_PARM_DESC(whitecrush_lower, "sets the white crush lower value, default is 127"); +MODULE_PARM_DESC(vcr_hack, "enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); +MODULE_PARM_DESC(irq_iswitch, "switch inputs in irq handler"); +MODULE_PARM_DESC(uv_ratio, "ratio between u and v gains, default is 50"); +MODULE_PARM_DESC(full_luma_range, "use the full luma range, default is 0 (no)"); +MODULE_PARM_DESC(coring, "set the luma coring level, default is 0 (no)");  MODULE_PARM_DESC(video_nr, "video device numbers");  MODULE_PARM_DESC(vbi_nr, "vbi device numbers");  MODULE_PARM_DESC(radio_nr, "radio device numbers"); @@ -168,6 +170,17 @@ MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");  MODULE_LICENSE("GPL");  MODULE_VERSION(BTTV_VERSION); +#define V4L2_CID_PRIVATE_COMBFILTER		(V4L2_CID_USER_BTTV_BASE + 0) +#define V4L2_CID_PRIVATE_AUTOMUTE		(V4L2_CID_USER_BTTV_BASE + 1) +#define V4L2_CID_PRIVATE_LUMAFILTER		(V4L2_CID_USER_BTTV_BASE + 2) +#define V4L2_CID_PRIVATE_AGC_CRUSH		(V4L2_CID_USER_BTTV_BASE + 3) +#define V4L2_CID_PRIVATE_VCR_HACK		(V4L2_CID_USER_BTTV_BASE + 4) +#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER	(V4L2_CID_USER_BTTV_BASE + 5) +#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER	(V4L2_CID_USER_BTTV_BASE + 6) +#define V4L2_CID_PRIVATE_UV_RATIO		(V4L2_CID_USER_BTTV_BASE + 7) +#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE	(V4L2_CID_USER_BTTV_BASE + 8) +#define V4L2_CID_PRIVATE_CORING			(V4L2_CID_USER_BTTV_BASE + 9) +  /* ----------------------------------------------------------------------- */  /* sysfs                                                                   */ @@ -250,17 +263,19 @@ static u8 SRAM_Table[][60] =     vdelay	start of active video in 2 * field lines relative to  		trailing edge of /VRESET pulse (VDELAY register).     sheight	height of active video in 2 * field lines. +   extraheight	Added to sheight for cropcap.bounds.height only     videostart0	ITU-R frame line number of the line corresponding  		to vdelay in the first field. */  #define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth,	 \ -		vdelay, sheight, videostart0)				 \ +		vdelay, sheight, extraheight, videostart0)		 \  	.cropcap.bounds.left = minhdelayx1,				 \  	/* * 2 because vertically we count field lines times two, */	 \  	/* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */		 \  	.cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \  	/* 4 is a safety margin at the end of the line. */		 \  	.cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4,	 \ -	.cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY,	 \ +	.cropcap.bounds.height = (sheight) + (extraheight) + (vdelay) -	 \ +				 MIN_VDELAY,				 \  	.cropcap.defrect.left = hdelayx1,				 \  	.cropcap.defrect.top = (videostart0) * 2,			 \  	.cropcap.defrect.width = swidth,				 \ @@ -301,9 +316,10 @@ const struct bttv_tvnorm bttv_tvnorms[] = {  			/* totalwidth */ 1135,  			/* sqwidth */ 944,  			/* vdelay */ 0x20, -		/* bt878 (and bt848?) can capture another -		   line below active video. */ -			/* sheight */ (576 + 2) + 0x20 - 2, +			/* sheight */ 576, +			/* bt878 (and bt848?) can capture another +			   line below active video. */ +			/* extraheight */ 2,  			/* videostart0 */ 23)  	},{  		.v4l2_id        = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, @@ -330,6 +346,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {  			/* sqwidth */ 780,  			/* vdelay */ 0x1a,  			/* sheight */ 480, +			/* extraheight */ 0,  			/* videostart0 */ 23)  	},{  		.v4l2_id        = V4L2_STD_SECAM, @@ -355,6 +372,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {  			/* sqwidth */ 944,  			/* vdelay */ 0x20,  			/* sheight */ 576, +			/* extraheight */ 0,  			/* videostart0 */ 23)  	},{  		.v4l2_id        = V4L2_STD_PAL_Nc, @@ -380,6 +398,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {  			/* sqwidth */ 780,  			/* vdelay */ 0x1a,  			/* sheight */ 576, +			/* extraheight */ 0,  			/* videostart0 */ 23)  	},{  		.v4l2_id        = V4L2_STD_PAL_M, @@ -405,6 +424,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {  			/* sqwidth */ 780,  			/* vdelay */ 0x1a,  			/* sheight */ 480, +			/* extraheight */ 0,  			/* videostart0 */ 23)  	},{  		.v4l2_id        = V4L2_STD_PAL_N, @@ -430,6 +450,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {  			/* sqwidth */ 944,  			/* vdelay */ 0x20,  			/* sheight */ 576, +			/* extraheight */ 0,  			/* videostart0 */ 23)  	},{  		.v4l2_id        = V4L2_STD_NTSC_M_JP, @@ -455,6 +476,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {  			/* sqwidth */ 780,  			/* vdelay */ 0x16,  			/* sheight */ 480, +			/* extraheight */ 0,  			/* videostart0 */ 23)  	},{  		/* that one hopefully works with the strange timing @@ -484,6 +506,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {  			/* sqwidth */ 944,  			/* vdelay */ 0x1a,  			/* sheight */ 480, +			/* extraheight */ 0,  			/* videostart0 */ 23)  	}  }; @@ -622,198 +645,6 @@ static const struct bttv_format formats[] = {  static const unsigned int FORMATS = ARRAY_SIZE(formats);  /* ----------------------------------------------------------------------- */ - -#define V4L2_CID_PRIVATE_CHROMA_AGC  (V4L2_CID_PRIVATE_BASE + 0) -#define V4L2_CID_PRIVATE_COMBFILTER  (V4L2_CID_PRIVATE_BASE + 1) -#define V4L2_CID_PRIVATE_AUTOMUTE    (V4L2_CID_PRIVATE_BASE + 2) -#define V4L2_CID_PRIVATE_LUMAFILTER  (V4L2_CID_PRIVATE_BASE + 3) -#define V4L2_CID_PRIVATE_AGC_CRUSH   (V4L2_CID_PRIVATE_BASE + 4) -#define V4L2_CID_PRIVATE_VCR_HACK    (V4L2_CID_PRIVATE_BASE + 5) -#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER   (V4L2_CID_PRIVATE_BASE + 6) -#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER   (V4L2_CID_PRIVATE_BASE + 7) -#define V4L2_CID_PRIVATE_UV_RATIO    (V4L2_CID_PRIVATE_BASE + 8) -#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE    (V4L2_CID_PRIVATE_BASE + 9) -#define V4L2_CID_PRIVATE_CORING      (V4L2_CID_PRIVATE_BASE + 10) -#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 11) - -static const struct v4l2_queryctrl no_ctl = { -	.name  = "42", -	.flags = V4L2_CTRL_FLAG_DISABLED, -}; -static const struct v4l2_queryctrl bttv_ctls[] = { -	/* --- video --- */ -	{ -		.id            = V4L2_CID_BRIGHTNESS, -		.name          = "Brightness", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 256, -		.default_value = 32768, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_CONTRAST, -		.name          = "Contrast", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 128, -		.default_value = 27648, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_SATURATION, -		.name          = "Saturation", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 128, -		.default_value = 32768, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_COLOR_KILLER, -		.name          = "Color killer", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	}, { -		.id            = V4L2_CID_HUE, -		.name          = "Hue", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 256, -		.default_value = 32768, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	}, -	/* --- audio --- */ -	{ -		.id            = V4L2_CID_AUDIO_MUTE, -		.name          = "Mute", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_AUDIO_VOLUME, -		.name          = "Volume", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 65535/100, -		.default_value = 65535, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_AUDIO_BALANCE, -		.name          = "Balance", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 65535/100, -		.default_value = 32768, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_AUDIO_BASS, -		.name          = "Bass", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 65535/100, -		.default_value = 32768, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_AUDIO_TREBLE, -		.name          = "Treble", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 65535/100, -		.default_value = 32768, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	}, -	/* --- private --- */ -	{ -		.id            = V4L2_CID_PRIVATE_CHROMA_AGC, -		.name          = "chroma agc", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_PRIVATE_COMBFILTER, -		.name          = "combfilter", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_PRIVATE_AUTOMUTE, -		.name          = "automute", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_PRIVATE_LUMAFILTER, -		.name          = "luma decimation filter", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_PRIVATE_AGC_CRUSH, -		.name          = "agc crush", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_PRIVATE_VCR_HACK, -		.name          = "vcr hack", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_PRIVATE_WHITECRUSH_UPPER, -		.name          = "whitecrush upper", -		.minimum       = 0, -		.maximum       = 255, -		.step          = 1, -		.default_value = 0xCF, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_PRIVATE_WHITECRUSH_LOWER, -		.name          = "whitecrush lower", -		.minimum       = 0, -		.maximum       = 255, -		.step          = 1, -		.default_value = 0x7F, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_PRIVATE_UV_RATIO, -		.name          = "uv ratio", -		.minimum       = 0, -		.maximum       = 100, -		.step          = 1, -		.default_value = 50, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, -		.name          = "full luma range", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_PRIVATE_CORING, -		.name          = "coring", -		.minimum       = 0, -		.maximum       = 3, -		.step          = 1, -		.default_value = 0, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	} - - - -}; - -static const struct v4l2_queryctrl *ctrl_by_id(int id) -{ -	int i; - -	for (i = 0; i < ARRAY_SIZE(bttv_ctls); i++) -		if (bttv_ctls[i].id == id) -			return bttv_ctls+i; - -	return NULL; -} - -/* ----------------------------------------------------------------------- */  /* resource management                                                     */  /* @@ -1168,23 +999,20 @@ static char *audio_modes[] = {  	"audio: intern", "audio: mute"  }; -static int -audio_mux(struct bttv *btv, int input, int mute) +static void +audio_mux_gpio(struct bttv *btv, int input, int mute)  { -	int gpio_val, signal; -	struct v4l2_control ctrl; +	int gpio_val, signal, mute_gpio;  	gpio_inout(bttv_tvcards[btv->c.type].gpiomask,  		   bttv_tvcards[btv->c.type].gpiomask);  	signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; -	btv->mute = mute; -	btv->audio = input; -  	/* automute */ -	mute = mute || (btv->opt_automute && !signal && !btv->radio_user); +	mute_gpio = mute || (btv->opt_automute && (!signal || !btv->users) +				&& !btv->has_radio_tuner); -	if (mute) +	if (mute_gpio)  		gpio_val = bttv_tvcards[btv->c.type].gpiomute;  	else  		gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; @@ -1200,13 +1028,39 @@ audio_mux(struct bttv *btv, int input, int mute)  	}  	if (bttv_gpio) -		bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]); -	if (in_interrupt()) -		return 0; +		bttv_gpio_tracking(btv, audio_modes[mute_gpio ? 4 : input]); +} + +static int +audio_mute(struct bttv *btv, int mute) +{ +	struct v4l2_ctrl *ctrl; + +	audio_mux_gpio(btv, btv->audio_input, mute); + +	if (btv->sd_msp34xx) { +		ctrl = v4l2_ctrl_find(btv->sd_msp34xx->ctrl_handler, V4L2_CID_AUDIO_MUTE); +		if (ctrl) +			v4l2_ctrl_s_ctrl(ctrl, mute); +	} +	if (btv->sd_tvaudio) { +		ctrl = v4l2_ctrl_find(btv->sd_tvaudio->ctrl_handler, V4L2_CID_AUDIO_MUTE); +		if (ctrl) +			v4l2_ctrl_s_ctrl(ctrl, mute); +	} +	if (btv->sd_tda7432) { +		ctrl = v4l2_ctrl_find(btv->sd_tda7432->ctrl_handler, V4L2_CID_AUDIO_MUTE); +		if (ctrl) +			v4l2_ctrl_s_ctrl(ctrl, mute); +	} +	return 0; +} + +static int +audio_input(struct bttv *btv, int input) +{ +	audio_mux_gpio(btv, input, btv->mute); -	ctrl.id = V4L2_CID_AUDIO_MUTE; -	ctrl.value = btv->mute; -	bttv_call_all(btv, core, s_ctrl, &ctrl);  	if (btv->sd_msp34xx) {  		u32 in; @@ -1255,23 +1109,11 @@ audio_mux(struct bttv *btv, int input, int mute)  	}  	if (btv->sd_tvaudio) {  		v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, -				input, 0, 0); +				 input, 0, 0);  	}  	return 0;  } -static inline int -audio_mute(struct bttv *btv, int mute) -{ -	return audio_mux(btv, btv->audio, mute); -} - -static inline int -audio_input(struct bttv *btv, int input) -{ -	return audio_mux(btv, input, btv->mute); -} -  static void  bttv_crop_calc_limits(struct bttv_crop *c)  { @@ -1365,8 +1207,9 @@ set_input(struct bttv *btv, unsigned int input, unsigned int norm)  	} else {  		video_mux(btv,input);  	} -	audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ? -			 TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN); +	btv->audio_input = (btv->tuner_type != TUNER_ABSENT && input == 0) ? +				TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN; +	audio_input(btv, btv->audio_input);  	set_tvnorm(btv, norm);  } @@ -1394,8 +1237,6 @@ static void init_irqreg(struct bttv *btv)  static void init_bt848(struct bttv *btv)  { -	int val; -  	if (bttv_tvcards[btv->c.type].no_video) {  		/* very basic init only */  		init_irqreg(btv); @@ -1415,30 +1256,10 @@ static void init_bt848(struct bttv *btv)  		BT848_GPIO_DMA_CTL_GPINTI,  		BT848_GPIO_DMA_CTL); -	val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; -	btwrite(val, BT848_E_SCLOOP); -	btwrite(val, BT848_O_SCLOOP); -  	btwrite(0x20, BT848_E_VSCALE_HI);  	btwrite(0x20, BT848_O_VSCALE_HI); -	btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), -		BT848_ADC); -	btwrite(whitecrush_upper, BT848_WC_UP); -	btwrite(whitecrush_lower, BT848_WC_DOWN); - -	if (btv->opt_lumafilter) { -		btwrite(0, BT848_E_CONTROL); -		btwrite(0, BT848_O_CONTROL); -	} else { -		btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL); -		btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL); -	} - -	bt848_bright(btv,   btv->bright); -	bt848_hue(btv,      btv->hue); -	bt848_contrast(btv, btv->contrast); -	bt848_sat(btv,      btv->saturation); +	v4l2_ctrl_handler_setup(&btv->ctrl_handler);  	/* interrupt */  	init_irqreg(btv); @@ -1460,103 +1281,26 @@ static void bttv_reinit_bt848(struct bttv *btv)  	set_input(btv, btv->input, btv->tvnorm);  } -static int bttv_g_ctrl(struct file *file, void *priv, -					struct v4l2_control *c) -{ -	struct bttv_fh *fh = priv; -	struct bttv *btv = fh->btv; - -	switch (c->id) { -	case V4L2_CID_BRIGHTNESS: -		c->value = btv->bright; -		break; -	case V4L2_CID_HUE: -		c->value = btv->hue; -		break; -	case V4L2_CID_CONTRAST: -		c->value = btv->contrast; -		break; -	case V4L2_CID_SATURATION: -		c->value = btv->saturation; -		break; -	case V4L2_CID_COLOR_KILLER: -		c->value = btv->opt_color_killer; -		break; - -	case V4L2_CID_AUDIO_MUTE: -	case V4L2_CID_AUDIO_VOLUME: -	case V4L2_CID_AUDIO_BALANCE: -	case V4L2_CID_AUDIO_BASS: -	case V4L2_CID_AUDIO_TREBLE: -		bttv_call_all(btv, core, g_ctrl, c); -		break; - -	case V4L2_CID_PRIVATE_CHROMA_AGC: -		c->value = btv->opt_chroma_agc; -		break; -	case V4L2_CID_PRIVATE_COMBFILTER: -		c->value = btv->opt_combfilter; -		break; -	case V4L2_CID_PRIVATE_LUMAFILTER: -		c->value = btv->opt_lumafilter; -		break; -	case V4L2_CID_PRIVATE_AUTOMUTE: -		c->value = btv->opt_automute; -		break; -	case V4L2_CID_PRIVATE_AGC_CRUSH: -		c->value = btv->opt_adc_crush; -		break; -	case V4L2_CID_PRIVATE_VCR_HACK: -		c->value = btv->opt_vcr_hack; -		break; -	case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: -		c->value = btv->opt_whitecrush_upper; -		break; -	case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: -		c->value = btv->opt_whitecrush_lower; -		break; -	case V4L2_CID_PRIVATE_UV_RATIO: -		c->value = btv->opt_uv_ratio; -		break; -	case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: -		c->value = btv->opt_full_luma_range; -		break; -	case V4L2_CID_PRIVATE_CORING: -		c->value = btv->opt_coring; -		break; -	default: -		return -EINVAL; -	} -	return 0; -} - -static int bttv_s_ctrl(struct file *file, void *f, -					struct v4l2_control *c) +static int bttv_s_ctrl(struct v4l2_ctrl *c)  { -	int err; -	struct bttv_fh *fh = f; -	struct bttv *btv = fh->btv; - -	err = v4l2_prio_check(&btv->prio, fh->prio); -	if (0 != err) -		return err; +	struct bttv *btv = container_of(c->handler, struct bttv, ctrl_handler); +	int val;  	switch (c->id) {  	case V4L2_CID_BRIGHTNESS: -		bt848_bright(btv, c->value); +		bt848_bright(btv, c->val);  		break;  	case V4L2_CID_HUE: -		bt848_hue(btv, c->value); +		bt848_hue(btv, c->val);  		break;  	case V4L2_CID_CONTRAST: -		bt848_contrast(btv, c->value); +		bt848_contrast(btv, c->val);  		break;  	case V4L2_CID_SATURATION: -		bt848_sat(btv, c->value); +		bt848_sat(btv, c->val);  		break;  	case V4L2_CID_COLOR_KILLER: -		btv->opt_color_killer = c->value; -		if (btv->opt_color_killer) { +		if (c->val) {  			btor(BT848_SCLOOP_CKILL, BT848_E_SCLOOP);  			btor(BT848_SCLOOP_CKILL, BT848_O_SCLOOP);  		} else { @@ -1565,36 +1309,23 @@ static int bttv_s_ctrl(struct file *file, void *f,  		}  		break;  	case V4L2_CID_AUDIO_MUTE: -		audio_mute(btv, c->value); -		/* fall through */ -	case V4L2_CID_AUDIO_VOLUME: -		if (btv->volume_gpio) -			btv->volume_gpio(btv, c->value); - -		bttv_call_all(btv, core, s_ctrl, c); +		audio_mute(btv, c->val); +		btv->mute = c->val;  		break; -	case V4L2_CID_AUDIO_BALANCE: -	case V4L2_CID_AUDIO_BASS: -	case V4L2_CID_AUDIO_TREBLE: -		bttv_call_all(btv, core, s_ctrl, c); +	case V4L2_CID_AUDIO_VOLUME: +		btv->volume_gpio(btv, c->val);  		break; -	case V4L2_CID_PRIVATE_CHROMA_AGC: -		btv->opt_chroma_agc = c->value; -		if (btv->opt_chroma_agc) { -			btor(BT848_SCLOOP_CAGC, BT848_E_SCLOOP); -			btor(BT848_SCLOOP_CAGC, BT848_O_SCLOOP); -		} else { -			btand(~BT848_SCLOOP_CAGC, BT848_E_SCLOOP); -			btand(~BT848_SCLOOP_CAGC, BT848_O_SCLOOP); -		} +	case V4L2_CID_CHROMA_AGC: +		val = c->val ? BT848_SCLOOP_CAGC : 0; +		btwrite(val, BT848_E_SCLOOP); +		btwrite(val, BT848_O_SCLOOP);  		break;  	case V4L2_CID_PRIVATE_COMBFILTER: -		btv->opt_combfilter = c->value; +		btv->opt_combfilter = c->val;  		break;  	case V4L2_CID_PRIVATE_LUMAFILTER: -		btv->opt_lumafilter = c->value; -		if (btv->opt_lumafilter) { +		if (c->val) {  			btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL);  			btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL);  		} else { @@ -1603,36 +1334,31 @@ static int bttv_s_ctrl(struct file *file, void *f,  		}  		break;  	case V4L2_CID_PRIVATE_AUTOMUTE: -		btv->opt_automute = c->value; +		btv->opt_automute = c->val;  		break;  	case V4L2_CID_PRIVATE_AGC_CRUSH: -		btv->opt_adc_crush = c->value;  		btwrite(BT848_ADC_RESERVED | -				(btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), +				(c->val ? BT848_ADC_CRUSH : 0),  				BT848_ADC);  		break;  	case V4L2_CID_PRIVATE_VCR_HACK: -		btv->opt_vcr_hack = c->value; +		btv->opt_vcr_hack = c->val;  		break;  	case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: -		btv->opt_whitecrush_upper = c->value; -		btwrite(c->value, BT848_WC_UP); +		btwrite(c->val, BT848_WC_UP);  		break;  	case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: -		btv->opt_whitecrush_lower = c->value; -		btwrite(c->value, BT848_WC_DOWN); +		btwrite(c->val, BT848_WC_DOWN);  		break;  	case V4L2_CID_PRIVATE_UV_RATIO: -		btv->opt_uv_ratio = c->value; +		btv->opt_uv_ratio = c->val;  		bt848_sat(btv, btv->saturation);  		break;  	case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: -		btv->opt_full_luma_range = c->value; -		btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM); +		btaor((c->val << 7), ~BT848_OFORM_RANGE, BT848_OFORM);  		break;  	case V4L2_CID_PRIVATE_CORING: -		btv->opt_coring = c->value; -		btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM); +		btaor((c->val << 5), ~BT848_OFORM_CORE32, BT848_OFORM);  		break;  	default:  		return -EINVAL; @@ -1642,6 +1368,121 @@ static int bttv_s_ctrl(struct file *file, void *f,  /* ----------------------------------------------------------------------- */ +static const struct v4l2_ctrl_ops bttv_ctrl_ops = { +	.s_ctrl = bttv_s_ctrl, +}; + +static struct v4l2_ctrl_config bttv_ctrl_combfilter = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_COMBFILTER, +	.name = "Comb Filter", +	.type = V4L2_CTRL_TYPE_BOOLEAN, +	.min = 0, +	.max = 1, +	.step = 1, +	.def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_automute = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_AUTOMUTE, +	.name = "Auto Mute", +	.type = V4L2_CTRL_TYPE_BOOLEAN, +	.min = 0, +	.max = 1, +	.step = 1, +	.def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_lumafilter = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_LUMAFILTER, +	.name = "Luma Decimation Filter", +	.type = V4L2_CTRL_TYPE_BOOLEAN, +	.min = 0, +	.max = 1, +	.step = 1, +	.def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_agc_crush = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_AGC_CRUSH, +	.name = "AGC Crush", +	.type = V4L2_CTRL_TYPE_BOOLEAN, +	.min = 0, +	.max = 1, +	.step = 1, +	.def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_vcr_hack = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_VCR_HACK, +	.name = "VCR Hack", +	.type = V4L2_CTRL_TYPE_BOOLEAN, +	.min = 0, +	.max = 1, +	.step = 1, +	.def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_whitecrush_lower = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER, +	.name = "Whitecrush Lower", +	.type = V4L2_CTRL_TYPE_INTEGER, +	.min = 0, +	.max = 255, +	.step = 1, +	.def = 0x7f, +}; + +static struct v4l2_ctrl_config bttv_ctrl_whitecrush_upper = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER, +	.name = "Whitecrush Upper", +	.type = V4L2_CTRL_TYPE_INTEGER, +	.min = 0, +	.max = 255, +	.step = 1, +	.def = 0xcf, +}; + +static struct v4l2_ctrl_config bttv_ctrl_uv_ratio = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_UV_RATIO, +	.name = "UV Ratio", +	.type = V4L2_CTRL_TYPE_INTEGER, +	.min = 0, +	.max = 100, +	.step = 1, +	.def = 50, +}; + +static struct v4l2_ctrl_config bttv_ctrl_full_luma = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, +	.name = "Full Luma Range", +	.type = V4L2_CTRL_TYPE_BOOLEAN, +	.min = 0, +	.max = 1, +	.step = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_coring = { +	.ops = &bttv_ctrl_ops, +	.id = V4L2_CID_PRIVATE_CORING, +	.name = "Coring", +	.type = V4L2_CTRL_TYPE_INTEGER, +	.min = 0, +	.max = 3, +	.step = 1, +}; + + +/* ----------------------------------------------------------------------- */ +  void bttv_gpio_tracking(struct bttv *btv, char *comment)  {  	unsigned int outbits, data; @@ -1871,25 +1712,33 @@ static struct videobuf_queue_ops bttv_video_qops = {  	.buf_release  = buffer_release,  }; -static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) +static void radio_enable(struct bttv *btv) +{ +	/* Switch to the radio tuner */ +	if (!btv->has_radio_tuner) { +		btv->has_radio_tuner = 1; +		bttv_call_all(btv, tuner, s_radio); +		btv->audio_input = TVAUDIO_INPUT_RADIO; +		audio_input(btv, btv->audio_input); +	} +} + +static int bttv_s_std(struct file *file, void *priv, v4l2_std_id id)  {  	struct bttv_fh *fh  = priv;  	struct bttv *btv = fh->btv;  	unsigned int i; -	int err; - -	err = v4l2_prio_check(&btv->prio, fh->prio); -	if (err) -		goto err; +	int err = 0;  	for (i = 0; i < BTTV_TVNORMS; i++) -		if (*id & bttv_tvnorms[i].v4l2_id) +		if (id & bttv_tvnorms[i].v4l2_id)  			break;  	if (i == BTTV_TVNORMS) {  		err = -EINVAL;  		goto err;  	} +	btv->std = id;  	set_tvnorm(btv, i);  err: @@ -1897,6 +1746,15 @@ err:  	return err;  } +static int bttv_g_std(struct file *file, void *priv, v4l2_std_id *id) +{ +	struct bttv_fh *fh  = priv; +	struct bttv *btv = fh->btv; + +	*id = btv->std; +	return 0; +} +  static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id)  {  	struct bttv_fh *fh = f; @@ -1922,7 +1780,7 @@ static int bttv_enum_input(struct file *file, void *priv,  	}  	i->type     = V4L2_INPUT_TYPE_CAMERA; -	i->audioset = 1; +	i->audioset = 0;  	if (btv->tuner_type != TUNER_ABSENT && i->index == 0) {  		sprintf(i->name, "Television"); @@ -1964,49 +1822,29 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i)  	struct bttv_fh *fh  = priv;  	struct bttv *btv = fh->btv; -	int err; - -	err = v4l2_prio_check(&btv->prio, fh->prio); -	if (unlikely(err)) -		goto err; - -	if (i > bttv_tvcards[btv->c.type].video_inputs) { -		err = -EINVAL; -		goto err; -	} +	if (i >= bttv_tvcards[btv->c.type].video_inputs) +		return -EINVAL;  	set_input(btv, i, btv->tvnorm); - -err:  	return 0;  }  static int bttv_s_tuner(struct file *file, void *priv, -					struct v4l2_tuner *t) +					const struct v4l2_tuner *t)  {  	struct bttv_fh *fh  = priv;  	struct bttv *btv = fh->btv; -	int err; -	if (unlikely(0 != t->index)) +	if (t->index)  		return -EINVAL; -	if (unlikely(btv->tuner_type == TUNER_ABSENT)) { -		err = -EINVAL; -		goto err; -	} - -	err = v4l2_prio_check(&btv->prio, fh->prio); -	if (unlikely(err)) -		goto err; -  	bttv_call_all(btv, tuner, s_tuner, t); -	if (btv->audio_mode_gpio) -		btv->audio_mode_gpio(btv, t, 1); - -err: +	if (btv->audio_mode_gpio) { +		struct v4l2_tuner copy = *t; +		btv->audio_mode_gpio(btv, ©, 1); +	}  	return 0;  } @@ -2016,49 +1854,81 @@ static int bttv_g_frequency(struct file *file, void *priv,  	struct bttv_fh *fh  = priv;  	struct bttv *btv = fh->btv; -	f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; -	f->frequency = btv->freq; +	if (f->tuner) +		return -EINVAL; + +	if (f->type == V4L2_TUNER_RADIO) +		radio_enable(btv); +	f->frequency = f->type == V4L2_TUNER_RADIO ? +				btv->radio_freq : btv->tv_freq;  	return 0;  } +static void bttv_set_frequency(struct bttv *btv, const struct v4l2_frequency *f) +{ +	struct v4l2_frequency new_freq = *f; + +	bttv_call_all(btv, tuner, s_frequency, f); +	/* s_frequency may clamp the frequency, so get the actual +	   frequency before assigning radio/tv_freq. */ +	bttv_call_all(btv, tuner, g_frequency, &new_freq); +	if (new_freq.type == V4L2_TUNER_RADIO) { +		radio_enable(btv); +		btv->radio_freq = new_freq.frequency; +		if (btv->has_matchbox) +			tea5757_set_freq(btv, btv->radio_freq); +	} else { +		btv->tv_freq = new_freq.frequency; +	} +} +  static int bttv_s_frequency(struct file *file, void *priv, -					struct v4l2_frequency *f) +					const struct v4l2_frequency *f)  {  	struct bttv_fh *fh  = priv;  	struct bttv *btv = fh->btv; -	int err; -	if (unlikely(f->tuner != 0)) +	if (f->tuner)  		return -EINVAL; -	err = v4l2_prio_check(&btv->prio, fh->prio); -	if (unlikely(err)) -		goto err; - -	if (unlikely(f->type != (btv->radio_user -		? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV))) { -		err = -EINVAL; -		goto err; -	} -	btv->freq = f->frequency; -	bttv_call_all(btv, tuner, s_frequency, f); -	if (btv->has_matchbox && btv->radio_user) -		tea5757_set_freq(btv, btv->freq); -err: - +	bttv_set_frequency(btv, f);  	return 0;  }  static int bttv_log_status(struct file *file, void *f)  { +	struct video_device *vdev = video_devdata(file);  	struct bttv_fh *fh  = f;  	struct bttv *btv = fh->btv; +	v4l2_ctrl_handler_log_status(vdev->ctrl_handler, btv->c.v4l2_dev.name);  	bttv_call_all(btv, core, log_status);  	return 0;  } +static int bttv_g_chip_ident(struct file *file, void *f, struct v4l2_dbg_chip_ident *chip) +{ +	struct bttv_fh *fh  = f; +	struct bttv *btv = fh->btv; + +	chip->ident = V4L2_IDENT_NONE; +	chip->revision = 0; +	if (chip->match.type == V4L2_CHIP_MATCH_HOST) { +		if (v4l2_chip_match_host(&chip->match)) { +			chip->ident = btv->id; +			if (chip->ident == PCI_DEVICE_ID_FUSION879) +				chip->ident = V4L2_IDENT_BT879; +		} +		return 0; +	} +	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && +	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) +		return -EINVAL; +	/* TODO: is this correct? */ +	return bttv_call_all_err(btv, core, g_chip_ident, chip); +} +  #ifdef CONFIG_VIDEO_ADV_DEBUG  static int bttv_g_register(struct file *file, void *f,  					struct v4l2_dbg_register *reg) @@ -2069,8 +1939,12 @@ static int bttv_g_register(struct file *file, void *f,  	if (!capable(CAP_SYS_ADMIN))  		return -EPERM; -	if (!v4l2_chip_match_host(®->match)) -		return -EINVAL; +	if (!v4l2_chip_match_host(®->match)) { +		/* TODO: subdev errors should not be ignored, this should become a +		   subdev helper function. */ +		bttv_call_all(btv, core, g_register, reg); +		return 0; +	}  	/* bt848 has a 12-bit register space */  	reg->reg &= 0xfff; @@ -2081,7 +1955,7 @@ static int bttv_g_register(struct file *file, void *f,  }  static int bttv_s_register(struct file *file, void *f, -					struct v4l2_dbg_register *reg) +					const struct v4l2_dbg_register *reg)  {  	struct bttv_fh *fh = f;  	struct bttv *btv = fh->btv; @@ -2089,12 +1963,15 @@ static int bttv_s_register(struct file *file, void *f,  	if (!capable(CAP_SYS_ADMIN))  		return -EPERM; -	if (!v4l2_chip_match_host(®->match)) -		return -EINVAL; +	if (!v4l2_chip_match_host(®->match)) { +		/* TODO: subdev errors should not be ignored, this should become a +		   subdev helper function. */ +		bttv_call_all(btv, core, s_register, reg); +		return 0; +	}  	/* bt848 has a 12-bit register space */ -	reg->reg &= 0xfff; -	btwrite(reg->val, reg->reg); +	btwrite(reg->val, reg->reg & 0xfff);  	return 0;  } @@ -2263,22 +2140,33 @@ limit_scaled_size_lock       (struct bttv_fh *               fh,     may also adjust the current cropping parameters to get closer     to the desired window size. */  static int -verify_window_lock		(struct bttv_fh *               fh, -			 struct v4l2_window *           win, -			 int                            adjust_size, -			 int                            adjust_crop) +verify_window_lock(struct bttv_fh *fh, struct v4l2_window *win, +			 int adjust_size, int adjust_crop)  {  	enum v4l2_field field;  	unsigned int width_mask;  	int rc; -	if (win->w.width  < 48 || win->w.height < 32) -		return -EINVAL; +	if (win->w.width < 48) +		win->w.width = 48; +	if (win->w.height < 32) +		win->w.height = 32;  	if (win->clipcount > 2048) -		return -EINVAL; +		win->clipcount = 2048; +	win->chromakey = 0; +	win->global_alpha = 0;  	field = win->field; +	switch (field) { +	case V4L2_FIELD_TOP: +	case V4L2_FIELD_BOTTOM: +	case V4L2_FIELD_INTERLACED: +		break; +	default: +		field = V4L2_FIELD_ANY; +		break; +	}  	if (V4L2_FIELD_ANY == field) {  		__s32 height2; @@ -2287,18 +2175,11 @@ verify_window_lock		(struct bttv_fh *               fh,  			? V4L2_FIELD_INTERLACED  			: V4L2_FIELD_TOP;  	} -	switch (field) { -	case V4L2_FIELD_TOP: -	case V4L2_FIELD_BOTTOM: -	case V4L2_FIELD_INTERLACED: -		break; -	default: -		return -EINVAL; -	} +	win->field = field; -	/* 4-byte alignment. */  	if (NULL == fh->ovfmt)  		return -EINVAL; +	/* 4-byte alignment. */  	width_mask = ~0;  	switch (fh->ovfmt->depth) {  	case 8: @@ -2323,8 +2204,6 @@ verify_window_lock		(struct bttv_fh *               fh,  			       adjust_size, adjust_crop);  	if (0 != rc)  		return rc; - -	win->field = field;  	return 0;  } @@ -2481,6 +2360,7 @@ static int bttv_g_fmt_vid_cap(struct file *file, void *priv,  				fh->width, fh->height);  	f->fmt.pix.field        = fh->cap.field;  	f->fmt.pix.pixelformat  = fh->fmt->fourcc; +	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;  	return 0;  } @@ -2504,6 +2384,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv,  	struct bttv *btv = fh->btv;  	enum v4l2_field field;  	__s32 width, height; +	__s32 height2;  	int rc;  	fmt = format_by_fourcc(f->fmt.pix.pixelformat); @@ -2512,30 +2393,25 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv,  	field = f->fmt.pix.field; -	if (V4L2_FIELD_ANY == field) { -		__s32 height2; - -		height2 = btv->crop[!!fh->do_crop].rect.height >> 1; -		field = (f->fmt.pix.height > height2) -			? V4L2_FIELD_INTERLACED -			: V4L2_FIELD_BOTTOM; -	} - -	if (V4L2_FIELD_SEQ_BT == field) -		field = V4L2_FIELD_SEQ_TB; -  	switch (field) {  	case V4L2_FIELD_TOP:  	case V4L2_FIELD_BOTTOM:  	case V4L2_FIELD_ALTERNATE:  	case V4L2_FIELD_INTERLACED:  		break; +	case V4L2_FIELD_SEQ_BT:  	case V4L2_FIELD_SEQ_TB: -		if (fmt->flags & FORMAT_FLAGS_PLANAR) -			return -EINVAL; +		if (!(fmt->flags & FORMAT_FLAGS_PLANAR)) { +			field = V4L2_FIELD_SEQ_TB; +			break; +		} +		/* fall through */ +	default: /* FIELD_ANY case */ +		height2 = btv->crop[!!fh->do_crop].rect.height >> 1; +		field = (f->fmt.pix.height > height2) +			? V4L2_FIELD_INTERLACED +			: V4L2_FIELD_BOTTOM;  		break; -	default: -		return -EINVAL;  	}  	width = f->fmt.pix.width; @@ -2552,6 +2428,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv,  	/* update data for the application */  	f->fmt.pix.field = field;  	pix_format_set_size(&f->fmt.pix, fmt, width, height); +	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;  	return 0;  } @@ -2561,9 +2438,10 @@ static int bttv_try_fmt_vid_overlay(struct file *file, void *priv,  {  	struct bttv_fh *fh = priv; -	return verify_window_lock(fh, &f->fmt.win, +	verify_window_lock(fh, &f->fmt.win,  			/* adjust_size */ 1,  			/* adjust_crop */ 0); +	return 0;  }  static int bttv_s_fmt_vid_cap(struct file *file, void *priv, @@ -2630,6 +2508,7 @@ static int bttv_s_fmt_vid_overlay(struct file *file, void *priv,  static int bttv_querycap(struct file *file, void  *priv,  				struct v4l2_capability *cap)  { +	struct video_device *vdev = video_devdata(file);  	struct bttv_fh *fh = priv;  	struct bttv *btv = fh->btv; @@ -2642,11 +2521,15 @@ static int bttv_querycap(struct file *file, void  *priv,  		 "PCI:%s", pci_name(btv->c.pci));  	cap->capabilities =  		V4L2_CAP_VIDEO_CAPTURE | -		V4L2_CAP_VBI_CAPTURE |  		V4L2_CAP_READWRITE | -		V4L2_CAP_STREAMING; +		V4L2_CAP_STREAMING | +		V4L2_CAP_DEVICE_CAPS;  	if (no_overlay <= 0)  		cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; +	if (btv->vbi_dev) +		cap->capabilities |= V4L2_CAP_VBI_CAPTURE; +	if (btv->radio_dev) +		cap->capabilities |= V4L2_CAP_RADIO;  	/*  	 * No need to lock here: those vars are initialized during board @@ -2656,6 +2539,25 @@ static int bttv_querycap(struct file *file, void  *priv,  		cap->capabilities |= V4L2_CAP_RDS_CAPTURE;  	if (btv->tuner_type != TUNER_ABSENT)  		cap->capabilities |= V4L2_CAP_TUNER; +	if (vdev->vfl_type == VFL_TYPE_GRABBER) +		cap->device_caps = cap->capabilities & +			(V4L2_CAP_VIDEO_CAPTURE | +			 V4L2_CAP_READWRITE | +			 V4L2_CAP_STREAMING | +			 V4L2_CAP_VIDEO_OVERLAY | +			 V4L2_CAP_TUNER); +	else if (vdev->vfl_type == VFL_TYPE_VBI) +		cap->device_caps = cap->capabilities & +			(V4L2_CAP_VBI_CAPTURE | +			 V4L2_CAP_READWRITE | +			 V4L2_CAP_STREAMING | +			 V4L2_CAP_TUNER); +	else { +		cap->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER; +		if (btv->has_saa6588) +			cap->device_caps |= V4L2_CAP_READWRITE | +						V4L2_CAP_RDS_CAPTURE; +	}  	return 0;  } @@ -2718,6 +2620,7 @@ static int bttv_g_fbuf(struct file *file, void *f,  	*fb = btv->fbuf;  	fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; +	fb->flags = V4L2_FBUF_FLAG_PRIMARY;  	if (fh->ovfmt)  		fb->fmt.pixelformat  = fh->ovfmt->fourcc;  	return 0; @@ -2891,36 +2794,15 @@ static int bttv_streamoff(struct file *file, void *priv,  	return 0;  } -static int bttv_queryctrl(struct file *file, void *priv, -					struct v4l2_queryctrl *c) -{ -	struct bttv_fh *fh = priv; -	struct bttv *btv = fh->btv; -	const struct v4l2_queryctrl *ctrl; - -	if ((c->id <  V4L2_CID_BASE || -	     c->id >= V4L2_CID_LASTP1) && -	    (c->id <  V4L2_CID_PRIVATE_BASE || -	     c->id >= V4L2_CID_PRIVATE_LASTP1)) -		return -EINVAL; - -	if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) -		*c = no_ctl; -	else { -		ctrl = ctrl_by_id(c->id); - -		*c = (NULL != ctrl) ? *ctrl : no_ctl; -	} - -	return 0; -} -  static int bttv_g_parm(struct file *file, void *f,  				struct v4l2_streamparm *parm)  {  	struct bttv_fh *fh = f;  	struct bttv *btv = fh->btv; +	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) +		return -EINVAL; +	parm->parm.capture.readbuffers = gbuffers;  	v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,  				    &parm->parm.capture.timeperframe); @@ -2933,15 +2815,13 @@ static int bttv_g_tuner(struct file *file, void *priv,  	struct bttv_fh *fh = priv;  	struct bttv *btv = fh->btv; -	if (btv->tuner_type == TUNER_ABSENT) -		return -EINVAL;  	if (0 != t->index)  		return -EINVAL;  	t->rxsubchans = V4L2_TUNER_SUB_MONO; +	t->capability = V4L2_TUNER_CAP_NORM;  	bttv_call_all(btv, tuner, g_tuner, t);  	strcpy(t->name, "Television"); -	t->capability = V4L2_TUNER_CAP_NORM;  	t->type       = V4L2_TUNER_ANALOG_TV;  	if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)  		t->signal = 0xffff; @@ -2952,28 +2832,6 @@ static int bttv_g_tuner(struct file *file, void *priv,  	return 0;  } -static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p) -{ -	struct bttv_fh *fh = f; -	struct bttv *btv = fh->btv; - -	*p = v4l2_prio_max(&btv->prio); - -	return 0; -} - -static int bttv_s_priority(struct file *file, void *f, -					enum v4l2_priority prio) -{ -	struct bttv_fh *fh = f; -	struct bttv *btv = fh->btv; -	int	rc; - -	rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); - -	return rc; -} -  static int bttv_cropcap(struct file *file, void *priv,  				struct v4l2_cropcap *cap)  { @@ -3026,11 +2884,6 @@ static int bttv_s_crop(struct file *file, void *f, const struct v4l2_crop *crop)  	/* Make sure tvnorm, vbi_end and the current cropping  	   parameters remain consistent until we're done. Note  	   read() may change vbi_end in check_alloc_btres_lock(). */ -	retval = v4l2_prio_check(&btv->prio, fh->prio); -	if (0 != retval) { -		return retval; -	} -  	retval = -EBUSY;  	if (locked_btres(fh->btv, VIDEO_RESOURCES)) { @@ -3088,23 +2941,6 @@ static int bttv_s_crop(struct file *file, void *f, const struct v4l2_crop *crop)  	return 0;  } -static int bttv_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ -	if (unlikely(a->index)) -		return -EINVAL; - -	strcpy(a->name, "audio"); -	return 0; -} - -static int bttv_s_audio(struct file *file, void *priv, const struct v4l2_audio *a) -{ -	if (unlikely(a->index)) -		return -EINVAL; - -	return 0; -} -  static ssize_t bttv_read(struct file *file, char __user *data,  			 size_t count, loff_t *ppos)  { @@ -3144,34 +2980,43 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)  	struct bttv_fh *fh = file->private_data;  	struct bttv_buffer *buf;  	enum v4l2_field field; -	unsigned int rc = POLLERR; +	unsigned int rc = 0; +	unsigned long req_events = poll_requested_events(wait); + +	if (v4l2_event_pending(&fh->fh)) +		rc = POLLPRI; +	else if (req_events & POLLPRI) +		poll_wait(file, &fh->fh.wait, wait); + +	if (!(req_events & (POLLIN | POLLRDNORM))) +		return rc;  	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {  		if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI)) -			return POLLERR; -		return videobuf_poll_stream(file, &fh->vbi, wait); +			return rc | POLLERR; +		return rc | videobuf_poll_stream(file, &fh->vbi, wait);  	}  	if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {  		/* streaming capture */  		if (list_empty(&fh->cap.stream)) -			goto err; +			return rc | POLLERR;  		buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);  	} else {  		/* read() capture */  		if (NULL == fh->cap.read_buf) {  			/* need to capture a new frame */  			if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) -				goto err; +				return rc | POLLERR;  			fh->cap.read_buf = videobuf_sg_alloc(fh->cap.msize);  			if (NULL == fh->cap.read_buf) -				goto err; +				return rc | POLLERR;  			fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;  			field = videobuf_next_field(&fh->cap);  			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {  				kfree (fh->cap.read_buf);  				fh->cap.read_buf = NULL; -				goto err; +				return rc | POLLERR;  			}  			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);  			fh->cap.read_off = 0; @@ -3182,10 +3027,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)  	poll_wait(file, &buf->vb.done, wait);  	if (buf->vb.state == VIDEOBUF_DONE ||  	    buf->vb.state == VIDEOBUF_ERROR) -		rc =  POLLIN|POLLRDNORM; -	else -		rc = 0; -err: +		rc = rc | POLLIN|POLLRDNORM;  	return rc;  } @@ -3214,15 +3056,15 @@ static int bttv_open(struct file *file)  	fh = kmalloc(sizeof(*fh), GFP_KERNEL);  	if (unlikely(!fh))  		return -ENOMEM; +	btv->users++;  	file->private_data = fh;  	*fh = btv->init; +	v4l2_fh_init(&fh->fh, vdev);  	fh->type = type;  	fh->ov.setup_ok = 0; -	v4l2_prio_open(&btv->prio, &fh->prio); -  	videobuf_queue_sg_init(&fh->cap, &bttv_video_qops,  			    &btv->c.pci->dev, &btv->s_lock,  			    V4L2_BUF_TYPE_VIDEO_CAPTURE, @@ -3237,8 +3079,7 @@ static int bttv_open(struct file *file)  			    fh, &btv->lock);  	set_tvnorm(btv,btv->tvnorm);  	set_input(btv, btv->input, btv->tvnorm); - -	btv->users++; +	audio_mute(btv, btv->mute);  	/* The V4L2 spec requires one global set of cropping parameters  	   which only change on request. These are stored in btv->crop[1]. @@ -3257,6 +3098,7 @@ static int bttv_open(struct file *file)  	bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm);  	bttv_field_count(btv); +	v4l2_fh_add(&fh->fh);  	return 0;  } @@ -3292,16 +3134,17 @@ static int bttv_release(struct file *file)  	videobuf_mmap_free(&fh->cap);  	videobuf_mmap_free(&fh->vbi); -	v4l2_prio_close(&btv->prio, fh->prio);  	file->private_data = NULL; -	kfree(fh);  	btv->users--;  	bttv_field_count(btv);  	if (!btv->users) -		audio_mute(btv, 1); +		audio_mute(btv, btv->mute); +	v4l2_fh_del(&fh->fh); +	v4l2_fh_exit(&fh->fh); +	kfree(fh);  	return 0;  } @@ -3340,20 +3183,16 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = {  	.vidioc_g_fmt_vbi_cap           = bttv_g_fmt_vbi_cap,  	.vidioc_try_fmt_vbi_cap         = bttv_try_fmt_vbi_cap,  	.vidioc_s_fmt_vbi_cap           = bttv_s_fmt_vbi_cap, -	.vidioc_g_audio                 = bttv_g_audio, -	.vidioc_s_audio                 = bttv_s_audio,  	.vidioc_cropcap                 = bttv_cropcap,  	.vidioc_reqbufs                 = bttv_reqbufs,  	.vidioc_querybuf                = bttv_querybuf,  	.vidioc_qbuf                    = bttv_qbuf,  	.vidioc_dqbuf                   = bttv_dqbuf,  	.vidioc_s_std                   = bttv_s_std, +	.vidioc_g_std                   = bttv_g_std,  	.vidioc_enum_input              = bttv_enum_input,  	.vidioc_g_input                 = bttv_g_input,  	.vidioc_s_input                 = bttv_s_input, -	.vidioc_queryctrl               = bttv_queryctrl, -	.vidioc_g_ctrl                  = bttv_g_ctrl, -	.vidioc_s_ctrl                  = bttv_s_ctrl,  	.vidioc_streamon                = bttv_streamon,  	.vidioc_streamoff               = bttv_streamoff,  	.vidioc_g_tuner                 = bttv_g_tuner, @@ -3363,13 +3202,14 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = {  	.vidioc_g_fbuf                  = bttv_g_fbuf,  	.vidioc_s_fbuf                  = bttv_s_fbuf,  	.vidioc_overlay                 = bttv_overlay, -	.vidioc_g_priority              = bttv_g_priority, -	.vidioc_s_priority              = bttv_s_priority,  	.vidioc_g_parm                  = bttv_g_parm,  	.vidioc_g_frequency             = bttv_g_frequency,  	.vidioc_s_frequency             = bttv_s_frequency,  	.vidioc_log_status		= bttv_log_status,  	.vidioc_querystd		= bttv_querystd, +	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event, +	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe, +	.vidioc_g_chip_ident		= bttv_g_chip_ident,  #ifdef CONFIG_VIDEO_ADV_DEBUG  	.vidioc_g_register		= bttv_g_register,  	.vidioc_s_register		= bttv_s_register, @@ -3380,7 +3220,6 @@ static struct video_device bttv_video_template = {  	.fops         = &bttv_fops,  	.ioctl_ops    = &bttv_ioctl_ops,  	.tvnorms      = BTTV_NORMS, -	.current_norm = V4L2_STD_PAL,  };  /* ----------------------------------------------------------------------- */ @@ -3402,13 +3241,12 @@ static int radio_open(struct file *file)  		return -ENOMEM;  	file->private_data = fh;  	*fh = btv->init; - -	v4l2_prio_open(&btv->prio, &fh->prio); +	v4l2_fh_init(&fh->fh, vdev);  	btv->radio_user++; +	audio_mute(btv, btv->mute); -	bttv_call_all(btv, tuner, s_radio); -	audio_input(btv,TVAUDIO_INPUT_RADIO); +	v4l2_fh_add(&fh->fh);  	return 0;  } @@ -3419,28 +3257,17 @@ static int radio_release(struct file *file)  	struct bttv *btv = fh->btv;  	struct saa6588_command cmd; -	v4l2_prio_close(&btv->prio, fh->prio);  	file->private_data = NULL; +	v4l2_fh_del(&fh->fh); +	v4l2_fh_exit(&fh->fh);  	kfree(fh);  	btv->radio_user--;  	bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); -	return 0; -} - -static int radio_querycap(struct file *file, void *priv, -					struct v4l2_capability *cap) -{ -	struct bttv_fh *fh = priv; -	struct bttv *btv = fh->btv; - -	strcpy(cap->driver, "bttv"); -	strlcpy(cap->card, btv->radio_dev->name, sizeof(cap->card)); -	sprintf(cap->bus_info, "PCI:%s", pci_name(btv->c.pci)); -	cap->capabilities = V4L2_CAP_TUNER; - +	if (btv->radio_user == 0) +		btv->has_radio_tuner = 0;  	return 0;  } @@ -3449,12 +3276,11 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)  	struct bttv_fh *fh = priv;  	struct bttv *btv = fh->btv; -	if (btv->tuner_type == TUNER_ABSENT) -		return -EINVAL;  	if (0 != t->index)  		return -EINVAL;  	strcpy(t->name, "Radio");  	t->type = V4L2_TUNER_RADIO; +	radio_enable(btv);  	bttv_call_all(btv, tuner, g_tuner, t); @@ -3464,31 +3290,8 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)  	return 0;  } -static int radio_enum_input(struct file *file, void *priv, -				struct v4l2_input *i) -{ -	if (i->index != 0) -		return -EINVAL; - -	strcpy(i->name, "Radio"); -	i->type = V4L2_INPUT_TYPE_TUNER; - -	return 0; -} - -static int radio_g_audio(struct file *file, void *priv, -					struct v4l2_audio *a) -{ -	if (unlikely(a->index)) -		return -EINVAL; - -	strcpy(a->name, "Radio"); - -	return 0; -} -  static int radio_s_tuner(struct file *file, void *priv, -					struct v4l2_tuner *t) +					const struct v4l2_tuner *t)  {  	struct bttv_fh *fh = priv;  	struct bttv *btv = fh->btv; @@ -3496,56 +3299,11 @@ static int radio_s_tuner(struct file *file, void *priv,  	if (0 != t->index)  		return -EINVAL; +	radio_enable(btv);  	bttv_call_all(btv, tuner, s_tuner, t);  	return 0;  } -static int radio_s_audio(struct file *file, void *priv, -					const struct v4l2_audio *a) -{ -	if (unlikely(a->index)) -		return -EINVAL; - -	return 0; -} - -static int radio_s_input(struct file *filp, void *priv, unsigned int i) -{ -	if (unlikely(i)) -		return -EINVAL; - -	return 0; -} - -static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) -{ -	return 0; -} - -static int radio_queryctrl(struct file *file, void *priv, -					struct v4l2_queryctrl *c) -{ -	const struct v4l2_queryctrl *ctrl; - -	if (c->id <  V4L2_CID_BASE || -			c->id >= V4L2_CID_LASTP1) -		return -EINVAL; - -	if (c->id == V4L2_CID_AUDIO_MUTE) { -		ctrl = ctrl_by_id(c->id); -		*c = *ctrl; -	} else -		*c = no_ctl; - -	return 0; -} - -static int radio_g_input(struct file *filp, void *priv, unsigned int *i) -{ -	*i = 0; -	return 0; -} -  static ssize_t radio_read(struct file *file, char __user *data,  			 size_t count, loff_t *ppos)  { @@ -3556,6 +3314,7 @@ static ssize_t radio_read(struct file *file, char __user *data,  	cmd.buffer = data;  	cmd.instance = file;  	cmd.result = -ENODEV; +	radio_enable(btv);  	bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); @@ -3566,10 +3325,18 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)  {  	struct bttv_fh *fh = file->private_data;  	struct bttv *btv = fh->btv; +	unsigned long req_events = poll_requested_events(wait);  	struct saa6588_command cmd; +	unsigned int res = 0; + +	if (v4l2_event_pending(&fh->fh)) +		res = POLLPRI; +	else if (req_events & POLLPRI) +		poll_wait(file, &fh->fh.wait, wait); +	radio_enable(btv);  	cmd.instance = file;  	cmd.event_list = wait; -	cmd.result = -ENODEV; +	cmd.result = res;  	bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd);  	return cmd.result; @@ -3586,20 +3353,14 @@ static const struct v4l2_file_operations radio_fops =  };  static const struct v4l2_ioctl_ops radio_ioctl_ops = { -	.vidioc_querycap        = radio_querycap, +	.vidioc_querycap        = bttv_querycap, +	.vidioc_log_status	= bttv_log_status,  	.vidioc_g_tuner         = radio_g_tuner, -	.vidioc_enum_input      = radio_enum_input, -	.vidioc_g_audio         = radio_g_audio,  	.vidioc_s_tuner         = radio_s_tuner, -	.vidioc_s_audio         = radio_s_audio, -	.vidioc_s_input         = radio_s_input, -	.vidioc_s_std           = radio_s_std, -	.vidioc_queryctrl       = radio_queryctrl, -	.vidioc_g_input         = radio_g_input, -	.vidioc_g_ctrl          = bttv_g_ctrl, -	.vidioc_s_ctrl          = bttv_s_ctrl,  	.vidioc_g_frequency     = bttv_g_frequency,  	.vidioc_s_frequency     = bttv_s_frequency, +	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event, +	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,  };  static struct video_device radio_template = { @@ -4102,7 +3863,8 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)  			bttv_irq_switch_video(btv);  		if ((astat & BT848_INT_HLOCK)  &&  btv->opt_automute) -			audio_mute(btv, btv->mute);  /* trigger automute */ +			/* trigger automute */ +			audio_mux_gpio(btv, btv->audio_input, btv->mute);  		if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {  			pr_info("%d: %s%s @ %08x,", @@ -4151,7 +3913,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)  /* ----------------------------------------------------------------------- */ -/* initialitation                                                          */ +/* initialization                                                          */  static struct video_device *vdev_init(struct bttv *btv,  				      const struct video_device *template, @@ -4166,10 +3928,17 @@ static struct video_device *vdev_init(struct bttv *btv,  	vfd->v4l2_dev = &btv->c.v4l2_dev;  	vfd->release = video_device_release;  	vfd->debug   = bttv_debug; +	set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);  	video_set_drvdata(vfd, btv);  	snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",  		 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",  		 type_name, bttv_tvcards[btv->c.type].name); +	if (btv->tuner_type == TUNER_ABSENT) { +		v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); +		v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY); +		v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); +		v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); +	}  	return vfd;  } @@ -4237,6 +4006,7 @@ static int bttv_register_video(struct bttv *btv)  	btv->radio_dev = vdev_init(btv, &radio_template, "radio");  	if (NULL == btv->radio_dev)  		goto err; +	btv->radio_dev->ctrl_handler = &btv->radio_ctrl_handler;  	if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,  				  radio_nr[btv->c.nr]) < 0)  		goto err; @@ -4267,9 +4037,15 @@ static void pci_set_command(struct pci_dev *dev)  static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  { +	struct v4l2_frequency init_freq = { +		.tuner = 0, +		.type = V4L2_TUNER_ANALOG_TV, +		.frequency = 980, +	};  	int result;  	unsigned char lat;  	struct bttv *btv; +	struct v4l2_ctrl_handler *hdl;  	if (bttv_num == BTTV_MAX)  		return -ENOMEM; @@ -4291,7 +4067,6 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  	INIT_LIST_HEAD(&btv->c.subs);  	INIT_LIST_HEAD(&btv->capture);  	INIT_LIST_HEAD(&btv->vcapture); -	v4l2_prio_init(&btv->prio);  	init_timer(&btv->timeout);  	btv->timeout.function = bttv_irq_timeout; @@ -4329,6 +4104,10 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  		pr_warn("%d: v4l2_device_register() failed\n", btv->c.nr);  		goto fail0;  	} +	hdl = &btv->ctrl_handler; +	v4l2_ctrl_handler_init(hdl, 20); +	btv->c.v4l2_dev.ctrl_handler = hdl; +	v4l2_ctrl_handler_init(&btv->radio_ctrl_handler, 6);  	btv->revision = dev->revision;  	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); @@ -4365,16 +4144,19 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  	/* init options from insmod args */  	btv->opt_combfilter = combfilter; -	btv->opt_lumafilter = lumafilter; +	bttv_ctrl_combfilter.def = combfilter; +	bttv_ctrl_lumafilter.def = lumafilter;  	btv->opt_automute   = automute; -	btv->opt_chroma_agc = chroma_agc; -	btv->opt_adc_crush  = adc_crush; +	bttv_ctrl_automute.def = automute; +	bttv_ctrl_agc_crush.def = agc_crush;  	btv->opt_vcr_hack   = vcr_hack; -	btv->opt_whitecrush_upper  = whitecrush_upper; -	btv->opt_whitecrush_lower  = whitecrush_lower; +	bttv_ctrl_vcr_hack.def = vcr_hack; +	bttv_ctrl_whitecrush_upper.def = whitecrush_upper; +	bttv_ctrl_whitecrush_lower.def = whitecrush_lower;  	btv->opt_uv_ratio   = uv_ratio; -	btv->opt_full_luma_range   = full_luma_range; -	btv->opt_coring     = coring; +	bttv_ctrl_uv_ratio.def = uv_ratio; +	bttv_ctrl_full_luma.def = full_luma_range; +	bttv_ctrl_coring.def = coring;  	/* fill struct bttv with some useful defaults */  	btv->init.btv         = btv; @@ -4383,8 +4165,39 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  	btv->init.fmt         = format_by_fourcc(V4L2_PIX_FMT_BGR24);  	btv->init.width       = 320;  	btv->init.height      = 240; +	btv->init.ov.w.width  = 320; +	btv->init.ov.w.height = 240; +	btv->init.ov.field    = V4L2_FIELD_INTERLACED;  	btv->input = 0; +	v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, +			V4L2_CID_BRIGHTNESS, 0, 0xff00, 0x100, 32768); +	v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, +			V4L2_CID_CONTRAST, 0, 0xff80, 0x80, 0x6c00); +	v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, +			V4L2_CID_SATURATION, 0, 0xff80, 0x80, 32768); +	v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, +			V4L2_CID_COLOR_KILLER, 0, 1, 1, 0); +	v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, +			V4L2_CID_HUE, 0, 0xff00, 0x100, 32768); +	v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, +			V4L2_CID_CHROMA_AGC, 0, 1, 1, !!chroma_agc); +	v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, +		V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); +	if (btv->volume_gpio) +		v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, +			V4L2_CID_AUDIO_VOLUME, 0, 0xff00, 0x100, 0xff00); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_combfilter, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_automute, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_lumafilter, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_agc_crush, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_vcr_hack, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_whitecrush_lower, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_whitecrush_upper, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_uv_ratio, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_full_luma, NULL); +	v4l2_ctrl_new_custom(hdl, &bttv_ctrl_coring, NULL); +  	/* initialize hardware */  	if (bttv_gpio)  		bttv_gpio_tracking(btv,"pre-init"); @@ -4407,21 +4220,34 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  	/* some card-specific stuff (needs working i2c) */  	bttv_init_card2(btv);  	bttv_init_tuner(btv); +	if (btv->tuner_type != TUNER_ABSENT) { +		bttv_set_frequency(btv, &init_freq); +		btv->radio_freq = 90500 * 16; /* 90.5Mhz default */ +	} +	btv->std = V4L2_STD_PAL;  	init_irqreg(btv); +	v4l2_ctrl_handler_setup(hdl); +	if (hdl->error) { +		result = hdl->error; +		goto fail2; +	} +	/* mute device */ +	audio_mute(btv, 1);  	/* register video4linux + input */  	if (!bttv_tvcards[btv->c.type].no_video) { -		bttv_register_video(btv); -		bt848_bright(btv,32768); -		bt848_contrast(btv, 27648); -		bt848_hue(btv,32768); -		bt848_sat(btv,32768); -		audio_mute(btv, 1); +		v4l2_ctrl_add_handler(&btv->radio_ctrl_handler, hdl, +				v4l2_ctrl_radio_filter); +		if (btv->radio_ctrl_handler.error) { +			result = btv->radio_ctrl_handler.error; +			goto fail2; +		}  		set_input(btv, 0, btv->tvnorm);  		bttv_crop_reset(&btv->crop[0], btv->tvnorm);  		btv->crop[1] = btv->crop[0]; /* current = default */  		disclaim_vbi_lines(btv);  		disclaim_video_lines(btv); +		bttv_register_video(btv);  	}  	/* add subdevices and autoload dvb-bt8xx if needed */ @@ -4443,6 +4269,8 @@ fail2:  	free_irq(btv->c.pci->irq,btv);  fail1: +	v4l2_ctrl_handler_free(&btv->ctrl_handler); +	v4l2_ctrl_handler_free(&btv->radio_ctrl_handler);  	v4l2_device_unregister(&btv->c.v4l2_dev);  fail0: @@ -4484,9 +4312,11 @@ static void bttv_remove(struct pci_dev *pci_dev)  	bttv_unregister_video(btv);  	/* free allocated memory */ +	v4l2_ctrl_handler_free(&btv->ctrl_handler); +	v4l2_ctrl_handler_free(&btv->radio_ctrl_handler);  	btcx_riscmem_free(btv->c.pci,&btv->main); -	/* free ressources */ +	/* free resources */  	free_irq(btv->c.pci->irq,btv);  	iounmap(btv->bt848_mmio);  	release_mem_region(pci_resource_start(btv->c.pci,0), diff --git a/drivers/media/pci/bt8xx/bttv-i2c.c b/drivers/media/pci/bt8xx/bttv-i2c.c index c63c643ed1f..b7c52dc8999 100644 --- a/drivers/media/pci/bt8xx/bttv-i2c.c +++ b/drivers/media/pci/bt8xx/bttv-i2c.c @@ -394,3 +394,11 @@ int init_bttv_i2c(struct bttv *btv)  	return btv->i2c_rc;  } + +int fini_bttv_i2c(struct bttv *btv) +{ +	if (0 != btv->i2c_rc) +		return 0; + +	return i2c_del_adapter(&btv->c.i2c_adap); +} diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index 04207a79905..f36821367d8 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -375,6 +375,7 @@ void init_bttv_i2c_ir(struct bttv *btv)  		I2C_CLIENT_END  	};  	struct i2c_board_info info; +	struct i2c_client *i2c_dev;  	if (0 != btv->i2c_rc)  		return; @@ -390,7 +391,12 @@ void init_bttv_i2c_ir(struct bttv *btv)  		btv->init_data.ir_codes = RC_MAP_PV951;  		info.addr = 0x4b;  		break; -	default: +	} + +	if (btv->init_data.name) { +		info.platform_data = &btv->init_data; +		i2c_dev = i2c_new_device(&btv->c.i2c_adap, &info); +	} else {  		/*  		 * The external IR receiver is at i2c address 0x34 (0x35 for  		 * reads).  Future Hauppauge cards will have an internal @@ -399,24 +405,14 @@ void init_bttv_i2c_ir(struct bttv *btv)  		 * internal.  		 * That's why we probe 0x1a (~0x34) first. CB  		 */ - -		i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL); -		return; +		i2c_dev = i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL);  	} +	if (NULL == i2c_dev) +		return; -	if (btv->init_data.name) -		info.platform_data = &btv->init_data; -	i2c_new_device(&btv->c.i2c_adap, &info); - -	return; -} - -int fini_bttv_i2c(struct bttv *btv) -{ -	if (0 != btv->i2c_rc) -		return 0; - -	return i2c_del_adapter(&btv->c.i2c_adap); +#if defined(CONFIG_MODULES) && defined(MODULE) +	request_module("ir-kbd-i2c"); +#endif  }  int bttv_input_init(struct bttv *btv) diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h index 79a11240a59..6139ce26dc2 100644 --- a/drivers/media/pci/bt8xx/bttv.h +++ b/drivers/media/pci/bt8xx/bttv.h @@ -359,6 +359,9 @@ void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits);  #define bttv_call_all(btv, o, f, args...) \  	v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args) +#define bttv_call_all_err(btv, o, f, args...) \ +	v4l2_device_call_until_err(&btv->c.v4l2_dev, 0, o, f, ##args) +  extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);  extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,  			 unsigned char b2, int both); diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index 9ec0adba236..9c1cc2c50ee 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -33,9 +33,11 @@  #include <linux/input.h>  #include <linux/mutex.h>  #include <linux/scatterlist.h> +#include <linux/device.h>  #include <asm/io.h>  #include <media/v4l2-common.h> -#include <linux/device.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-fh.h>  #include <media/videobuf-dma-sg.h>  #include <media/tveeprom.h>  #include <media/rc-core.h> @@ -214,11 +216,11 @@ struct bttv_crop {  };  struct bttv_fh { +	/* This must be the first field in this struct */ +	struct v4l2_fh		 fh; +  	struct bttv              *btv;  	int resources; -#ifdef VIDIOC_G_PRIORITY -	enum v4l2_priority       prio; -#endif  	enum v4l2_buf_type       type;  	/* video capture */ @@ -298,6 +300,10 @@ extern int no_overlay;  /* bttv-input.c                                               */  extern void init_bttv_i2c_ir(struct bttv *btv); + +/* ---------------------------------------------------------- */ +/* bttv-i2c.c                                                 */ +extern int init_bttv_i2c(struct bttv *btv);  extern int fini_bttv_i2c(struct bttv *btv);  /* ---------------------------------------------------------- */ @@ -308,7 +314,6 @@ extern unsigned int bttv_verbose;  extern unsigned int bttv_debug;  extern unsigned int bttv_gpio;  extern void bttv_gpio_tracking(struct bttv *btv, char *comment); -extern int init_bttv_i2c(struct bttv *btv);  #define dprintk(fmt, ...)			\  do {						\ @@ -393,12 +398,17 @@ struct bttv {  	wait_queue_head_t          i2c_queue;  	struct v4l2_subdev 	  *sd_msp34xx;  	struct v4l2_subdev 	  *sd_tvaudio; +	struct v4l2_subdev	  *sd_tda7432;  	/* video4linux (1) */  	struct video_device *video_dev;  	struct video_device *radio_dev;  	struct video_device *vbi_dev; +	/* controls */ +	struct v4l2_ctrl_handler   ctrl_handler; +	struct v4l2_ctrl_handler   radio_ctrl_handler; +  	/* infrared remote */  	int has_remote;  	struct bttv_ir *remote; @@ -410,38 +420,30 @@ struct bttv {  	spinlock_t s_lock;  	struct mutex lock;  	int resources; -#ifdef VIDIOC_G_PRIORITY -	struct v4l2_prio_state prio; -#endif  	/* video state */  	unsigned int input; -	unsigned int audio; +	unsigned int audio_input;  	unsigned int mute; -	unsigned long freq; +	unsigned long tv_freq;  	unsigned int tvnorm; +	v4l2_std_id std;  	int hue, contrast, bright, saturation;  	struct v4l2_framebuffer fbuf;  	unsigned int field_count;  	/* various options */  	int opt_combfilter; -	int opt_lumafilter;  	int opt_automute; -	int opt_chroma_agc; -	int opt_color_killer; -	int opt_adc_crush;  	int opt_vcr_hack; -	int opt_whitecrush_upper; -	int opt_whitecrush_lower;  	int opt_uv_ratio; -	int opt_full_luma_range; -	int opt_coring;  	/* radio data/state */  	int has_radio; +	int has_radio_tuner;  	int radio_user;  	int radio_uses_msp_demodulator; +	unsigned long radio_freq;  	/* miro/pinnacle + Aimslab VHX  	   philips matchbox (tea5757 radio tuner) support */ diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index f164b7f610a..38b1d64ffc2 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c @@ -576,7 +576,7 @@ static void input_change(struct cx18 *cx)  }  static int cx18_av_s_frequency(struct v4l2_subdev *sd, -			       struct v4l2_frequency *freq) +			       const struct v4l2_frequency *freq)  {  	struct cx18 *cx = v4l2_get_subdevdata(sd);  	input_change(cx); @@ -809,7 +809,7 @@ static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)  	return 0;  } -static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) +static int cx18_av_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)  {  	struct cx18_av_state *state = to_cx18_av_state(sd);  	struct cx18 *cx = v4l2_get_subdevdata(sd); @@ -1266,7 +1266,7 @@ static int cx18_av_g_register(struct v4l2_subdev *sd,  }  static int cx18_av_s_register(struct v4l2_subdev *sd, -			      struct v4l2_dbg_register *reg) +			      const struct v4l2_dbg_register *reg)  {  	struct cx18 *cx = v4l2_get_subdevdata(sd); diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index 613e5ae7d5c..67b61cf3e03 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c @@ -1243,7 +1243,7 @@ int cx18_init_on_first_open(struct cx18 *cx)  	   in one place. */  	cx->std++;		/* Force full standard initialization */  	std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std; -	cx18_s_std(NULL, &fh, &std); +	cx18_s_std(NULL, &fh, std);  	cx18_s_frequency(NULL, &fh, &vf);  	return 0;  } diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index cd8d2c2b162..aee7b6dacbf 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c @@ -415,42 +415,34 @@ static int cx18_g_chip_ident(struct file *file, void *fh,  }  #ifdef CONFIG_VIDEO_ADV_DEBUG -static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) -{ -	struct v4l2_dbg_register *regs = arg; - -	if (!capable(CAP_SYS_ADMIN)) -		return -EPERM; -	if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) -		return -EINVAL; - -	regs->size = 4; -	if (cmd == VIDIOC_DBG_S_REGISTER) -		cx18_write_enc(cx, regs->val, regs->reg); -	else -		regs->val = cx18_read_enc(cx, regs->reg); -	return 0; -} -  static int cx18_g_register(struct file *file, void *fh,  				struct v4l2_dbg_register *reg)  {  	struct cx18 *cx = fh2id(fh)->cx; -	if (v4l2_chip_match_host(®->match)) -		return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); +	if (v4l2_chip_match_host(®->match)) { +		if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) +			return -EINVAL; +		reg->size = 4; +		reg->val = cx18_read_enc(cx, reg->reg); +		return 0; +	}  	/* FIXME - errors shouldn't be ignored */  	cx18_call_all(cx, core, g_register, reg);  	return 0;  }  static int cx18_s_register(struct file *file, void *fh, -				struct v4l2_dbg_register *reg) +				const struct v4l2_dbg_register *reg)  {  	struct cx18 *cx = fh2id(fh)->cx; -	if (v4l2_chip_match_host(®->match)) -		return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); +	if (v4l2_chip_match_host(®->match)) { +		if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) +			return -EINVAL; +		cx18_write_enc(cx, reg->val, reg->reg); +		return 0; +	}  	/* FIXME - errors shouldn't be ignored */  	cx18_call_all(cx, core, s_register, reg);  	return 0; @@ -614,7 +606,7 @@ static int cx18_g_frequency(struct file *file, void *fh,  	return 0;  } -int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) +int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)  {  	struct cx18_open_id *id = fh2id(fh);  	struct cx18 *cx = id->cx; @@ -637,15 +629,15 @@ static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)  	return 0;  } -int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) +int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)  {  	struct cx18_open_id *id = fh2id(fh);  	struct cx18 *cx = id->cx; -	if ((*std & V4L2_STD_ALL) == 0) +	if ((std & V4L2_STD_ALL) == 0)  		return -EINVAL; -	if (*std == cx->std) +	if (std == cx->std)  		return 0;  	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || @@ -656,8 +648,8 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)  		return -EBUSY;  	} -	cx->std = *std; -	cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; +	cx->std = std; +	cx->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;  	cx->is_50hz = !cx->is_60hz;  	cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);  	cx->cxhdl.width = 720; @@ -673,7 +665,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)  	return 0;  } -static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) +static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)  {  	struct cx18_open_id *id = fh2id(fh);  	struct cx18 *cx = id->cx; @@ -1118,7 +1110,7 @@ static int cx18_log_status(struct file *file, void *fh)  }  static long cx18_default(struct file *file, void *fh, bool valid_prio, -							int cmd, void *arg) +			 unsigned int cmd, void *arg)  {  	struct cx18 *cx = fh2id(fh)->cx; diff --git a/drivers/media/pci/cx18/cx18-ioctl.h b/drivers/media/pci/cx18/cx18-ioctl.h index 2f9dd591ee0..43433969d63 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.h +++ b/drivers/media/pci/cx18/cx18-ioctl.h @@ -26,6 +26,6 @@ u16 cx18_service2vbi(int type);  void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);  u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);  void cx18_set_funcs(struct video_device *vdev); -int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std); -int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); +int cx18_s_std(struct file *file, void *fh, v4l2_std_id std); +int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);  int cx18_s_input(struct file *file, void *fh, unsigned int inp); diff --git a/drivers/media/pci/cx23885/altera-ci.h b/drivers/media/pci/cx23885/altera-ci.h index 70e4fd69ad9..4998c96caeb 100644 --- a/drivers/media/pci/cx23885/altera-ci.h +++ b/drivers/media/pci/cx23885/altera-ci.h @@ -24,6 +24,8 @@  #ifndef __ALTERA_CI_H  #define __ALTERA_CI_H +#include <linux/kconfig.h> +  #define ALT_DATA	0x000000ff  #define ALT_TDI		0x00008000  #define ALT_TDO		0x00004000 @@ -41,8 +43,7 @@ struct altera_ci_config {  	int (*fpga_rw) (void *dev, int ad_rg, int val, int rw);  }; -#if defined(CONFIG_MEDIA_ALTERA_CI) || (defined(CONFIG_MEDIA_ALTERA_CI_MODULE) \ -							&& defined(MODULE)) +#if IS_ENABLED(CONFIG_MEDIA_ALTERA_CI)  extern int altera_ci_init(struct altera_ci_config *config, int ci_nr);  extern void altera_ci_release(void *dev, int ci_nr); diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index 5d5052d0253..6dea11a7a85 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c @@ -1222,14 +1222,14 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)  	return 0;  } -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)  {  	struct cx23885_fh  *fh  = file->private_data;  	struct cx23885_dev *dev = fh->dev;  	unsigned int i;  	for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++) -		if (*id & cx23885_tvnorms[i].id) +		if (id & cx23885_tvnorms[i].id)  			break;  	if (i == ARRAY_SIZE(cx23885_tvnorms))  		return -EINVAL; @@ -1237,7 +1237,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)  	/* Have the drier core notify the subdevices */  	mutex_lock(&dev->lock); -	cx23885_set_tvnorm(dev, *id); +	cx23885_set_tvnorm(dev, id);  	mutex_unlock(&dev->lock);  	return 0; @@ -1280,7 +1280,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,  }  static int vidioc_s_tuner(struct file *file, void *priv, -				struct v4l2_tuner *t) +				const struct v4l2_tuner *t)  {  	struct cx23885_fh  *fh  = file->private_data;  	struct cx23885_dev *dev = fh->dev; @@ -1311,7 +1311,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,  }  static int vidioc_s_frequency(struct file *file, void *priv, -	struct v4l2_frequency *f) +	const struct v4l2_frequency *f)  {  	return cx23885_set_frequency(file, priv, f);  } diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.c b/drivers/media/pci/cx23885/cx23885-ioctl.c index ea9a614f3bb..acdb6d58db5 100644 --- a/drivers/media/pci/cx23885/cx23885-ioctl.c +++ b/drivers/media/pci/cx23885/cx23885-ioctl.c @@ -158,18 +158,17 @@ int cx23885_g_register(struct file *file, void *fh,  }  static int cx23885_s_host_register(struct cx23885_dev *dev, -				   struct v4l2_dbg_register *reg) +				   const struct v4l2_dbg_register *reg)  {  	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))  		return -EINVAL; -	reg->size = 4;  	cx_write(reg->reg, reg->val);  	return 0;  }  static int cx23417_s_register(struct cx23885_dev *dev, -			      struct v4l2_dbg_register *reg) +			      const struct v4l2_dbg_register *reg)  {  	if (dev->v4l_device == NULL)  		return -EINVAL; @@ -179,13 +178,11 @@ static int cx23417_s_register(struct cx23885_dev *dev,  	if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val))  		return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */ - -	reg->size = 4;  	return 0;  }  int cx23885_s_register(struct file *file, void *fh, -		       struct v4l2_dbg_register *reg) +		       const struct v4l2_dbg_register *reg)  {  	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.h b/drivers/media/pci/cx23885/cx23885-ioctl.h index 315be0ca5a0..a6080964a9e 100644 --- a/drivers/media/pci/cx23885/cx23885-ioctl.h +++ b/drivers/media/pci/cx23885/cx23885-ioctl.h @@ -33,7 +33,7 @@ int cx23885_g_register(struct file *file, void *fh,  int cx23885_s_register(struct file *file, void *fh, -		       struct v4l2_dbg_register *reg); +		       const struct v4l2_dbg_register *reg);  #endif  #endif diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 5991bc8dc15..ed08c89adde 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -1259,13 +1259,13 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)  	return 0;  } -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)  {  	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;  	dprintk(1, "%s()\n", __func__);  	mutex_lock(&dev->lock); -	cx23885_set_tvnorm(dev, *tvnorms); +	cx23885_set_tvnorm(dev, tvnorms);  	mutex_unlock(&dev->lock);  	return 0; @@ -1486,7 +1486,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,  }  static int vidioc_s_tuner(struct file *file, void *priv, -				struct v4l2_tuner *t) +				const struct v4l2_tuner *t)  {  	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; @@ -1518,7 +1518,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,  	return 0;  } -static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) +static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency *f)  {  	struct v4l2_control ctrl; @@ -1550,7 +1550,7 @@ static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)  }  static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, -	struct v4l2_frequency *f) +	const struct v4l2_frequency *f)  {  	struct v4l2_control ctrl;  	struct videobuf_dvb_frontend *vfe; @@ -1608,7 +1608,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,  }  int cx23885_set_frequency(struct file *file, void *priv, -	struct v4l2_frequency *f) +	const struct v4l2_frequency *f)  {  	struct cx23885_fh *fh = priv;  	struct cx23885_dev *dev = fh->dev; @@ -1628,7 +1628,7 @@ int cx23885_set_frequency(struct file *file, void *priv,  }  static int vidioc_s_frequency(struct file *file, void *priv, -	struct v4l2_frequency *f) +	const struct v4l2_frequency *f)  {  	return cx23885_set_frequency(file, priv, f);  } diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 59c322d870f..5687d3f678d 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -587,7 +587,7 @@ extern void cx23885_video_wakeup(struct cx23885_dev *dev,  int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i);  int cx23885_set_input(struct file *file, void *priv, unsigned int i);  int cx23885_get_input(struct file *file, void *priv, unsigned int *i); -int cx23885_set_frequency(struct file *file, void *priv, struct v4l2_frequency *f); +int cx23885_set_frequency(struct file *file, void *priv, const struct v4l2_frequency *f);  int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl);  int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl);  int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm); diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index d51eed051d5..fa672fe4107 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -1124,7 +1124,7 @@ static int cx23888_ir_g_register(struct v4l2_subdev *sd,  }  static int cx23888_ir_s_register(struct v4l2_subdev *sd, -				 struct v4l2_dbg_register *reg) +				 const struct v4l2_dbg_register *reg)  {  	struct cx23888_ir_state *state = to_state(sd);  	u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg; diff --git a/drivers/media/pci/cx25821/Kconfig b/drivers/media/pci/cx25821/Kconfig index 4017c942034..6439a847680 100644 --- a/drivers/media/pci/cx25821/Kconfig +++ b/drivers/media/pci/cx25821/Kconfig @@ -1,14 +1,9 @@  config VIDEO_CX25821  	tristate "Conexant cx25821 support" -	depends on DVB_CORE && VIDEO_DEV && PCI && I2C +	depends on VIDEO_DEV && PCI && I2C  	select I2C_ALGOBIT  	select VIDEO_BTCX -	select VIDEO_TVEEPROM -	depends on RC_CORE -	select VIDEOBUF_DVB  	select VIDEOBUF_DMA_SG -	select VIDEO_CX25840 -	select VIDEO_CX2341X  	---help---  	  This is a video4linux driver for Conexant 25821 based  	  TV cards. diff --git a/drivers/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile index caa32b7b51f..fb76c3d3713 100644 --- a/drivers/media/pci/cx25821/Makefile +++ b/drivers/media/pci/cx25821/Makefile @@ -1,14 +1,9 @@  cx25821-y   := cx25821-core.o cx25821-cards.o cx25821-i2c.o \  		       cx25821-gpio.o cx25821-medusa-video.o \ -		       cx25821-video.o cx25821-video-upstream.o \ -		       cx25821-video-upstream-ch2.o \ -		       cx25821-audio-upstream.o +		       cx25821-video.o cx25821-video-upstream.o  obj-$(CONFIG_VIDEO_CX25821) += cx25821.o  obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o  ccflags-y += -Idrivers/media/i2c  ccflags-y += -Idrivers/media/common -ccflags-y += -Idrivers/media/tuners -ccflags-y += -Idrivers/media/dvb-core -ccflags-y += -Idrivers/media/dvb-frontends diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index 1858a45dd08..6e91e84d6bf 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -59,7 +59,6 @@ do {									\  	Data type declarations - Can be moded to a header file later   ****************************************************************************/ -static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];  static int devno;  struct cx25821_audio_buffer { @@ -151,7 +150,7 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip)  {  	struct cx25821_audio_buffer *buf = chip->buf;  	struct cx25821_dev *dev = chip->dev; -	struct sram_channel *audio_ch = +	const struct sram_channel *audio_ch =  	    &cx25821_sram_channels[AUDIO_SRAM_CHANNEL];  	u32 tmp = 0; @@ -627,34 +626,6 @@ static DEFINE_PCI_DEVICE_TABLE(cx25821_audio_pci_tbl) = {  MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);  /* - * Not used in the function snd_cx25821_dev_free so removing - * from the file. - */ -/* -static int snd_cx25821_free(struct cx25821_audio_dev *chip) -{ -	if (chip->irq >= 0) -		free_irq(chip->irq, chip); - -	cx25821_dev_unregister(chip->dev); -	pci_disable_device(chip->pci); - -	return 0; -} -*/ - -/* - * Component Destructor - */ -static void snd_cx25821_dev_free(struct snd_card *card) -{ -	struct cx25821_audio_dev *chip = card->private_data; - -	/* snd_cx25821_free(chip); */ -	snd_card_free(chip->card); -} - -/*   * Alsa Constructor - Component probe   */  static int cx25821_audio_initdev(struct cx25821_dev *dev) @@ -685,7 +656,6 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)  	strcpy(card->driver, "cx25821");  	/* Card "creation" */ -	card->private_free = snd_cx25821_dev_free;  	chip = card->private_data;  	spin_lock_init(&chip->reg_lock); @@ -729,8 +699,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)  		goto error;  	} -	snd_cx25821_cards[devno] = card; - +	dev->card = card;  	devno++;  	return 0; @@ -742,9 +711,33 @@ error:  /****************************************************************************  				LINUX MODULE INIT   ****************************************************************************/ + +static int cx25821_alsa_exit_callback(struct device *dev, void *data) +{ +	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); +	struct cx25821_dev *cxdev = get_cx25821(v4l2_dev); + +	snd_card_free(cxdev->card); +	return 0; +} +  static void cx25821_audio_fini(void)  { -	snd_card_free(snd_cx25821_cards[0]); +	struct device_driver *drv = driver_find("cx25821", &pci_bus_type); +	int ret; + +	ret = driver_for_each_device(drv, NULL, NULL, cx25821_alsa_exit_callback); +	if (ret) +		pr_err("%s failed to find a cx25821 driver.\n", __func__); +} + +static int cx25821_alsa_init_callback(struct device *dev, void *data) +{ +	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); +	struct cx25821_dev *cxdev = get_cx25821(v4l2_dev); + +	cx25821_audio_initdev(cxdev); +	return 0;  }  /* @@ -756,29 +749,11 @@ static void cx25821_audio_fini(void)   */  static int cx25821_alsa_init(void)  { -	struct cx25821_dev *dev = NULL; -	struct list_head *list; +	struct device_driver *drv = driver_find("cx25821", &pci_bus_type); -	mutex_lock(&cx25821_devlist_mutex); -	list_for_each(list, &cx25821_devlist) { -		dev = list_entry(list, struct cx25821_dev, devlist); -		cx25821_audio_initdev(dev); -	} -	mutex_unlock(&cx25821_devlist_mutex); - -	if (dev == NULL) -		pr_info("ERROR ALSA: no cx25821 cards found\n"); - -	return 0; +	return driver_for_each_device(drv, NULL, NULL, cx25821_alsa_init_callback);  }  late_initcall(cx25821_alsa_init);  module_exit(cx25821_audio_fini); - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/cx25821/cx25821-audio-upstream.c b/drivers/media/pci/cx25821/cx25821-audio-upstream.c index 87491ca05ee..b9be535e32b 100644 --- a/drivers/media/pci/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.c @@ -45,7 +45,7 @@ static int _intr_msk = FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF |  			FLD_AUD_SRC_SYNC | FLD_AUD_SRC_OPC_ERR;  static int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev, -					      struct sram_channel *ch, +					      const struct sram_channel *ch,  					      unsigned int bpl, u32 risc)  {  	unsigned int i, lines; @@ -106,7 +106,7 @@ static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,  						 int fifo_enable)  {  	unsigned int line; -	struct sram_channel *sram_ch = +	const struct sram_channel *sram_ch =  		dev->channels[dev->_audio_upstream_channel].sram_channels;  	int offset = 0; @@ -215,7 +215,7 @@ static void cx25821_free_memory_audio(struct cx25821_dev *dev)  void cx25821_stop_upstream_audio(struct cx25821_dev *dev)  { -	struct sram_channel *sram_ch = +	const struct sram_channel *sram_ch =  		dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels;  	u32 tmp = 0; @@ -257,7 +257,7 @@ void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)  }  static int cx25821_get_audio_data(struct cx25821_dev *dev, -			   struct sram_channel *sram_ch) +			   const struct sram_channel *sram_ch)  {  	struct file *myfile;  	int frame_index_temp = dev->_audioframe_index; @@ -352,7 +352,7 @@ static void cx25821_audioups_handler(struct work_struct *work)  }  static int cx25821_openfile_audio(struct cx25821_dev *dev, -			   struct sram_channel *sram_ch) +			   const struct sram_channel *sram_ch)  {  	struct file *myfile;  	int i = 0, j = 0; @@ -433,7 +433,7 @@ static int cx25821_openfile_audio(struct cx25821_dev *dev,  }  static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, -						 struct sram_channel *sram_ch, +						 const struct sram_channel *sram_ch,  						 int bpl)  {  	int ret = 0; @@ -495,7 +495,7 @@ static int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,  {  	int i = 0;  	u32 int_msk_tmp; -	struct sram_channel *channel = dev->channels[chan_num].sram_channels; +	const struct sram_channel *channel = dev->channels[chan_num].sram_channels;  	dma_addr_t risc_phys_jump_addr;  	__le32 *rp; @@ -587,7 +587,7 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)  	struct cx25821_dev *dev = dev_id;  	u32 audio_status;  	int handled = 0; -	struct sram_channel *sram_ch; +	const struct sram_channel *sram_ch;  	if (!dev)  		return -1; @@ -611,7 +611,7 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)  }  static void cx25821_wait_fifo_enable(struct cx25821_dev *dev, -				     struct sram_channel *sram_ch) +				     const struct sram_channel *sram_ch)  {  	int count = 0;  	u32 tmp; @@ -635,7 +635,7 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,  }  static int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, -					    struct sram_channel *sram_ch) +					    const struct sram_channel *sram_ch)  {  	u32 tmp = 0;  	int err = 0; @@ -699,7 +699,7 @@ fail_irq:  int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)  { -	struct sram_channel *sram_ch; +	const struct sram_channel *sram_ch;  	int err = 0;  	if (dev->_audio_is_running) { @@ -728,26 +728,17 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)  	dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;  	_line_size = AUDIO_LINE_SIZE; -	if (dev->input_audiofilename) { +	if ((dev->input_audiofilename) && +	    (strcmp(dev->input_audiofilename, "") != 0))  		dev->_audiofilename = kstrdup(dev->input_audiofilename,  					      GFP_KERNEL); - -		if (!dev->_audiofilename) { -			err = -ENOMEM; -			goto error; -		} - -		/* Default if filename is empty string */ -		if (strcmp(dev->input_audiofilename, "") == 0) -			dev->_audiofilename = "/root/audioGOOD.wav"; -	} else { +	else  		dev->_audiofilename = kstrdup(_defaultAudioName,  					      GFP_KERNEL); -		if (!dev->_audiofilename) { -			err = -ENOMEM; -			goto error; -		} +	if (!dev->_audiofilename) { +		err = -ENOMEM; +		goto error;  	}  	cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, diff --git a/drivers/media/pci/cx25821/cx25821-cards.c b/drivers/media/pci/cx25821/cx25821-cards.c index 99988c98809..3b409feb03d 100644 --- a/drivers/media/pci/cx25821/cx25821-cards.c +++ b/drivers/media/pci/cx25821/cx25821-cards.c @@ -26,11 +26,8 @@  #include <linux/init.h>  #include <linux/module.h>  #include <linux/pci.h> -#include <linux/delay.h> -#include <media/cx25840.h>  #include "cx25821.h" -#include "tuner-xc2028.h"  /* board config info */ @@ -45,28 +42,8 @@ struct cx25821_board cx25821_boards[] = {  		.name = "CX25821",  		.portb = CX25821_RAW,  		.portc = CX25821_264, -		.input[0].type = CX25821_VMUX_COMPOSITE,  	},  };  const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards); - -struct cx25821_subid cx25821_subids[] = { -	{ -		.subvendor = 0x14f1, -		.subdevice = 0x0920, -		.card = CX25821_BOARD, -	}, -}; - -void cx25821_card_setup(struct cx25821_dev *dev) -{ -	static u8 eeprom[256]; - -	if (dev->i2c_bus[0].i2c_rc == 0) { -		dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; -		tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, -				sizeof(eeprom)); -	} -} diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 1884e2cc35e..b762c5b2ca1 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -41,14 +41,7 @@ static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };  module_param_array(card, int, NULL, 0444);  MODULE_PARM_DESC(card, "card type"); -static unsigned int cx25821_devcount; - -DEFINE_MUTEX(cx25821_devlist_mutex); -EXPORT_SYMBOL(cx25821_devlist_mutex); -LIST_HEAD(cx25821_devlist); -EXPORT_SYMBOL(cx25821_devlist); - -struct sram_channel cx25821_sram_channels[] = { +const struct sram_channel cx25821_sram_channels[] = {  	[SRAM_CH00] = {  		.i = SRAM_CH00,  		.name = "VID A", @@ -317,20 +310,6 @@ struct sram_channel cx25821_sram_channels[] = {  };  EXPORT_SYMBOL(cx25821_sram_channels); -struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00]; -struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01]; -struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02]; -struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03]; -struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04]; -struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05]; -struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06]; -struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07]; -struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09]; -struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10]; -struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11]; - -struct cx25821_dmaqueue mpegq; -  static int cx25821_risc_decode(u32 risc)  {  	static const char * const instr[16] = { @@ -457,7 +436,7 @@ static void cx25821_registers_init(struct cx25821_dev *dev)  }  int cx25821_sram_channel_setup(struct cx25821_dev *dev, -			       struct sram_channel *ch, +			       const struct sram_channel *ch,  			       unsigned int bpl, u32 risc)  {  	unsigned int i, lines; @@ -523,10 +502,9 @@ int cx25821_sram_channel_setup(struct cx25821_dev *dev,  	return 0;  } -EXPORT_SYMBOL(cx25821_sram_channel_setup);  int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, -				     struct sram_channel *ch, +				     const struct sram_channel *ch,  				     unsigned int bpl, u32 risc)  {  	unsigned int i, lines; @@ -592,7 +570,7 @@ int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,  }  EXPORT_SYMBOL(cx25821_sram_channel_setup_audio); -void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch) +void cx25821_sram_channel_dump(struct cx25821_dev *dev, const struct sram_channel *ch)  {  	static char *name[] = {  		"init risc lo", @@ -652,10 +630,9 @@ void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)  	pr_warn("        :   cnt2_reg: 0x%08x\n",  		cx_read(ch->cnt2_reg));  } -EXPORT_SYMBOL(cx25821_sram_channel_dump);  void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, -				     struct sram_channel *ch) +				     const struct sram_channel *ch)  {  	static const char * const name[] = {  		"init risc lo", @@ -798,12 +775,12 @@ void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,  	if (channel_select <= 7 && channel_select >= 0) {  		cx_write(dev->channels[channel_select].sram_channels->pix_frmt,  				format); -		dev->channels[channel_select].pixel_formats = format;  	} +	dev->channels[channel_select].pixel_formats = format;  }  static void cx25821_set_vip_mode(struct cx25821_dev *dev, -				 struct sram_channel *ch) +				 const struct sram_channel *ch)  {  	cx_write(ch->pix_frmt, PIXEL_FRMT_422);  	cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1); @@ -837,12 +814,13 @@ static void cx25821_initialize(struct cx25821_dev *dev)  		cx25821_sram_channel_setup(dev, dev->channels[i].sram_channels,  						1440, 0);  		dev->channels[i].pixel_formats = PIXEL_FRMT_422; -		dev->channels[i].use_cif_resolution = FALSE; +		dev->channels[i].use_cif_resolution = 0;  	}  	/* Probably only affect Downstream */  	for (i = VID_UPSTREAM_SRAM_CHANNEL_I;  		i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) { +		dev->channels[i].pixel_formats = PIXEL_FRMT_422;  		cx25821_set_vip_mode(dev, dev->channels[i].sram_channels);  	} @@ -868,8 +846,7 @@ static void cx25821_dev_checkrevision(struct cx25821_dev *dev)  {  	dev->hwrevision = cx_read(RDR_CFG2) & 0xff; -	pr_info("%s(): Hardware revision = 0x%02x\n", -		__func__, dev->hwrevision); +	pr_info("Hardware revision = 0x%02x\n", dev->hwrevision);  }  static void cx25821_iounmap(struct cx25821_dev *dev) @@ -879,7 +856,6 @@ static void cx25821_iounmap(struct cx25821_dev *dev)  	/* Releasing IO memory */  	if (dev->lmmio != NULL) { -		CX25821_INFO("Releasing lmmio.\n");  		iounmap(dev->lmmio);  		dev->lmmio = NULL;  	} @@ -887,23 +863,14 @@ static void cx25821_iounmap(struct cx25821_dev *dev)  static int cx25821_dev_setup(struct cx25821_dev *dev)  { +	static unsigned int cx25821_devcount;  	int i; -	pr_info("\n***********************************\n"); -	pr_info("cx25821 set up\n"); -	pr_info("***********************************\n\n"); -  	mutex_init(&dev->lock); -	atomic_inc(&dev->refcount); -  	dev->nr = ++cx25821_devcount;  	sprintf(dev->name, "cx25821[%d]", dev->nr); -	mutex_lock(&cx25821_devlist_mutex); -	list_add_tail(&dev->devlist, &cx25821_devlist); -	mutex_unlock(&cx25821_devlist_mutex); -  	if (dev->pci->device != 0x8210) {  		pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",  			__func__, dev->pci->device); @@ -914,8 +881,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)  	/* Apply a sensible clock frequency for the PCIe bridge */  	dev->clk_freq = 28000000; -	for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) +	for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { +		dev->channels[i].dev = dev; +		dev->channels[i].id = i;  		dev->channels[i].sram_channels = &cx25821_sram_channels[i]; +	}  	if (dev->nr > 1)  		CX25821_INFO("dev->nr > 1!"); @@ -978,63 +948,15 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)  /*  cx25821_i2c_register(&dev->i2c_bus[1]);   *  cx25821_i2c_register(&dev->i2c_bus[2]); */ -	CX25821_INFO("i2c register! bus->i2c_rc = %d\n", -			dev->i2c_bus[0].i2c_rc); - -	cx25821_card_setup(dev); -  	if (medusa_video_init(dev) < 0)  		CX25821_ERR("%s(): Failed to initialize medusa!\n", __func__);  	cx25821_video_register(dev); -	/* register IOCTL device */ -	dev->ioctl_dev = cx25821_vdev_init(dev, dev->pci, -			&cx25821_videoioctl_template, "video"); - -	if (video_register_device -	    (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) { -		cx25821_videoioctl_unregister(dev); -		pr_err("%s(): Failed to register video adapter for IOCTL, so unregistering videoioctl device\n", -		       __func__); -	} -  	cx25821_dev_checkrevision(dev); -	CX25821_INFO("setup done!\n"); -  	return 0;  } -void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, -				      struct upstream_user_struct *up_data) -{ -	dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0; - -	dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M; -	medusa_set_videostandard(dev); - -	cx25821_vidupstream_init_ch1(dev, dev->channel_select, -				     dev->pixel_format); -} - -void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, -				      struct upstream_user_struct *up_data) -{ -	dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0; - -	dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M; -	medusa_set_videostandard(dev); - -	cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2, -				     dev->pixel_format_ch2); -} - -void cx25821_start_upstream_audio(struct cx25821_dev *dev, -				  struct upstream_user_struct *up_data) -{ -	cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B); -} -  void cx25821_dev_unregister(struct cx25821_dev *dev)  {  	int i; @@ -1042,25 +964,16 @@ void cx25821_dev_unregister(struct cx25821_dev *dev)  	if (!dev->base_io_addr)  		return; -	cx25821_free_mem_upstream_ch1(dev); -	cx25821_free_mem_upstream_ch2(dev); -	cx25821_free_mem_upstream_audio(dev); -  	release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0)); -	if (!atomic_dec_and_test(&dev->refcount)) -		return; - -	for (i = 0; i < VID_CHANNEL_NUM; i++) -		cx25821_video_unregister(dev, i); - -	for (i = VID_UPSTREAM_SRAM_CHANNEL_I; -	     i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) { +	for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { +		if (i == SRAM_CH08) /* audio channel */ +			continue; +		if (i == SRAM_CH09 || i == SRAM_CH10) +			cx25821_free_mem_upstream(&dev->channels[i]);  		cx25821_video_unregister(dev, i);  	} -	cx25821_videoioctl_unregister(dev); -  	cx25821_i2c_unregister(&dev->i2c_bus[0]);  	cx25821_iounmap(dev);  } @@ -1385,8 +1298,6 @@ static int cx25821_initdev(struct pci_dev *pci_dev,  		goto fail_unregister_device;  	} -	pr_info("Athena pci enable !\n"); -  	err = cx25821_dev_setup(dev);  	if (err) {  		if (err == -EBUSY) @@ -1445,10 +1356,6 @@ static void cx25821_finidev(struct pci_dev *pci_dev)  	if (pci_dev->irq)  		free_irq(pci_dev->irq, dev); -	mutex_lock(&cx25821_devlist_mutex); -	list_del(&dev->devlist); -	mutex_unlock(&cx25821_devlist_mutex); -  	cx25821_dev_unregister(dev);  	v4l2_device_unregister(v4l2_dev);  	kfree(dev); diff --git a/drivers/media/pci/cx25821/cx25821-gpio.c b/drivers/media/pci/cx25821/cx25821-gpio.c index 29e43b03c85..95e8ddf6294 100644 --- a/drivers/media/pci/cx25821/cx25821-gpio.c +++ b/drivers/media/pci/cx25821/cx25821-gpio.c @@ -20,6 +20,7 @@   *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */ +#include <linux/module.h>  #include "cx25821.h"  /********************* GPIO stuffs *********************/ diff --git a/drivers/media/pci/cx25821/cx25821-i2c.c b/drivers/media/pci/cx25821/cx25821-i2c.c index a8dc945bbe1..dca37c7dba7 100644 --- a/drivers/media/pci/cx25821/cx25821-i2c.c +++ b/drivers/media/pci/cx25821/cx25821-i2c.c @@ -23,8 +23,9 @@  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include "cx25821.h" +#include <linux/module.h>  #include <linux/i2c.h> +#include "cx25821.h"  static unsigned int i2c_debug;  module_param(i2c_debug, int, 0644); diff --git a/drivers/media/pci/cx25821/cx25821-medusa-video.c b/drivers/media/pci/cx25821/cx25821-medusa-video.c index 6a92e5c70c2..22fa04415cc 100644 --- a/drivers/media/pci/cx25821/cx25821-medusa-video.c +++ b/drivers/media/pci/cx25821/cx25821-medusa-video.c @@ -94,8 +94,6 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)  	u32 value = 0;  	u32 tmp = 0; -	mutex_lock(&dev->lock); -  	for (i = 0; i < MAX_DECODERS; i++) {  		/* set video format NTSC-M */  		value = cx25821_i2c_read(&dev->i2c_bus[0], @@ -222,8 +220,6 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)  	value |= 0x00080200;  	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); -	mutex_unlock(&dev->lock); -  	return ret_val;  } @@ -265,8 +261,6 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)  	u32 value = 0;  	u32 tmp = 0; -	mutex_lock(&dev->lock); -  	for (i = 0; i < MAX_DECODERS; i++) {  		/* set video format PAL-BDGHI */  		value = cx25821_i2c_read(&dev->i2c_bus[0], @@ -397,14 +391,12 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)  	value &= 0xFFF7FDFF;  	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); -	mutex_unlock(&dev->lock); -  	return ret_val;  }  int medusa_set_videostandard(struct cx25821_dev *dev)  { -	int status = STATUS_SUCCESS; +	int status = 0;  	u32 value = 0, tmp = 0;  	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) @@ -434,8 +426,6 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,  	u32 vscale = 0x0;  	const int MAX_WIDTH = 720; -	mutex_lock(&dev->lock); -  	/* validate the width */  	if (width > MAX_WIDTH) {  		pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n", @@ -485,8 +475,6 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,  		cx25821_i2c_write(&dev->i2c_bus[0],  				VSCALE_CTRL + (0x200 * decoder), vscale);  	} - -	mutex_unlock(&dev->lock);  }  static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, @@ -496,11 +484,8 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,  	u32 tmp = 0;  	u32 disp_cnt_reg = DISP_AB_CNT; -	mutex_lock(&dev->lock); -  	/* no support */  	if (decoder < VDEC_A || decoder > VDEC_H) { -		mutex_unlock(&dev->lock);  		return;  	} @@ -535,8 +520,6 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,  	}  	cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt); - -	mutex_unlock(&dev->lock);  }  /* Map to Medusa register setting */ @@ -587,10 +570,8 @@ int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)  	int value = 0;  	u32 val = 0, tmp = 0; -	mutex_lock(&dev->lock);  	if ((brightness > VIDEO_PROCAMP_MAX) ||  	    (brightness < VIDEO_PROCAMP_MIN)) { -		mutex_unlock(&dev->lock);  		return -1;  	}  	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, @@ -601,7 +582,6 @@ int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)  	val &= 0xFFFFFF00;  	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],  			VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value); -	mutex_unlock(&dev->lock);  	return ret_val;  } @@ -611,10 +591,7 @@ int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)  	int value = 0;  	u32 val = 0, tmp = 0; -	mutex_lock(&dev->lock); -  	if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) { -		mutex_unlock(&dev->lock);  		return -1;  	} @@ -626,7 +603,6 @@ int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)  	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],  			VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value); -	mutex_unlock(&dev->lock);  	return ret_val;  } @@ -636,10 +612,7 @@ int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)  	int value = 0;  	u32 val = 0, tmp = 0; -	mutex_lock(&dev->lock); -  	if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) { -		mutex_unlock(&dev->lock);  		return -1;  	} @@ -654,7 +627,6 @@ int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)  	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],  			VDEC_A_HUE_CTRL + (0x200 * decoder), val | value); -	mutex_unlock(&dev->lock);  	return ret_val;  } @@ -664,11 +636,8 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)  	int value = 0;  	u32 val = 0, tmp = 0; -	mutex_lock(&dev->lock); -  	if ((saturation > VIDEO_PROCAMP_MAX) ||  	    (saturation < VIDEO_PROCAMP_MIN)) { -		mutex_unlock(&dev->lock);  		return -1;  	} @@ -687,7 +656,6 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)  	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],  			VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value); -	mutex_unlock(&dev->lock);  	return ret_val;  } @@ -699,8 +667,6 @@ int medusa_video_init(struct cx25821_dev *dev)  	int ret_val = 0;  	int i = 0; -	mutex_lock(&dev->lock); -  	_num_decoders = dev->_max_num_decoders;  	/* disable Auto source selection on all video decoders */ @@ -719,13 +685,9 @@ int medusa_video_init(struct cx25821_dev *dev)  	if (ret_val < 0)  		goto error; -	mutex_unlock(&dev->lock); -  	for (i = 0; i < _num_decoders; i++)  		medusa_set_decoderduration(dev, i, _display_field_cnt[i]); -	mutex_lock(&dev->lock); -  	/* Select monitor as DENC A input, power up the DAC */  	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);  	value &= 0xFF70FF70; @@ -774,14 +736,8 @@ int medusa_video_init(struct cx25821_dev *dev)  	if (ret_val < 0)  		goto error; - -	mutex_unlock(&dev->lock); -  	ret_val = medusa_set_videostandard(dev); -	return ret_val; -  error: -	mutex_unlock(&dev->lock);  	return ret_val;  } diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c deleted file mode 100644 index cf2723c7197..00000000000 --- a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c +++ /dev/null @@ -1,800 +0,0 @@ -/* - *  Driver for the Conexant CX25821 PCIe bridge - * - *  Copyright (C) 2009 Conexant Systems Inc. - *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.com> - * - *  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. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "cx25821-video.h" -#include "cx25821-video-upstream-ch2.h" - -#include <linux/fs.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/syscalls.h> -#include <linux/file.h> -#include <linux/fcntl.h> -#include <linux/slab.h> -#include <linux/uaccess.h> - -MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); -MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); -MODULE_LICENSE("GPL"); - -static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | -			FLD_VID_SRC_OPC_ERR; - -static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, -					      __le32 *rp, unsigned int offset, -					      unsigned int bpl, u32 sync_line, -					      unsigned int lines, -					      int fifo_enable, int field_type) -{ -	unsigned int line, i; -	int dist_betwn_starts = bpl * 2; - -	*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); - -	if (USE_RISC_NOOP_VIDEO) { -		for (i = 0; i < NUM_NO_OPS; i++) -			*(rp++) = cpu_to_le32(RISC_NOOP); -	} - -	/* scan lines */ -	for (line = 0; line < lines; line++) { -		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); -		*(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset); -		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */ - -		if ((lines <= NTSC_FIELD_HEIGHT) || -		    (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { -			offset += dist_betwn_starts; -		} -	} - -	return rp; -} - -static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, -					       __le32 *rp, -					       dma_addr_t databuf_phys_addr, -					       unsigned int offset, -					       u32 sync_line, unsigned int bpl, -					       unsigned int lines, -					       int fifo_enable, int field_type) -{ -	unsigned int line, i; -	struct sram_channel *sram_ch = -		dev->channels[dev->_channel2_upstream_select].sram_channels; -	int dist_betwn_starts = bpl * 2; - -	/* sync instruction */ -	if (sync_line != NO_SYNC_LINE) -		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); - -	if (USE_RISC_NOOP_VIDEO) { -		for (i = 0; i < NUM_NO_OPS; i++) -			*(rp++) = cpu_to_le32(RISC_NOOP); -	} - -	/* scan lines */ -	for (line = 0; line < lines; line++) { -		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); -		*(rp++) = cpu_to_le32(databuf_phys_addr + offset); -		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */ - -		if ((lines <= NTSC_FIELD_HEIGHT) || -		    (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { -			offset += dist_betwn_starts; -		} - -	       /* -		 check if we need to enable the FIFO after the first 4 lines -		  For the upstream video channel, the risc engine will enable -		  the FIFO. -	       */ -		if (fifo_enable && line == 3) { -			*(rp++) = RISC_WRITECR; -			*(rp++) = sram_ch->dma_ctl; -			*(rp++) = FLD_VID_FIFO_EN; -			*(rp++) = 0x00000001; -		} -	} - -	return rp; -} - -static int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, -					    struct pci_dev *pci, -					    unsigned int top_offset, -					    unsigned int bpl, -					    unsigned int lines) -{ -	__le32 *rp; -	int fifo_enable = 0; -	int singlefield_lines = lines >> 1; /*get line count for single field */ -	int odd_num_lines = singlefield_lines; -	int frame = 0; -	int frame_size = 0; -	int databuf_offset = 0; -	int risc_program_size = 0; -	int risc_flag = RISC_CNT_RESET; -	unsigned int bottom_offset = bpl; -	dma_addr_t risc_phys_jump_addr; - -	if (dev->_isNTSC_ch2) { -		odd_num_lines = singlefield_lines + 1; -		risc_program_size = FRAME1_VID_PROG_SIZE; -		if (bpl == Y411_LINE_SZ) -			frame_size = FRAME_SIZE_NTSC_Y411; -		else -			frame_size = FRAME_SIZE_NTSC_Y422; -	} else { -		risc_program_size = PAL_VID_PROG_SIZE; -		if (bpl == Y411_LINE_SZ) -			frame_size = FRAME_SIZE_PAL_Y411; -		else -			frame_size = FRAME_SIZE_PAL_Y422; -	} - -	/* Virtual address of Risc buffer program */ -	rp = dev->_dma_virt_addr_ch2; - -	for (frame = 0; frame < NUM_FRAMES; frame++) { -		databuf_offset = frame_size * frame; - -		if (UNSET != top_offset) { -			fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; -			rp = cx25821_risc_field_upstream_ch2(dev, rp, -				dev->_data_buf_phys_addr_ch2 + databuf_offset, -				top_offset, 0, bpl, odd_num_lines, fifo_enable, -				ODD_FIELD); -		} - -		fifo_enable = FIFO_DISABLE; - -		/* Even field */ -		rp = cx25821_risc_field_upstream_ch2(dev, rp, -				dev->_data_buf_phys_addr_ch2 + databuf_offset, -				bottom_offset, 0x200, bpl, singlefield_lines, -				fifo_enable, EVEN_FIELD); - -		if (frame == 0) { -			risc_flag = RISC_CNT_RESET; -			risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2 + -					risc_program_size; -		} else { -			risc_flag = RISC_CNT_INC; -			risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2; -		} - -	       /* -		* Loop to 2ndFrameRISC or to Start of -		* Risc program & generate IRQ -		*/ -		*(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); -		*(rp++) = cpu_to_le32(risc_phys_jump_addr); -		*(rp++) = cpu_to_le32(0); -	} - -	return 0; -} - -void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) -{ -	struct sram_channel *sram_ch = -		dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; -	u32 tmp = 0; - -	if (!dev->_is_running_ch2) { -		pr_info("No video file is currently running so return!\n"); -		return; -	} -	/* Disable RISC interrupts */ -	tmp = cx_read(sram_ch->int_msk); -	cx_write(sram_ch->int_msk, tmp & ~_intr_msk); - -	/* Turn OFF risc and fifo */ -	tmp = cx_read(sram_ch->dma_ctl); -	cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); - -	/* Clear data buffer memory */ -	if (dev->_data_buf_virt_addr_ch2) -		memset(dev->_data_buf_virt_addr_ch2, 0, -		       dev->_data_buf_size_ch2); - -	dev->_is_running_ch2 = 0; -	dev->_is_first_frame_ch2 = 0; -	dev->_frame_count_ch2 = 0; -	dev->_file_status_ch2 = END_OF_FILE; - -	kfree(dev->_irq_queues_ch2); -	dev->_irq_queues_ch2 = NULL; - -	kfree(dev->_filename_ch2); - -	tmp = cx_read(VID_CH_MODE_SEL); -	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); -} - -void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev) -{ -	if (dev->_is_running_ch2) -		cx25821_stop_upstream_video_ch2(dev); - -	if (dev->_dma_virt_addr_ch2) { -		pci_free_consistent(dev->pci, dev->_risc_size_ch2, -				    dev->_dma_virt_addr_ch2, -				    dev->_dma_phys_addr_ch2); -		dev->_dma_virt_addr_ch2 = NULL; -	} - -	if (dev->_data_buf_virt_addr_ch2) { -		pci_free_consistent(dev->pci, dev->_data_buf_size_ch2, -				    dev->_data_buf_virt_addr_ch2, -				    dev->_data_buf_phys_addr_ch2); -		dev->_data_buf_virt_addr_ch2 = NULL; -	} -} - -static int cx25821_get_frame_ch2(struct cx25821_dev *dev, -				 struct sram_channel *sram_ch) -{ -	struct file *myfile; -	int frame_index_temp = dev->_frame_index_ch2; -	int i = 0; -	int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? -		Y411_LINE_SZ : Y422_LINE_SZ; -	int frame_size = 0; -	int frame_offset = 0; -	ssize_t vfs_read_retval = 0; -	char mybuf[line_size]; -	loff_t file_offset; -	loff_t pos; -	mm_segment_t old_fs; - -	if (dev->_file_status_ch2 == END_OF_FILE) -		return 0; - -	if (dev->_isNTSC_ch2) { -		frame_size = (line_size == Y411_LINE_SZ) ? -			FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; -	} else { -		frame_size = (line_size == Y411_LINE_SZ) ? -			FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; -	} - -	frame_offset = (frame_index_temp > 0) ? frame_size : 0; -	file_offset = dev->_frame_count_ch2 * frame_size; - -	myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); -	if (IS_ERR(myfile)) { -		const int open_errno = -PTR_ERR(myfile); -		pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", -		       __func__, dev->_filename_ch2, open_errno); -		return PTR_ERR(myfile); -	} else { -		if (!(myfile->f_op)) { -			pr_err("%s(): File has no file operations registered!\n", -			       __func__); -			filp_close(myfile, NULL); -			return -EIO; -		} - -		if (!myfile->f_op->read) { -			pr_err("%s(): File has no READ operations registered!\n", -			       __func__); -			filp_close(myfile, NULL); -			return -EIO; -		} - -		pos = myfile->f_pos; -		old_fs = get_fs(); -		set_fs(KERNEL_DS); - -		for (i = 0; i < dev->_lines_count_ch2; i++) { -			pos = file_offset; - -			vfs_read_retval = vfs_read(myfile, mybuf, line_size, -					&pos); - -			if (vfs_read_retval > 0 && vfs_read_retval == line_size -			    && dev->_data_buf_virt_addr_ch2 != NULL) { -				memcpy((void *)(dev->_data_buf_virt_addr_ch2 + -						frame_offset / 4), mybuf, -						vfs_read_retval); -			} - -			file_offset += vfs_read_retval; -			frame_offset += vfs_read_retval; - -			if (vfs_read_retval < line_size) { -				pr_info("Done: exit %s() since no more bytes to read from Video file\n", -					__func__); -				break; -			} -		} - -		if (i > 0) -			dev->_frame_count_ch2++; - -		dev->_file_status_ch2 = (vfs_read_retval == line_size) ? -			IN_PROGRESS : END_OF_FILE; - -		set_fs(old_fs); -		filp_close(myfile, NULL); -	} - -	return 0; -} - -static void cx25821_vidups_handler_ch2(struct work_struct *work) -{ -	struct cx25821_dev *dev = container_of(work, struct cx25821_dev, -			_irq_work_entry_ch2); - -	if (!dev) { -		pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", -		       __func__); -		return; -	} - -	cx25821_get_frame_ch2(dev, dev->channels[dev-> -			_channel2_upstream_select].sram_channels); -} - -static int cx25821_openfile_ch2(struct cx25821_dev *dev, -				struct sram_channel *sram_ch) -{ -	struct file *myfile; -	int i = 0, j = 0; -	int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? -		Y411_LINE_SZ : Y422_LINE_SZ; -	ssize_t vfs_read_retval = 0; -	char mybuf[line_size]; -	loff_t pos; -	loff_t offset = (unsigned long)0; -	mm_segment_t old_fs; - -	myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); - -	if (IS_ERR(myfile)) { -		const int open_errno = -PTR_ERR(myfile); -		pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", -		       __func__, dev->_filename_ch2, open_errno); -		return PTR_ERR(myfile); -	} else { -		if (!(myfile->f_op)) { -			pr_err("%s(): File has no file operations registered!\n", -			       __func__); -			filp_close(myfile, NULL); -			return -EIO; -		} - -		if (!myfile->f_op->read) { -			pr_err("%s(): File has no READ operations registered!  Returning\n", -			       __func__); -			filp_close(myfile, NULL); -			return -EIO; -		} - -		pos = myfile->f_pos; -		old_fs = get_fs(); -		set_fs(KERNEL_DS); - -		for (j = 0; j < NUM_FRAMES; j++) { -			for (i = 0; i < dev->_lines_count_ch2; i++) { -				pos = offset; - -				vfs_read_retval = vfs_read(myfile, mybuf, -						line_size, &pos); - -				if (vfs_read_retval > 0 && -				    vfs_read_retval == line_size && -				    dev->_data_buf_virt_addr_ch2 != NULL) { -					memcpy((void *)(dev-> -							_data_buf_virt_addr_ch2 -							+ offset / 4), mybuf, -							vfs_read_retval); -				} - -				offset += vfs_read_retval; - -				if (vfs_read_retval < line_size) { -					pr_info("Done: exit %s() since no more bytes to read from Video file\n", -						__func__); -					break; -				} -			} - -			if (i > 0) -				dev->_frame_count_ch2++; - -			if (vfs_read_retval < line_size) -				break; -		} - -		dev->_file_status_ch2 = (vfs_read_retval == line_size) ? -			IN_PROGRESS : END_OF_FILE; - -		set_fs(old_fs); -		myfile->f_pos = 0; -		filp_close(myfile, NULL); -	} - -	return 0; -} - -static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, -					       struct sram_channel *sram_ch, -					       int bpl) -{ -	int ret = 0; -	dma_addr_t dma_addr; -	dma_addr_t data_dma_addr; - -	if (dev->_dma_virt_addr_ch2 != NULL) { -		pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2, -				    dev->_dma_virt_addr_ch2, -				    dev->_dma_phys_addr_ch2); -	} - -	dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci, -			dev->upstream_riscbuf_size_ch2, &dma_addr); -	dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2; -	dev->_dma_phys_start_addr_ch2 = dma_addr; -	dev->_dma_phys_addr_ch2 = dma_addr; -	dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2; - -	if (!dev->_dma_virt_addr_ch2) { -		pr_err("FAILED to allocate memory for Risc buffer! Returning\n"); -		return -ENOMEM; -	} - -	/* Iniitize at this address until n bytes to 0 */ -	memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2); - -	if (dev->_data_buf_virt_addr_ch2 != NULL) { -		pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2, -				    dev->_data_buf_virt_addr_ch2, -				    dev->_data_buf_phys_addr_ch2); -	} -	/* For Video Data buffer allocation */ -	dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci, -			dev->upstream_databuf_size_ch2, &data_dma_addr); -	dev->_data_buf_phys_addr_ch2 = data_dma_addr; -	dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2; - -	if (!dev->_data_buf_virt_addr_ch2) { -		pr_err("FAILED to allocate memory for data buffer! Returning\n"); -		return -ENOMEM; -	} - -	/* Initialize at this address until n bytes to 0 */ -	memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2); - -	ret = cx25821_openfile_ch2(dev, sram_ch); -	if (ret < 0) -		return ret; - -	/* Creating RISC programs */ -	ret = cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl, -						dev->_lines_count_ch2); -	if (ret < 0) { -		pr_info("Failed creating Video Upstream Risc programs!\n"); -		goto error; -	} - -	return 0; - -error: -	return ret; -} - -static int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, -					  int chan_num, -					  u32 status) -{ -	u32 int_msk_tmp; -	struct sram_channel *channel = dev->channels[chan_num].sram_channels; -	int singlefield_lines = NTSC_FIELD_HEIGHT; -	int line_size_in_bytes = Y422_LINE_SZ; -	int odd_risc_prog_size = 0; -	dma_addr_t risc_phys_jump_addr; -	__le32 *rp; - -	if (status & FLD_VID_SRC_RISC1) { -		/* We should only process one program per call */ -		u32 prog_cnt = cx_read(channel->gpcnt); - -		/* -		 *  Since we've identified our IRQ, clear our bits from the -		 *  interrupt mask and interrupt status registers -		 */ -		int_msk_tmp = cx_read(channel->int_msk); -		cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); -		cx_write(channel->int_stat, _intr_msk); - -		spin_lock(&dev->slock); - -		dev->_frame_index_ch2 = prog_cnt; - -		queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2); - -		if (dev->_is_first_frame_ch2) { -			dev->_is_first_frame_ch2 = 0; - -			if (dev->_isNTSC_ch2) { -				singlefield_lines += 1; -				odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; -			} else { -				singlefield_lines = PAL_FIELD_HEIGHT; -				odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; -			} - -			if (dev->_dma_virt_start_addr_ch2 != NULL) { -				if (dev->_pixel_format_ch2 == PIXEL_FRMT_411) -					line_size_in_bytes = Y411_LINE_SZ; -				else -					line_size_in_bytes = Y422_LINE_SZ; -				risc_phys_jump_addr = -					dev->_dma_phys_start_addr_ch2 + -					odd_risc_prog_size; - -				rp = cx25821_update_riscprogram_ch2(dev, -						dev->_dma_virt_start_addr_ch2, -						TOP_OFFSET, line_size_in_bytes, -						0x0, singlefield_lines, -						FIFO_DISABLE, ODD_FIELD); - -			       /* Jump to Even Risc program of 1st Frame */ -				*(rp++) = cpu_to_le32(RISC_JUMP); -				*(rp++) = cpu_to_le32(risc_phys_jump_addr); -				*(rp++) = cpu_to_le32(0); -			} -		} - -		spin_unlock(&dev->slock); -	} - -	if (dev->_file_status_ch2 == END_OF_FILE) { -		pr_info("EOF Channel 2 Framecount = %d\n", -			dev->_frame_count_ch2); -		return -1; -	} -	/* ElSE, set the interrupt mask register, re-enable irq. */ -	int_msk_tmp = cx_read(channel->int_msk); -	cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); - -	return 0; -} - -static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) -{ -	struct cx25821_dev *dev = dev_id; -	u32 vid_status; -	int handled = 0; -	int channel_num = 0; -	struct sram_channel *sram_ch; - -	if (!dev) -		return -1; - -	channel_num = VID_UPSTREAM_SRAM_CHANNEL_J; -	sram_ch = dev->channels[channel_num].sram_channels; - -	vid_status = cx_read(sram_ch->int_stat); - -	/* Only deal with our interrupt */ -	if (vid_status) -		handled = cx25821_video_upstream_irq_ch2(dev, channel_num, -				vid_status); - -	if (handled < 0) -		cx25821_stop_upstream_video_ch2(dev); -	else -		handled += handled; - -	return IRQ_RETVAL(handled); -} - -static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev, -					struct sram_channel *ch, int pix_format) -{ -	int width = WIDTH_D1; -	int height = dev->_lines_count_ch2; -	int num_lines, odd_num_lines; -	u32 value; -	int vip_mode = PIXEL_ENGINE_VIP1; - -	value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7); -	value &= 0xFFFFFFEF; -	value |= dev->_isNTSC_ch2 ? 0 : 0x10; -	cx_write(ch->vid_fmt_ctl, value); - -	/* -	 *  set number of active pixels in each line. Default is 720 -	 * pixels in both NTSC and PAL format -	 */ -	cx_write(ch->vid_active_ctl1, width); - -	num_lines = (height / 2) & 0x3FF; -	odd_num_lines = num_lines; - -	if (dev->_isNTSC_ch2) -		odd_num_lines += 1; - -	value = (num_lines << 16) | odd_num_lines; - -	/* set number of active lines in field 0 (top) and field 1 (bottom) */ -	cx_write(ch->vid_active_ctl2, value); - -	cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); -} - -static int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, -						struct sram_channel *sram_ch) -{ -	u32 tmp = 0; -	int err = 0; - -	/* -	 *  656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface -	 * for channel A-C -	 */ -	tmp = cx_read(VID_CH_MODE_SEL); -	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); - -	/* -	 *  Set the physical start address of the RISC program in the initial -	 *  program counter(IPC) member of the cmds. -	 */ -	cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2); -	cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ - -	/* reset counter */ -	cx_write(sram_ch->gpcnt_ctl, 3); - -	/* Clear our bits from the interrupt status register. */ -	cx_write(sram_ch->int_stat, _intr_msk); - -	/* Set the interrupt mask register, enable irq. */ -	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); -	tmp = cx_read(sram_ch->int_msk); -	cx_write(sram_ch->int_msk, tmp |= _intr_msk); - -	err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, -			IRQF_SHARED, dev->name, dev); -	if (err < 0) { -		pr_err("%s: can't get upstream IRQ %d\n", -		       dev->name, dev->pci->irq); -		goto fail_irq; -	} -	/* Start the DMA  engine */ -	tmp = cx_read(sram_ch->dma_ctl); -	cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); - -	dev->_is_running_ch2 = 1; -	dev->_is_first_frame_ch2 = 1; - -	return 0; - -fail_irq: -	cx25821_dev_unregister(dev); -	return err; -} - -int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, -				 int pixel_format) -{ -	struct sram_channel *sram_ch; -	u32 tmp; -	int err = 0; -	int data_frame_size = 0; -	int risc_buffer_size = 0; - -	if (dev->_is_running_ch2) { -		pr_info("Video Channel is still running so return!\n"); -		return 0; -	} - -	dev->_channel2_upstream_select = channel_select; -	sram_ch = dev->channels[channel_select].sram_channels; - -	INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2); -	dev->_irq_queues_ch2 = -	    create_singlethread_workqueue("cx25821_workqueue2"); - -	if (!dev->_irq_queues_ch2) { -		pr_err("create_singlethread_workqueue() for Video FAILED!\n"); -		return -ENOMEM; -	} -	/* -	 * 656/VIP SRC Upstream Channel I & J and 7 - -	 * Host Bus Interface for channel A-C -	 */ -	tmp = cx_read(VID_CH_MODE_SEL); -	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); - -	dev->_is_running_ch2 = 0; -	dev->_frame_count_ch2 = 0; -	dev->_file_status_ch2 = RESET_STATUS; -	dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576; -	dev->_pixel_format_ch2 = pixel_format; -	dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ? -		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; -	data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; -	risc_buffer_size = dev->_isNTSC_ch2 ? -		NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; - -	if (dev->input_filename_ch2) -		dev->_filename_ch2 = kstrdup(dev->input_filename_ch2, -								GFP_KERNEL); -	else -		dev->_filename_ch2 = kstrdup(dev->_defaultname_ch2, -								GFP_KERNEL); - -	if (!dev->_filename_ch2) { -		err = -ENOENT; -		goto error; -	} - -	/* Default if filename is empty string */ -	if (strcmp(dev->_filename_ch2, "") == 0) { -		if (dev->_isNTSC_ch2) { -			dev->_filename_ch2 = (dev->_pixel_format_ch2 == -				PIXEL_FRMT_411) ? "/root/vid411.yuv" : -				"/root/vidtest.yuv"; -		} else { -			dev->_filename_ch2 = (dev->_pixel_format_ch2 == -				PIXEL_FRMT_411) ? "/root/pal411.yuv" : -				"/root/pal422.yuv"; -		} -	} - -	err = cx25821_sram_channel_setup_upstream(dev, sram_ch, -						dev->_line_size_ch2, 0); - -	/* setup fifo + format */ -	cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2); - -	dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2; -	dev->upstream_databuf_size_ch2 = data_frame_size * 2; - -	/* Allocating buffers and prepare RISC program */ -	err = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch, -						dev->_line_size_ch2); -	if (err < 0) { -		pr_err("%s: Failed to set up Video upstream buffers!\n", -		       dev->name); -		goto error; -	} - -	cx25821_start_video_dma_upstream_ch2(dev, sram_ch); - -	return 0; - -error: -	cx25821_dev_unregister(dev); - -	return err; -} diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h deleted file mode 100644 index d42dab59b66..00000000000 --- a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - *  Driver for the Conexant CX25821 PCIe bridge - * - *  Copyright (C) 2009 Conexant Systems Inc. - *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.com> - * - *  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 <linux/mutex.h> -#include <linux/workqueue.h> - -#define OPEN_FILE_1           0 -#define NUM_PROGS             8 -#define NUM_FRAMES            2 -#define ODD_FIELD             0 -#define EVEN_FIELD            1 -#define TOP_OFFSET            0 -#define FIFO_DISABLE          0 -#define FIFO_ENABLE           1 -#define TEST_FRAMES           5 -#define END_OF_FILE           0 -#define IN_PROGRESS           1 -#define RESET_STATUS          -1 -#define NUM_NO_OPS            5 - -/* PAL and NTSC line sizes and number of lines. */ -#define WIDTH_D1              720 -#define NTSC_LINES_PER_FRAME  480 -#define PAL_LINES_PER_FRAME   576 -#define PAL_LINE_SZ           1440 -#define Y422_LINE_SZ          1440 -#define Y411_LINE_SZ          1080 -#define NTSC_FIELD_HEIGHT     240 -#define NTSC_ODD_FLD_LINES    241 -#define PAL_FIELD_HEIGHT      288 - -#define FRAME_SIZE_NTSC_Y422    (NTSC_LINES_PER_FRAME * Y422_LINE_SZ) -#define FRAME_SIZE_NTSC_Y411    (NTSC_LINES_PER_FRAME * Y411_LINE_SZ) -#define FRAME_SIZE_PAL_Y422     (PAL_LINES_PER_FRAME * Y422_LINE_SZ) -#define FRAME_SIZE_PAL_Y411     (PAL_LINES_PER_FRAME * Y411_LINE_SZ) - -#define NTSC_DATA_BUF_SZ        (Y422_LINE_SZ * NTSC_LINES_PER_FRAME) -#define PAL_DATA_BUF_SZ         (Y422_LINE_SZ * PAL_LINES_PER_FRAME) - -#define RISC_WRITECR_INSTRUCTION_SIZE   16 -#define RISC_SYNC_INSTRUCTION_SIZE      4 -#define JUMP_INSTRUCTION_SIZE           12 -#define MAXSIZE_NO_OPS                  36 -#define DWORD_SIZE                      4 - -#define USE_RISC_NOOP_VIDEO   1 - -#ifdef USE_RISC_NOOP_VIDEO -#define PAL_US_VID_PROG_SIZE						\ -	(PAL_FIELD_HEIGHT * 3 * DWORD_SIZE +				\ -	 RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE +	\ -	 NUM_NO_OPS * DWORD_SIZE) - -#define PAL_RISC_BUF_SIZE         (2 * PAL_US_VID_PROG_SIZE) - -#define PAL_VID_PROG_SIZE						\ -	((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE +			\ -	 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ -	 JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE) - -#define ODD_FLD_PAL_PROG_SIZE						\ -	(PAL_FIELD_HEIGHT * 3 * DWORD_SIZE +				\ -	 RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE +	\ -	 NUM_NO_OPS * DWORD_SIZE) - -#define NTSC_US_VID_PROG_SIZE						\ -	((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE +			\ -	 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE +	\ -	 NUM_NO_OPS * DWORD_SIZE) - -#define NTSC_RISC_BUF_SIZE						\ -	(2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) - -#define FRAME1_VID_PROG_SIZE						\ -	((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) *			\ -	 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE +		\ -	 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE +	\ -	 2 * NUM_NO_OPS * DWORD_SIZE) - -#define ODD_FLD_NTSC_PROG_SIZE						\ -	(NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE +				\ -	 RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE +	\ -	 NUM_NO_OPS * DWORD_SIZE) -#endif - -#ifndef USE_RISC_NOOP_VIDEO -#define PAL_US_VID_PROG_SIZE						\ -	((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE +			\ -	 RISC_WRITECR_INSTRUCTION_SIZE) - -#define PAL_RISC_BUF_SIZE						\ -	(2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE)) - -#define PAL_VID_PROG_SIZE						\ -	((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE +			\ -	 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ -	 JUMP_INSTRUCTION_SIZE) - -#define ODD_FLD_PAL_PROG_SIZE						\ -	(PAL_FIELD_HEIGHT * 3 * DWORD_SIZE +				\ -	 RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) - -#define ODD_FLD_NTSC_PROG_SIZE						\ -	(NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE +				\ -	 RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) - -#define NTSC_US_VID_PROG_SIZE						\ -	((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE +			\ -	 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) - -#define NTSC_RISC_BUF_SIZE						\ -	(2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) - -#define FRAME1_VID_PROG_SIZE						\ -	((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) *			\ -	 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE +		\ -	 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) - -#endif diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c index 7fc97110d97..88ffef410c5 100644 --- a/drivers/media/pci/cx25821/cx25821-video-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c @@ -25,16 +25,11 @@  #include "cx25821-video.h"  #include "cx25821-video-upstream.h" -#include <linux/fs.h>  #include <linux/errno.h>  #include <linux/kernel.h>  #include <linux/init.h>  #include <linux/module.h> -#include <linux/syscalls.h> -#include <linux/file.h> -#include <linux/fcntl.h>  #include <linux/slab.h> -#include <linux/uaccess.h>  MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");  MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); @@ -44,7 +39,7 @@ static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC |  			FLD_VID_SRC_OPC_ERR;  int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, -					struct sram_channel *ch, +					const struct sram_channel *ch,  					unsigned int bpl, u32 risc)  {  	unsigned int i, lines; @@ -97,12 +92,13 @@ int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,  	return 0;  } -static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, +static __le32 *cx25821_update_riscprogram(struct cx25821_channel *chan,  					  __le32 *rp, unsigned int offset,  					  unsigned int bpl, u32 sync_line,  					  unsigned int lines, int fifo_enable,  					  int field_type)  { +	struct cx25821_video_out_data *out = chan->out;  	unsigned int line, i;  	int dist_betwn_starts = bpl * 2; @@ -116,11 +112,11 @@ static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,  	/* scan lines */  	for (line = 0; line < lines; line++) {  		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); -		*(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset); +		*(rp++) = cpu_to_le32(out->_data_buf_phys_addr + offset);  		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */  		if ((lines <= NTSC_FIELD_HEIGHT) -		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) { +		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(out->is_60hz)) {  			offset += dist_betwn_starts;  		}  	} @@ -128,15 +124,15 @@ static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,  	return rp;  } -static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, +static __le32 *cx25821_risc_field_upstream(struct cx25821_channel *chan, __le32 *rp,  					   dma_addr_t databuf_phys_addr,  					   unsigned int offset, u32 sync_line,  					   unsigned int bpl, unsigned int lines,  					   int fifo_enable, int field_type)  { +	struct cx25821_video_out_data *out = chan->out;  	unsigned int line, i; -	struct sram_channel *sram_ch = -		dev->channels[dev->_channel_upstream_select].sram_channels; +	const struct sram_channel *sram_ch = chan->sram_channels;  	int dist_betwn_starts = bpl * 2;  	/* sync instruction */ @@ -155,7 +151,7 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,  		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */  		if ((lines <= NTSC_FIELD_HEIGHT) -		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) +		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(out->is_60hz))  			/* to skip the other field line */  			offset += dist_betwn_starts; @@ -173,11 +169,12 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,  	return rp;  } -static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, +static int cx25821_risc_buffer_upstream(struct cx25821_channel *chan,  					struct pci_dev *pci,  					unsigned int top_offset,  					unsigned int bpl, unsigned int lines)  { +	struct cx25821_video_out_data *out = chan->out;  	__le32 *rp;  	int fifo_enable = 0;  	/* get line count for single field */ @@ -191,7 +188,7 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,  	unsigned int bottom_offset = bpl;  	dma_addr_t risc_phys_jump_addr; -	if (dev->_isNTSC) { +	if (out->is_60hz) {  		odd_num_lines = singlefield_lines + 1;  		risc_program_size = FRAME1_VID_PROG_SIZE;  		frame_size = (bpl == Y411_LINE_SZ) ? @@ -203,15 +200,15 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,  	}  	/* Virtual address of Risc buffer program */ -	rp = dev->_dma_virt_addr; +	rp = out->_dma_virt_addr;  	for (frame = 0; frame < NUM_FRAMES; frame++) {  		databuf_offset = frame_size * frame;  		if (UNSET != top_offset) {  			fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; -			rp = cx25821_risc_field_upstream(dev, rp, -					dev->_data_buf_phys_addr + +			rp = cx25821_risc_field_upstream(chan, rp, +					out->_data_buf_phys_addr +  					databuf_offset, top_offset, 0, bpl,  					odd_num_lines, fifo_enable, ODD_FIELD);  		} @@ -219,18 +216,18 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,  		fifo_enable = FIFO_DISABLE;  		/* Even Field */ -		rp = cx25821_risc_field_upstream(dev, rp, -						 dev->_data_buf_phys_addr + +		rp = cx25821_risc_field_upstream(chan, rp, +						 out->_data_buf_phys_addr +  						 databuf_offset, bottom_offset,  						 0x200, bpl, singlefield_lines,  						 fifo_enable, EVEN_FIELD);  		if (frame == 0) {  			risc_flag = RISC_CNT_RESET; -			risc_phys_jump_addr = dev->_dma_phys_start_addr + +			risc_phys_jump_addr = out->_dma_phys_start_addr +  				risc_program_size;  		} else { -			risc_phys_jump_addr = dev->_dma_phys_start_addr; +			risc_phys_jump_addr = out->_dma_phys_start_addr;  			risc_flag = RISC_CNT_INC;  		} @@ -245,16 +242,21 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,  	return 0;  } -void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) +void cx25821_stop_upstream_video(struct cx25821_channel *chan)  { -	struct sram_channel *sram_ch = -		dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; +	struct cx25821_video_out_data *out = chan->out; +	struct cx25821_dev *dev = chan->dev; +	const struct sram_channel *sram_ch = chan->sram_channels;  	u32 tmp = 0; -	if (!dev->_is_running) { +	if (!out->_is_running) {  		pr_info("No video file is currently running so return!\n");  		return;  	} + +	/* Set the interrupt mask register, disable irq. */ +	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) & ~(1 << sram_ch->irq_bit)); +  	/* Disable RISC interrupts */  	tmp = cx_read(sram_ch->int_msk);  	cx_write(sram_ch->int_msk, tmp & ~_intr_msk); @@ -263,283 +265,133 @@ void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)  	tmp = cx_read(sram_ch->dma_ctl);  	cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); -	/* Clear data buffer memory */ -	if (dev->_data_buf_virt_addr) -		memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); +	free_irq(dev->pci->irq, chan); -	dev->_is_running = 0; -	dev->_is_first_frame = 0; -	dev->_frame_count = 0; -	dev->_file_status = END_OF_FILE; - -	kfree(dev->_irq_queues); -	dev->_irq_queues = NULL; +	/* Clear data buffer memory */ +	if (out->_data_buf_virt_addr) +		memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); -	kfree(dev->_filename); +	out->_is_running = 0; +	out->_is_first_frame = 0; +	out->_frame_count = 0; +	out->_file_status = END_OF_FILE;  	tmp = cx_read(VID_CH_MODE_SEL);  	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);  } -void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev) +void cx25821_free_mem_upstream(struct cx25821_channel *chan)  { -	if (dev->_is_running) -		cx25821_stop_upstream_video_ch1(dev); +	struct cx25821_video_out_data *out = chan->out; +	struct cx25821_dev *dev = chan->dev; -	if (dev->_dma_virt_addr) { -		pci_free_consistent(dev->pci, dev->_risc_size, -				    dev->_dma_virt_addr, dev->_dma_phys_addr); -		dev->_dma_virt_addr = NULL; +	if (out->_is_running) +		cx25821_stop_upstream_video(chan); + +	if (out->_dma_virt_addr) { +		pci_free_consistent(dev->pci, out->_risc_size, +				    out->_dma_virt_addr, out->_dma_phys_addr); +		out->_dma_virt_addr = NULL;  	} -	if (dev->_data_buf_virt_addr) { -		pci_free_consistent(dev->pci, dev->_data_buf_size, -				    dev->_data_buf_virt_addr, -				    dev->_data_buf_phys_addr); -		dev->_data_buf_virt_addr = NULL; +	if (out->_data_buf_virt_addr) { +		pci_free_consistent(dev->pci, out->_data_buf_size, +				    out->_data_buf_virt_addr, +				    out->_data_buf_phys_addr); +		out->_data_buf_virt_addr = NULL;  	}  } -static int cx25821_get_frame(struct cx25821_dev *dev, -			     struct sram_channel *sram_ch) +int cx25821_write_frame(struct cx25821_channel *chan, +		const char __user *data, size_t count)  { -	struct file *myfile; -	int frame_index_temp = dev->_frame_index; -	int i = 0; -	int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? +	struct cx25821_video_out_data *out = chan->out; +	int line_size = (out->_pixel_format == PIXEL_FRMT_411) ?  		Y411_LINE_SZ : Y422_LINE_SZ;  	int frame_size = 0;  	int frame_offset = 0; -	ssize_t vfs_read_retval = 0; -	char mybuf[line_size]; -	loff_t file_offset; -	loff_t pos; -	mm_segment_t old_fs; - -	if (dev->_file_status == END_OF_FILE) -		return 0; +	int curpos = out->curpos; -	if (dev->_isNTSC) +	if (out->is_60hz)  		frame_size = (line_size == Y411_LINE_SZ) ?  			FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;  	else  		frame_size = (line_size == Y411_LINE_SZ) ?  			FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; -	frame_offset = (frame_index_temp > 0) ? frame_size : 0; -	file_offset = dev->_frame_count * frame_size; - -	myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0); - -	if (IS_ERR(myfile)) { -		const int open_errno = -PTR_ERR(myfile); -		pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", -		       __func__, dev->_filename, open_errno); -		return PTR_ERR(myfile); -	} else { -		if (!(myfile->f_op)) { -			pr_err("%s(): File has no file operations registered!\n", -			       __func__); -			filp_close(myfile, NULL); -			return -EIO; -		} - -		if (!myfile->f_op->read) { -			pr_err("%s(): File has no READ operations registered!\n", -			       __func__); -			filp_close(myfile, NULL); -			return -EIO; -		} - -		pos = myfile->f_pos; -		old_fs = get_fs(); -		set_fs(KERNEL_DS); - -		for (i = 0; i < dev->_lines_count; i++) { -			pos = file_offset; - -			vfs_read_retval = vfs_read(myfile, mybuf, line_size, -					&pos); - -			if (vfs_read_retval > 0 && vfs_read_retval == line_size -			    && dev->_data_buf_virt_addr != NULL) { -				memcpy((void *)(dev->_data_buf_virt_addr + -						frame_offset / 4), mybuf, -				       vfs_read_retval); -			} - -			file_offset += vfs_read_retval; -			frame_offset += vfs_read_retval; - -			if (vfs_read_retval < line_size) { -				pr_info("Done: exit %s() since no more bytes to read from Video file\n", -					__func__); -				break; -			} -		} - -		if (i > 0) -			dev->_frame_count++; - -		dev->_file_status = (vfs_read_retval == line_size) ? -			IN_PROGRESS : END_OF_FILE; - -		set_fs(old_fs); -		filp_close(myfile, NULL); +	if (curpos == 0) { +		out->cur_frame_index = out->_frame_index; +		if (wait_event_interruptible(out->waitq, out->cur_frame_index != out->_frame_index)) +			return -EINTR; +		out->cur_frame_index = out->_frame_index;  	} -	return 0; -} - -static void cx25821_vidups_handler(struct work_struct *work) -{ -	struct cx25821_dev *dev = container_of(work, struct cx25821_dev, -			_irq_work_entry); +	frame_offset = out->cur_frame_index ? frame_size : 0; -	if (!dev) { -		pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", -		       __func__); -		return; +	if (frame_size - curpos < count) +		count = frame_size - curpos; +	memcpy((char *)out->_data_buf_virt_addr + frame_offset + curpos, +			data, count); +	curpos += count; +	if (curpos == frame_size) { +		out->_frame_count++; +		curpos = 0;  	} +	out->curpos = curpos; -	cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select]. -			sram_channels); +	return count;  } -static int cx25821_openfile(struct cx25821_dev *dev, -			    struct sram_channel *sram_ch) -{ -	struct file *myfile; -	int i = 0, j = 0; -	int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? -		Y411_LINE_SZ : Y422_LINE_SZ; -	ssize_t vfs_read_retval = 0; -	char mybuf[line_size]; -	loff_t pos; -	loff_t offset = (unsigned long)0; -	mm_segment_t old_fs; - -	myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0); - -	if (IS_ERR(myfile)) { -		const int open_errno = -PTR_ERR(myfile); -		pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", -		       __func__, dev->_filename, open_errno); -		return PTR_ERR(myfile); -	} else { -		if (!(myfile->f_op)) { -			pr_err("%s(): File has no file operations registered!\n", -			       __func__); -			filp_close(myfile, NULL); -			return -EIO; -		} - -		if (!myfile->f_op->read) { -			pr_err("%s(): File has no READ operations registered!  Returning\n", -			       __func__); -			filp_close(myfile, NULL); -			return -EIO; -		} - -		pos = myfile->f_pos; -		old_fs = get_fs(); -		set_fs(KERNEL_DS); - -		for (j = 0; j < NUM_FRAMES; j++) { -			for (i = 0; i < dev->_lines_count; i++) { -				pos = offset; - -				vfs_read_retval = vfs_read(myfile, mybuf, -						line_size, &pos); - -				if (vfs_read_retval > 0 -				    && vfs_read_retval == line_size -				    && dev->_data_buf_virt_addr != NULL) { -					memcpy((void *)(dev-> -							_data_buf_virt_addr + -							offset / 4), mybuf, -					       vfs_read_retval); -				} - -				offset += vfs_read_retval; - -				if (vfs_read_retval < line_size) { -					pr_info("Done: exit %s() since no more bytes to read from Video file\n", -						__func__); -					break; -				} -			} - -			if (i > 0) -				dev->_frame_count++; - -			if (vfs_read_retval < line_size) -				break; -		} - -		dev->_file_status = (vfs_read_retval == line_size) ? -			IN_PROGRESS : END_OF_FILE; - -		set_fs(old_fs); -		myfile->f_pos = 0; -		filp_close(myfile, NULL); -	} - -	return 0; -} - -static int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, -					   struct sram_channel *sram_ch, +static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan, +					   const struct sram_channel *sram_ch,  					   int bpl)  { +	struct cx25821_video_out_data *out = chan->out; +	struct cx25821_dev *dev = chan->dev;  	int ret = 0;  	dma_addr_t dma_addr;  	dma_addr_t data_dma_addr; -	if (dev->_dma_virt_addr != NULL) -		pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, -				dev->_dma_virt_addr, dev->_dma_phys_addr); +	if (out->_dma_virt_addr != NULL) +		pci_free_consistent(dev->pci, out->upstream_riscbuf_size, +				out->_dma_virt_addr, out->_dma_phys_addr); -	dev->_dma_virt_addr = pci_alloc_consistent(dev->pci, -			dev->upstream_riscbuf_size, &dma_addr); -	dev->_dma_virt_start_addr = dev->_dma_virt_addr; -	dev->_dma_phys_start_addr = dma_addr; -	dev->_dma_phys_addr = dma_addr; -	dev->_risc_size = dev->upstream_riscbuf_size; +	out->_dma_virt_addr = pci_alloc_consistent(dev->pci, +			out->upstream_riscbuf_size, &dma_addr); +	out->_dma_virt_start_addr = out->_dma_virt_addr; +	out->_dma_phys_start_addr = dma_addr; +	out->_dma_phys_addr = dma_addr; +	out->_risc_size = out->upstream_riscbuf_size; -	if (!dev->_dma_virt_addr) { +	if (!out->_dma_virt_addr) {  		pr_err("FAILED to allocate memory for Risc buffer! Returning\n");  		return -ENOMEM;  	}  	/* Clear memory at address */ -	memset(dev->_dma_virt_addr, 0, dev->_risc_size); +	memset(out->_dma_virt_addr, 0, out->_risc_size); -	if (dev->_data_buf_virt_addr != NULL) -		pci_free_consistent(dev->pci, dev->upstream_databuf_size, -				dev->_data_buf_virt_addr, -				dev->_data_buf_phys_addr); +	if (out->_data_buf_virt_addr != NULL) +		pci_free_consistent(dev->pci, out->upstream_databuf_size, +				out->_data_buf_virt_addr, +				out->_data_buf_phys_addr);  	/* For Video Data buffer allocation */ -	dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, -			dev->upstream_databuf_size, &data_dma_addr); -	dev->_data_buf_phys_addr = data_dma_addr; -	dev->_data_buf_size = dev->upstream_databuf_size; +	out->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, +			out->upstream_databuf_size, &data_dma_addr); +	out->_data_buf_phys_addr = data_dma_addr; +	out->_data_buf_size = out->upstream_databuf_size; -	if (!dev->_data_buf_virt_addr) { +	if (!out->_data_buf_virt_addr) {  		pr_err("FAILED to allocate memory for data buffer! Returning\n");  		return -ENOMEM;  	}  	/* Clear memory at address */ -	memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); - -	ret = cx25821_openfile(dev, sram_ch); -	if (ret < 0) -		return ret; +	memset(out->_data_buf_virt_addr, 0, out->_data_buf_size);  	/* Create RISC programs */ -	ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, -			dev->_lines_count); +	ret = cx25821_risc_buffer_upstream(chan, dev->pci, 0, bpl, +			out->_lines_count);  	if (ret < 0) {  		pr_info("Failed creating Video Upstream Risc programs!\n");  		goto error; @@ -551,11 +403,12 @@ error:  	return ret;  } -static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, -				      u32 status) +static int cx25821_video_upstream_irq(struct cx25821_channel *chan, u32 status)  { +	struct cx25821_video_out_data *out = chan->out; +	struct cx25821_dev *dev = chan->dev;  	u32 int_msk_tmp; -	struct sram_channel *channel = dev->channels[chan_num].sram_channels; +	const struct sram_channel *channel = chan->sram_channels;  	int singlefield_lines = NTSC_FIELD_HEIGHT;  	int line_size_in_bytes = Y422_LINE_SZ;  	int odd_risc_prog_size = 0; @@ -572,16 +425,16 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,  		cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);  		cx_write(channel->int_stat, _intr_msk); -		spin_lock(&dev->slock); +		wake_up(&out->waitq); -		dev->_frame_index = prog_cnt; +		spin_lock(&dev->slock); -		queue_work(dev->_irq_queues, &dev->_irq_work_entry); +		out->_frame_index = prog_cnt; -		if (dev->_is_first_frame) { -			dev->_is_first_frame = 0; +		if (out->_is_first_frame) { +			out->_is_first_frame = 0; -			if (dev->_isNTSC) { +			if (out->is_60hz) {  				singlefield_lines += 1;  				odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;  			} else { @@ -589,17 +442,17 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,  				odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;  			} -			if (dev->_dma_virt_start_addr != NULL) { +			if (out->_dma_virt_start_addr != NULL) {  				line_size_in_bytes = -				    (dev->_pixel_format == +				    (out->_pixel_format ==  				     PIXEL_FRMT_411) ? Y411_LINE_SZ :  				    Y422_LINE_SZ;  				risc_phys_jump_addr = -				    dev->_dma_phys_start_addr + +				    out->_dma_phys_start_addr +  				    odd_risc_prog_size; -				rp = cx25821_update_riscprogram(dev, -					dev->_dma_virt_start_addr, TOP_OFFSET, +				rp = cx25821_update_riscprogram(chan, +					out->_dma_virt_start_addr, TOP_OFFSET,  					line_size_in_bytes, 0x0,  					singlefield_lines, FIFO_DISABLE,  					ODD_FIELD); @@ -626,8 +479,8 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,  			       __func__);  	} -	if (dev->_file_status == END_OF_FILE) { -		pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count); +	if (out->_file_status == END_OF_FILE) { +		pr_err("EOF Channel 1 Framecount = %d\n", out->_frame_count);  		return -1;  	}  	/* ElSE, set the interrupt mask register, re-enable irq. */ @@ -639,47 +492,41 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,  static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)  { -	struct cx25821_dev *dev = dev_id; +	struct cx25821_channel *chan = dev_id; +	struct cx25821_dev *dev = chan->dev;  	u32 vid_status;  	int handled = 0; -	int channel_num = 0; -	struct sram_channel *sram_ch; +	const struct sram_channel *sram_ch;  	if (!dev)  		return -1; -	channel_num = VID_UPSTREAM_SRAM_CHANNEL_I; - -	sram_ch = dev->channels[channel_num].sram_channels; +	sram_ch = chan->sram_channels;  	vid_status = cx_read(sram_ch->int_stat);  	/* Only deal with our interrupt */  	if (vid_status) -		handled = cx25821_video_upstream_irq(dev, channel_num, -				vid_status); - -	if (handled < 0) -		cx25821_stop_upstream_video_ch1(dev); -	else -		handled += handled; +		handled = cx25821_video_upstream_irq(chan, vid_status);  	return IRQ_RETVAL(handled);  } -static void cx25821_set_pixelengine(struct cx25821_dev *dev, -				    struct sram_channel *ch, +static void cx25821_set_pixelengine(struct cx25821_channel *chan, +				    const struct sram_channel *ch,  				    int pix_format)  { +	struct cx25821_video_out_data *out = chan->out; +	struct cx25821_dev *dev = chan->dev;  	int width = WIDTH_D1; -	int height = dev->_lines_count; +	int height = out->_lines_count;  	int num_lines, odd_num_lines;  	u32 value;  	int vip_mode = OUTPUT_FRMT_656;  	value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);  	value &= 0xFFFFFFEF; -	value |= dev->_isNTSC ? 0 : 0x10; +	value |= out->is_60hz ? 0 : 0x10;  	cx_write(ch->vid_fmt_ctl, value);  	/* set number of active pixels in each line. @@ -689,7 +536,7 @@ static void cx25821_set_pixelengine(struct cx25821_dev *dev,  	num_lines = (height / 2) & 0x3FF;  	odd_num_lines = num_lines; -	if (dev->_isNTSC) +	if (out->is_60hz)  		odd_num_lines += 1;  	value = (num_lines << 16) | odd_num_lines; @@ -700,9 +547,11 @@ static void cx25821_set_pixelengine(struct cx25821_dev *dev,  	cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);  } -static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, -					    struct sram_channel *sram_ch) +static int cx25821_start_video_dma_upstream(struct cx25821_channel *chan, +					    const struct sram_channel *sram_ch)  { +	struct cx25821_video_out_data *out = chan->out; +	struct cx25821_dev *dev = chan->dev;  	u32 tmp = 0;  	int err = 0; @@ -715,7 +564,7 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,  	/* Set the physical start address of the RISC program in the initial  	 * program counter(IPC) member of the cmds.  	 */ -	cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr); +	cx_write(sram_ch->cmds_start + 0, out->_dma_phys_addr);  	/* Risc IPC High 64 bits 63-32 */  	cx_write(sram_ch->cmds_start + 4, 0); @@ -731,7 +580,7 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,  	cx_write(sram_ch->int_msk, tmp |= _intr_msk);  	err = request_irq(dev->pci->irq, cx25821_upstream_irq, -			IRQF_SHARED, dev->name, dev); +			IRQF_SHARED, dev->name, chan);  	if (err < 0) {  		pr_err("%s: can't get upstream IRQ %d\n",  		       dev->name, dev->pci->irq); @@ -742,8 +591,8 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,  	tmp = cx_read(sram_ch->dma_ctl);  	cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); -	dev->_is_running = 1; -	dev->_is_first_frame = 1; +	out->_is_running = 1; +	out->_is_first_frame = 1;  	return 0; @@ -752,107 +601,71 @@ fail_irq:  	return err;  } -int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, +int cx25821_vidupstream_init(struct cx25821_channel *chan,  				 int pixel_format)  { -	struct sram_channel *sram_ch; +	struct cx25821_video_out_data *out = chan->out; +	struct cx25821_dev *dev = chan->dev; +	const struct sram_channel *sram_ch;  	u32 tmp;  	int err = 0;  	int data_frame_size = 0;  	int risc_buffer_size = 0; -	int str_length = 0; -	if (dev->_is_running) { +	if (out->_is_running) {  		pr_info("Video Channel is still running so return!\n");  		return 0;  	} -	dev->_channel_upstream_select = channel_select; -	sram_ch = dev->channels[channel_select].sram_channels; +	sram_ch = chan->sram_channels; -	INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler); -	dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); +	out->is_60hz = dev->tvnorm & V4L2_STD_525_60; -	if (!dev->_irq_queues) { -		pr_err("create_singlethread_workqueue() for Video FAILED!\n"); -		return -ENOMEM; -	}  	/* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for  	 * channel A-C  	 */  	tmp = cx_read(VID_CH_MODE_SEL);  	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); -	dev->_is_running = 0; -	dev->_frame_count = 0; -	dev->_file_status = RESET_STATUS; -	dev->_lines_count = dev->_isNTSC ? 480 : 576; -	dev->_pixel_format = pixel_format; -	dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? +	out->_is_running = 0; +	out->_frame_count = 0; +	out->_file_status = RESET_STATUS; +	out->_lines_count = out->is_60hz ? 480 : 576; +	out->_pixel_format = pixel_format; +	out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ?  		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; -	data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; -	risc_buffer_size = dev->_isNTSC ? +	data_frame_size = out->is_60hz ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; +	risc_buffer_size = out->is_60hz ?  		NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; -	if (dev->input_filename) { -		str_length = strlen(dev->input_filename); -		dev->_filename = kmemdup(dev->input_filename, str_length + 1, -					 GFP_KERNEL); - -		if (!dev->_filename) { -			err = -ENOENT; -			goto error; -		} -	} else { -		str_length = strlen(dev->_defaultname); -		dev->_filename = kmemdup(dev->_defaultname, str_length + 1, -					 GFP_KERNEL); - -		if (!dev->_filename) { -			err = -ENOENT; -			goto error; -		} -	} - -	/* Default if filename is empty string */ -	if (strcmp(dev->_filename, "") == 0) { -		if (dev->_isNTSC) { -			dev->_filename = -				(dev->_pixel_format == PIXEL_FRMT_411) ? -				"/root/vid411.yuv" : "/root/vidtest.yuv"; -		} else { -			dev->_filename = -				(dev->_pixel_format == PIXEL_FRMT_411) ? -				"/root/pal411.yuv" : "/root/pal422.yuv"; -		} -	} - -	dev->_is_running = 0; -	dev->_frame_count = 0; -	dev->_file_status = RESET_STATUS; -	dev->_lines_count = dev->_isNTSC ? 480 : 576; -	dev->_pixel_format = pixel_format; -	dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? +	out->_is_running = 0; +	out->_frame_count = 0; +	out->_file_status = RESET_STATUS; +	out->_lines_count = out->is_60hz ? 480 : 576; +	out->_pixel_format = pixel_format; +	out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ?  		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; +	out->curpos = 0; +	init_waitqueue_head(&out->waitq);  	err = cx25821_sram_channel_setup_upstream(dev, sram_ch, -			dev->_line_size, 0); +			out->_line_size, 0);  	/* setup fifo + format */ -	cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format); +	cx25821_set_pixelengine(chan, sram_ch, out->_pixel_format); -	dev->upstream_riscbuf_size = risc_buffer_size * 2; -	dev->upstream_databuf_size = data_frame_size * 2; +	out->upstream_riscbuf_size = risc_buffer_size * 2; +	out->upstream_databuf_size = data_frame_size * 2;  	/* Allocating buffers and prepare RISC program */ -	err = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size); +	err = cx25821_upstream_buffer_prepare(chan, sram_ch, out->_line_size);  	if (err < 0) {  		pr_err("%s: Failed to set up Video upstream buffers!\n",  		       dev->name);  		goto error;  	} -	cx25821_start_video_dma_upstream(dev, sram_ch); +	cx25821_start_video_dma_upstream(chan, sram_ch);  	return 0; diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index d4de021dc84..d270819fd87 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -33,13 +33,10 @@ MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");  MODULE_LICENSE("GPL");  static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET }; -static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };  module_param_array(video_nr, int, NULL, 0444); -module_param_array(radio_nr, int, NULL, 0444);  MODULE_PARM_DESC(video_nr, "video device numbers"); -MODULE_PARM_DESC(radio_nr, "radio device numbers");  static unsigned int video_debug = VIDEO_DEBUG;  module_param(video_debug, int, 0644); @@ -49,24 +46,14 @@ static unsigned int irq_debug;  module_param(irq_debug, int, 0644);  MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); -unsigned int vid_limit = 16; +static unsigned int vid_limit = 16;  module_param(vid_limit, int, 0644);  MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); -static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num); - -static const struct v4l2_file_operations video_fops; -static const struct v4l2_ioctl_ops video_ioctl_ops; -  #define FORMAT_FLAGS_PACKED       0x01 -struct cx25821_fmt formats[] = { +static const struct cx25821_fmt formats[] = {  	{ -		.name = "8 bpp, gray", -		.fourcc = V4L2_PIX_FMT_GREY, -		.depth = 8, -		.flags = FORMAT_FLAGS_PACKED, -	 }, {  		.name = "4:1:1, packed, Y41P",  		.fourcc = V4L2_PIX_FMT_Y41P,  		.depth = 12, @@ -76,36 +63,16 @@ struct cx25821_fmt formats[] = {  		.fourcc = V4L2_PIX_FMT_YUYV,  		.depth = 16,  		.flags = FORMAT_FLAGS_PACKED, -	}, { -		.name = "4:2:2, packed, UYVY", -		.fourcc = V4L2_PIX_FMT_UYVY, -		.depth = 16, -		.flags = FORMAT_FLAGS_PACKED, -	}, { -		.name = "4:2:0, YUV", -		.fourcc = V4L2_PIX_FMT_YUV420, -		.depth = 12, -		.flags = FORMAT_FLAGS_PACKED,  	},  }; -int cx25821_get_format_size(void) -{ -	return ARRAY_SIZE(formats); -} - -struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc) +static const struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)  {  	unsigned int i; -	if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) -		return formats + 1; -  	for (i = 0; i < ARRAY_SIZE(formats); i++)  		if (formats[i].fourcc == fourcc)  			return formats + i; - -	pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc);  	return NULL;  } @@ -144,129 +111,10 @@ void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,  		pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc);  } -#ifdef TUNER_FLAG -int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) -{ -	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", -		__func__, (unsigned int)norm, v4l2_norm_to_name(norm)); - -	dev->tvnorm = norm; - -	/* Tell the internal A/V decoder */ -	cx25821_call_all(dev, core, s_std, norm); - -	return 0; -} -#endif - -struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, -				       struct pci_dev *pci, -				       struct video_device *template, -				       char *type) -{ -	struct video_device *vfd; -	dprintk(1, "%s()\n", __func__); - -	vfd = video_device_alloc(); -	if (NULL == vfd) -		return NULL; -	*vfd = *template; -	vfd->v4l2_dev = &dev->v4l2_dev; -	vfd->release = video_device_release; -	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, -		 cx25821_boards[dev->board].name); -	video_set_drvdata(vfd, dev); -	return vfd; -} - -/* -static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) -{ -	int i; - -	if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1) -		return -EINVAL; -	for (i = 0; i < CX25821_CTLS; i++) -		if (cx25821_ctls[i].v.id == qctrl->id) -			break; -	if (i == CX25821_CTLS) { -		*qctrl = no_ctl; -		return 0; -	} -	*qctrl = cx25821_ctls[i].v; -	return 0; -} -*/ - -/* resource management */ -int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, -		    unsigned int bit) -{ -	dprintk(1, "%s()\n", __func__); -	if (fh->resources & bit) -		/* have it already allocated */ -		return 1; - -	/* is it free? */ -	mutex_lock(&dev->lock); -	if (dev->channels[fh->channel_id].resources & bit) { -		/* no, someone else uses it */ -		mutex_unlock(&dev->lock); -		return 0; -	} -	/* it's free, grab it */ -	fh->resources |= bit; -	dev->channels[fh->channel_id].resources |= bit; -	dprintk(1, "res: get %d\n", bit); -	mutex_unlock(&dev->lock); -	return 1; -} - -int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit) -{ -	return fh->resources & bit; -} - -int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit) -{ -	return fh->dev->channels[fh->channel_id].resources & bit; -} - -void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, -		      unsigned int bits) -{ -	BUG_ON((fh->resources & bits) != bits); -	dprintk(1, "%s()\n", __func__); - -	mutex_lock(&dev->lock); -	fh->resources &= ~bits; -	dev->channels[fh->channel_id].resources &= ~bits; -	dprintk(1, "res: put %d\n", bits); -	mutex_unlock(&dev->lock); -} - -int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) -{ -	struct v4l2_routing route; -	memset(&route, 0, sizeof(route)); - -	dprintk(1, "%s(): video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", -		__func__, input, INPUT(input)->vmux, INPUT(input)->gpio0, -		INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3); -	dev->input = input; - -	route.input = INPUT(input)->vmux; - -	/* Tell the internal A/V decoder */ -	cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0); - -	return 0; -} -  int cx25821_start_video_dma(struct cx25821_dev *dev,  			    struct cx25821_dmaqueue *q,  			    struct cx25821_buffer *buf, -			    struct sram_channel *channel) +			    const struct sram_channel *channel)  {  	int tmp = 0; @@ -293,7 +141,7 @@ int cx25821_start_video_dma(struct cx25821_dev *dev,  static int cx25821_restart_video_queue(struct cx25821_dev *dev,  				       struct cx25821_dmaqueue *q, -				       struct sram_channel *channel) +				       const struct sram_channel *channel)  {  	struct cx25821_buffer *buf, *prev;  	struct list_head *item; @@ -346,8 +194,8 @@ static void cx25821_vid_timeout(unsigned long data)  {  	struct cx25821_data *timeout_data = (struct cx25821_data *)data;  	struct cx25821_dev *dev = timeout_data->dev; -	struct sram_channel *channel = timeout_data->channel; -	struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq; +	const struct sram_channel *channel = timeout_data->channel; +	struct cx25821_dmaqueue *q = &dev->channels[channel->i].dma_vidq;  	struct cx25821_buffer *buf;  	unsigned long flags; @@ -373,7 +221,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)  	u32 count = 0;  	int handled = 0;  	u32 mask; -	struct sram_channel *channel = dev->channels[chan_num].sram_channels; +	const struct sram_channel *channel = dev->channels[chan_num].sram_channels;  	mask = cx_read(channel->int_msk);  	if (0 == (status & mask)) @@ -393,7 +241,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)  	if (status & FLD_VID_DST_RISC1) {  		spin_lock(&dev->slock);  		count = cx_read(channel->gpcnt); -		cx25821_video_wakeup(dev, &dev->channels[channel->i].vidq, +		cx25821_video_wakeup(dev, &dev->channels[channel->i].dma_vidq,  				count);  		spin_unlock(&dev->slock);  		handled++; @@ -404,122 +252,19 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)  		dprintk(2, "stopper video\n");  		spin_lock(&dev->slock);  		cx25821_restart_video_queue(dev, -				&dev->channels[channel->i].vidq, channel); +				&dev->channels[channel->i].dma_vidq, channel);  		spin_unlock(&dev->slock);  		handled++;  	}  	return handled;  } -void cx25821_videoioctl_unregister(struct cx25821_dev *dev) -{ -	if (dev->ioctl_dev) { -		if (video_is_registered(dev->ioctl_dev)) -			video_unregister_device(dev->ioctl_dev); -		else -			video_device_release(dev->ioctl_dev); - -		dev->ioctl_dev = NULL; -	} -} - -void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) -{ -	cx_clear(PCI_INT_MSK, 1); - -	if (dev->channels[chan_num].video_dev) { -		if (video_is_registered(dev->channels[chan_num].video_dev)) -			video_unregister_device( -					dev->channels[chan_num].video_dev); -		else -			video_device_release( -					dev->channels[chan_num].video_dev); - -		dev->channels[chan_num].video_dev = NULL; - -		btcx_riscmem_free(dev->pci, -				&dev->channels[chan_num].vidq.stopper); - -		pr_warn("device %d released!\n", chan_num); -	} - -} - -int cx25821_video_register(struct cx25821_dev *dev) -{ -	int err; -	int i; - -	struct video_device cx25821_video_device = { -		.name = "cx25821-video", -		.fops = &video_fops, -		.minor = -1, -		.ioctl_ops = &video_ioctl_ops, -		.tvnorms = CX25821_NORMS, -		.current_norm = V4L2_STD_NTSC_M, -	}; - -	spin_lock_init(&dev->slock); - -	for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) { -		cx25821_init_controls(dev, i); - -		cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, -			dev->channels[i].sram_channels->dma_ctl, 0x11, 0); - -		dev->channels[i].sram_channels = &cx25821_sram_channels[i]; -		dev->channels[i].video_dev = NULL; -		dev->channels[i].resources = 0; - -		cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); - -		INIT_LIST_HEAD(&dev->channels[i].vidq.active); -		INIT_LIST_HEAD(&dev->channels[i].vidq.queued); - -		dev->channels[i].timeout_data.dev = dev; -		dev->channels[i].timeout_data.channel = -			&cx25821_sram_channels[i]; -		dev->channels[i].vidq.timeout.function = cx25821_vid_timeout; -		dev->channels[i].vidq.timeout.data = -			(unsigned long)&dev->channels[i].timeout_data; -		init_timer(&dev->channels[i].vidq.timeout); - -		/* register v4l devices */ -		dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci, -				&cx25821_video_device, "video"); - -		err = video_register_device(dev->channels[i].video_dev, -				VFL_TYPE_GRABBER, video_nr[dev->nr]); - -		if (err < 0) -			goto fail_unreg; - -	} - -	/* set PCI interrupt */ -	cx_set(PCI_INT_MSK, 0xff); - -	/* initial device configuration */ -	mutex_lock(&dev->lock); -#ifdef TUNER_FLAG -	dev->tvnorm = cx25821_video_device.current_norm; -	cx25821_set_tvnorm(dev, dev->tvnorm); -#endif -	mutex_unlock(&dev->lock); - -	return 0; - -fail_unreg: -	cx25821_video_unregister(dev, i); -	return err; -} - -int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, +static int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,  		 unsigned int *size)  { -	struct cx25821_fh *fh = q->priv_data; +	struct cx25821_channel *chan = q->priv_data; -	*size = fh->fmt->depth * fh->width * fh->height >> 3; +	*size = chan->fmt->depth * chan->width * chan->height >> 3;  	if (0 == *count)  		*count = 32; @@ -530,35 +275,34 @@ int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,  	return 0;  } -int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, +static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,  		   enum v4l2_field field)  { -	struct cx25821_fh *fh = q->priv_data; -	struct cx25821_dev *dev = fh->dev; +	struct cx25821_channel *chan = q->priv_data; +	struct cx25821_dev *dev = chan->dev;  	struct cx25821_buffer *buf =  		container_of(vb, struct cx25821_buffer, vb);  	int rc, init_buffer = 0;  	u32 line0_offset;  	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);  	int bpl_local = LINE_SIZE_D1; -	int channel_opened = fh->channel_id; -	BUG_ON(NULL == fh->fmt); -	if (fh->width < 48 || fh->width > 720 || -	    fh->height < 32 || fh->height > 576) +	BUG_ON(NULL == chan->fmt); +	if (chan->width < 48 || chan->width > 720 || +	    chan->height < 32 || chan->height > 576)  		return -EINVAL; -	buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; +	buf->vb.size = (chan->width * chan->height * chan->fmt->depth) >> 3;  	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)  		return -EINVAL; -	if (buf->fmt != fh->fmt || -	    buf->vb.width != fh->width || -	    buf->vb.height != fh->height || buf->vb.field != field) { -		buf->fmt = fh->fmt; -		buf->vb.width = fh->width; -		buf->vb.height = fh->height; +	if (buf->fmt != chan->fmt || +	    buf->vb.width != chan->width || +	    buf->vb.height != chan->height || buf->vb.field != field) { +		buf->fmt = chan->fmt; +		buf->vb.width = chan->width; +		buf->vb.height = chan->height;  		buf->vb.field = field;  		init_buffer = 1;  	} @@ -575,34 +319,21 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,  	dprintk(1, "init_buffer=%d\n", init_buffer);  	if (init_buffer) { - -		channel_opened = dev->channel_opened; -		if (channel_opened < 0 || channel_opened > 7) -			channel_opened = 7; - -		if (dev->channels[channel_opened].pixel_formats == -				PIXEL_FRMT_411) +		if (chan->pixel_formats == PIXEL_FRMT_411)  			buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;  		else  			buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width); -		if (dev->channels[channel_opened].pixel_formats == -				PIXEL_FRMT_411) { +		if (chan->pixel_formats == PIXEL_FRMT_411) {  			bpl_local = buf->bpl;  		} else {  			bpl_local = buf->bpl;   /* Default */ -			if (channel_opened >= 0 && channel_opened <= 7) { -				if (dev->channels[channel_opened] -						.use_cif_resolution) { -					if (dev->tvnorm & V4L2_STD_PAL_BG || -					    dev->tvnorm & V4L2_STD_PAL_DK) -						bpl_local = 352 << 1; -					else -						bpl_local = dev->channels[ -							channel_opened]. -							cif_width << 1; -				} +			if (chan->use_cif_resolution) { +				if (dev->tvnorm & V4L2_STD_625_50) +					bpl_local = 352 << 1; +				else +					bpl_local = chan->cif_width << 1;  			}  		} @@ -645,8 +376,8 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,  	}  	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", -		buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth, -		fh->fmt->name, (unsigned long)buf->risc.dma); +		buf, buf->vb.i, chan->width, chan->height, chan->fmt->depth, +		chan->fmt->name, (unsigned long)buf->risc.dma);  	buf->vb.state = VIDEOBUF_PREPARED; @@ -657,7 +388,7 @@ fail:  	return rc;  } -void cx25821_buffer_release(struct videobuf_queue *q, +static void cx25821_buffer_release(struct videobuf_queue *q,  			    struct videobuf_buffer *vb)  {  	struct cx25821_buffer *buf = @@ -666,33 +397,11 @@ void cx25821_buffer_release(struct videobuf_queue *q,  	cx25821_free_buffer(q, buf);  } -struct videobuf_queue *get_queue(struct cx25821_fh *fh) -{ -	switch (fh->type) { -	case V4L2_BUF_TYPE_VIDEO_CAPTURE: -		return &fh->vidq; -	default: -		BUG(); -		return NULL; -	} -} - -int cx25821_get_resource(struct cx25821_fh *fh, int resource) -{ -	switch (fh->type) { -	case V4L2_BUF_TYPE_VIDEO_CAPTURE: -		return resource; -	default: -		BUG(); -		return 0; -	} -} - -int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) +static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)  { -	struct cx25821_fh *fh = file->private_data; +	struct cx25821_channel *chan = video_drvdata(file); -	return videobuf_mmap_mapper(get_queue(fh), vma); +	return videobuf_mmap_mapper(&chan->vidq, vma);  } @@ -701,9 +410,9 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)  	struct cx25821_buffer *buf =  		container_of(vb, struct cx25821_buffer, vb);  	struct cx25821_buffer *prev; -	struct cx25821_fh *fh = vq->priv_data; -	struct cx25821_dev *dev = fh->dev; -	struct cx25821_dmaqueue *q = &dev->channels[fh->channel_id].vidq; +	struct cx25821_channel *chan = vq->priv_data; +	struct cx25821_dev *dev = chan->dev; +	struct cx25821_dmaqueue *q = &dev->channels[chan->id].dma_vidq;  	/* add jump to stopper */  	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); @@ -720,8 +429,7 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)  	} else if (list_empty(&q->active)) {  		list_add_tail(&buf->vb.queue, &q->active); -		cx25821_start_video_dma(dev, q, buf, -				dev->channels[fh->channel_id].sram_channels); +		cx25821_start_video_dma(dev, q, buf, chan->sram_channels);  		buf->vb.state = VIDEOBUF_ACTIVE;  		buf->count = q->count++;  		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); @@ -762,1183 +470,487 @@ static struct videobuf_queue_ops cx25821_video_qops = {  	.buf_release = cx25821_buffer_release,  }; -static int video_open(struct file *file) -{ -	struct video_device *vdev = video_devdata(file); -	struct cx25821_dev *h, *dev = video_drvdata(file); -	struct cx25821_fh *fh; -	struct list_head *list; -	int minor = video_devdata(file)->minor; -	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -	u32 pix_format; -	int ch_id = 0; -	int i; - -	dprintk(1, "open dev=%s type=%s\n", video_device_node_name(vdev), -			v4l2_type_names[type]); - -	/* allocate + initialize per filehandle data */ -	fh = kzalloc(sizeof(*fh), GFP_KERNEL); -	if (NULL == fh) -		return -ENOMEM; - -	mutex_lock(&cx25821_devlist_mutex); - -	list_for_each(list, &cx25821_devlist) -	{ -		h = list_entry(list, struct cx25821_dev, devlist); - -		for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { -			if (h->channels[i].video_dev && -			    h->channels[i].video_dev->minor == minor) { -				dev = h; -				ch_id = i; -				type  = V4L2_BUF_TYPE_VIDEO_CAPTURE; -			} -		} -	} - -	if (NULL == dev) { -		mutex_unlock(&cx25821_devlist_mutex); -		kfree(fh); -		return -ENODEV; -	} - -	file->private_data = fh; -	fh->dev = dev; -	fh->type = type; -	fh->width = 720; -	fh->channel_id = ch_id; - -	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) -		fh->height = 576; -	else -		fh->height = 480; - -	dev->channel_opened = fh->channel_id; -	if (dev->channels[ch_id].pixel_formats == PIXEL_FRMT_411) -		pix_format = V4L2_PIX_FMT_Y41P; -	else -		pix_format = V4L2_PIX_FMT_YUYV; -	fh->fmt = cx25821_format_by_fourcc(pix_format); - -	v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); - -	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev, -			&dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, -			V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), -			fh, NULL); - -	dprintk(1, "post videobuf_queue_init()\n"); -	mutex_unlock(&cx25821_devlist_mutex); - -	return 0; -} -  static ssize_t video_read(struct file *file, char __user * data, size_t count,  			 loff_t *ppos)  { -	struct cx25821_fh *fh = file->private_data; +	struct v4l2_fh *fh = file->private_data; +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev; +	int err = 0; -	switch (fh->type) { -	case V4L2_BUF_TYPE_VIDEO_CAPTURE: -		if (cx25821_res_locked(fh, RESOURCE_VIDEO0)) -			return -EBUSY; - -		return videobuf_read_one(&fh->vidq, data, count, ppos, -					file->f_flags & O_NONBLOCK); - -	default: -		BUG(); -		return 0; +	if (mutex_lock_interruptible(&dev->lock)) +		return -ERESTARTSYS; +	if (chan->streaming_fh && chan->streaming_fh != fh) { +		err = -EBUSY; +		goto unlock;  	} +	chan->streaming_fh = fh; + +	err = videobuf_read_one(&chan->vidq, data, count, ppos, +				file->f_flags & O_NONBLOCK); +unlock: +	mutex_unlock(&dev->lock); +	return err;  }  static unsigned int video_poll(struct file *file,  			      struct poll_table_struct *wait)  { -	struct cx25821_fh *fh = file->private_data; -	struct cx25821_buffer *buf; +	struct cx25821_channel *chan = video_drvdata(file); +	unsigned long req_events = poll_requested_events(wait); +	unsigned int res = v4l2_ctrl_poll(file, wait); -	if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { -		/* streaming capture */ -		if (list_empty(&fh->vidq.stream)) -			return POLLERR; -		buf = list_entry(fh->vidq.stream.next, -				struct cx25821_buffer, vb.stream); -	} else { -		/* read() capture */ -		buf = (struct cx25821_buffer *)fh->vidq.read_buf; -		if (NULL == buf) -			return POLLERR; -	} +	if (req_events & (POLLIN | POLLRDNORM)) +		res |= videobuf_poll_stream(file, &chan->vidq, wait); +	return res; -	poll_wait(file, &buf->vb.done, wait); -	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) { -		if (buf->vb.state == VIDEOBUF_DONE) { -			struct cx25821_dev *dev = fh->dev; +	/* This doesn't belong in poll(). This can be done +	 * much better with vb2. We keep this code here as a +	 * reminder. +	if ((res & POLLIN) && buf->vb.state == VIDEOBUF_DONE) { +		struct cx25821_dev *dev = chan->dev; -			if (dev && dev->channels[fh->channel_id] -					.use_cif_resolution) { -				u8 cam_id = *((char *)buf->vb.baddr + 3); -				memcpy((char *)buf->vb.baddr, -				      (char *)buf->vb.baddr + (fh->width * 2), -				      (fh->width * 2)); -				*((char *)buf->vb.baddr + 3) = cam_id; -			} +		if (dev && chan->use_cif_resolution) { +			u8 cam_id = *((char *)buf->vb.baddr + 3); +			memcpy((char *)buf->vb.baddr, +					(char *)buf->vb.baddr + (chan->width * 2), +					(chan->width * 2)); +			*((char *)buf->vb.baddr + 3) = cam_id;  		} - -		return POLLIN | POLLRDNORM;  	} - -	return 0; +	 */  }  static int video_release(struct file *file)  { -	struct cx25821_fh *fh = file->private_data; -	struct cx25821_dev *dev = fh->dev; +	struct cx25821_channel *chan = video_drvdata(file); +	struct v4l2_fh *fh = file->private_data; +	struct cx25821_dev *dev = chan->dev; +	const struct sram_channel *sram_ch = +		dev->channels[0].sram_channels; +	mutex_lock(&dev->lock);  	/* stop the risc engine and fifo */ -	cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */ +	cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */  	/* stop video capture */ -	if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { -		videobuf_queue_cancel(&fh->vidq); -		cx25821_res_free(dev, fh, RESOURCE_VIDEO0); +	if (chan->streaming_fh == fh) { +		videobuf_queue_cancel(&chan->vidq); +		chan->streaming_fh = NULL;  	} -	if (fh->vidq.read_buf) { -		cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf); -		kfree(fh->vidq.read_buf); +	if (chan->vidq.read_buf) { +		cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf); +		kfree(chan->vidq.read_buf);  	} -	videobuf_mmap_free(&fh->vidq); - -	v4l2_prio_close(&dev->channels[fh->channel_id].prio, fh->prio); -	file->private_data = NULL; -	kfree(fh); +	videobuf_mmap_free(&chan->vidq); +	mutex_unlock(&dev->lock); -	return 0; +	return v4l2_fh_release(file);  } -static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev = fh->dev; +/* VIDEO IOCTLS */ -	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) +static int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, +			    struct v4l2_fmtdesc *f) +{ +	if (unlikely(f->index >= ARRAY_SIZE(formats)))  		return -EINVAL; -	if (unlikely(i != fh->type)) -		return -EINVAL; +	strlcpy(f->description, formats[f->index].name, sizeof(f->description)); +	f->pixelformat = formats[f->index].fourcc; -	if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, -						RESOURCE_VIDEO0)))) -		return -EBUSY; +	return 0; +} -	return videobuf_streamon(get_queue(fh)); +static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, +				 struct v4l2_format *f) +{ +	struct cx25821_channel *chan = video_drvdata(file); + +	f->fmt.pix.width = chan->width; +	f->fmt.pix.height = chan->height; +	f->fmt.pix.field = chan->vidq.field; +	f->fmt.pix.pixelformat = chan->fmt->fourcc; +	f->fmt.pix.bytesperline = (chan->width * chan->fmt->depth) >> 3; +	f->fmt.pix.sizeimage = chan->height * f->fmt.pix.bytesperline; +	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; +	f->fmt.pix.priv = 0; + +	return 0;  } -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) +static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, +				   struct v4l2_format *f)  { -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev = fh->dev; -	int err, res; +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev; +	const struct cx25821_fmt *fmt; +	enum v4l2_field field = f->fmt.pix.field; +	unsigned int maxh; +	unsigned w; -	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -		return -EINVAL; -	if (i != fh->type) +	fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); +	if (NULL == fmt)  		return -EINVAL; +	maxh = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480; + +	w = f->fmt.pix.width; +	if (field != V4L2_FIELD_BOTTOM) +		field = V4L2_FIELD_TOP; +	if (w < 352) { +		w = 176; +		f->fmt.pix.height = maxh / 4; +	} else if (w < 720) { +		w = 352; +		f->fmt.pix.height = maxh / 2; +	} else { +		w = 720; +		f->fmt.pix.height = maxh; +		field = V4L2_FIELD_INTERLACED; +	} +	f->fmt.pix.field = field; +	f->fmt.pix.width = w; +	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; +	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; +	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; +	f->fmt.pix.priv = 0; -	res = cx25821_get_resource(fh, RESOURCE_VIDEO0); -	err = videobuf_streamoff(get_queue(fh)); -	if (err < 0) -		return err; -	cx25821_res_free(dev, fh, res);  	return 0;  }  static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,  				struct v4l2_format *f)  { -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	struct v4l2_mbus_framefmt mbus_fmt; -	int err; +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev;  	int pix_format = PIXEL_FRMT_422; +	int err; -	if (fh) { -		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, -				      fh->prio); -		if (0 != err) -			return err; -	} - -	dprintk(2, "%s()\n", __func__);  	err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);  	if (0 != err)  		return err; -	fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); -	fh->vidq.field = f->fmt.pix.field; - -	/* check if width and height is valid based on set standard */ -	if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) -		fh->width = f->fmt.pix.width; - -	if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) -		fh->height = f->fmt.pix.height; +	chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); +	chan->vidq.field = f->fmt.pix.field; +	chan->width = f->fmt.pix.width; +	chan->height = f->fmt.pix.height;  	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)  		pix_format = PIXEL_FRMT_411; -	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) -		pix_format = PIXEL_FRMT_422;  	else -		return -EINVAL; +		pix_format = PIXEL_FRMT_422;  	cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);  	/* check if cif resolution */ -	if (fh->width == 320 || fh->width == 352) -		dev->channels[fh->channel_id].use_cif_resolution = 1; +	if (chan->width == 320 || chan->width == 352) +		chan->use_cif_resolution = 1;  	else -		dev->channels[fh->channel_id].use_cif_resolution = 0; - -	dev->channels[fh->channel_id].cif_width = fh->width; -	medusa_set_resolution(dev, fh->width, SRAM_CH00); - -	dprintk(2, "%s(): width=%d height=%d field=%d\n", __func__, fh->width, -		fh->height, fh->vidq.field); -	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); -	cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt); +		chan->use_cif_resolution = 0; +	chan->cif_width = chan->width; +	medusa_set_resolution(dev, chan->width, SRAM_CH00);  	return 0;  } -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) +static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)  { -	int ret_val = 0; -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; +	struct cx25821_channel *chan = video_drvdata(file); -	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK); +	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) +		return -EINVAL; -	p->sequence = dev->channels[fh->channel_id].vidq.count; +	if (chan->streaming_fh && chan->streaming_fh != priv) +		return -EBUSY; +	chan->streaming_fh = priv; -	return ret_val; +	return videobuf_streamon(&chan->vidq);  } -static int vidioc_log_status(struct file *file, void *priv) +static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)  { -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	struct cx25821_fh *fh = priv; -	char name[32 + 2]; +	struct cx25821_channel *chan = video_drvdata(file); -	struct sram_channel *sram_ch = dev->channels[fh->channel_id] -								.sram_channels; -	u32 tmp = 0; - -	snprintf(name, sizeof(name), "%s/2", dev->name); -	pr_info("%s/2: ============  START LOG STATUS  ============\n", -		dev->name); -	cx25821_call_all(dev, core, log_status); -	tmp = cx_read(sram_ch->dma_ctl); -	pr_info("Video input 0 is %s\n", -		(tmp & 0x11) ? "streaming" : "stopped"); -	pr_info("%s/2: =============  END LOG STATUS  =============\n", -		dev->name); -	return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, -			struct v4l2_control *ctl) -{ -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	int err; +	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) +		return -EINVAL; -	if (fh) { -		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, -				      fh->prio); -		if (0 != err) -			return err; -	} +	if (chan->streaming_fh && chan->streaming_fh != priv) +		return -EBUSY; +	if (chan->streaming_fh == NULL) +		return 0; -	return cx25821_set_control(dev, ctl, fh->channel_id); +	chan->streaming_fh = NULL; +	return videobuf_streamoff(&chan->vidq);  } -/* VIDEO IOCTLS */ -int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, -				 struct v4l2_format *f) +static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)  { -	struct cx25821_fh *fh = priv; +	int ret_val = 0; +	struct cx25821_channel *chan = video_drvdata(file); -	f->fmt.pix.width = fh->width; -	f->fmt.pix.height = fh->height; -	f->fmt.pix.field = fh->vidq.field; -	f->fmt.pix.pixelformat = fh->fmt->fourcc; -	f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3; -	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; +	ret_val = videobuf_dqbuf(&chan->vidq, p, file->f_flags & O_NONBLOCK); +	p->sequence = chan->dma_vidq.count; -	return 0; +	return ret_val;  } -int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, -				   struct v4l2_format *f) +static int vidioc_log_status(struct file *file, void *priv)  { -	struct cx25821_fmt *fmt; -	enum v4l2_field field; -	unsigned int maxw, maxh; - -	fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); -	if (NULL == fmt) -		return -EINVAL; - -	field = f->fmt.pix.field; -	maxw = 720; -	maxh = 576; - -	if (V4L2_FIELD_ANY == field) { -		if (f->fmt.pix.height > maxh / 2) -			field = V4L2_FIELD_INTERLACED; -		else -			field = V4L2_FIELD_TOP; -	} - -	switch (field) { -	case V4L2_FIELD_TOP: -	case V4L2_FIELD_BOTTOM: -		maxh = maxh / 2; -		break; -	case V4L2_FIELD_INTERLACED: -		break; -	default: -		return -EINVAL; -	} - -	f->fmt.pix.field = field; -	if (f->fmt.pix.height < 32) -		f->fmt.pix.height = 32; -	if (f->fmt.pix.height > maxh) -		f->fmt.pix.height = maxh; -	if (f->fmt.pix.width < 48) -		f->fmt.pix.width = 48; -	if (f->fmt.pix.width > maxw) -		f->fmt.pix.width = maxw; -	f->fmt.pix.width &= ~0x03; -	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; -	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev; +	const struct sram_channel *sram_ch = chan->sram_channels; +	u32 tmp = 0; +	tmp = cx_read(sram_ch->dma_ctl); +	pr_info("Video input 0 is %s\n", +		(tmp & 0x11) ? "streaming" : "stopped");  	return 0;  } -int cx25821_vidioc_querycap(struct file *file, void *priv, + +static int cx25821_vidioc_querycap(struct file *file, void *priv,  			    struct v4l2_capability *cap)  { -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev; +	const u32 cap_input = V4L2_CAP_VIDEO_CAPTURE | +			V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; +	const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE;  	strcpy(cap->driver, "cx25821");  	strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));  	sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); -	cap->version = CX25821_VERSION_CODE; -	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | -		V4L2_CAP_STREAMING; -	if (UNSET != dev->tuner_type) -		cap->capabilities |= V4L2_CAP_TUNER; -	return 0; -} - -int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, -			    struct v4l2_fmtdesc *f) -{ -	if (unlikely(f->index >= ARRAY_SIZE(formats))) -		return -EINVAL; - -	strlcpy(f->description, formats[f->index].name, sizeof(f->description)); -	f->pixelformat = formats[f->index].fourcc; - +	if (chan->id >= VID_CHANNEL_NUM) +		cap->device_caps = cap_output; +	else +		cap->device_caps = cap_input; +	cap->capabilities = cap_input | cap_output | V4L2_CAP_DEVICE_CAPS;  	return 0;  } -int cx25821_vidioc_reqbufs(struct file *file, void *priv, +static int cx25821_vidioc_reqbufs(struct file *file, void *priv,  			   struct v4l2_requestbuffers *p)  { -	struct cx25821_fh *fh = priv; -	return videobuf_reqbufs(get_queue(fh), p); +	struct cx25821_channel *chan = video_drvdata(file); + +	return videobuf_reqbufs(&chan->vidq, p);  } -int cx25821_vidioc_querybuf(struct file *file, void *priv, +static int cx25821_vidioc_querybuf(struct file *file, void *priv,  			    struct v4l2_buffer *p)  { -	struct cx25821_fh *fh = priv; -	return videobuf_querybuf(get_queue(fh), p); -} +	struct cx25821_channel *chan = video_drvdata(file); -int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) -{ -	struct cx25821_fh *fh = priv; -	return videobuf_qbuf(get_queue(fh), p); +	return videobuf_querybuf(&chan->vidq, p);  } -int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) +static int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)  { -	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; -	struct cx25821_fh *fh = f; - -	*p = v4l2_prio_max(&dev->channels[fh->channel_id].prio); +	struct cx25821_channel *chan = video_drvdata(file); -	return 0; +	return videobuf_qbuf(&chan->vidq, p);  } -int cx25821_vidioc_s_priority(struct file *file, void *f, -			      enum v4l2_priority prio) +static int cx25821_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms)  { -	struct cx25821_fh *fh = f; -	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; +	struct cx25821_channel *chan = video_drvdata(file); -	return v4l2_prio_change(&dev->channels[fh->channel_id].prio, &fh->prio, -			prio); +	*tvnorms = chan->dev->tvnorm; +	return 0;  } -#ifdef TUNER_FLAG -int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms) +static int cx25821_vidioc_s_std(struct file *file, void *priv, +				v4l2_std_id tvnorms)  { -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	int err; +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev; -	dprintk(1, "%s()\n", __func__); - -	if (fh) { -		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, -				      fh->prio); -		if (0 != err) -			return err; -	} - -	if (dev->tvnorm == *tvnorms) +	if (dev->tvnorm == tvnorms)  		return 0; -	mutex_lock(&dev->lock); -	cx25821_set_tvnorm(dev, *tvnorms); -	mutex_unlock(&dev->lock); +	dev->tvnorm = tvnorms; +	chan->width = 720; +	chan->height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;  	medusa_set_videostandard(dev);  	return 0;  } -#endif -int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i) +static int cx25821_vidioc_enum_input(struct file *file, void *priv, +			      struct v4l2_input *i)  { -	static const char * const iname[] = { -		[CX25821_VMUX_COMPOSITE] = "Composite", -		[CX25821_VMUX_SVIDEO] = "S-Video", -		[CX25821_VMUX_DEBUG] = "for debug only", -	}; -	unsigned int n; -	dprintk(1, "%s()\n", __func__); - -	n = i->index; -	if (n >= 2) -		return -EINVAL; - -	if (0 == INPUT(n)->type) +	if (i->index)  		return -EINVAL;  	i->type = V4L2_INPUT_TYPE_CAMERA; -	strcpy(i->name, iname[INPUT(n)->type]); -  	i->std = CX25821_NORMS; +	strcpy(i->name, "Composite");  	return 0;  } -int cx25821_vidioc_enum_input(struct file *file, void *priv, -			      struct v4l2_input *i) +static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)  { -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	dprintk(1, "%s()\n", __func__); -	return cx25821_enum_input(dev, i); -} - -int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - -	*i = dev->input; -	dprintk(1, "%s(): returns %d\n", __func__, *i); +	*i = 0;  	return 0;  } -int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) +static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)  { -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	int err; - -	dprintk(1, "%s(%d)\n", __func__, i); - -	if (fh) { -		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, -				      fh->prio); -		if (0 != err) -			return err; -	} - -	if (i >= CX25821_NR_INPUT) { -		dprintk(1, "%s(): -EINVAL\n", __func__); -		return -EINVAL; -	} - -	mutex_lock(&dev->lock); -	cx25821_video_mux(dev, i); -	mutex_unlock(&dev->lock); -	return 0; -} - -#ifdef TUNER_FLAG -int cx25821_vidioc_g_frequency(struct file *file, void *priv, -			       struct v4l2_frequency *f) -{ -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev = fh->dev; - -	f->frequency = dev->freq; - -	cx25821_call_all(dev, tuner, g_frequency, f); - -	return 0; -} - -int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f) -{ -	mutex_lock(&dev->lock); -	dev->freq = f->frequency; - -	cx25821_call_all(dev, tuner, s_frequency, f); - -	/* When changing channels it is required to reset TVAUDIO */ -	msleep(10); - -	mutex_unlock(&dev->lock); - -	return 0; -} - -int cx25821_vidioc_s_frequency(struct file *file, void *priv, -			       struct v4l2_frequency *f) -{ -	struct cx25821_fh *fh = priv; -	struct cx25821_dev *dev; -	int err; - -	if (fh) { -		dev = fh->dev; -		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, -				      fh->prio); -		if (0 != err) -			return err; -	} else { -		pr_err("Invalid fh pointer!\n"); -		return -EINVAL; -	} - -	return cx25821_set_freq(dev, f); -} -#endif - -#ifdef CONFIG_VIDEO_ADV_DEBUG -int cx25821_vidioc_g_register(struct file *file, void *fh, -		      struct v4l2_dbg_register *reg) -{ -	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev; - -	if (!v4l2_chip_match_host(®->match)) -		return -EINVAL; - -	cx25821_call_all(dev, core, g_register, reg); - -	return 0; +	return i ? -EINVAL : 0;  } -int cx25821_vidioc_s_register(struct file *file, void *fh, -		      struct v4l2_dbg_register *reg) +static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl)  { -	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev; - -	if (!v4l2_chip_match_host(®->match)) -		return -EINVAL; +	struct cx25821_channel *chan = +		container_of(ctrl->handler, struct cx25821_channel, hdl); +	struct cx25821_dev *dev = chan->dev; -	cx25821_call_all(dev, core, s_register, reg); - -	return 0; -} - -#endif - -#ifdef TUNER_FLAG -int cx25821_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) -{ -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - -	if (unlikely(UNSET == dev->tuner_type)) -		return -EINVAL; -	if (0 != t->index) -		return -EINVAL; - -	strcpy(t->name, "Television"); -	t->type = V4L2_TUNER_ANALOG_TV; -	t->capability = V4L2_TUNER_CAP_NORM; -	t->rangehigh = 0xffffffffUL; - -	t->signal = 0xffff;	/* LOCKED */ -	return 0; -} - -int cx25821_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) -{ -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	struct cx25821_fh *fh = priv; -	int err; - -	if (fh) { -		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, -				      fh->prio); -		if (0 != err) -			return err; -	} - -	dprintk(1, "%s()\n", __func__); -	if (UNSET == dev->tuner_type) -		return -EINVAL; -	if (0 != t->index) -		return -EINVAL; - -	return 0; -} - -#endif -/*****************************************************************************/ -static const struct v4l2_queryctrl no_ctl = { -	.name = "42", -	.flags = V4L2_CTRL_FLAG_DISABLED, -}; - -static struct v4l2_queryctrl cx25821_ctls[] = { -	/* --- video --- */ -	{ -		.id = V4L2_CID_BRIGHTNESS, -		.name = "Brightness", -		.minimum = 0, -		.maximum = 10000, -		.step = 1, -		.default_value = 6200, -		.type = V4L2_CTRL_TYPE_INTEGER, -	}, { -		.id = V4L2_CID_CONTRAST, -		.name = "Contrast", -		.minimum = 0, -		.maximum = 10000, -		.step = 1, -		.default_value = 5000, -		.type = V4L2_CTRL_TYPE_INTEGER, -	}, { -		.id = V4L2_CID_SATURATION, -		.name = "Saturation", -		.minimum = 0, -		.maximum = 10000, -		.step = 1, -		.default_value = 5000, -		.type = V4L2_CTRL_TYPE_INTEGER, -	}, { -		.id = V4L2_CID_HUE, -		.name = "Hue", -		.minimum = 0, -		.maximum = 10000, -		.step = 1, -		.default_value = 5000, -		.type = V4L2_CTRL_TYPE_INTEGER, -	} -}; -static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls); - -static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) -{ -	int i; - -	if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1) -		return -EINVAL; -	for (i = 0; i < CX25821_CTLS; i++) -		if (cx25821_ctls[i].id == qctrl->id) -			break; -	if (i == CX25821_CTLS) { -		*qctrl = no_ctl; -		return 0; -	} -	*qctrl = cx25821_ctls[i]; -	return 0; -} - -int cx25821_vidioc_queryctrl(struct file *file, void *priv, -		     struct v4l2_queryctrl *qctrl) -{ -	return cx25821_ctrl_query(qctrl); -} - -/* ------------------------------------------------------------------ */ -/* VIDEO CTRL IOCTLS                                                  */ - -static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id) -{ -	unsigned int i; - -	for (i = 0; i < CX25821_CTLS; i++) -		if (cx25821_ctls[i].id == id) -			return cx25821_ctls + i; -	return NULL; -} - -int cx25821_vidioc_g_ctrl(struct file *file, void *priv, -			  struct v4l2_control *ctl) -{ -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	struct cx25821_fh *fh = priv; - -	const struct v4l2_queryctrl *ctrl; - -	ctrl = ctrl_by_id(ctl->id); - -	if (NULL == ctrl) -		return -EINVAL; -	switch (ctl->id) { +	switch (ctrl->id) {  	case V4L2_CID_BRIGHTNESS: -		ctl->value = dev->channels[fh->channel_id].ctl_bright; +		medusa_set_brightness(dev, ctrl->val, chan->id);  		break;  	case V4L2_CID_HUE: -		ctl->value = dev->channels[fh->channel_id].ctl_hue; +		medusa_set_hue(dev, ctrl->val, chan->id);  		break;  	case V4L2_CID_CONTRAST: -		ctl->value = dev->channels[fh->channel_id].ctl_contrast; +		medusa_set_contrast(dev, ctrl->val, chan->id);  		break;  	case V4L2_CID_SATURATION: -		ctl->value = dev->channels[fh->channel_id].ctl_saturation; -		break; -	} -	return 0; -} - -int cx25821_set_control(struct cx25821_dev *dev, -			struct v4l2_control *ctl, int chan_num) -{ -	int err; -	const struct v4l2_queryctrl *ctrl; - -	err = -EINVAL; - -	ctrl = ctrl_by_id(ctl->id); - -	if (NULL == ctrl) -		return err; - -	switch (ctrl->type) { -	case V4L2_CTRL_TYPE_BOOLEAN: -	case V4L2_CTRL_TYPE_MENU: -	case V4L2_CTRL_TYPE_INTEGER: -		if (ctl->value < ctrl->minimum) -			ctl->value = ctrl->minimum; -		if (ctl->value > ctrl->maximum) -			ctl->value = ctrl->maximum; +		medusa_set_saturation(dev, ctrl->val, chan->id);  		break;  	default: -		/* nothing */ ; -	} - -	switch (ctl->id) { -	case V4L2_CID_BRIGHTNESS: -		dev->channels[chan_num].ctl_bright = ctl->value; -		medusa_set_brightness(dev, ctl->value, chan_num); -		break; -	case V4L2_CID_HUE: -		dev->channels[chan_num].ctl_hue = ctl->value; -		medusa_set_hue(dev, ctl->value, chan_num); -		break; -	case V4L2_CID_CONTRAST: -		dev->channels[chan_num].ctl_contrast = ctl->value; -		medusa_set_contrast(dev, ctl->value, chan_num); -		break; -	case V4L2_CID_SATURATION: -		dev->channels[chan_num].ctl_saturation = ctl->value; -		medusa_set_saturation(dev, ctl->value, chan_num); -		break; -	} - -	err = 0; - -	return err; -} - -static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num) -{ -	struct v4l2_control ctrl; -	int i; -	for (i = 0; i < CX25821_CTLS; i++) { -		ctrl.id = cx25821_ctls[i].id; -		ctrl.value = cx25821_ctls[i].default_value; - -		cx25821_set_control(dev, &ctrl, chan_num); -	} -} - -int cx25821_vidioc_cropcap(struct file *file, void *priv, -			   struct v4l2_cropcap *cropcap) -{ -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - -	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)  		return -EINVAL; -	cropcap->bounds.top = 0; -	cropcap->bounds.left = 0; -	cropcap->bounds.width = 720; -	cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480; -	cropcap->pixelaspect.numerator = -		dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10; -	cropcap->pixelaspect.denominator = -		dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11; -	cropcap->defrect = cropcap->bounds; -	return 0; -} - -int cx25821_vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop) -{ -	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; -	struct cx25821_fh *fh = priv; -	int err; - -	if (fh) { -		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, -				      fh->prio); -		if (0 != err) -			return err;  	} -	/* cx25821_vidioc_s_crop not supported */ -	return -EINVAL; -} - -int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) -{ -	/* cx25821_vidioc_g_crop not supported */ -	return -EINVAL; -} - -int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm) -{ -	/* medusa does not support video standard sensing of current input */ -	*norm = CX25821_NORMS; -  	return 0;  } -int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) +static int cx25821_vidioc_enum_output(struct file *file, void *priv, +			      struct v4l2_output *o)  { -	if (tvnorm == V4L2_STD_PAL_BG) { -		if (width == 352 || width == 720) -			return 1; -		else -			return 0; -	} +	if (o->index) +		return -EINVAL; -	if (tvnorm == V4L2_STD_NTSC_M) { -		if (width == 320 || width == 352 || width == 720) -			return 1; -		else -			return 0; -	} +	o->type = V4L2_INPUT_TYPE_CAMERA; +	o->std = CX25821_NORMS; +	strcpy(o->name, "Composite");  	return 0;  } -int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm) +static int cx25821_vidioc_g_output(struct file *file, void *priv, unsigned int *o)  { -	if (tvnorm == V4L2_STD_PAL_BG) { -		if (height == 576 || height == 288) -			return 1; -		else -			return 0; -	} - -	if (tvnorm == V4L2_STD_NTSC_M) { -		if (height == 480 || height == 240) -			return 1; -		else -			return 0; -	} - +	*o = 0;  	return 0;  } -static long video_ioctl_upstream9(struct file *file, unsigned int cmd, -				 unsigned long arg) +static int cx25821_vidioc_s_output(struct file *file, void *priv, unsigned int o)  { -	struct cx25821_fh *fh = file->private_data; -	struct cx25821_dev *dev = fh->dev; -	int command = 0; -	struct upstream_user_struct *data_from_user; - -	data_from_user = (struct upstream_user_struct *)arg; - -	if (!data_from_user) { -		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); -		return 0; -	} - -	command = data_from_user->command; - -	if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) -		return 0; - -	dev->input_filename = data_from_user->input_filename; -	dev->input_audiofilename = data_from_user->input_filename; -	dev->vid_stdname = data_from_user->vid_stdname; -	dev->pixel_format = data_from_user->pixel_format; -	dev->channel_select = data_from_user->channel_select; -	dev->command = data_from_user->command; - -	switch (command) { -	case UPSTREAM_START_VIDEO: -		cx25821_start_upstream_video_ch1(dev, data_from_user); -		break; - -	case UPSTREAM_STOP_VIDEO: -		cx25821_stop_upstream_video_ch1(dev); -		break; -	} - -	return 0; +	return o ? -EINVAL : 0;  } -static long video_ioctl_upstream10(struct file *file, unsigned int cmd, -				  unsigned long arg) +static int cx25821_vidioc_try_fmt_vid_out(struct file *file, void *priv, +				   struct v4l2_format *f)  { -	struct cx25821_fh *fh = file->private_data; -	struct cx25821_dev *dev = fh->dev; -	int command = 0; -	struct upstream_user_struct *data_from_user; - -	data_from_user = (struct upstream_user_struct *)arg; - -	if (!data_from_user) { -		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); -		return 0; -	} - -	command = data_from_user->command; - -	if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) -		return 0; - -	dev->input_filename_ch2 = data_from_user->input_filename; -	dev->input_audiofilename = data_from_user->input_filename; -	dev->vid_stdname_ch2 = data_from_user->vid_stdname; -	dev->pixel_format_ch2 = data_from_user->pixel_format; -	dev->channel_select_ch2 = data_from_user->channel_select; -	dev->command_ch2 = data_from_user->command; - -	switch (command) { -	case UPSTREAM_START_VIDEO: -		cx25821_start_upstream_video_ch2(dev, data_from_user); -		break; - -	case UPSTREAM_STOP_VIDEO: -		cx25821_stop_upstream_video_ch2(dev); -		break; -	} +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev; +	const struct cx25821_fmt *fmt; +	fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); +	if (NULL == fmt) +		return -EINVAL; +	f->fmt.pix.width = 720; +	f->fmt.pix.height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480; +	f->fmt.pix.field = V4L2_FIELD_INTERLACED; +	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; +	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; +	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; +	f->fmt.pix.priv = 0;  	return 0;  } -static long video_ioctl_upstream11(struct file *file, unsigned int cmd, -				  unsigned long arg) +static int vidioc_s_fmt_vid_out(struct file *file, void *priv, +				struct v4l2_format *f)  { -	struct cx25821_fh *fh = file->private_data; -	struct cx25821_dev *dev = fh->dev; -	int command = 0; -	struct upstream_user_struct *data_from_user; - -	data_from_user = (struct upstream_user_struct *)arg; - -	if (!data_from_user) { -		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); -		return 0; -	} - -	command = data_from_user->command; - -	if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) -		return 0; - -	dev->input_filename = data_from_user->input_filename; -	dev->input_audiofilename = data_from_user->input_filename; -	dev->vid_stdname = data_from_user->vid_stdname; -	dev->pixel_format = data_from_user->pixel_format; -	dev->channel_select = data_from_user->channel_select; -	dev->command = data_from_user->command; +	struct cx25821_channel *chan = video_drvdata(file); +	int err; -	switch (command) { -	case UPSTREAM_START_AUDIO: -		cx25821_start_upstream_audio(dev, data_from_user); -		break; +	err = cx25821_vidioc_try_fmt_vid_out(file, priv, f); -	case UPSTREAM_STOP_AUDIO: -		cx25821_stop_upstream_audio(dev); -		break; -	} +	if (0 != err) +		return err; +	chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); +	chan->vidq.field = f->fmt.pix.field; +	chan->width = f->fmt.pix.width; +	chan->height = f->fmt.pix.height; +	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P) +		chan->pixel_formats = PIXEL_FRMT_411; +	else +		chan->pixel_formats = PIXEL_FRMT_422;  	return 0;  } -static long video_ioctl_set(struct file *file, unsigned int cmd, -			   unsigned long arg) +static ssize_t video_write(struct file *file, const char __user *data, size_t count, +			 loff_t *ppos)  { -	struct cx25821_fh *fh = file->private_data; -	struct cx25821_dev *dev = fh->dev; -	struct downstream_user_struct *data_from_user; -	int command; -	int width = 720; -	int selected_channel = 0; -	int pix_format = 0; -	int i = 0; -	int cif_enable = 0; -	int cif_width = 0; - -	data_from_user = (struct downstream_user_struct *)arg; +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev; +	struct v4l2_fh *fh = file->private_data; +	int err = 0; -	if (!data_from_user) { -		pr_err("%s(): User data is INVALID. Returning\n", __func__); -		return 0; +	if (mutex_lock_interruptible(&dev->lock)) +		return -ERESTARTSYS; +	if (chan->streaming_fh && chan->streaming_fh != fh) { +		err = -EBUSY; +		goto unlock;  	} - -	command = data_from_user->command; - -	if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT -	   && command != ENABLE_CIF_RESOLUTION && command != REG_READ -	   && command != REG_WRITE && command != MEDUSA_READ -	   && command != MEDUSA_WRITE) { -		return 0; +	if (!chan->streaming_fh) { +		err = cx25821_vidupstream_init(chan, chan->pixel_formats); +		if (err) +			goto unlock; +		chan->streaming_fh = fh;  	} -	switch (command) { -	case SET_VIDEO_STD: -		if (!strcmp(data_from_user->vid_stdname, "PAL")) -			dev->tvnorm = V4L2_STD_PAL_BG; -		else -			dev->tvnorm = V4L2_STD_NTSC_M; -		medusa_set_videostandard(dev); -		break; - -	case SET_PIXEL_FORMAT: -		selected_channel = data_from_user->decoder_select; -		pix_format = data_from_user->pixel_format; - -		if (!(selected_channel <= 7 && selected_channel >= 0)) { -			selected_channel -= 4; -			selected_channel = selected_channel % 8; -		} - -		if (selected_channel >= 0) -			cx25821_set_pixel_format(dev, selected_channel, -						pix_format); - -		break; - -	case ENABLE_CIF_RESOLUTION: -		selected_channel = data_from_user->decoder_select; -		cif_enable = data_from_user->cif_resolution_enable; -		cif_width = data_from_user->cif_width; - -		if (cif_enable) { -			if (dev->tvnorm & V4L2_STD_PAL_BG -			    || dev->tvnorm & V4L2_STD_PAL_DK) { -				width = 352; -			} else { -				width = cif_width; -				if (cif_width != 320 && cif_width != 352) -					width = 320; -			} -		} - -		if (!(selected_channel <= 7 && selected_channel >= 0)) { -			selected_channel -= 4; -			selected_channel = selected_channel % 8; -		} - -		if (selected_channel <= 7 && selected_channel >= 0) { -			dev->channels[selected_channel].use_cif_resolution = -				cif_enable; -			dev->channels[selected_channel].cif_width = width; -		} else { -			for (i = 0; i < VID_CHANNEL_NUM; i++) { -				dev->channels[i].use_cif_resolution = -					cif_enable; -				dev->channels[i].cif_width = width; -			} -		} - -		medusa_set_resolution(dev, width, selected_channel); -		break; -	case REG_READ: -		data_from_user->reg_data = cx_read(data_from_user->reg_address); -		break; -	case REG_WRITE: -		cx_write(data_from_user->reg_address, data_from_user->reg_data); -		break; -	case MEDUSA_READ: -		cx25821_i2c_read(&dev->i2c_bus[0], -					 (u16) data_from_user->reg_address, -					 &data_from_user->reg_data); -		break; -	case MEDUSA_WRITE: -		cx25821_i2c_write(&dev->i2c_bus[0], -				  (u16) data_from_user->reg_address, -				  data_from_user->reg_data); -		break; -	} +	err = cx25821_write_frame(chan, data, count); +	count -= err; +	*ppos += err; -	return 0; +unlock: +	mutex_unlock(&dev->lock); +	return err;  } -static long cx25821_video_ioctl(struct file *file, -				unsigned int cmd, unsigned long arg) +static int video_out_release(struct file *file)  { -	int ret = 0; - -	struct cx25821_fh *fh = file->private_data; +	struct cx25821_channel *chan = video_drvdata(file); +	struct cx25821_dev *dev = chan->dev; +	struct v4l2_fh *fh = file->private_data; -	/* check to see if it's the video upstream */ -	if (fh->channel_id == SRAM_CH09) { -		ret = video_ioctl_upstream9(file, cmd, arg); -		return ret; -	} else if (fh->channel_id == SRAM_CH10) { -		ret = video_ioctl_upstream10(file, cmd, arg); -		return ret; -	} else if (fh->channel_id == SRAM_CH11) { -		ret = video_ioctl_upstream11(file, cmd, arg); -		ret = video_ioctl_set(file, cmd, arg); -		return ret; +	mutex_lock(&dev->lock); +	if (chan->streaming_fh == fh) { +		cx25821_stop_upstream_video(chan); +		chan->streaming_fh = NULL;  	} +	mutex_unlock(&dev->lock); -	return video_ioctl2(file, cmd, arg); +	return v4l2_fh_release(file);  } -/* exported stuff */ +static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { +	.s_ctrl = cx25821_s_ctrl, +}; +  static const struct v4l2_file_operations video_fops = {  	.owner = THIS_MODULE, -	.open = video_open, +	.open = v4l2_fh_open,  	.release = video_release,  	.read = video_read,  	.poll = video_poll,  	.mmap = cx25821_video_mmap, -	.ioctl = cx25821_video_ioctl, +	.unlocked_ioctl = video_ioctl2,  };  static const struct v4l2_ioctl_ops video_ioctl_ops = { @@ -1951,40 +963,170 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {  	.vidioc_querybuf = cx25821_vidioc_querybuf,  	.vidioc_qbuf = cx25821_vidioc_qbuf,  	.vidioc_dqbuf = vidioc_dqbuf, -#ifdef TUNER_FLAG +	.vidioc_g_std = cx25821_vidioc_g_std,  	.vidioc_s_std = cx25821_vidioc_s_std, -	.vidioc_querystd = cx25821_vidioc_querystd, -#endif -	.vidioc_cropcap = cx25821_vidioc_cropcap, -	.vidioc_s_crop = cx25821_vidioc_s_crop, -	.vidioc_g_crop = cx25821_vidioc_g_crop,  	.vidioc_enum_input = cx25821_vidioc_enum_input,  	.vidioc_g_input = cx25821_vidioc_g_input,  	.vidioc_s_input = cx25821_vidioc_s_input, -	.vidioc_g_ctrl = cx25821_vidioc_g_ctrl, -	.vidioc_s_ctrl = vidioc_s_ctrl, -	.vidioc_queryctrl = cx25821_vidioc_queryctrl,  	.vidioc_streamon = vidioc_streamon,  	.vidioc_streamoff = vidioc_streamoff,  	.vidioc_log_status = vidioc_log_status, -	.vidioc_g_priority = cx25821_vidioc_g_priority, -	.vidioc_s_priority = cx25821_vidioc_s_priority, -#ifdef TUNER_FLAG -	.vidioc_g_tuner = cx25821_vidioc_g_tuner, -	.vidioc_s_tuner = cx25821_vidioc_s_tuner, -	.vidioc_g_frequency = cx25821_vidioc_g_frequency, -	.vidioc_s_frequency = cx25821_vidioc_s_frequency, -#endif -#ifdef CONFIG_VIDEO_ADV_DEBUG -	.vidioc_g_register = cx25821_vidioc_g_register, -	.vidioc_s_register = cx25821_vidioc_s_register, -#endif +	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event, +	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,  }; -struct video_device cx25821_videoioctl_template = { -	.name = "cx25821-videoioctl", +static const struct video_device cx25821_video_device = { +	.name = "cx25821-video",  	.fops = &video_fops, +	.release = video_device_release_empty, +	.minor = -1,  	.ioctl_ops = &video_ioctl_ops,  	.tvnorms = CX25821_NORMS, -	.current_norm = V4L2_STD_NTSC_M,  }; + +static const struct v4l2_file_operations video_out_fops = { +	.owner = THIS_MODULE, +	.open = v4l2_fh_open, +	.write = video_write, +	.release = video_out_release, +	.unlocked_ioctl = video_ioctl2, +}; + +static const struct v4l2_ioctl_ops video_out_ioctl_ops = { +	.vidioc_querycap = cx25821_vidioc_querycap, +	.vidioc_enum_fmt_vid_out = cx25821_vidioc_enum_fmt_vid_cap, +	.vidioc_g_fmt_vid_out = cx25821_vidioc_g_fmt_vid_cap, +	.vidioc_try_fmt_vid_out = cx25821_vidioc_try_fmt_vid_out, +	.vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, +	.vidioc_g_std = cx25821_vidioc_g_std, +	.vidioc_s_std = cx25821_vidioc_s_std, +	.vidioc_enum_output = cx25821_vidioc_enum_output, +	.vidioc_g_output = cx25821_vidioc_g_output, +	.vidioc_s_output = cx25821_vidioc_s_output, +	.vidioc_log_status = vidioc_log_status, +}; + +static const struct video_device cx25821_video_out_device = { +	.name = "cx25821-video", +	.fops = &video_out_fops, +	.release = video_device_release_empty, +	.minor = -1, +	.ioctl_ops = &video_out_ioctl_ops, +	.tvnorms = CX25821_NORMS, +}; + +void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) +{ +	cx_clear(PCI_INT_MSK, 1); + +	if (video_is_registered(&dev->channels[chan_num].vdev)) { +		video_unregister_device(&dev->channels[chan_num].vdev); +		v4l2_ctrl_handler_free(&dev->channels[chan_num].hdl); + +		btcx_riscmem_free(dev->pci, +				&dev->channels[chan_num].dma_vidq.stopper); +	} +} + +int cx25821_video_register(struct cx25821_dev *dev) +{ +	int err; +	int i; + +	/* initial device configuration */ +	dev->tvnorm = V4L2_STD_NTSC_M; + +	spin_lock_init(&dev->slock); + +	for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) { +		struct cx25821_channel *chan = &dev->channels[i]; +		struct video_device *vdev = &chan->vdev; +		struct v4l2_ctrl_handler *hdl = &chan->hdl; +		bool is_output = i > SRAM_CH08; + +		if (i == SRAM_CH08) /* audio channel */ +			continue; + +		if (!is_output) { +			v4l2_ctrl_handler_init(hdl, 4); +			v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, +					V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200); +			v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, +					V4L2_CID_CONTRAST, 0, 10000, 1, 5000); +			v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, +					V4L2_CID_SATURATION, 0, 10000, 1, 5000); +			v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, +					V4L2_CID_HUE, 0, 10000, 1, 5000); +			if (hdl->error) { +				err = hdl->error; +				goto fail_unreg; +			} +			err = v4l2_ctrl_handler_setup(hdl); +			if (err) +				goto fail_unreg; +		} else { +			chan->out = &dev->vid_out_data[i - SRAM_CH09]; +			chan->out->chan = chan; +		} + +		cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper, +			chan->sram_channels->dma_ctl, 0x11, 0); + +		chan->sram_channels = &cx25821_sram_channels[i]; +		chan->width = 720; +		if (dev->tvnorm & V4L2_STD_625_50) +			chan->height = 576; +		else +			chan->height = 480; + +		if (chan->pixel_formats == PIXEL_FRMT_411) +			chan->fmt = cx25821_format_by_fourcc(V4L2_PIX_FMT_Y41P); +		else +			chan->fmt = cx25821_format_by_fourcc(V4L2_PIX_FMT_YUYV); + +		cx_write(chan->sram_channels->int_stat, 0xffffffff); + +		INIT_LIST_HEAD(&chan->dma_vidq.active); +		INIT_LIST_HEAD(&chan->dma_vidq.queued); + +		chan->timeout_data.dev = dev; +		chan->timeout_data.channel = &cx25821_sram_channels[i]; +		chan->dma_vidq.timeout.function = cx25821_vid_timeout; +		chan->dma_vidq.timeout.data = (unsigned long)&chan->timeout_data; +		init_timer(&chan->dma_vidq.timeout); + +		if (!is_output) +			videobuf_queue_sg_init(&chan->vidq, &cx25821_video_qops, &dev->pci->dev, +				&dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, +				V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), +				chan, &dev->lock); + +		/* register v4l devices */ +		*vdev = is_output ? cx25821_video_out_device : cx25821_video_device; +		vdev->v4l2_dev = &dev->v4l2_dev; +		if (!is_output) +			vdev->ctrl_handler = hdl; +		else +			vdev->vfl_dir = VFL_DIR_TX; +		vdev->lock = &dev->lock; +		set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); +		snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); +		video_set_drvdata(vdev, chan); + +		err = video_register_device(vdev, VFL_TYPE_GRABBER, +					    video_nr[dev->nr]); + +		if (err < 0) +			goto fail_unreg; +	} + +	/* set PCI interrupt */ +	cx_set(PCI_INT_MSK, 0xff); + +	return 0; + +fail_unreg: +	while (i >= 0) +		cx25821_video_unregister(dev, i--); +	return err; +} diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index c265e35b37c..ab63b3858ac 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -39,8 +39,7 @@  #include "cx25821.h"  #include <media/v4l2-common.h>  #include <media/v4l2-ioctl.h> - -#define TUNER_FLAG +#include <media/v4l2-event.h>  #define VIDEO_DEBUG 0 @@ -50,137 +49,17 @@ do {									\  		printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg);	\  } while (0) -/* For IOCTL to identify running upstream */ -#define UPSTREAM_START_VIDEO        700 -#define UPSTREAM_STOP_VIDEO         701 -#define UPSTREAM_START_AUDIO        702 -#define UPSTREAM_STOP_AUDIO         703 -#define UPSTREAM_DUMP_REGISTERS     702 -#define SET_VIDEO_STD               800 -#define SET_PIXEL_FORMAT            1000 -#define ENABLE_CIF_RESOLUTION       1001 - -#define REG_READ		    900 -#define REG_WRITE		    901 -#define MEDUSA_READ		    910 -#define MEDUSA_WRITE		    911 - -extern struct sram_channel *channel0; -extern struct sram_channel *channel1; -extern struct sram_channel *channel2; -extern struct sram_channel *channel3; -extern struct sram_channel *channel4; -extern struct sram_channel *channel5; -extern struct sram_channel *channel6; -extern struct sram_channel *channel7; -extern struct sram_channel *channel9; -extern struct sram_channel *channel10; -extern struct sram_channel *channel11; -extern struct video_device cx25821_videoioctl_template; -/* extern const u32 *ctrl_classes[]; */ - -extern unsigned int vid_limit; -  #define FORMAT_FLAGS_PACKED       0x01 -extern struct cx25821_fmt formats[]; -extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc); -extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; -  extern void cx25821_video_wakeup(struct cx25821_dev *dev,  				 struct cx25821_dmaqueue *q, u32 count); -#ifdef TUNER_FLAG -extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm); -#endif - -extern int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, -			   unsigned int bit); -extern int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit); -extern int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit); -extern void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, -			     unsigned int bits); -extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);  extern int cx25821_start_video_dma(struct cx25821_dev *dev,  				   struct cx25821_dmaqueue *q,  				   struct cx25821_buffer *buf, -				   struct sram_channel *channel); +				   const struct sram_channel *channel); -extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width, -			     unsigned int height, enum v4l2_field field);  extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);  extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);  extern int cx25821_video_register(struct cx25821_dev *dev); -extern int cx25821_get_format_size(void); - -extern int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, -				unsigned int *size); -extern int cx25821_buffer_prepare(struct videobuf_queue *q, -				  struct videobuf_buffer *vb, -				  enum v4l2_field field); -extern void cx25821_buffer_release(struct videobuf_queue *q, -				   struct videobuf_buffer *vb); -extern struct videobuf_queue *get_queue(struct cx25821_fh *fh); -extern int cx25821_get_resource(struct cx25821_fh *fh, int resource); -extern int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma); -extern int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, -					  struct v4l2_format *f); -extern int cx25821_vidioc_querycap(struct file *file, void *priv, -				   struct v4l2_capability *cap); -extern int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, -					   struct v4l2_fmtdesc *f); -extern int cx25821_vidioc_reqbufs(struct file *file, void *priv, -				  struct v4l2_requestbuffers *p); -extern int cx25821_vidioc_querybuf(struct file *file, void *priv, -				   struct v4l2_buffer *p); -extern int cx25821_vidioc_qbuf(struct file *file, void *priv, -			       struct v4l2_buffer *p); -extern int cx25821_vidioc_s_std(struct file *file, void *priv, -				v4l2_std_id *tvnorms); -extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i); -extern int cx25821_vidioc_enum_input(struct file *file, void *priv, -				     struct v4l2_input *i); -extern int cx25821_vidioc_g_input(struct file *file, void *priv, -				  unsigned int *i); -extern int cx25821_vidioc_s_input(struct file *file, void *priv, -				  unsigned int i); -extern int cx25821_vidioc_g_ctrl(struct file *file, void *priv, -				 struct v4l2_control *ctl); -extern int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, -					struct v4l2_format *f); -extern int cx25821_vidioc_g_frequency(struct file *file, void *priv, -				      struct v4l2_frequency *f); -extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f); -extern int cx25821_vidioc_s_frequency(struct file *file, void *priv, -				      struct v4l2_frequency *f); -extern int cx25821_vidioc_g_register(struct file *file, void *fh, -				     struct v4l2_dbg_register *reg); -extern int cx25821_vidioc_s_register(struct file *file, void *fh, -				     struct v4l2_dbg_register *reg); -extern int cx25821_vidioc_g_tuner(struct file *file, void *priv, -				  struct v4l2_tuner *t); -extern int cx25821_vidioc_s_tuner(struct file *file, void *priv, -				  struct v4l2_tuner *t); - -extern int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm); -extern int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm); - -extern int cx25821_vidioc_g_priority(struct file *file, void *f, -				     enum v4l2_priority *p); -extern int cx25821_vidioc_s_priority(struct file *file, void *f, -				     enum v4l2_priority prio); - -extern int cx25821_vidioc_queryctrl(struct file *file, void *priv, -				    struct v4l2_queryctrl *qctrl); -extern int cx25821_set_control(struct cx25821_dev *dev, -			       struct v4l2_control *ctrl, int chan_num); - -extern int cx25821_vidioc_cropcap(struct file *file, void *fh, -				  struct v4l2_cropcap *cropcap); -extern int cx25821_vidioc_s_crop(struct file *file, void *priv, -				 const struct v4l2_crop *crop); -extern int cx25821_vidioc_g_crop(struct file *file, void *priv, -				 struct v4l2_crop *crop); -extern int cx25821_vidioc_querystd(struct file *file, void *priv, -				   v4l2_std_id *norm);  #endif diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 8a9c0c86941..90bdc196929 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -33,17 +33,14 @@  #include <media/v4l2-common.h>  #include <media/v4l2-device.h> -#include <media/tuner.h> -#include <media/tveeprom.h> +#include <media/v4l2-ctrls.h>  #include <media/videobuf-dma-sg.h> -#include <media/videobuf-dvb.h>  #include "btcx-risc.h"  #include "cx25821-reg.h"  #include "cx25821-medusa-reg.h"  #include "cx25821-sram.h"  #include "cx25821-audio.h" -#include "media/cx2341x.h"  #include <linux/version.h>  #include <linux/mutex.h> @@ -55,8 +52,6 @@  #define CX25821_MAXBOARDS 2 -#define TRUE    1 -#define FALSE   0  #define LINE_SIZE_D1    1440  /* Number of decoders and encoders */ @@ -67,7 +62,6 @@  /* Max number of inputs by card */  #define MAX_CX25821_INPUT     8 -#define INPUT(nr) (&cx25821_boards[dev->board].input[nr])  #define RESOURCE_VIDEO0       1  #define RESOURCE_VIDEO1       2  #define RESOURCE_VIDEO2       4 @@ -80,7 +74,6 @@  #define RESOURCE_VIDEO9       512  #define RESOURCE_VIDEO10      1024  #define RESOURCE_VIDEO11      2048 -#define RESOURCE_VIDEO_IOCTL  4096  #define BUFFER_TIMEOUT     (HZ)	/* 0.5 seconds */ @@ -97,7 +90,6 @@  #define CX25821_BOARD_CONEXANT_ATHENA10 1  #define MAX_VID_CHANNEL_NUM     12  #define VID_CHANNEL_NUM 8 -#define CX25821_NR_INPUT 2  struct cx25821_fmt {  	char *name; @@ -107,14 +99,6 @@ struct cx25821_fmt {  	u32 cxformat;  }; -struct cx25821_ctrl { -	struct v4l2_queryctrl v; -	u32 off; -	u32 reg; -	u32 mask; -	u32 shift; -}; -  struct cx25821_tvnorm {  	char *name;  	v4l2_std_id id; @@ -122,40 +106,6 @@ struct cx25821_tvnorm {  	u32 cxoformat;  }; -struct cx25821_fh { -	struct cx25821_dev *dev; -	enum v4l2_buf_type type; -	int radio; -	u32 resources; - -	enum v4l2_priority prio; - -	/* video overlay */ -	struct v4l2_window win; -	struct v4l2_clip *clips; -	unsigned int nclips; - -	/* video capture */ -	struct cx25821_fmt *fmt; -	unsigned int width, height; -	int channel_id; - -	/* vbi capture */ -	struct videobuf_queue vidq; -	struct videobuf_queue vbiq; - -	/* H264 Encoder specifics ONLY */ -	struct videobuf_queue mpegq; -	atomic_t v4l_reading; -}; - -enum cx25821_itype { -	CX25821_VMUX_COMPOSITE = 1, -	CX25821_VMUX_SVIDEO, -	CX25821_VMUX_DEBUG, -	CX25821_RADIO, -}; -  enum cx25821_src_sel_type {  	CX25821_SRC_SEL_EXT_656_VIDEO = 0,  	CX25821_SRC_SEL_PARALLEL_MPEG_VIDEO @@ -169,16 +119,10 @@ struct cx25821_buffer {  	/* cx25821 specific */  	unsigned int bpl;  	struct btcx_riscmem risc; -	struct cx25821_fmt *fmt; +	const struct cx25821_fmt *fmt;  	u32 count;  }; -struct cx25821_input { -	enum cx25821_itype type; -	unsigned int vmux; -	u32 gpio0, gpio1, gpio2, gpio3; -}; -  enum port {  	CX25821_UNDEFINED = 0,  	CX25821_RAW, @@ -190,19 +134,8 @@ struct cx25821_board {  	enum port porta;  	enum port portb;  	enum port portc; -	unsigned int tuner_type; -	unsigned int radio_type; -	unsigned char tuner_addr; -	unsigned char radio_addr;  	u32 clk_freq; -	struct cx25821_input input[CX25821_NR_INPUT]; -}; - -struct cx25821_subid { -	u16 subvendor; -	u16 subdevice; -	u32 card;  };  struct cx25821_i2c { @@ -234,34 +167,70 @@ struct cx25821_dmaqueue {  struct cx25821_data {  	struct cx25821_dev *dev; -	struct sram_channel *channel; +	const struct sram_channel *channel; +}; + +struct cx25821_dev; + +struct cx25821_channel; + +struct cx25821_video_out_data { +	struct cx25821_channel *chan; +	int _line_size; +	int _prog_cnt; +	int _pixel_format; +	int _is_first_frame; +	int _is_running; +	int _file_status; +	int _lines_count; +	int _frame_count; +	unsigned int _risc_size; + +	__le32 *_dma_virt_start_addr; +	__le32 *_dma_virt_addr; +	dma_addr_t _dma_phys_addr; +	dma_addr_t _dma_phys_start_addr; + +	unsigned int _data_buf_size; +	__le32 *_data_buf_virt_addr; +	dma_addr_t _data_buf_phys_addr; + +	u32 upstream_riscbuf_size; +	u32 upstream_databuf_size; +	int is_60hz; +	int _frame_index; +	int cur_frame_index; +	int curpos; +	wait_queue_head_t waitq;  };  struct cx25821_channel { -	struct v4l2_prio_state prio; +	unsigned id; +	struct cx25821_dev *dev; +	struct v4l2_fh *streaming_fh; -	int ctl_bright; -	int ctl_contrast; -	int ctl_hue; -	int ctl_saturation; +	struct v4l2_ctrl_handler hdl;  	struct cx25821_data timeout_data; -	struct video_device *video_dev; -	struct cx25821_dmaqueue vidq; +	struct video_device vdev; +	struct cx25821_dmaqueue dma_vidq; +	struct videobuf_queue vidq; -	struct sram_channel *sram_channels; - -	struct mutex lock; -	int resources; +	const struct sram_channel *sram_channels; +	const struct cx25821_fmt *fmt; +	unsigned int width, height;  	int pixel_formats;  	int use_cif_resolution;  	int cif_width; + +	/* video output data for the video output channel */ +	struct cx25821_video_out_data *out;  }; +struct snd_card; +  struct cx25821_dev { -	struct list_head devlist; -	atomic_t refcount;  	struct v4l2_device v4l2_dev;  	/* pci stuff */ @@ -273,6 +242,8 @@ struct cx25821_dev {  	u8 __iomem *bmmio;  	int pci_irqmask;  	int hwrevision; +	/* used by cx25821-alsa */ +	struct snd_card *card;  	u32 clk_freq; @@ -289,17 +260,8 @@ struct cx25821_dev {  	char name[32];  	/* Analog video */ -	u32 resources;  	unsigned int input; -	u32 tvaudio;  	v4l2_std_id tvnorm; -	unsigned int tuner_type; -	unsigned char tuner_addr; -	unsigned int radio_type; -	unsigned char radio_addr; -	unsigned int has_radio; -	unsigned int videc_type; -	unsigned char videc_addr;  	unsigned short _max_num_decoders;  	/* Analog Audio Upstream */ @@ -323,132 +285,26 @@ struct cx25821_dev {  	__le32 *_audiodata_buf_virt_addr;  	dma_addr_t _audiodata_buf_phys_addr;  	char *_audiofilename; - -	/* V4l */ -	u32 freq; -	struct video_device *vbi_dev; -	struct video_device *radio_dev; -	struct video_device *ioctl_dev; - -	spinlock_t slock; - -	/* Video Upstream */ -	int _line_size; -	int _prog_cnt; -	int _pixel_format; -	int _is_first_frame; -	int _is_running; -	int _file_status; -	int _lines_count; -	int _frame_count; -	int _channel_upstream_select; -	unsigned int _risc_size; - -	__le32 *_dma_virt_start_addr; -	__le32 *_dma_virt_addr; -	dma_addr_t _dma_phys_addr; -	dma_addr_t _dma_phys_start_addr; - -	unsigned int _data_buf_size; -	__le32 *_data_buf_virt_addr; -	dma_addr_t _data_buf_phys_addr; -	char *_filename; -	char *_defaultname; - -	int _line_size_ch2; -	int _prog_cnt_ch2; -	int _pixel_format_ch2; -	int _is_first_frame_ch2; -	int _is_running_ch2; -	int _file_status_ch2; -	int _lines_count_ch2; -	int _frame_count_ch2; -	int _channel2_upstream_select; -	unsigned int _risc_size_ch2; - -	__le32 *_dma_virt_start_addr_ch2; -	__le32 *_dma_virt_addr_ch2; -	dma_addr_t _dma_phys_addr_ch2; -	dma_addr_t _dma_phys_start_addr_ch2; - -	unsigned int _data_buf_size_ch2; -	__le32 *_data_buf_virt_addr_ch2; -	dma_addr_t _data_buf_phys_addr_ch2; -	char *_filename_ch2; -	char *_defaultname_ch2; - -	/* MPEG Encoder ONLY settings */ -	u32 cx23417_mailbox; -	struct cx2341x_mpeg_params mpeg_params; -	struct video_device *v4l_device; -	atomic_t v4l_reader_count; -	struct cx25821_tvnorm encodernorm; - -	u32 upstream_riscbuf_size; -	u32 upstream_databuf_size; -	u32 upstream_riscbuf_size_ch2; -	u32 upstream_databuf_size_ch2;  	u32 audio_upstream_riscbuf_size;  	u32 audio_upstream_databuf_size; -	int _isNTSC; -	int _frame_index;  	int _audioframe_index; -	struct workqueue_struct *_irq_queues; -	struct work_struct _irq_work_entry; -	struct workqueue_struct *_irq_queues_ch2; -	struct work_struct _irq_work_entry_ch2;  	struct workqueue_struct *_irq_audio_queues;  	struct work_struct _audio_work_entry; -	char *input_filename; -	char *input_filename_ch2; -	int _frame_index_ch2; -	int _isNTSC_ch2; -	char *vid_stdname_ch2; -	int pixel_format_ch2; -	int channel_select_ch2; -	int command_ch2;  	char *input_audiofilename; -	char *vid_stdname; -	int pixel_format; -	int channel_select; -	int command; -	int channel_opened; -}; -struct upstream_user_struct { -	char *input_filename; -	char *vid_stdname; -	int pixel_format; -	int channel_select; -	int command; -}; +	/* V4l */ +	spinlock_t slock; -struct downstream_user_struct { -	char *vid_stdname; -	int pixel_format; -	int cif_resolution_enable; -	int cif_width; -	int decoder_select; -	int command; -	int reg_address; -	int reg_data; +	/* Video Upstream */ +	struct cx25821_video_out_data vid_out_data[2];  }; -extern struct upstream_user_struct *up_data; -  static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)  {  	return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev);  } -#define cx25821_call_all(dev, o, f, args...) \ -	v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) - -extern struct list_head cx25821_devlist; -extern struct mutex cx25821_devlist_mutex; -  extern struct cx25821_board cx25821_boards[]; -extern struct cx25821_subid cx25821_subids[];  #define SRAM_CH00  0		/* Video A */  #define SRAM_CH01  1		/* Video B */ @@ -467,7 +323,6 @@ extern struct cx25821_subid cx25821_subids[];  #define VID_UPSTREAM_SRAM_CHANNEL_I     SRAM_CH09  #define VID_UPSTREAM_SRAM_CHANNEL_J     SRAM_CH10  #define AUDIO_UPSTREAM_SRAM_CHANNEL_B   SRAM_CH11 -#define VIDEO_IOCTL_CH  11  struct sram_channel {  	char *name; @@ -503,10 +358,8 @@ struct sram_channel {  	u32 jumponly;  	u32 irq_bit;  }; -extern struct sram_channel cx25821_sram_channels[]; -#define STATUS_SUCCESS         0 -#define STATUS_UNSUCCESSFUL    -1 +extern const struct sram_channel cx25821_sram_channels[];  #define cx_read(reg)             readl(dev->lmmio + ((reg)>>2))  #define cx_write(reg, value)     writel((value), dev->lmmio + ((reg)>>2)) @@ -529,8 +382,6 @@ extern struct sram_channel cx25821_sram_channels[];  	pr_info("(%d): " fmt, dev->board, ##args)  extern int cx25821_i2c_register(struct cx25821_i2c *bus); -extern void cx25821_card_setup(struct cx25821_dev *dev); -extern int cx25821_ir_init(struct cx25821_dev *dev);  extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value);  extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value);  extern int cx25821_i2c_unregister(struct cx25821_i2c *bus); @@ -551,7 +402,7 @@ extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation,  				 int decoder);  extern int cx25821_sram_channel_setup(struct cx25821_dev *dev, -				      struct sram_channel *ch, unsigned int bpl, +				      const struct sram_channel *ch, unsigned int bpl,  				      u32 risc);  extern int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, @@ -570,46 +421,31 @@ extern void cx25821_free_buffer(struct videobuf_queue *q,  extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,  				u32 reg, u32 mask, u32 value);  extern void cx25821_sram_channel_dump(struct cx25821_dev *dev, -				      struct sram_channel *ch); +				      const struct sram_channel *ch);  extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, -					    struct sram_channel *ch); +					    const struct sram_channel *ch);  extern struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci);  extern void cx25821_print_irqbits(char *name, char *tag, char **strings,  				  int len, u32 bits, u32 mask);  extern void cx25821_dev_unregister(struct cx25821_dev *dev);  extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, -					    struct sram_channel *ch, +					    const struct sram_channel *ch,  					    unsigned int bpl, u32 risc); -extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, -					int channel_select, int pixel_format); -extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, -					int channel_select, int pixel_format); +extern int cx25821_vidupstream_init(struct cx25821_channel *chan, int pixel_format);  extern int cx25821_audio_upstream_init(struct cx25821_dev *dev,  				       int channel_select); -extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev); -extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev); +extern int cx25821_write_frame(struct cx25821_channel *chan, +		const char __user *data, size_t count); +extern void cx25821_free_mem_upstream(struct cx25821_channel *chan);  extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); -extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, -					     struct upstream_user_struct -					     *up_data); -extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, -					     struct upstream_user_struct -					     *up_data); -extern void cx25821_start_upstream_audio(struct cx25821_dev *dev, -					 struct upstream_user_struct *up_data); -extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); -extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); +extern void cx25821_stop_upstream_video(struct cx25821_channel *chan);  extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev);  extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, -					       struct sram_channel *ch, +					       const struct sram_channel *ch,  					       unsigned int bpl, u32 risc);  extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel,  				     u32 format); -extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev); -extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, -					      struct pci_dev *pci, -					      struct video_device *template, -					      char *type); +  #endif diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index a6ff8a6f4fc..150bb76e783 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -815,7 +815,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)  }  static int vidioc_s_frequency (struct file *file, void *priv, -				struct v4l2_frequency *f) +				const struct v4l2_frequency *f)  {  	struct cx8802_fh  *fh   = priv;  	struct cx8802_dev *dev  = fh->dev; @@ -918,7 +918,7 @@ static int vidioc_g_tuner (struct file *file, void *priv,  }  static int vidioc_s_tuner (struct file *file, void *priv, -				struct v4l2_tuner *t) +				const struct v4l2_tuner *t)  {  	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core; @@ -939,12 +939,12 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)  	return 0;  } -static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)  {  	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;  	mutex_lock(&core->lock); -	cx88_set_tvnorm(core,*id); +	cx88_set_tvnorm(core, id);  	mutex_unlock(&core->lock);  	return 0;  } diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index e2e0b8faf7a..a87a0e19593 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c @@ -59,6 +59,11 @@ MODULE_PARM_DESC(disable_ir, "Disable IR support");  #define err_printk(core, fmt, arg...) \  	printk(KERN_ERR "%s: " fmt, core->name , ## arg) +#define dprintk(level,fmt, arg...)	do {				\ +	if (cx88_core_debug >= level)					\ +		printk(KERN_DEBUG "%s: " fmt, core->name , ## arg);	\ +	} while(0) +  /* ------------------------------------------------------------------ */  /* board config info                                                  */ @@ -2855,6 +2860,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)  	core->board.tuner_type = tv.tuner_type;  	core->tuner_formats = tv.tuner_formats;  	core->board.radio.type = tv.has_radio ? CX88_RADIO : 0; +	core->model = tv.model;  	/* Make sure we support the board model */  	switch (tv.model) @@ -3133,7 +3139,7 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,  	case XC2028_TUNER_RESET:  		switch (INPUT(core->input).type) {  		case CX88_RADIO: -			info_printk(core, "setting GPIO to radio!\n"); +			dprintk(1, "setting GPIO to radio!\n");  			cx_write(MO_GP0_IO, 0x4ff);  			mdelay(250);  			cx_write(MO_GP2_IO, 0xff); @@ -3141,7 +3147,7 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,  			break;  		case CX88_VMUX_DVB:	/* Digital TV*/  		default:		/* Analog TV */ -			info_printk(core, "setting GPIO to TV!\n"); +			dprintk(1, "setting GPIO to TV!\n");  			break;  		}  		cx_write(MO_GP1_IO, 0x101010); @@ -3199,8 +3205,7 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core,  			   not having any tuning at all. */  			return 0;  		} else { -			err_printk(core, "xc5000: unknown tuner " -				   "callback command.\n"); +			dprintk(1, "xc5000: unknown tuner callback command.\n");  			return -EINVAL;  		}  		break; @@ -3211,8 +3216,7 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core,  			cx_set(MO_GP0_IO, 0x00000010);  			return 0;  		} else { -			printk(KERN_ERR -				"xc5000: unknown tuner callback command.\n"); +			dprintk(1, "xc5000: unknown tuner callback command.\n");  			return -EINVAL;  		}  		break; @@ -3242,13 +3246,13 @@ int cx88_tuner_callback(void *priv, int component, int command, int arg)  	switch (core->board.tuner_type) {  		case TUNER_XC2028: -			info_printk(core, "Calling XC2028/3028 callback\n"); +			dprintk(1, "Calling XC2028/3028 callback\n");  			return cx88_xc2028_tuner_callback(core, command, arg);  		case TUNER_XC4000: -			info_printk(core, "Calling XC4000 callback\n"); +			dprintk(1, "Calling XC4000 callback\n");  			return cx88_xc4000_tuner_callback(core, command, arg);  		case TUNER_XC5000: -			info_printk(core, "Calling XC5000 callback\n"); +			dprintk(1, "Calling XC5000 callback\n");  			return cx88_xc5000_tuner_callback(core, command, arg);  	}  	err_printk(core, "Error: Calling callback for tuner %d\n", @@ -3589,8 +3593,8 @@ static void cx88_card_setup(struct cx88_core *core)  		memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));  		xc2028_cfg.tuner = TUNER_XC2028;  		xc2028_cfg.priv  = &ctl; -		info_printk(core, "Asking xc2028/3028 to load firmware %s\n", -			    ctl.fname); +		dprintk(1, "Asking xc2028/3028 to load firmware %s\n", +			ctl.fname);  		call_all(core, tuner, s_config, &xc2028_cfg);  	}  	call_all(core, core, s_power, 0); @@ -3759,8 +3763,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)  	if (radio[core->nr] != UNSET)  		core->board.radio_type = radio[core->nr]; -	info_printk(core, "TV tuner type %d, Radio tuner type %d\n", -		    core->board.tuner_type, core->board.radio_type); +	dprintk(1, "TV tuner type %d, Radio tuner type %d\n", +		core->board.tuner_type, core->board.radio_type);  	/* init hardware */  	cx88_reset(core); diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 39f095c37ff..c8f3dcc579d 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -48,9 +48,9 @@ MODULE_LICENSE("GPL");  /* ------------------------------------------------------------------ */ -static unsigned int core_debug; -module_param(core_debug,int,0644); -MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); +unsigned int cx88_core_debug; +module_param_named(core_debug, cx88_core_debug, int, 0644); +MODULE_PARM_DESC(core_debug, "enable debug messages [core]");  static unsigned int nicam;  module_param(nicam,int,0644); @@ -60,8 +60,10 @@ static unsigned int nocomb;  module_param(nocomb,int,0644);  MODULE_PARM_DESC(nocomb,"disable comb filter"); -#define dprintk(level,fmt, arg...)	if (core_debug >= level)	\ -	printk(KERN_DEBUG "%s: " fmt, core->name , ## arg) +#define dprintk(level,fmt, arg...)	do {				\ +	if (cx88_core_debug >= level)					\ +		printk(KERN_DEBUG "%s: " fmt, core->name , ## arg);	\ +	} while(0)  static unsigned int cx88_devcount;  static LIST_HEAD(cx88_devlist); diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index 672b267a2d3..053ed1ba1d8 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -1042,7 +1042,7 @@ static int dvb_register(struct cx8802_dev *dev)  			if (!dvb_attach(isl6421_attach,  					fe0->dvb.frontend,  					&dev->core->i2c_adap, -					0x08, ISL6421_DCL, 0x00)) +					0x08, ISL6421_DCL, 0x00, false))  				goto frontend_detach;  		}  		/* MFE frontend 2 */ @@ -1279,8 +1279,16 @@ static int dvb_register(struct cx8802_dev *dev)  					       &hauppauge_novas_config,  					       &core->i2c_adap);  		if (fe0->dvb.frontend) { +			bool override_tone; + +			if (core->model == 92001) +				override_tone = true; +			else +				override_tone = false; +  			if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, -					&core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) +					&core->i2c_adap, 0x08, ISL6421_DCL, 0x00, +					override_tone))  				goto frontend_detach;  		}  		break; @@ -1403,7 +1411,7 @@ static int dvb_register(struct cx8802_dev *dev)  			if (!dvb_attach(isl6421_attach,  					fe0->dvb.frontend,  					&dev->core->i2c_adap, -					0x08, ISL6421_DCL, 0x00)) +					0x08, ISL6421_DCL, 0x00, false))  				goto frontend_detach;  		}  		/* MFE frontend 2 */ @@ -1431,7 +1439,7 @@ static int dvb_register(struct cx8802_dev *dev)  			if (!dvb_attach(isl6421_attach,  					fe0->dvb.frontend,  					&dev->core->i2c_adap, -					0x08, ISL6421_DCL, 0x00)) +					0x08, ISL6421_DCL, 0x00, false))  				goto frontend_detach;  		}  		break; diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index c9d3182f79d..2d3507eb489 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -532,16 +532,17 @@ static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)  {  	struct cx8802_dev *dev = pci_get_drvdata(pci_dev);  	struct cx88_core *core = dev->core; +	unsigned long flags;  	/* stop mpeg dma */ -	spin_lock(&dev->slock); +	spin_lock_irqsave(&dev->slock, flags);  	if (!list_empty(&dev->mpegq.active)) {  		dprintk( 2, "suspend\n" );  		printk("%s: suspend mpeg\n", core->name);  		cx8802_stop_dma(dev);  		del_timer(&dev->mpegq.timeout);  	} -	spin_unlock(&dev->slock); +	spin_unlock_irqrestore(&dev->slock, flags);  	/* FIXME -- shutdown device */  	cx88_shutdown(dev->core); @@ -558,6 +559,7 @@ static int cx8802_resume_common(struct pci_dev *pci_dev)  {  	struct cx8802_dev *dev = pci_get_drvdata(pci_dev);  	struct cx88_core *core = dev->core; +	unsigned long flags;  	int err;  	if (dev->state.disabled) { @@ -584,12 +586,12 @@ static int cx8802_resume_common(struct pci_dev *pci_dev)  	cx88_reset(dev->core);  	/* restart video+vbi capture */ -	spin_lock(&dev->slock); +	spin_lock_irqsave(&dev->slock, flags);  	if (!list_empty(&dev->mpegq.active)) {  		printk("%s: resume mpeg\n", core->name);  		cx8802_restart_queue(dev,&dev->mpegq);  	} -	spin_unlock(&dev->slock); +	spin_unlock_irqrestore(&dev->slock, flags);  	return 0;  } diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index bc78354262a..1b00615fd39 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -1193,12 +1193,12 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)  	return 0;  } -static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *tvnorms) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)  {  	struct cx88_core  *core = ((struct cx8800_fh *)priv)->dev->core;  	mutex_lock(&core->lock); -	cx88_set_tvnorm(core,*tvnorms); +	cx88_set_tvnorm(core, tvnorms);  	mutex_unlock(&core->lock);  	return 0; @@ -1289,7 +1289,7 @@ static int vidioc_g_tuner (struct file *file, void *priv,  }  static int vidioc_s_tuner (struct file *file, void *priv, -				struct v4l2_tuner *t) +				const struct v4l2_tuner *t)  {  	struct cx88_core  *core = ((struct cx8800_fh *)priv)->dev->core; @@ -1321,8 +1321,10 @@ static int vidioc_g_frequency (struct file *file, void *priv,  }  int cx88_set_freq (struct cx88_core  *core, -				struct v4l2_frequency *f) +				const struct v4l2_frequency *f)  { +	struct v4l2_frequency new_freq = *f; +  	if (unlikely(UNSET == core->board.tuner_type))  		return -EINVAL;  	if (unlikely(f->tuner != 0)) @@ -1331,8 +1333,8 @@ int cx88_set_freq (struct cx88_core  *core,  	mutex_lock(&core->lock);  	cx88_newstation(core);  	call_all(core, tuner, s_frequency, f); -	call_all(core, tuner, g_frequency, f); -	core->freq = f->frequency; +	call_all(core, tuner, g_frequency, &new_freq); +	core->freq = new_freq.frequency;  	/* When changing channels it is required to reset TVAUDIO */  	msleep (10); @@ -1345,7 +1347,7 @@ int cx88_set_freq (struct cx88_core  *core,  EXPORT_SYMBOL(cx88_set_freq);  static int vidioc_s_frequency (struct file *file, void *priv, -				struct v4l2_frequency *f) +				const struct v4l2_frequency *f)  {  	struct cx8800_fh  *fh   = priv;  	struct cx88_core  *core = fh->dev->core; @@ -1378,7 +1380,7 @@ static int vidioc_g_register (struct file *file, void *fh,  }  static int vidioc_s_register (struct file *file, void *fh, -				struct v4l2_dbg_register *reg) +				const struct v4l2_dbg_register *reg)  {  	struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; @@ -1407,20 +1409,15 @@ static int radio_g_tuner (struct file *file, void *priv,  	return 0;  } -/* FIXME: Should add a standard for radio */ -  static int radio_s_tuner (struct file *file, void *priv, -				struct v4l2_tuner *t) +				const struct v4l2_tuner *t)  {  	struct cx88_core  *core = ((struct cx8800_fh *)priv)->dev->core;  	if (0 != t->index)  		return -EINVAL; -	if (t->audmode > V4L2_TUNER_MODE_STEREO) -		t->audmode = V4L2_TUNER_MODE_STEREO;  	call_all(core, tuner, s_tuner, t); -  	return 0;  } @@ -1957,9 +1954,10 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)  {  	struct cx8800_dev *dev = pci_get_drvdata(pci_dev);  	struct cx88_core *core = dev->core; +	unsigned long flags;  	/* stop video+vbi capture */ -	spin_lock(&dev->slock); +	spin_lock_irqsave(&dev->slock, flags);  	if (!list_empty(&dev->vidq.active)) {  		printk("%s/0: suspend video\n", core->name);  		stop_video_dma(dev); @@ -1970,7 +1968,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)  		cx8800_stop_vbi_dma(dev);  		del_timer(&dev->vbiq.timeout);  	} -	spin_unlock(&dev->slock); +	spin_unlock_irqrestore(&dev->slock, flags);  	if (core->ir)  		cx88_ir_stop(core); @@ -1989,6 +1987,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)  {  	struct cx8800_dev *dev = pci_get_drvdata(pci_dev);  	struct cx88_core *core = dev->core; +	unsigned long flags;  	int err;  	if (dev->state.disabled) { @@ -2019,7 +2018,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)  	cx_set(MO_PCI_INTMSK, core->pci_irqmask);  	/* restart video+vbi capture */ -	spin_lock(&dev->slock); +	spin_lock_irqsave(&dev->slock, flags);  	if (!list_empty(&dev->vidq.active)) {  		printk("%s/0: resume video\n", core->name);  		restart_video_queue(dev,&dev->vidq); @@ -2028,7 +2027,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)  		printk("%s/0: resume vbi\n", core->name);  		cx8800_restart_vbi_queue(dev,&dev->vbiq);  	} -	spin_unlock(&dev->slock); +	spin_unlock_irqrestore(&dev->slock, flags);  	return 0;  } diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index feff53c0a25..51ce2c0e8bc 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -334,6 +334,7 @@ struct cx88_core {  	/* board name */  	int                        nr;  	char                       name[32]; +	u32			   model;  	/* pci stuff */  	int                        pci_bus; @@ -617,6 +618,8 @@ struct cx8802_dev {  /* ----------------------------------------------------------- */  /* cx88-core.c                                                 */ +extern unsigned int cx88_core_debug; +  extern void cx88_print_irqbits(const char *name, const char *tag, const char *strings[],  			       int len, u32 bits, u32 mask); @@ -740,7 +743,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev);  /* ----------------------------------------------------------- */  /* cx88-video.c*/  int cx88_enum_input (struct cx88_core  *core,struct v4l2_input *i); -int cx88_set_freq (struct cx88_core  *core,struct v4l2_frequency *f); +int cx88_set_freq(struct cx88_core  *core, const struct v4l2_frequency *f);  int cx88_video_mux(struct cx88_core *core, unsigned int input);  void cx88_querycap(struct file *file, struct cx88_core *core,  		struct v4l2_capability *cap); diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index 2928e7287da..07b8460953b 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -1387,7 +1387,7 @@ int ivtv_init_on_first_open(struct ivtv *itv)  	if (!itv->has_cx23415)  		write_reg_sync(0x03, IVTV_REG_DMACONTROL); -	ivtv_s_std_enc(itv, &itv->tuner_std); +	ivtv_s_std_enc(itv, itv->tuner_std);  	/* Default interrupts enabled. For the PVR350 this includes the  	   decoder VSYNC interrupt, which is always on. It is not only used @@ -1397,7 +1397,7 @@ int ivtv_init_on_first_open(struct ivtv *itv)  	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {  		ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);  		ivtv_set_osd_alpha(itv); -		ivtv_s_std_dec(itv, &itv->tuner_std); +		ivtv_s_std_dec(itv, itv->tuner_std);  	} else {  		ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);  	} diff --git a/drivers/media/pci/ivtv/ivtv-firmware.c b/drivers/media/pci/ivtv/ivtv-firmware.c index 68387d4369d..ed73edd2bcd 100644 --- a/drivers/media/pci/ivtv/ivtv-firmware.c +++ b/drivers/media/pci/ivtv/ivtv-firmware.c @@ -302,7 +302,7 @@ static int ivtv_firmware_restart(struct ivtv *itv)  	/* Restore encoder video standard */  	std = itv->std;  	itv->std = 0; -	ivtv_s_std_enc(itv, &std); +	ivtv_s_std_enc(itv, std);  	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {  		ivtv_init_mpeg_decoder(itv); @@ -310,7 +310,7 @@ static int ivtv_firmware_restart(struct ivtv *itv)  		/* Restore decoder video standard */  		std = itv->std_out;  		itv->std_out = 0; -		ivtv_s_std_dec(itv, &std); +		ivtv_s_std_dec(itv, std);  		/* Restore framebuffer if active */  		if (itv->ivtvfb_restore) diff --git a/drivers/media/pci/ivtv/ivtv-gpio.c b/drivers/media/pci/ivtv/ivtv-gpio.c index 8f0d0778905..af52def700c 100644 --- a/drivers/media/pci/ivtv/ivtv-gpio.c +++ b/drivers/media/pci/ivtv/ivtv-gpio.c @@ -192,7 +192,7 @@ static int subdev_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)  	return 0;  } -static int subdev_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) +static int subdev_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)  {  	struct ivtv *itv = sd_to_ivtv(sd);  	u16 mask, data; diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 7a8b0d0b612..9cbbce0eaed 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -711,28 +711,26 @@ static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_i  }  #ifdef CONFIG_VIDEO_ADV_DEBUG -static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) +static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)  { -	struct v4l2_dbg_register *regs = arg;  	volatile u8 __iomem *reg_start;  	if (!capable(CAP_SYS_ADMIN))  		return -EPERM; -	if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE) +	if (reg >= IVTV_REG_OFFSET && reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)  		reg_start = itv->reg_mem - IVTV_REG_OFFSET; -	else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && -			regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) +	else if (itv->has_cx23415 && reg >= IVTV_DECODER_OFFSET && +			reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)  		reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; -	else if (regs->reg < IVTV_ENCODER_SIZE) +	else if (reg < IVTV_ENCODER_SIZE)  		reg_start = itv->enc_mem;  	else  		return -EINVAL; -	regs->size = 4; -	if (cmd == VIDIOC_DBG_G_REGISTER) -		regs->val = readl(regs->reg + reg_start); +	if (get) +		*val = readl(reg + reg_start);  	else -		writel(regs->val, regs->reg + reg_start); +		writel(*val, reg + reg_start);  	return 0;  } @@ -740,20 +738,25 @@ static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register  {  	struct ivtv *itv = fh2id(fh)->itv; -	if (v4l2_chip_match_host(®->match)) -		return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); +	if (v4l2_chip_match_host(®->match)) { +		reg->size = 4; +		return ivtv_itvc(itv, true, reg->reg, ®->val); +	}  	/* TODO: subdev errors should not be ignored, this should become a  	   subdev helper function. */  	ivtv_call_all(itv, core, g_register, reg);  	return 0;  } -static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) +static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)  {  	struct ivtv *itv = fh2id(fh)->itv; -	if (v4l2_chip_match_host(®->match)) -		return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); +	if (v4l2_chip_match_host(®->match)) { +		u64 val = reg->val; + +		return ivtv_itvc(itv, false, reg->reg, &val); +	}  	/* TODO: subdev errors should not be ignored, this should become a  	   subdev helper function. */  	ivtv_call_all(itv, core, s_register, reg); @@ -1078,7 +1081,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *  	return 0;  } -int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) +int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)  {  	struct ivtv *itv = fh2id(fh)->itv;  	struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; @@ -1103,10 +1106,10 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)  	return 0;  } -void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std) +void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std)  { -	itv->std = *std; -	itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; +	itv->std = std; +	itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;  	itv->is_50hz = !itv->is_60hz;  	cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);  	itv->cxhdl.width = 720; @@ -1122,15 +1125,15 @@ void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)  	ivtv_call_all(itv, core, s_std, itv->std);  } -void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std) +void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)  {  	struct yuv_playback_info *yi = &itv->yuv_info;  	DEFINE_WAIT(wait);  	int f;  	/* set display standard */ -	itv->std_out = *std; -	itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; +	itv->std_out = std; +	itv->is_out_60hz = (std & V4L2_STD_525_60) ? 1 : 0;  	itv->is_out_50hz = !itv->is_out_60hz;  	ivtv_call_all(itv, video, s_std_output, itv->std_out); @@ -1168,14 +1171,14 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)  	}  } -static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) +static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id std)  {  	struct ivtv *itv = fh2id(fh)->itv; -	if ((*std & V4L2_STD_ALL) == 0) +	if ((std & V4L2_STD_ALL) == 0)  		return -EINVAL; -	if (*std == itv->std) +	if (std == itv->std)  		return 0;  	if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) || @@ -1196,7 +1199,7 @@ static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)  	return 0;  } -static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) +static int ivtv_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)  {  	struct ivtv_open_id *id = fh2id(fh);  	struct ivtv *itv = id->itv; @@ -1804,7 +1807,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)  }  static long ivtv_default(struct file *file, void *fh, bool valid_prio, -			 int cmd, void *arg) +			 unsigned int cmd, void *arg)  {  	struct ivtv *itv = fh2id(fh)->itv; diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.h b/drivers/media/pci/ivtv/ivtv-ioctl.h index 7c553d16579..75c39775611 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.h +++ b/drivers/media/pci/ivtv/ivtv-ioctl.h @@ -27,9 +27,9 @@ u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);  void ivtv_set_osd_alpha(struct ivtv *itv);  int ivtv_set_speed(struct ivtv *itv, int speed);  void ivtv_set_funcs(struct video_device *vdev); -void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std); -void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std); -int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); +void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std); +void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std); +int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);  int ivtv_s_input(struct file *file, void *fh, unsigned int inp);  #endif diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index 05b94aa8ba3..9ff1230192e 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c @@ -1171,8 +1171,7 @@ static void ivtvfb_release_buffers (struct ivtv *itv)  		fb_dealloc_cmap(&oi->ivtvfb_info.cmap);  	/* Release pseudo palette */ -	if (oi->ivtvfb_info.pseudo_palette) -		kfree(oi->ivtvfb_info.pseudo_palette); +	kfree(oi->ivtvfb_info.pseudo_palette);  #ifdef CONFIG_MTRR  	if (oi->fb_end_aligned_physaddr) { diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 7859c43479d..2381b05432e 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1410,7 +1410,7 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)  }  static long vidioc_default(struct file *file, void *fh, bool valid_prio, -						int cmd, void *arg) +			   unsigned int cmd, void *arg)  {  	switch (cmd) {  	case MEYEIOC_G_PARAMS: diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index dc68cf1070f..d45e7f6ff33 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -50,6 +50,11 @@ static char name_svideo[]  = "S-Video";  /* ------------------------------------------------------------------ */  /* board config info                                                  */ +static struct tda18271_std_map aver_a706_std_map = { +	.fm_radio = { .if_freq = 5500, .fm_rfn = 0, .agc_mode = 3, .std = 0, +		      .if_lvl = 0, .rfagc_top = 0x2c, }, +}; +  /* If radio_type !=UNSET, radio_addr should be specified   */ @@ -2760,7 +2765,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET, -		.tuner_config   = 0, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_OFF },  		.mpeg           = SAA7134_MPEG_DVB,  		.gpiomask       = 0x0200000,  		.inputs = {{ @@ -3291,7 +3296,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 1, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_ON },  		.mpeg           = SAA7134_MPEG_DVB,  		.gpiomask       = 0x000200000,  		.inputs         = {{ @@ -3395,7 +3400,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 1, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_ON },  		.mpeg           = SAA7134_MPEG_DVB,  		.gpiomask       = 0x0200100,  		.inputs         = {{ @@ -3426,7 +3431,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 3, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_ON_BRIDGE },  		.mpeg           = SAA7134_MPEG_DVB,  		.ts_type	= SAA7134_MPEG_TS_SERIAL,  		.ts_force_val   = 1, @@ -3459,7 +3464,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 3, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_ON_BRIDGE },  		.mpeg           = SAA7134_MPEG_DVB,  		.ts_type	= SAA7134_MPEG_TS_SERIAL,  		.gpiomask       = 0x0800100, /* GPIO 21 is an INPUT */ @@ -3683,7 +3688,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET, -		.tuner_config   = 2, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_OFF },  		.mpeg           = SAA7134_MPEG_DVB,  		.gpiomask       = 0x0200000,  		.inputs = {{ @@ -3736,7 +3741,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET, -		.tuner_config   = 2, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_OFF },  		.mpeg           = SAA7134_MPEG_DVB,  		.gpiomask       = 0x0200000,  		.inputs = {{ @@ -3754,7 +3759,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET, -		.tuner_config   = 2, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_OFF },  		.gpiomask	= 1 << 21,  		.mpeg           = SAA7134_MPEG_DVB,  		.inputs         = {{ @@ -3887,7 +3892,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 0, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_OFF },  		.mpeg           = SAA7134_MPEG_DVB,  		.inputs = {{  			.name   = name_tv, /* FIXME: analog tv untested */ @@ -3903,7 +3908,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 2, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_OFF },  		.gpiomask       = 0x020200000,  		.inputs         = {{  			.name = name_tv, @@ -3937,7 +3942,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type	= UNSET,  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET, -		.tuner_config	= 0, +		.tda829x_conf	= { .lna_cfg = TDA8290_LNA_OFF },  		.gpiomask	= 0x020200000,  		.inputs		= {{  			.name = name_tv, @@ -4737,7 +4742,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET, -		.tuner_config   = 2, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_OFF },  		.mpeg           = SAA7134_MPEG_DVB,  		.gpiomask       = 0x0200000,  		.inputs = {{ @@ -4823,7 +4828,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type   = UNSET,  		.tuner_addr   = ADDR_UNSET,  		.radio_addr   = ADDR_UNSET, -		.tuner_config = 0, +		.tda829x_conf = { .lna_cfg = TDA8290_LNA_OFF },  		.mpeg         = SAA7134_MPEG_DVB,  		.inputs       = {{  			.name = name_tv, @@ -4847,7 +4852,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET, -		.tuner_config   = 2, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_OFF },  		.mpeg           = SAA7134_MPEG_DVB,  		.gpiomask       = 0x0200000,  		.inputs = { { @@ -5057,7 +5062,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 2, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_OFF },  		.gpiomask       = 1 << 21,  		.mpeg           = SAA7134_MPEG_DVB,  		.inputs         = {{ @@ -5087,7 +5092,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 2, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_GP0_HIGH_OFF },  		.gpiomask       = 1 << 21,  		.mpeg           = SAA7134_MPEG_DVB,  		.inputs         = {{ @@ -5176,7 +5181,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET, -		.tuner_config   = 0, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_OFF },  		.mpeg           = SAA7134_MPEG_DVB,  		.gpiomask       = 0x0200000,  		.inputs = { { @@ -5406,7 +5411,7 @@ struct saa7134_board saa7134_boards[] = {  		.radio_type     = UNSET,  		.tuner_addr     = ADDR_UNSET,  		.radio_addr     = ADDR_UNSET, -		.tuner_config   = 0, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_OFF },  		.mpeg           = SAA7134_MPEG_DVB,  		.ts_type	= SAA7134_MPEG_TS_PARALLEL,  		.inputs         = {{ @@ -5629,7 +5634,7 @@ struct saa7134_board saa7134_boards[] = {  		.audio_clock	= 0x00187de7,  		.tuner_type	= TUNER_PHILIPS_TDA8290,  		.radio_type	= UNSET, -		.tuner_config	= 3, +		.tda829x_conf	= { .lna_cfg = TDA8290_LNA_ON_BRIDGE },  		.tuner_addr	= ADDR_UNSET,  		.radio_addr	= ADDR_UNSET,  		.gpiomask	= 0x02050000, @@ -5790,6 +5795,38 @@ struct saa7134_board saa7134_boards[] = {  			.gpio = 0x6010000,  		} },  	}, +	[SAA7134_BOARD_AVERMEDIA_A706] = { +		.name           = "AverMedia AverTV Satellite Hybrid+FM A706", +		.audio_clock    = 0x00187de7, +		.tuner_type     = TUNER_PHILIPS_TDA8290, +		.radio_type     = UNSET, +		.tuner_addr     = ADDR_UNSET, +		.radio_addr     = ADDR_UNSET, +		.tda829x_conf   = { .lna_cfg = TDA8290_LNA_OFF, +				    .no_i2c_gate = 1, +				    .tda18271_std_map = &aver_a706_std_map }, +		.gpiomask       = 1 << 11, +		.mpeg           = SAA7134_MPEG_DVB, +		.inputs         = {{ +			.name = name_tv, +			.vmux = 1, +			.amux = TV, +			.tv   = 1, +		}, { +			.name = name_comp, +			.vmux = 4, +			.amux = LINE1, +		}, { +			.name = name_svideo, +			.vmux = 8, +			.amux = LINE1, +		} }, +		.radio = { +			.name = name_radio, +			.amux = TV, +			.gpio = 0x0000800, +		}, +	},  }; @@ -7037,6 +7074,12 @@ struct pci_device_id saa7134_pci_tbl[] = {  		.subdevice    = 0x0911,  		.driver_data  = SAA7134_BOARD_SENSORAY811_911,  	}, { +		.vendor       = PCI_VENDOR_ID_PHILIPS, +		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133, +		.subvendor    = 0x1461, /* Avermedia Technologies Inc */ +		.subdevice    = 0x2055, /* AverTV Satellite Hybrid+FM A706 */ +		.driver_data  = SAA7134_BOARD_AVERMEDIA_A706, +	}, {  		/* --- boards without eeprom + subsystem ID --- */  		.vendor       = PCI_VENDOR_ID_PHILIPS,  		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -7585,6 +7628,17 @@ int saa7134_board_init1(struct saa7134_dev *dev)  		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x80040100, 0x80040100);  		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);  		break; +	case SAA7134_BOARD_AVERMEDIA_A706: +		/* radio antenna select: tristate both as in Windows driver */ +		saa7134_set_gpio(dev, 12, 3);	/* TV antenna */ +		saa7134_set_gpio(dev, 13, 3);	/* FM antenna */ +		dev->has_remote = SAA7134_REMOTE_I2C; +		/* +		 * Disable CE5039 DVB-S tuner now (SLEEP pin high) to prevent +		 * it from interfering with analog tuner detection +		 */ +		saa7134_set_gpio(dev, 23, 1); +		break;  	case SAA7134_BOARD_VIDEOMATE_S350:  		dev->has_remote = SAA7134_REMOTE_GPIO;  		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x0000C000, 0x0000C000); @@ -7633,7 +7687,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)  	if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type != UNSET)) {  		tun_setup.type = dev->tuner_type;  		tun_setup.addr = dev->tuner_addr; -		tun_setup.config = saa7134_boards[dev->board].tuner_config; +		tun_setup.config = &saa7134_boards[dev->board].tda829x_conf;  		tun_setup.tuner_callback = saa7134_tuner_callback;  		tun_setup.mode_mask = mode_mask; diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 8fd24e7c940..45f0aca597a 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -805,6 +805,7 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,  	vfd->debug   = video_debug;  	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",  		 dev->name, type, saa7134_boards[dev->board].name); +	set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);  	video_set_drvdata(vfd, dev);  	return vfd;  } @@ -1028,8 +1029,6 @@ static int saa7134_initdev(struct pci_dev *pci_dev,  		}  	} -	v4l2_prio_init(&dev->prio); -  	mutex_lock(&saa7134_devlist_lock);  	list_for_each_entry(mops, &mops_list, next)  		mpeg_ops_attach(mops, dev); diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index 27915e501db..4a08ae31df2 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -1073,6 +1073,10 @@ static struct mt312_config zl10313_compro_s350_config = {  	.demod_address = 0x0e,  }; +static struct mt312_config zl10313_avermedia_a706_config = { +	.demod_address = 0x0e, +}; +  static struct lgdt3305_config hcw_lgdt3305_config = {  	.i2c_addr           = 0x0e,  	.mpeg_mode          = LGDT3305_MPEG_SERIAL, @@ -1391,8 +1395,9 @@ static int dvb_init(struct saa7134_dev *dev)  					wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);  					goto detach_frontend;  				} -				if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, -										0x08, 0, 0) == NULL) { +				if (dvb_attach(isl6421_attach, fe0->dvb.frontend, +					       &dev->i2c_adap, +					       0x08, 0, 0, false) == NULL) {  					wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);  					goto detach_frontend;  				} @@ -1509,7 +1514,8 @@ static int dvb_init(struct saa7134_dev *dev)  				goto detach_frontend;  			}  			if (dvb_attach(isl6421_attach, fe0->dvb.frontend, -				       &dev->i2c_adap, 0x08, 0, 0) == NULL) { +				       &dev->i2c_adap, +				       0x08, 0, 0, false) == NULL) {  				wprintk("%s: No ISL6421 found!\n", __func__);  				goto detach_frontend;  			} @@ -1820,6 +1826,25 @@ static int dvb_init(struct saa7134_dev *dev)  				   &prohdtv_pro2_tda18271_config);  		}  		break; +	case SAA7134_BOARD_AVERMEDIA_A706: +		/* Enable all DVB-S devices now */ +		/* CE5039 DVB-S tuner SLEEP pin low */ +		saa7134_set_gpio(dev, 23, 0); +		/* CE6313 DVB-S demod SLEEP pin low */ +		saa7134_set_gpio(dev, 9, 0); +		/* CE6313 DVB-S demod RESET# pin high */ +		saa7134_set_gpio(dev, 25, 1); +		msleep(1); +		fe0->dvb.frontend = dvb_attach(mt312_attach, +				&zl10313_avermedia_a706_config, &dev->i2c_adap); +		if (fe0->dvb.frontend) { +			fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; +			if (dvb_attach(zl10039_attach, fe0->dvb.frontend, +					0x60, &dev->i2c_adap) == NULL) +				wprintk("%s: No zl10039 found!\n", +					__func__); +		} +		break;  	default:  		wprintk("Huh? unknown DVB card?\n");  		break; diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 4df79c65690..66a70814004 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -428,7 +428,7 @@ static int empress_g_chip_ident(struct file *file, void *fh,  	return -EINVAL;  } -static int empress_s_std(struct file *file, void *priv, v4l2_std_id *id) +static int empress_s_std(struct file *file, void *priv, v4l2_std_id id)  {  	struct saa7134_dev *dev = file->private_data; diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index a176ec3285e..c68169d7580 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -256,6 +256,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,  				addr |= 1;  			if (i > 0 && msgs[i].flags &  			    I2C_M_RD && msgs[i].addr != 0x40 && +			    msgs[i].addr != 0x41 &&  			    msgs[i].addr != 0x19) {  				/* workaround for a saa7134 i2c bug  				 * needed to talk to the mt352 demux diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index e761262f747..6f4312663bd 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -997,6 +997,9 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)  	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:  		info.addr = 0x40;  		break; +	case SAA7134_BOARD_AVERMEDIA_A706: +		info.addr = 0x41; +		break;  	case SAA7134_BOARD_FLYDVB_TRIO:  		dev->init_data.name = "FlyDVB Trio";  		dev->init_data.get_key = get_key_flydvb_trio; diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index b7a99bee2f9..0f34e09d98d 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -796,6 +796,7 @@ static int tvaudio_thread_ddep(void *data)  			dprintk("FM Radio\n");  			if (dev->tuner_type == TUNER_PHILIPS_TDA8290) {  				norms = (0x11 << 2) | 0x01; +				/* set IF frequency to 5.5 MHz */  				saa_dsp_writel(dev, 0x42c >> 2, 0x729555);  			} else {  				norms = (0x0f << 2) | 0x01; diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 7c503fb6852..cc409380ee1 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -1176,14 +1176,6 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, str  	int restart_overlay = 0;  	int err; -	/* When called from the empress code fh == NULL. -	   That needs to be fixed somehow, but for now this is -	   good enough. */ -	if (fh) { -		err = v4l2_prio_check(&dev->prio, fh->prio); -		if (0 != err) -			return err; -	}  	err = -EINVAL;  	mutex_lock(&dev->lock); @@ -1352,6 +1344,7 @@ static int video_open(struct file *file)  	if (NULL == fh)  		return -ENOMEM; +	v4l2_fh_init(&fh->fh, vdev);  	file->private_data = fh;  	fh->dev      = dev;  	fh->radio    = radio; @@ -1359,7 +1352,6 @@ static int video_open(struct file *file)  	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);  	fh->width    = 720;  	fh->height   = 576; -	v4l2_prio_open(&dev->prio, &fh->prio);  	videobuf_queue_sg_init(&fh->cap, &video_qops,  			    &dev->pci->dev, &dev->slock, @@ -1384,6 +1376,8 @@ static int video_open(struct file *file)  		/* switch to video/vbi mode */  		video_mux(dev,dev->ctl_input);  	} +	v4l2_fh_add(&fh->fh); +  	return 0;  } @@ -1504,7 +1498,8 @@ static int video_release(struct file *file)  	saa7134_pgtable_free(dev->pci,&fh->pt_cap);  	saa7134_pgtable_free(dev->pci,&fh->pt_vbi); -	v4l2_prio_close(&dev->prio, fh->prio); +	v4l2_fh_del(&fh->fh); +	v4l2_fh_exit(&fh->fh);  	file->private_data = NULL;  	kfree(fh);  	return 0; @@ -1557,6 +1552,7 @@ static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,  	struct saa7134_dev *dev = fh->dev;  	struct saa7134_tvnorm *norm = dev->tvnorm; +	memset(&f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved));  	f->fmt.vbi.sampling_rate = 6750000 * 4;  	f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;  	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; @@ -1755,7 +1751,6 @@ static int saa7134_enum_input(struct file *file, void *priv,  	strcpy(i->name, card_in(dev, n).name);  	if (card_in(dev, n).tv)  		i->type = V4L2_INPUT_TYPE_TUNER; -	i->audioset = 1;  	if (n == dev->ctl_input) {  		int v1 = saa_readb(SAA7134_STATUS_VIDEO1);  		int v2 = saa_readb(SAA7134_STATUS_VIDEO2); @@ -1784,11 +1779,6 @@ static int saa7134_s_input(struct file *file, void *priv, unsigned int i)  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; -	int err; - -	err = v4l2_prio_check(&dev->prio, fh->prio); -	if (0 != err) -		return err;  	if (i >= SAA7134_INPUT_MAX)  		return -EINVAL; @@ -1805,6 +1795,8 @@ static int saa7134_querycap(struct file *file, void  *priv,  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; +	struct video_device *vdev = video_devdata(file); +	u32 radio_caps, video_caps, vbi_caps;  	unsigned int tuner_type = dev->tuner_type; @@ -1812,54 +1804,67 @@ static int saa7134_querycap(struct file *file, void  *priv,  	strlcpy(cap->card, saa7134_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_VBI_CAPTURE | -		V4L2_CAP_READWRITE | -		V4L2_CAP_STREAMING | -		V4L2_CAP_TUNER; + +	cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; +	if ((tuner_type != TUNER_ABSENT) && (tuner_type != UNSET)) +		cap->device_caps |= V4L2_CAP_TUNER; + +	radio_caps = V4L2_CAP_RADIO;  	if (dev->has_rds) -		cap->capabilities |= V4L2_CAP_RDS_CAPTURE; +		radio_caps |= V4L2_CAP_RDS_CAPTURE; + +	video_caps = V4L2_CAP_VIDEO_CAPTURE;  	if (saa7134_no_overlay <= 0) -		cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; +		video_caps |= V4L2_CAP_VIDEO_OVERLAY; + +	vbi_caps = V4L2_CAP_VBI_CAPTURE; + +	switch (vdev->vfl_type) { +	case VFL_TYPE_RADIO: +		cap->device_caps |= radio_caps; +		break; +	case VFL_TYPE_GRABBER: +		cap->device_caps |= video_caps; +		break; +	case VFL_TYPE_VBI: +		cap->device_caps |= vbi_caps; +		break; +	} +	cap->capabilities = radio_caps | video_caps | vbi_caps | +		cap->device_caps | V4L2_CAP_DEVICE_CAPS; +	if (vdev->vfl_type == VFL_TYPE_RADIO) { +		cap->device_caps &= ~V4L2_CAP_STREAMING; +		if (!dev->has_rds) +			cap->device_caps &= ~V4L2_CAP_READWRITE; +	} -	if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) -		cap->capabilities &= ~V4L2_CAP_TUNER;  	return 0;  } -int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id) +int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id id)  {  	unsigned long flags;  	unsigned int i;  	v4l2_std_id fixup; -	int err; -	/* When called from the empress code fh == NULL. -	   That needs to be fixed somehow, but for now this is -	   good enough. */ -	if (fh) { -		err = v4l2_prio_check(&dev->prio, fh->prio); -		if (0 != err) -			return err; -	} else if (res_locked(dev, RESOURCE_OVERLAY)) { +	if (!fh && res_locked(dev, RESOURCE_OVERLAY)) {  		/* Don't change the std from the mpeg device  		   if overlay is active. */  		return -EBUSY;  	}  	for (i = 0; i < TVNORMS; i++) -		if (*id == tvnorms[i].id) +		if (id == tvnorms[i].id)  			break;  	if (i == TVNORMS)  		for (i = 0; i < TVNORMS; i++) -			if (*id & tvnorms[i].id) +			if (id & tvnorms[i].id)  				break;  	if (i == TVNORMS)  		return -EINVAL; -	if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) { +	if ((id & V4L2_STD_SECAM) && (secam[0] != '-')) {  		if (secam[0] == 'L' || secam[0] == 'l') {  			if (secam[1] == 'C' || secam[1] == 'c')  				fixup = V4L2_STD_SECAM_LC; @@ -1879,7 +1884,7 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_  			return -EINVAL;  	} -	*id = tvnorms[i].id; +	id = tvnorms[i].id;  	mutex_lock(&dev->lock);  	if (fh && res_check(fh, RESOURCE_OVERLAY)) { @@ -1901,7 +1906,7 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_  }  EXPORT_SYMBOL_GPL(saa7134_s_std_internal); -static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) +static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id)  {  	struct saa7134_fh *fh = priv; @@ -2009,11 +2014,11 @@ static int saa7134_g_tuner(struct file *file, void *priv,  	if (NULL != card_in(dev, n).name) {  		strcpy(t->name, "Television");  		t->type = V4L2_TUNER_ANALOG_TV; +		saa_call_all(dev, tuner, g_tuner, t);  		t->capability = V4L2_TUNER_CAP_NORM |  			V4L2_TUNER_CAP_STEREO |  			V4L2_TUNER_CAP_LANG1 |  			V4L2_TUNER_CAP_LANG2; -		t->rangehigh = 0xffffffffUL;  		t->rxsubchans = saa7134_tvaudio_getstereo(dev);  		t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);  	} @@ -2023,15 +2028,14 @@ static int saa7134_g_tuner(struct file *file, void *priv,  }  static int saa7134_s_tuner(struct file *file, void *priv, -					struct v4l2_tuner *t) +					const struct v4l2_tuner *t)  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; -	int rx, mode, err; +	int rx, mode; -	err = v4l2_prio_check(&dev->prio, fh->prio); -	if (0 != err) -		return err; +	if (0 != t->index) +		return -EINVAL;  	mode = dev->thread.mode;  	if (UNSET == mode) { @@ -2050,22 +2054,20 @@ static int saa7134_g_frequency(struct file *file, void *priv,  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; +	if (0 != f->tuner) +		return -EINVAL; +  	f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; -	f->frequency = dev->ctl_freq; +	saa_call_all(dev, tuner, g_frequency, f);  	return 0;  }  static int saa7134_s_frequency(struct file *file, void *priv, -					struct v4l2_frequency *f) +					const struct v4l2_frequency *f)  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; -	int err; - -	err = v4l2_prio_check(&dev->prio, fh->prio); -	if (0 != err) -		return err;  	if (0 != f->tuner)  		return -EINVAL; @@ -2074,7 +2076,6 @@ static int saa7134_s_frequency(struct file *file, void *priv,  	if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)  		return -EINVAL;  	mutex_lock(&dev->lock); -	dev->ctl_freq = f->frequency;  	saa_call_all(dev, tuner, s_frequency, f); @@ -2083,35 +2084,6 @@ static int saa7134_s_frequency(struct file *file, void *priv,  	return 0;  } -static int saa7134_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ -	strcpy(a->name, "audio"); -	return 0; -} - -static int saa7134_s_audio(struct file *file, void *priv, const struct v4l2_audio *a) -{ -	return 0; -} - -static int saa7134_g_priority(struct file *file, void *f, enum v4l2_priority *p) -{ -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; - -	*p = v4l2_prio_max(&dev->prio); -	return 0; -} - -static int saa7134_s_priority(struct file *file, void *f, -					enum v4l2_priority prio) -{ -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; - -	return v4l2_prio_change(&dev->prio, &fh->prio, prio); -} -  static int saa7134_enum_fmt_vid_cap(struct file *file, void  *priv,  					struct v4l2_fmtdesc *f)  { @@ -2279,12 +2251,6 @@ static int saa7134_streamoff(struct file *file, void *priv,  	return 0;  } -static int saa7134_g_parm(struct file *file, void *fh, -				struct v4l2_streamparm *parm) -{ -	return 0; -} -  #ifdef CONFIG_VIDEO_ADV_DEBUG  static int vidioc_g_register (struct file *file, void *priv,  			      struct v4l2_dbg_register *reg) @@ -2300,7 +2266,7 @@ static int vidioc_g_register (struct file *file, void *priv,  }  static int vidioc_s_register (struct file *file, void *priv, -				struct v4l2_dbg_register *reg) +				const struct v4l2_dbg_register *reg)  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; @@ -2312,19 +2278,6 @@ static int vidioc_s_register (struct file *file, void *priv,  }  #endif -static int radio_querycap(struct file *file, void *priv, -					struct v4l2_capability *cap) -{ -	struct saa7134_fh *fh = file->private_data; -	struct saa7134_dev *dev = fh->dev; - -	strcpy(cap->driver, "saa7134"); -	strlcpy(cap->card, saa7134_boards[dev->board].name, sizeof(cap->card)); -	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); -	cap->capabilities = V4L2_CAP_TUNER; -	return 0; -} -  static int radio_g_tuner(struct file *file, void *priv,  					struct v4l2_tuner *t)  { @@ -2339,6 +2292,7 @@ static int radio_g_tuner(struct file *file, void *priv,  	t->type = V4L2_TUNER_RADIO;  	saa_call_all(dev, tuner, g_tuner, t); +	t->audmode &= V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO;  	if (dev->input->amux == TV) {  		t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);  		t->rxsubchans = (saa_readb(0x529) & 0x08) ? @@ -2347,7 +2301,7 @@ static int radio_g_tuner(struct file *file, void *priv,  	return 0;  }  static int radio_s_tuner(struct file *file, void *priv, -					struct v4l2_tuner *t) +					const struct v4l2_tuner *t)  {  	struct saa7134_fh *fh = file->private_data;  	struct saa7134_dev *dev = fh->dev; @@ -2377,26 +2331,12 @@ static int radio_g_input(struct file *filp, void *priv, unsigned int *i)  	return 0;  } -static int radio_g_audio(struct file *file, void *priv, -					struct v4l2_audio *a) -{ -	memset(a, 0, sizeof(*a)); -	strcpy(a->name, "Radio"); -	return 0; -} - -static int radio_s_audio(struct file *file, void *priv, -					const struct v4l2_audio *a) -{ -	return 0; -} -  static int radio_s_input(struct file *filp, void *priv, unsigned int i)  {  	return 0;  } -static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) +static int radio_s_std(struct file *file, void *fh, v4l2_std_id norm)  {  	return 0;  } @@ -2441,8 +2381,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {  	.vidioc_g_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap,  	.vidioc_try_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap,  	.vidioc_s_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap, -	.vidioc_g_audio			= saa7134_g_audio, -	.vidioc_s_audio			= saa7134_s_audio,  	.vidioc_cropcap			= saa7134_cropcap,  	.vidioc_reqbufs			= saa7134_reqbufs,  	.vidioc_querybuf		= saa7134_querybuf, @@ -2465,9 +2403,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {  	.vidioc_g_fbuf			= saa7134_g_fbuf,  	.vidioc_s_fbuf			= saa7134_s_fbuf,  	.vidioc_overlay			= saa7134_overlay, -	.vidioc_g_priority		= saa7134_g_priority, -	.vidioc_s_priority		= saa7134_s_priority, -	.vidioc_g_parm			= saa7134_g_parm,  	.vidioc_g_frequency		= saa7134_g_frequency,  	.vidioc_s_frequency		= saa7134_s_frequency,  #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -2486,12 +2421,10 @@ static const struct v4l2_file_operations radio_fops = {  };  static const struct v4l2_ioctl_ops radio_ioctl_ops = { -	.vidioc_querycap	= radio_querycap, +	.vidioc_querycap	= saa7134_querycap,  	.vidioc_g_tuner		= radio_g_tuner,  	.vidioc_enum_input	= radio_enum_input, -	.vidioc_g_audio		= radio_g_audio,  	.vidioc_s_tuner		= radio_s_tuner, -	.vidioc_s_audio		= radio_s_audio,  	.vidioc_s_input		= radio_s_input,  	.vidioc_s_std		= radio_s_std,  	.vidioc_queryctrl	= radio_queryctrl, diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 71eefef5e32..d2ad16c1569 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -36,6 +36,7 @@  #include <media/v4l2-common.h>  #include <media/v4l2-ioctl.h>  #include <media/v4l2-device.h> +#include <media/v4l2-fh.h>  #include <media/tuner.h>  #include <media/rc-core.h>  #include <media/ir-kbd-i2c.h> @@ -45,6 +46,7 @@  #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)  #include <media/videobuf-dvb.h>  #endif +#include "tda8290.h"  #define UNSET (-1U) @@ -334,6 +336,7 @@ struct saa7134_card_ir {  #define SAA7134_BOARD_KWORLD_PC150U         189  #define SAA7134_BOARD_ASUSTeK_PS3_100      190  #define SAA7134_BOARD_HAWELL_HW_9004V1      191 +#define SAA7134_BOARD_AVERMEDIA_A706		192  #define SAA7134_MAXBOARDS 32  #define SAA7134_INPUT_MAX 8 @@ -390,7 +393,7 @@ struct saa7134_board {  	unsigned char		rds_addr;  	unsigned int            tda9887_conf; -	unsigned int            tuner_config; +	struct tda829x_config   tda829x_conf;  	/* peripheral I/O */  	enum saa7134_video_out  video_out; @@ -466,11 +469,11 @@ struct saa7134_dmaqueue {  /* video filehandle status */  struct saa7134_fh { +	struct v4l2_fh             fh;  	struct saa7134_dev         *dev;  	unsigned int               radio;  	enum v4l2_buf_type         type;  	unsigned int               resources; -	enum v4l2_priority	   prio;  	struct pm_qos_request	   qos_request;  	/* video overlay */ @@ -542,7 +545,6 @@ struct saa7134_dev {  	struct list_head           devlist;  	struct mutex               lock;  	spinlock_t                 slock; -	struct v4l2_prio_state     prio;  	struct v4l2_device         v4l2_dev;  	/* workstruct for loading modules */  	struct work_struct request_module_wk; @@ -605,7 +607,6 @@ struct saa7134_dev {  	int                        ctl_contrast;  	int                        ctl_hue;  	int                        ctl_saturation; -	int                        ctl_freq;  	int                        ctl_mute;             /* audio */  	int                        ctl_volume;  	int                        ctl_invert;           /* private */ @@ -766,7 +767,7 @@ extern struct video_device saa7134_radio_template;  int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, struct v4l2_control *c);  int saa7134_g_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, struct v4l2_control *c);  int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c); -int saa7134_s_std_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, v4l2_std_id *id); +int saa7134_s_std_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, v4l2_std_id id);  int saa7134_videoport_init(struct saa7134_dev *dev);  void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index 91369daad72..71e8bead321 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c @@ -560,7 +560,7 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)  	return call_all(dev, tuner, g_tuner, t);  } -static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t) +static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *t)  {  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;  	struct mxb *mxb = (struct mxb *)dev->ext_priv; @@ -595,7 +595,7 @@ static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency  	return 0;  } -static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f) +static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f)  {  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;  	struct mxb *mxb = (struct mxb *)dev->ext_priv; @@ -612,8 +612,8 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency  	/* tune in desired frequency */  	tuner_call(mxb, tuner, s_frequency, f);  	/* let the tuner subdev clamp the frequency to the tuner range */ -	tuner_call(mxb, tuner, g_frequency, f);  	mxb->cur_freq = *f; +	tuner_call(mxb, tuner, g_frequency, &mxb->cur_freq);  	if (mxb->cur_audinput == 0)  		mxb_update_audmode(mxb); @@ -680,7 +680,7 @@ static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_regist  	return 0;  } -static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) +static int vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)  {  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; @@ -688,7 +688,6 @@ static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_regist  		return -EPERM;  	if (v4l2_chip_match_host(®->match)) {  		saa7146_write(dev, reg->reg, reg->val); -		reg->size = 4;  		return 0;  	}  	return call_all(dev, core, s_register, reg); diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 63502e7a2a7..7618fdae811 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug, "enable debug messages");  unsigned int fw_debug;  module_param(fw_debug, int, 0644); -MODULE_PARM_DESC(fw_debug, "Firware debug level def:2"); +MODULE_PARM_DESC(fw_debug, "Firmware debug level def:2");  unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS;  module_param(encoder_buffers, int, 0644); diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c index 9bb0903ee5f..0b74fb2300d 100644 --- a/drivers/media/pci/saa7164/saa7164-encoder.c +++ b/drivers/media/pci/saa7164/saa7164-encoder.c @@ -211,17 +211,17 @@ static int saa7164_encoder_initialize(struct saa7164_port *port)  }  /* -- V4L2 --------------------------------------------------------- */ -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) +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); +	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) +		if (id & saa7164_tvnorms[i].id)  			break;  	}  	if (i == ARRAY_SIZE(saa7164_tvnorms)) @@ -234,7 +234,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)  	 */  	saa7164_api_set_audio_std(port); -	dprintk(DBGLVL_ENC, "%s(id=0x%x) OK\n", __func__, (u32)*id); +	dprintk(DBGLVL_ENC, "%s(id=0x%x) OK\n", __func__, (u32)id);  	return 0;  } @@ -318,7 +318,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,  }  static int vidioc_s_tuner(struct file *file, void *priv, -	struct v4l2_tuner *t) +	const struct v4l2_tuner *t)  {  	/* Update the A/V core */  	return 0; @@ -337,7 +337,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,  }  static int vidioc_s_frequency(struct file *file, void *priv, -	struct v4l2_frequency *f) +	const struct v4l2_frequency *f)  {  	struct saa7164_encoder_fh *fh = file->private_data;  	struct saa7164_port *port = fh->port; @@ -1313,7 +1313,7 @@ static int saa7164_g_register(struct file *file, void *fh,  }  static int saa7164_s_register(struct file *file, void *fh, -			      struct v4l2_dbg_register *reg) +			      const struct v4l2_dbg_register *reg)  {  	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;  	struct saa7164_dev *dev = port->dev; diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c index b4532299c0e..da224eb39b9 100644 --- a/drivers/media/pci/saa7164/saa7164-vbi.c +++ b/drivers/media/pci/saa7164/saa7164-vbi.c @@ -183,17 +183,17 @@ static int saa7164_vbi_initialize(struct saa7164_port *port)  }  /* -- V4L2 --------------------------------------------------------- */ -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) +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); +	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) +		if (id & saa7164_tvnorms[i].id)  			break;  	}  	if (i == ARRAY_SIZE(saa7164_tvnorms)) @@ -206,7 +206,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)  	 */  	saa7164_api_set_audio_std(port); -	dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)*id); +	dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)id);  	return 0;  } @@ -290,7 +290,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,  }  static int vidioc_s_tuner(struct file *file, void *priv, -	struct v4l2_tuner *t) +	const struct v4l2_tuner *t)  {  	/* Update the A/V core */  	return 0; @@ -309,7 +309,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,  }  static int vidioc_s_frequency(struct file *file, void *priv, -	struct v4l2_frequency *f) +	const struct v4l2_frequency *f)  {  	struct saa7164_vbi_fh *fh = file->private_data;  	struct saa7164_port *port = fh->port; diff --git a/drivers/media/pci/sta2x11/Kconfig b/drivers/media/pci/sta2x11/Kconfig index a94ccad0206..03130157db8 100644 --- a/drivers/media/pci/sta2x11/Kconfig +++ b/drivers/media/pci/sta2x11/Kconfig @@ -4,6 +4,7 @@ config STA2X11_VIP  	select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT  	select VIDEOBUF2_DMA_CONTIG  	depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS +	depends on I2C  	help  	  Say Y for support for STA2X11 VIP (Video Input Port) capture  	  device. diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index 4b703fe8c95..7005695aa4b 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c @@ -439,22 +439,22 @@ static int vidioc_querycap(struct file *file, void *priv,   *   * other, returned from video DAC.   */ -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)  {  	struct sta2x11_vip *vip = video_drvdata(file);  	v4l2_std_id oldstd = vip->std, newstd;  	int status; -	if (V4L2_STD_ALL == *std) { -		v4l2_subdev_call(vip->decoder, core, s_std, *std); +	if (V4L2_STD_ALL == std) { +		v4l2_subdev_call(vip->decoder, core, s_std, std);  		ssleep(2);  		v4l2_subdev_call(vip->decoder, video, querystd, &newstd);  		v4l2_subdev_call(vip->decoder, video, g_input_status, &status);  		if (status & V4L2_IN_ST_NO_SIGNAL)  			return -EIO; -		*std = vip->std = newstd; -		if (oldstd != *std) { -			if (V4L2_STD_525_60 & (*std)) +		std = vip->std = newstd; +		if (oldstd != std) { +			if (V4L2_STD_525_60 & std)  				vip->format = formats_60[0];  			else  				vip->format = formats_50[0]; @@ -462,14 +462,14 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)  		return 0;  	} -	if (oldstd != *std) { -		if (V4L2_STD_525_60 & (*std)) +	if (oldstd != std) { +		if (V4L2_STD_525_60 & std)  			vip->format = formats_60[0];  		else  			vip->format = formats_50[0];  	} -	return v4l2_subdev_call(vip->decoder, core, s_std, *std); +	return v4l2_subdev_call(vip->decoder, core, s_std, std);  }  /** diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index 3dc7aa9b6f4..f38329d29da 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -990,7 +990,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)  	if (feed->type == DMX_TYPE_TS) {  		if ((feed->ts_type & TS_DECODER) && -		    (feed->pes_type <= DMX_TS_PES_PCR)) { +		    (feed->pes_type <= DMX_PES_PCR)) {  			switch (demux->dmx.frontend->source) {  			case DMX_MEMORY_FE:  				if (feed->ts_type & TS_DECODER) @@ -1051,14 +1051,14 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)  	if (feed->type == DMX_TYPE_TS) {  		if (feed->ts_type & TS_DECODER) { -			if (feed->pes_type >= DMX_TS_PES_OTHER || +			if (feed->pes_type >= DMX_PES_OTHER ||  			    !demux->pesfilter[feed->pes_type])  				return -EINVAL;  			demux->pids[feed->pes_type] |= 0x8000;  			demux->pesfilter[feed->pes_type] = NULL;  		}  		if (feed->ts_type & TS_DECODER && -		    feed->pes_type < DMX_TS_PES_OTHER) { +		    feed->pes_type < DMX_PES_OTHER) {  			ret = dvb_feed_stop_pid(feed);  		} else  			if ((feed->ts_type & TS_PACKET) && diff --git a/drivers/media/pci/ttpci/av7110_v4l.c b/drivers/media/pci/ttpci/av7110_v4l.c index 730e906ea91..6c4076acb13 100644 --- a/drivers/media/pci/ttpci/av7110_v4l.c +++ b/drivers/media/pci/ttpci/av7110_v4l.c @@ -366,7 +366,7 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)  	return 0;  } -static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t) +static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *t)  {  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;  	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; @@ -426,7 +426,7 @@ static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency  	return 0;  } -static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f) +static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f)  {  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;  	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c index 7e6e43ae5c5..6ccc48833fd 100644 --- a/drivers/media/pci/ttpci/budget.c +++ b/drivers/media/pci/ttpci/budget.c @@ -537,6 +537,16 @@ static void frontend_init(struct budget *budget)  		}  		break; +	case 0x4f52: /* Cards based on Philips Semi Sylt PCI ref. design */ +		budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); +		if (budget->dvb_frontend) { +			printk(KERN_INFO "budget: tuner ALPS BSRU6 in Philips Semi. Sylt detected\n"); +			budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; +			budget->dvb_frontend->tuner_priv = &budget->i2c_adap; +			break; +		} +		break; +  	case 0x4f60: /* Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/tsa5059) */  	{  		int subtype = i2c_readreg(&budget->i2c_adap, 0x50, 0x67); @@ -818,6 +828,7 @@ MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps front  MAKE_BUDGET_INFO(fsact,	 "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY);  MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY);  MAKE_BUDGET_INFO(omicom, "Omicom S2 PCI", BUDGET_TT); +MAKE_BUDGET_INFO(sylt,   "Philips Semi Sylt PCI", BUDGET_TT_HW_DISEQC);  static struct pci_device_id pci_tbl[] = {  	MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003), @@ -832,6 +843,7 @@ static struct pci_device_id pci_tbl[] = {  	MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60),  	MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61),  	MAKE_EXTENSION_PCI(omicom, 0x14c4, 0x1020), +	MAKE_EXTENSION_PCI(sylt, 0x1131, 0x4f52),  	{  		.vendor    = 0,  	} diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index 2e8f518f298..1168a84a737 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c @@ -2435,14 +2435,14 @@ static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)  	return 0;  } -static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std) +static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id std)  {  	struct zoran_fh *fh = __fh;  	struct zoran *zr = fh->zr;  	int res = 0;  	mutex_lock(&zr->resource_lock); -	res = zoran_set_norm(zr, *std); +	res = zoran_set_norm(zr, std);  	if (res)  		goto sstd_unlock_and_return; diff --git a/drivers/media/pci/zoran/zoran_procfs.c b/drivers/media/pci/zoran/zoran_procfs.c index e084b0a21b1..1512b5d4053 100644 --- a/drivers/media/pci/zoran/zoran_procfs.c +++ b/drivers/media/pci/zoran/zoran_procfs.c @@ -201,7 +201,7 @@ zoran_proc_init (struct zoran *zr)  		dprintk(2,  			KERN_INFO  			"%s: procfs entry /proc/%s allocated. data=%p\n", -			ZR_DEVNAME(zr), name, zr->zoran_proc->data); +			ZR_DEVNAME(zr), name, zr);  	} else {  		dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n",  			ZR_DEVNAME(zr), name);  |