diff options
Diffstat (limited to 'drivers/media/pci')
72 files changed, 1502 insertions, 2516 deletions
diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c index 447afbd904a..8b5e0b3a92a 100644 --- a/drivers/media/pci/b2c2/flexcop-pci.c +++ b/drivers/media/pci/b2c2/flexcop-pci.c @@ -319,7 +319,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)  err_pci_iounmap:  	pci_iounmap(fc_pci->pdev, fc_pci->io_mem); -	pci_set_drvdata(fc_pci->pdev, NULL);  err_pci_release_regions:  	pci_release_regions(fc_pci->pdev);  err_pci_disable_device: @@ -332,7 +331,6 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci)  	if (fc_pci->init_state & FC_PCI_INIT) {  		free_irq(fc_pci->pdev->irq, fc_pci);  		pci_iounmap(fc_pci->pdev, fc_pci->io_mem); -		pci_set_drvdata(fc_pci->pdev, NULL);  		pci_release_regions(fc_pci->pdev);  		pci_disable_device(fc_pci->pdev);  	} diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 66eb0baab0e..d0c281f41a0 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c @@ -488,8 +488,7 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  	btwrite(0, BT848_INT_MASK);  	result = request_irq(bt->irq, bt878_irq, -			     IRQF_SHARED | IRQF_DISABLED, "bt878", -			     (void *) bt); +			     IRQF_SHARED, "bt878", (void *) bt);  	if (result == -EINVAL) {  		printk(KERN_ERR "bt878(%d): Bad irq number or handler\n",  		       bt878_num); @@ -563,7 +562,6 @@ static void bt878_remove(struct pci_dev *pci_dev)  	bt->shutdown = 1;  	bt878_mem_free(bt); -	pci_set_drvdata(pci_dev, NULL);  	pci_disable_device(pci_dev);  	return;  } diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index d85cb0ace4d..d8ec583c154 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -52,6 +52,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 ee[256]);  static void modtec_eeprom(struct bttv *btv);  static void init_PXC200(struct bttv *btv);  static void init_RTV24(struct bttv *btv); +static void init_PCI8604PW(struct bttv *btv);  static void rv605_muxsel(struct bttv *btv, unsigned int input);  static void eagle_muxsel(struct bttv *btv, unsigned int input); @@ -2426,7 +2427,7 @@ struct tvcard bttv_tvcards[] = {  	},  		/* ---- card 0x87---------------------------------- */  	[BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { -		/* Michael Krufky <mkrufky@m1k.net> */ +		/* Michael Krufky <mkrufky@linuxtv.org> */  		.name           = "DViCO FusionHDTV 5 Lite",  		.tuner_type     = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */  		.tuner_addr	= ADDR_UNSET, @@ -2855,7 +2856,38 @@ struct tvcard bttv_tvcards[] = {  		.tuner_type	= TUNER_ABSENT,  		.tuner_addr	= ADDR_UNSET,  	}, - +	[BTTV_BOARD_KWORLD_VSTREAM_XPERT] = { +		/* Pojar George <geoubuntu@gmail.com> */ +		.name           = "Kworld V-Stream Xpert TV PVR878", +		.video_inputs   = 3, +		/* .audio_inputs= 1, */ +		.svhs           = 2, +		.gpiomask       = 0x001c0007, +		.muxsel         = MUXSEL(2, 3, 1, 1), +		.gpiomux        = { 0, 1, 2, 2 }, +		.gpiomute       = 3, +		.pll            = PLL_28, +		.tuner_type     = TUNER_TENA_9533_DI, +		.tuner_addr    = ADDR_UNSET, +		.has_remote     = 1, +		.has_radio      = 1, +	}, +	/* ---- card 0xa6---------------------------------- */ +	[BTTV_BOARD_PCI_8604PW] = { +		/* PCI-8604PW with special unlock sequence */ +		.name           = "PCI-8604PW", +		.video_inputs   = 2, +		/* .audio_inputs= 0, */ +		.svhs           = NO_SVHS, +		/* The second input is available on CN4, if populated. +		 * The other 5x2 header (CN2?) connects to the same inputs +		 * as the on-board BNCs */ +		.muxsel         = MUXSEL(2, 3), +		.tuner_type     = TUNER_ABSENT, +		.no_msp34xx	= 1, +		.no_tda7432	= 1, +		.pll            = PLL_35, +	},  };  static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -3290,6 +3322,9 @@ void bttv_init_card1(struct bttv *btv)  	case BTTV_BOARD_ADLINK_RTV24:  		init_RTV24( btv );  		break; +	case BTTV_BOARD_PCI_8604PW: +		init_PCI8604PW(btv); +		break;  	}  	if (!bttv_tvcards[btv->c.type].has_dvb) @@ -4170,6 +4205,96 @@ init_RTV24 (struct bttv *btv)  /* ----------------------------------------------------------------------- */ +/* + *  The PCI-8604PW contains a CPLD, probably an ispMACH 4A, that filters + *  the PCI REQ signals comming from the four BT878 chips. After power + *  up, the CPLD does not forward requests to the bus, which prevents + *  the BT878 from fetching RISC instructions from memory. While the + *  CPLD is connected to most of the GPIOs of PCI device 0xD, only + *  five appear to play a role in unlocking the REQ signal. The following + *  sequence has been determined by trial and error without access to the + *  original driver. + * + *  Eight GPIOs of device 0xC are provided on connector CN4 (4 in, 4 out). + *  Devices 0xE and 0xF do not appear to have anything connected to their + *  GPIOs. + * + *  The correct GPIO_OUT_EN value might have some more bits set. It should + *  be possible to derive it from a boundary scan of the CPLD. Its JTAG + *  pins are routed to test points. + * + */ +/* ----------------------------------------------------------------------- */ +static void +init_PCI8604PW(struct bttv *btv) +{ +	int state; + +	if ((PCI_SLOT(btv->c.pci->devfn) & ~3) != 0xC) { +		pr_warn("This is not a PCI-8604PW\n"); +		return; +	} + +	if (PCI_SLOT(btv->c.pci->devfn) != 0xD) +		return; + +	btwrite(0x080002, BT848_GPIO_OUT_EN); + +	state = (btread(BT848_GPIO_DATA) >> 21) & 7; + +	for (;;) { +		switch (state) { +		case 1: +		case 5: +		case 6: +		case 4: +			pr_debug("PCI-8604PW in state %i, toggling pin\n", +				 state); +			btwrite(0x080000, BT848_GPIO_DATA); +			msleep(1); +			btwrite(0x000000, BT848_GPIO_DATA); +			msleep(1); +			break; +		case 7: +			pr_info("PCI-8604PW unlocked\n"); +			return; +		case 0: +			/* FIXME: If we are in state 7 and toggle GPIO[19] one +			   more time, the CPLD goes into state 0, where PCI bus +			   mastering is inhibited again. We have not managed to +			   get out of that state. */ + +			pr_err("PCI-8604PW locked until reset\n"); +			return; +		default: +			pr_err("PCI-8604PW in unknown state %i\n", state); +			return; +		} + +		state = (state << 4) | ((btread(BT848_GPIO_DATA) >> 21) & 7); + +		switch (state) { +		case 0x15: +		case 0x56: +		case 0x64: +		case 0x47: +		/* The transition from state 7 to state 0 is, as explained +		   above, valid but undesired and with this code impossible +		   as we exit as soon as we are in state 7. +		case 0x70: */ +			break; +		default: +			pr_err("PCI-8604PW invalid transition %i -> %i\n", +			       state >> 4, state & 7); +			return; +		} +		state &= 7; +	} +} + + + +/* ----------------------------------------------------------------------- */  /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports     */  /*   * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu> diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index c6532de0eac..da780f42b12 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -1126,9 +1126,9 @@ bttv_crop_calc_limits(struct bttv_crop *c)  		c->min_scaled_height = 32;  	} else {  		c->min_scaled_width = -			(max(48, c->rect.width >> 4) + 3) & ~3; +			(max_t(unsigned int, 48, c->rect.width >> 4) + 3) & ~3;  		c->min_scaled_height = -			max(32, c->rect.height >> 4); +			max_t(unsigned int, 32, c->rect.height >> 4);  	}  	c->max_scaled_width  = c->rect.width & ~3; @@ -1182,7 +1182,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)  		break;  	}  	id = tvnorm->v4l2_id; -	bttv_call_all(btv, core, s_std, id); +	bttv_call_all(btv, video, s_std, id);  	return 0;  } @@ -2024,7 +2024,7 @@ limit_scaled_size_lock       (struct bttv_fh *               fh,  		/* We cannot scale up. When the scaled image is larger  		   than crop.rect we adjust the crop.rect as required  		   by the V4L2 spec, hence cropcap.bounds are our limit. */ -		max_width = min(b->width, (__s32) MAX_HACTIVE); +		max_width = min_t(unsigned int, b->width, MAX_HACTIVE);  		max_height = b->height;  		/* We cannot capture the same line as video and VBI data. @@ -3266,7 +3266,9 @@ static ssize_t radio_read(struct file *file, char __user *data,  	struct bttv_fh *fh = file->private_data;  	struct bttv *btv = fh->btv;  	struct saa6588_command cmd; -	cmd.block_count = count/3; + +	cmd.block_count = count / 3; +	cmd.nonblocking = file->f_flags & O_NONBLOCK;  	cmd.buffer = data;  	cmd.instance = file;  	cmd.result = -ENODEV; @@ -4086,7 +4088,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  	/* disable irqs, register irq handler */  	btwrite(0, BT848_INT_MASK);  	result = request_irq(btv->c.pci->irq, bttv_irq, -	    IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv); +	    IRQF_SHARED, btv->c.v4l2_dev.name, (void *)btv);  	if (result < 0) {  		pr_err("%d: can't get IRQ %d\n",  		       bttv_num, btv->c.pci->irq); @@ -4182,7 +4184,8 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)  	}  	btv->std = V4L2_STD_PAL;  	init_irqreg(btv); -	v4l2_ctrl_handler_setup(hdl); +	if (!bttv_tvcards[btv->c.type].no_video) +		v4l2_ctrl_handler_setup(hdl);  	if (hdl->error) {  		result = hdl->error;  		goto fail2; diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c index 922e8233fd0..3f364b7062b 100644 --- a/drivers/media/pci/bt8xx/bttv-gpio.c +++ b/drivers/media/pci/bt8xx/bttv-gpio.c @@ -98,7 +98,7 @@ int bttv_sub_add_device(struct bttv_core *core, char *name)  	err = device_register(&sub->dev);  	if (0 != err) { -		kfree(sub); +		put_device(&sub->dev);  		return err;  	}  	pr_info("%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev)); diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index f36821367d8..5930bce1665 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -483,6 +483,7 @@ int bttv_input_init(struct bttv *btv)  	case BTTV_BOARD_ASKEY_CPH03X:  	case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:  	case BTTV_BOARD_CONTVFMI: +	case BTTV_BOARD_KWORLD_VSTREAM_XPERT:  		ir_codes         = RC_MAP_PIXELVIEW;  		ir->mask_keycode = 0x001F00;  		ir->mask_keyup   = 0x006000; diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h index df578efe03c..f0812624466 100644 --- a/drivers/media/pci/bt8xx/bttv.h +++ b/drivers/media/pci/bt8xx/bttv.h @@ -188,6 +188,8 @@  #define BTTV_BOARD_ADLINK_MPG24            0xa2  #define BTTV_BOARD_BT848_CAP_14            0xa3  #define BTTV_BOARD_CYBERVISION_CV06        0xa4 +#define BTTV_BOARD_KWORLD_VSTREAM_XPERT    0xa5 +#define BTTV_BOARD_PCI_8604PW              0xa6  /* more card-specific defines */  #define PT2254_L_CHANNEL 0x10 diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c index 430b3eb1181..f2261dfe5d1 100644 --- a/drivers/media/pci/bt8xx/dst.c +++ b/drivers/media/pci/bt8xx/dst.c @@ -1544,7 +1544,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)  } -static int dst_init(struct dvb_frontend *fe) +static int bt8xx_dst_init(struct dvb_frontend *fe)  {  	struct dst_state *state = fe->demodulator_priv; @@ -1707,7 +1707,7 @@ static int dst_get_frontend(struct dvb_frontend *fe)  	return 0;  } -static void dst_release(struct dvb_frontend *fe) +static void bt8xx_dst_release(struct dvb_frontend *fe)  {  	struct dst_state *state = fe->demodulator_priv;  	if (state->dst_ca) { @@ -1776,8 +1776,8 @@ static struct dvb_frontend_ops dst_dvbt_ops = {  			FE_CAN_GUARD_INTERVAL_AUTO  	}, -	.release = dst_release, -	.init = dst_init, +	.release = bt8xx_dst_release, +	.init = bt8xx_dst_init,  	.tune = dst_tune_frontend,  	.set_frontend = dst_set_frontend,  	.get_frontend = dst_get_frontend, @@ -1801,8 +1801,8 @@ static struct dvb_frontend_ops dst_dvbs_ops = {  		.caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK  	}, -	.release = dst_release, -	.init = dst_init, +	.release = bt8xx_dst_release, +	.init = bt8xx_dst_init,  	.tune = dst_tune_frontend,  	.set_frontend = dst_set_frontend,  	.get_frontend = dst_get_frontend, @@ -1834,8 +1834,8 @@ static struct dvb_frontend_ops dst_dvbc_ops = {  			FE_CAN_QAM_256  	}, -	.release = dst_release, -	.init = dst_init, +	.release = bt8xx_dst_release, +	.init = bt8xx_dst_init,  	.tune = dst_tune_frontend,  	.set_frontend = dst_set_frontend,  	.get_frontend = dst_get_frontend, @@ -1857,8 +1857,8 @@ static struct dvb_frontend_ops dst_atsc_ops = {  		.caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB  	}, -	.release = dst_release, -	.init = dst_init, +	.release = bt8xx_dst_release, +	.init = bt8xx_dst_init,  	.tune = dst_tune_frontend,  	.set_frontend = dst_set_frontend,  	.get_frontend = dst_get_frontend, diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c index b2c8c3439fe..ea272bcb38d 100644 --- a/drivers/media/pci/cx18/cx18-alsa-main.c +++ b/drivers/media/pci/cx18/cx18-alsa-main.c @@ -145,11 +145,12 @@ static int snd_cx18_init(struct v4l2_device *v4l2_dev)  	/* This is a no-op for us.  We'll use the cx->instance */  	/* (2) Create a card instance */ -	ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */ -			      SNDRV_DEFAULT_STR1, /* xid from end of shortname*/ -			      THIS_MODULE, 0, &sc); +	ret = snd_card_new(&cx->pci_dev->dev, +			   SNDRV_DEFAULT_IDX1, /* use first available id */ +			   SNDRV_DEFAULT_STR1, /* xid from end of shortname*/ +			   THIS_MODULE, 0, &sc);  	if (ret) { -		CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n", +		CX18_ALSA_ERR("%s: snd_card_new() failed with err %d\n",  			      __func__, ret);  		goto err_exit;  	} diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index c4890a430dc..2d3afe0431a 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c @@ -1263,7 +1263,6 @@ static const struct v4l2_subdev_core_ops cx18_av_general_ops = {  	.log_status = cx18_av_log_status,  	.load_fw = cx18_av_load_fw,  	.reset = cx18_av_reset, -	.s_std = cx18_av_s_std,  #ifdef CONFIG_VIDEO_ADV_DEBUG  	.g_register = cx18_av_g_register,  	.s_register = cx18_av_s_register, @@ -1283,6 +1282,7 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {  };  static const struct v4l2_subdev_video_ops cx18_av_video_ops = { +	.s_std = cx18_av_s_std,  	.s_routing = cx18_av_s_video_routing,  	.s_stream = cx18_av_s_stream,  	.s_mbus_fmt = cx18_av_s_mbus_fmt, diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index 004d8ace501..716bdc57fac 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c @@ -324,23 +324,27 @@ static void cx18_eeprom_dump(struct cx18 *cx, unsigned char *eedata, int len)  /* Hauppauge card? get values from tveeprom */  void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)  { -	struct i2c_client c; +	struct i2c_client *c;  	u8 eedata[256]; -	memset(&c, 0, sizeof(c)); -	strlcpy(c.name, "cx18 tveeprom tmp", sizeof(c.name)); -	c.adapter = &cx->i2c_adap[0]; -	c.addr = 0xA0 >> 1; -  	memset(tv, 0, sizeof(*tv)); -	if (tveeprom_read(&c, eedata, sizeof(eedata))) + +	c = kzalloc(sizeof(*c), GFP_KERNEL); +	if (!c)  		return; +	strlcpy(c->name, "cx18 tveeprom tmp", sizeof(c->name)); +	c->adapter = &cx->i2c_adap[0]; +	c->addr = 0xa0 >> 1; + +	if (tveeprom_read(c, eedata, sizeof(eedata))) +		goto ret; +  	switch (cx->card->type) {  	case CX18_CARD_HVR_1600_ESMT:  	case CX18_CARD_HVR_1600_SAMSUNG:  	case CX18_CARD_HVR_1600_S5H1411: -		tveeprom_hauppauge_analog(&c, tv, eedata); +		tveeprom_hauppauge_analog(c, tv, eedata);  		break;  	case CX18_CARD_YUAN_MPC718:  	case CX18_CARD_GOTVIEW_PCI_DVD3: @@ -354,6 +358,9 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)  		cx18_eeprom_dump(cx, eedata, sizeof(eedata));  		break;  	} + +ret: +	kfree(c);  }  static void cx18_process_eeprom(struct cx18 *cx) @@ -1031,8 +1038,7 @@ static int cx18_probe(struct pci_dev *pci_dev,  	/* Register IRQ */  	retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, -			     IRQF_SHARED | IRQF_DISABLED, -			     cx->v4l2_dev.name, (void *)cx); +			     IRQF_SHARED, cx->v4l2_dev.name, (void *)cx);  	if (retval) {  		CX18_ERR("Failed to register irq %d\n", retval);  		goto free_i2c; diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h index 2767c64df0c..57f4688ea55 100644 --- a/drivers/media/pci/cx18/cx18-driver.h +++ b/drivers/media/pci/cx18/cx18-driver.h @@ -262,7 +262,7 @@ struct cx18_options {  };  /* per-mdl bit flags */ -#define CX18_F_M_NEED_SWAP  0	/* mdl buffer data must be endianess swapped */ +#define CX18_F_M_NEED_SWAP  0	/* mdl buffer data must be endianness swapped */  /* per-stream, s_flags */  #define CX18_F_S_CLAIMED 	3	/* this stream is claimed */ diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index 4bfd865a410..76a3b4ac541 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c @@ -760,7 +760,7 @@ int cx18_v4l2_close(struct file *filp)  		/* Mark that the radio is no longer in use */  		clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);  		/* Switch tuner to TV */ -		cx18_call_all(cx, core, s_std, cx->std); +		cx18_call_all(cx, video, s_std, cx->std);  		/* Select correct audio input (i.e. TV tuner or Line in) */  		cx18_audio_set_io(cx);  		if (atomic_read(&cx->ana_capturing) > 0) { diff --git a/drivers/media/pci/cx18/cx18-gpio.c b/drivers/media/pci/cx18/cx18-gpio.c index 5374aeb0cd2..38dc6b8f825 100644 --- a/drivers/media/pci/cx18/cx18-gpio.c +++ b/drivers/media/pci/cx18/cx18-gpio.c @@ -180,7 +180,6 @@ static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,  static const struct v4l2_subdev_core_ops gpiomux_core_ops = {  	.log_status = gpiomux_log_status, -	.s_std = gpiomux_s_std,  };  static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = { @@ -191,10 +190,15 @@ static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {  	.s_routing = gpiomux_s_audio_routing,  }; +static const struct v4l2_subdev_video_ops gpiomux_video_ops = { +	.s_std = gpiomux_s_std, +}; +  static const struct v4l2_subdev_ops gpiomux_ops = {  	.core = &gpiomux_core_ops,  	.tuner = &gpiomux_tuner_ops,  	.audio = &gpiomux_audio_ops, +	.video = &gpiomux_video_ops,  };  /* diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index 1110bcb14e2..fefb2cd3583 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c @@ -602,7 +602,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)  			(unsigned long long) cx->std);  	/* Tuner */ -	cx18_call_all(cx, core, s_std, cx->std); +	cx18_call_all(cx, video, s_std, cx->std);  	return 0;  } diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig index 5104c802f72..d1dcb1d2e08 100644 --- a/drivers/media/pci/cx23885/Kconfig +++ b/drivers/media/pci/cx23885/Kconfig @@ -23,6 +23,7 @@ config VIDEO_CX23885  	select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT  	select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT  	select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT +	select DVB_CX24117 if MEDIA_SUBDRV_AUTOSELECT  	select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT  	select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT  	select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c index 7344849183a..16fa7ea4d4a 100644 --- a/drivers/media/pci/cx23885/cimax2.c +++ b/drivers/media/pci/cx23885/cimax2.c @@ -26,6 +26,10 @@  #include "cx23885.h"  #include "cimax2.h"  #include "dvb_ca_en50221.h" + +/* Max transfer size done by I2C transfer functions */ +#define MAX_XFER_SIZE  64 +  /**** Bit definitions for MC417_RWD and MC417_OEN registers  ***    bits 31-16  +-----------+ @@ -125,7 +129,7 @@ static int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,  						u8 *buf, int len)  {  	int ret; -	u8 buffer[len + 1]; +	u8 buffer[MAX_XFER_SIZE];  	struct i2c_msg msg = {  		.addr	= addr, @@ -134,6 +138,13 @@ static int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,  		.len	= len + 1  	}; +	if (1 + len > sizeof(buffer)) { +		printk(KERN_WARNING +		       "%s: i2c wr reg=%04x: len=%d is too big!\n", +		       KBUILD_MODNAME, reg, len); +		return -EINVAL; +	} +  	buffer[0] = reg;  	memcpy(&buffer[1], buf, len); diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index e3fc2c71808..95666eee7b2 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c @@ -427,7 +427,7 @@ int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)  	cx_write(MC417_RWD, regval);  	/* Transition RD to effect read transaction across bus. -	 * Transtion 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)? +	 * Transition 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)?  	 * Should it be 0x9000 -> 0xF000 (also why is RDY being set, its  	 * input only...)  	 */ diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index c6c9bd58f8b..554798dcedd 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -489,7 +489,8 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev)  		return NULL;  	} -	err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, +	err = snd_card_new(&dev->pci->dev, +			   SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,  			THIS_MODULE, sizeof(struct cx23885_audio_dev), &card);  	if (err < 0)  		goto error; @@ -500,8 +501,6 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev)  	chip->card = card;  	spin_lock_init(&chip->lock); -	snd_card_set_dev(card, &dev->pci->dev); -  	err = snd_cx23885_pcm(chip, 0, "CX23885 Digital");  	if (err < 0)  		goto error; diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 6a71a965e75..79f20c8c842 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -223,6 +223,39 @@ struct cx23885_board cx23885_boards[] = {  		.name		= "Leadtek Winfast PxDVR3200 H",  		.portc		= CX23885_MPEG_DVB,  	}, +	[CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200] = { +		.name		= "Leadtek Winfast PxPVR2200", +		.porta		= CX23885_ANALOG_VIDEO, +		.tuner_type	= TUNER_XC2028, +		.tuner_addr	= 0x61, +		.tuner_bus	= 1, +		.input		= {{ +			.type	= CX23885_VMUX_TELEVISION, +			.vmux	= CX25840_VIN2_CH1 | +				  CX25840_VIN5_CH2, +			.amux	= CX25840_AUDIO8, +			.gpio0	= 0x704040, +		}, { +			.type	= CX23885_VMUX_COMPOSITE1, +			.vmux	= CX25840_COMPOSITE1, +			.amux	= CX25840_AUDIO7, +			.gpio0	= 0x704040, +		}, { +			.type	= CX23885_VMUX_SVIDEO, +			.vmux	= CX25840_SVIDEO_LUMA3 | +				  CX25840_SVIDEO_CHROMA4, +			.amux	= CX25840_AUDIO7, +			.gpio0	= 0x704040, +		}, { +			.type	= CX23885_VMUX_COMPONENT, +			.vmux	= CX25840_VIN7_CH1 | +				  CX25840_VIN6_CH2 | +				  CX25840_VIN8_CH3 | +				  CX25840_COMPONENT_ON, +			.amux	= CX25840_AUDIO7, +			.gpio0	= 0x704040, +		} }, +	},  	[CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = {  		.name		= "Leadtek Winfast PxDVR3200 H XC4000",  		.porta		= CX23885_ANALOG_VIDEO, @@ -259,6 +292,16 @@ struct cx23885_board cx23885_boards[] = {  		.name		= "TurboSight TBS 6920",  		.portb		= CX23885_MPEG_DVB,  	}, +	[CX23885_BOARD_TBS_6980] = { +		.name		= "TurboSight TBS 6980", +		.portb		= CX23885_MPEG_DVB, +		.portc		= CX23885_MPEG_DVB, +	}, +	[CX23885_BOARD_TBS_6981] = { +		.name		= "TurboSight TBS 6981", +		.portb		= CX23885_MPEG_DVB, +		.portc		= CX23885_MPEG_DVB, +	},  	[CX23885_BOARD_TEVII_S470] = {  		.name		= "TeVii S470",  		.portb		= CX23885_MPEG_DVB, @@ -688,6 +731,10 @@ struct cx23885_subid cx23885_subids[] = {  		.card      = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H,  	}, {  		.subvendor = 0x107d, +		.subdevice = 0x6f21, +		.card      = CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200, +	}, { +		.subvendor = 0x107d,  		.subdevice = 0x6f39,  		.card	   = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000,  	}, { @@ -699,6 +746,14 @@ struct cx23885_subid cx23885_subids[] = {  		.subdevice = 0x8888,  		.card      = CX23885_BOARD_TBS_6920,  	}, { +		.subvendor = 0x6980, +		.subdevice = 0x8888, +		.card      = CX23885_BOARD_TBS_6980, +	}, { +		.subvendor = 0x6981, +		.subdevice = 0x8888, +		.card      = CX23885_BOARD_TBS_6981, +	}, {  		.subvendor = 0xd470,  		.subdevice = 0x9022,  		.card      = CX23885_BOARD_TEVII_S470, @@ -1023,6 +1078,35 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)  			dev->name, tv.model);  } +/* Some TBS cards require initing a chip using a bitbanged SPI attached +   to the cx23885 gpio's. If this chip doesn't get init'ed the demod +   doesn't respond to any command. */ +static void tbs_card_init(struct cx23885_dev *dev) +{ +	int i; +	const u8 buf[] = { +		0xe0, 0x06, 0x66, 0x33, 0x65, +		0x01, 0x17, 0x06, 0xde}; + +	switch (dev->board) { +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981: +		cx_set(GP0_IO, 0x00070007); +		usleep_range(1000, 10000); +		cx_clear(GP0_IO, 2); +		usleep_range(1000, 10000); +		for (i = 0; i < 9 * 8; i++) { +			cx_clear(GP0_IO, 7); +			usleep_range(1000, 10000); +			cx_set(GP0_IO, +				((buf[i >> 3] >> (7 - (i & 7))) & 1) | 4); +			usleep_range(1000, 10000); +		} +		cx_set(GP0_IO, 7); +		break; +	} +} +  int cx23885_tuner_callback(void *priv, int component, int command, int arg)  {  	struct cx23885_tsport *port = priv; @@ -1043,6 +1127,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)  	case CX23885_BOARD_HAUPPAUGE_HVR1500:  	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:  	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: +	case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:  	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:  	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:  	case CX23885_BOARD_COMPRO_VIDEOMATE_E800: @@ -1208,6 +1293,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)  		cx_set(GP0_IO, 0x000f000f);  		break;  	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: +	case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:  	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:  	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:  	case CX23885_BOARD_COMPRO_VIDEOMATE_E800: @@ -1225,6 +1311,8 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)  		cx_set(GP0_IO, 0x00040004);  		break;  	case CX23885_BOARD_TBS_6920: +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981:  	case CX23885_BOARD_PROF_8000:  		cx_write(MC417_CTL, 0x00000036);  		cx_write(MC417_OEN, 0x00001000); @@ -1473,6 +1561,8 @@ int cx23885_ir_init(struct cx23885_dev *dev)  	case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:  	case CX23885_BOARD_TEVII_S470:  	case CX23885_BOARD_MYGICA_X8507: +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981:  		if (!enable_885_ir)  			break;  		dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); @@ -1516,6 +1606,8 @@ void cx23885_ir_fini(struct cx23885_dev *dev)  	case CX23885_BOARD_TEVII_S470:  	case CX23885_BOARD_HAUPPAUGE_HVR1250:  	case CX23885_BOARD_MYGICA_X8507: +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981:  		cx23885_irq_remove(dev, PCI_MSK_AV_CORE);  		/* sd_ir is a duplicate pointer to the AV Core, just clear it */  		dev->sd_ir = NULL; @@ -1561,6 +1653,8 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)  	case CX23885_BOARD_TEVII_S470:  	case CX23885_BOARD_HAUPPAUGE_HVR1250:  	case CX23885_BOARD_MYGICA_X8507: +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981:  		if (dev->sd_ir)  			cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE);  		break; @@ -1676,6 +1770,16 @@ void cx23885_card_setup(struct cx23885_dev *dev)  		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */  		ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;  		break; +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981: +		ts1->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */ +		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ +		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; +		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */ +		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ +		ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; +		tbs_card_init(dev); +		break;  	case CX23885_BOARD_MYGICA_X8506:  	case CX23885_BOARD_MAGICPRO_PROHDTVE2:  	case CX23885_BOARD_MYGICA_X8507: @@ -1704,6 +1808,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)  	case CX23885_BOARD_HAUPPAUGE_HVR1700:  	case CX23885_BOARD_HAUPPAUGE_HVR1400:  	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: +	case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:  	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:  	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:  	case CX23885_BOARD_HAUPPAUGE_HVR1270: @@ -1733,6 +1838,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)  	case CX23885_BOARD_HAUPPAUGE_HVR1800lp:  	case CX23885_BOARD_HAUPPAUGE_HVR1700:  	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: +	case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:  	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:  	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:  	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: @@ -1752,6 +1858,8 @@ void cx23885_card_setup(struct cx23885_dev *dev)  	case CX23885_BOARD_MYGICA_X8507:  	case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:  	case CX23885_BOARD_AVERMEDIA_HC81R: +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981:  		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,  				&dev->i2c_bus[2].i2c_adap,  				"cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 9f63d93239e..edcd79db1e4 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2129,7 +2129,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev,  	}  	err = request_irq(pci_dev->irq, cx23885_irq, -			  IRQF_SHARED | IRQF_DISABLED, dev->name, dev); +			  IRQF_SHARED, dev->name, dev);  	if (err < 0) {  		printk(KERN_ERR "%s: can't get IRQ %d\n",  		       dev->name, pci_dev->irq); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 971e4ff1b87..4be01b3bd4f 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -51,6 +51,7 @@  #include "stv6110.h"  #include "lnbh24.h"  #include "cx24116.h" +#include "cx24117.h"  #include "cimax2.h"  #include "lgs8gxx.h"  #include "netup-eeprom.h" @@ -461,6 +462,10 @@ static struct cx24116_config tbs_cx24116_config = {  	.demod_address = 0x55,  }; +static struct cx24117_config tbs_cx24117_config = { +	.demod_address = 0x55, +}; +  static struct ds3000_config tevii_ds3000_config = {  	.demod_address = 0x68,  }; @@ -468,6 +473,7 @@ static struct ds3000_config tevii_ds3000_config = {  static struct ts2020_config tevii_ts2020_config  = {  	.tuner_address = 0x60,  	.clk_out_div = 1, +	.frequency_div = 1146000,  };  static struct cx24116_config dvbworld_cx24116_config = { @@ -1044,6 +1050,25 @@ static int dvb_register(struct cx23885_tsport *port)  			fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;  		break; +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981: +		i2c_bus = &dev->i2c_bus[1]; + +		switch (port->nr) { +		/* PORT B */ +		case 1: +			fe0->dvb.frontend = dvb_attach(cx24117_attach, +					&tbs_cx24117_config, +					&i2c_bus->i2c_adap); +			break; +		/* PORT C */ +		case 2: +			fe0->dvb.frontend = dvb_attach(cx24117_attach, +					&tbs_cx24117_config, +					&i2c_bus->i2c_adap); +			break; +		} +		break;  	case CX23885_BOARD_TEVII_S470:  		i2c_bus = &dev->i2c_bus[1]; diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 7875dfbe09f..097d0a0b5f5 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -90,6 +90,8 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)  	case CX23885_BOARD_TEVII_S470:  	case CX23885_BOARD_HAUPPAUGE_HVR1250:  	case CX23885_BOARD_MYGICA_X8507: +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981:  		/*  		 * The only boards we handle right now.  However other boards  		 * using the CX2388x integrated IR controller should be similar @@ -168,6 +170,8 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev)  		break;  	case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:  	case CX23885_BOARD_TEVII_S470: +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981:  		/*  		 * The IR controller on this board only returns pulse widths.  		 * Any other mode setting will fail to set up the device. @@ -298,6 +302,14 @@ int cx23885_input_init(struct cx23885_dev *dev)  		/* A guess at the remote */  		rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02;  		break; +	case CX23885_BOARD_TBS_6980: +	case CX23885_BOARD_TBS_6981: +		/* Integrated CX23885 IR controller */ +		driver_type = RC_DRIVER_IR_RAW; +		allowed_protos = RC_BIT_ALL; +		/* A guess at the remote */ +		rc_map = RC_MAP_TBS_NEC; +		break;  	default:  		return -ENODEV;  	} @@ -334,7 +346,7 @@ int cx23885_input_init(struct cx23885_dev *dev)  	}  	rc->dev.parent = &dev->pci->dev;  	rc->driver_type = driver_type; -	rc->allowed_protos = allowed_protos; +	rc_set_allowed_protocols(rc, allowed_protos);  	rc->priv = kernel_ir;  	rc->open = cx23885_input_ir_open;  	rc->close = cx23885_input_ir_close; diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 161686832b2..e0a59523cf3 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -326,7 +326,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)  	dev->tvnorm = norm; -	call_all(dev, core, s_std, norm); +	call_all(dev, video, s_std, norm);  	return 0;  } @@ -1589,7 +1589,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,  		fe = &dev->ts1.analog_fe;  	if (fe && fe->ops.tuner_ops.set_analog_params) { -		call_all(dev, core, s_std, dev->tvnorm); +		call_all(dev, video, s_std, dev->tvnorm);  		fe->ops.tuner_ops.set_analog_params(fe, ¶ms);  	}  	else @@ -1865,7 +1865,8 @@ int cx23885_video_register(struct cx23885_dev *dev)  			v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); -			if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) { +			if ((dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) || +			    (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200)) {  				struct xc2028_ctrl ctrl = {  					.fname = XC2028_DEFAULT_FIRMWARE,  					.max_len = 64 diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 038caf53908..0fa4048ab87 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -93,6 +93,9 @@  #define CX23885_BOARD_PROF_8000                37  #define CX23885_BOARD_HAUPPAUGE_HVR4400        38  #define CX23885_BOARD_AVERMEDIA_HC81R          39 +#define CX23885_BOARD_TBS_6981                 40 +#define CX23885_BOARD_TBS_6980                 41 +#define CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200 42  #define GPIO_0 0x00000001  #define GPIO_1 0x00000002 diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index 6e91e84d6bf..2dd5bcaa7e5 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -618,7 +618,7 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,   * Only boards with eeprom and byte 1 at eeprom=1 have it   */ -static DEFINE_PCI_DEVICE_TABLE(cx25821_audio_pci_tbl) = { +static const struct pci_device_id cx25821_audio_pci_tbl[] = {  	{0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},  	{0,}  }; @@ -645,8 +645,9 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)  		return -ENOENT;  	} -	err = snd_card_create(index[devno], id[devno], THIS_MODULE, -			sizeof(struct cx25821_audio_dev), &card); +	err = snd_card_new(&dev->pci->dev, index[devno], id[devno], +			   THIS_MODULE, +			   sizeof(struct cx25821_audio_dev), &card);  	if (err < 0) {  		pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n",  			__func__); @@ -682,8 +683,6 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)  		goto error;  	} -	snd_card_set_dev(card, &chip->pci->dev); -  	strcpy(card->shortname, "cx25821");  	sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name,  		chip->iobase, chip->irq); diff --git a/drivers/media/pci/cx25821/cx25821-cards.c b/drivers/media/pci/cx25821/cx25821-cards.c index 3b409feb03d..f2ebc989b30 100644 --- a/drivers/media/pci/cx25821/cx25821-cards.c +++ b/drivers/media/pci/cx25821/cx25821-cards.c @@ -45,5 +45,3 @@ struct cx25821_board cx25821_boards[] = {  	},  }; - -const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards); diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index b762c5b2ca1..e81173c41e5 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -1361,7 +1361,7 @@ static void cx25821_finidev(struct pci_dev *pci_dev)  	kfree(dev);  } -static DEFINE_PCI_DEVICE_TABLE(cx25821_pci_tbl) = { +static const struct pci_device_id cx25821_pci_tbl[] = {  	{  		/* CX25821 Athena */  		.vendor = 0x14f1, diff --git a/drivers/media/pci/cx25821/cx25821-medusa-video.c b/drivers/media/pci/cx25821/cx25821-medusa-video.c index 22fa04415cc..43bdfa4dfba 100644 --- a/drivers/media/pci/cx25821/cx25821-medusa-video.c +++ b/drivers/media/pci/cx25821/cx25821-medusa-video.c @@ -438,7 +438,7 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,  		decoder_count = decoder_select + 1;  	} else {  		decoder = 0; -		decoder_count = _num_decoders; +		decoder_count = dev->_max_num_decoders;  	}  	switch (width) { @@ -506,8 +506,6 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,  		break;  	} -	_display_field_cnt[decoder] = duration; -  	/* update hardware */  	fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp); @@ -667,8 +665,6 @@ int medusa_video_init(struct cx25821_dev *dev)  	int ret_val = 0;  	int i = 0; -	_num_decoders = dev->_max_num_decoders; -  	/* disable Auto source selection on all video decoders */  	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);  	value &= 0xFFFFF0FF; @@ -685,8 +681,14 @@ int medusa_video_init(struct cx25821_dev *dev)  	if (ret_val < 0)  		goto error; -	for (i = 0; i < _num_decoders; i++) -		medusa_set_decoderduration(dev, i, _display_field_cnt[i]); +	/* +	 * FIXME: due to a coding bug the duration was always 0. It's +	 * likely that it really should be something else, but due to the +	 * lack of documentation I have no idea what it should be. For +	 * now just fill in 0 as the duration. +	 */ +	for (i = 0; i < dev->_max_num_decoders; i++) +		medusa_set_decoderduration(dev, i, 0);  	/* Select monitor as DENC A input, power up the DAC */  	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp); @@ -717,7 +719,7 @@ int medusa_video_init(struct cx25821_dev *dev)  	/* Turn on all of the data out and control output pins. */  	value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);  	value &= 0xFEF0FE00; -	if (_num_decoders == MAX_DECODERS) { +	if (dev->_max_num_decoders == MAX_DECODERS) {  		/*  		 * Note: The octal board does not support control pins(bit16-19)  		 * These bits are ignored in the octal board. diff --git a/drivers/media/pci/cx25821/cx25821-medusa-video.h b/drivers/media/pci/cx25821/cx25821-medusa-video.h index 6175e096185..8bf602ff27b 100644 --- a/drivers/media/pci/cx25821/cx25821-medusa-video.h +++ b/drivers/media/pci/cx25821/cx25821-medusa-video.h @@ -40,10 +40,4 @@  #define CONTRAST_DEFAULT                5000  #define HUE_DEFAULT                     5000 -unsigned short _num_decoders; -unsigned short _num_cameras; - -unsigned int _video_standard; -int _display_field_cnt[MAX_DECODERS]; -  #endif diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c index 88ffef410c5..1f43be0b04c 100644 --- a/drivers/media/pci/cx25821/cx25821-video-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c @@ -159,10 +159,10 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_channel *chan, __le32  		 * 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; +			*(rp++) = cpu_to_le32(RISC_WRITECR); +			*(rp++) = cpu_to_le32(sram_ch->dma_ctl); +			*(rp++) = cpu_to_le32(FLD_VID_FIFO_EN); +			*(rp++) = cpu_to_le32(0x00000001);  		}  	} diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index aba5b1c649e..a72579a9f67 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -834,7 +834,7 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci,  	/* get irq */  	err = request_irq(chip->pci->irq, cx8801_irq, -			  IRQF_SHARED | IRQF_DISABLED, chip->core->name, chip); +			  IRQF_SHARED, chip->core->name, chip);  	if (err < 0) {  		dprintk(0, "%s: can't get IRQ %d\n",  		       chip->core->name, chip->pci->irq); @@ -852,8 +852,6 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci,  	chip->irq = pci->irq;  	synchronize_irq(chip->irq); -	snd_card_set_dev(card, &pci->dev); -  	*rchip = chip;  	*core_ptr = core; @@ -876,8 +874,8 @@ static int cx88_audio_initdev(struct pci_dev *pci,  		return (-ENOENT);  	} -	err = snd_card_create(index[devno], id[devno], THIS_MODULE, -			      sizeof(snd_cx88_card_t), &card); +	err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE, +			   sizeof(snd_cx88_card_t), &card);  	if (err < 0)  		return err; @@ -931,11 +929,9 @@ error:   */  static void cx88_audio_finidev(struct pci_dev *pci)  { -	struct cx88_audio_dev *card = pci_get_drvdata(pci); - -	snd_card_free((void *)card); +	struct snd_card *card = pci_get_drvdata(pci); -	pci_set_drvdata(pci, NULL); +	snd_card_free(card);  	devno--;  } @@ -951,27 +947,4 @@ static struct pci_driver cx88_audio_pci_driver = {  	.remove   = cx88_audio_finidev,  }; -/**************************************************************************** -				LINUX MODULE INIT - ****************************************************************************/ - -/* - * module init - */ -static int __init cx88_audio_init(void) -{ -	printk(KERN_INFO "cx2388x alsa driver version %s loaded\n", -	       CX88_VERSION); -	return pci_register_driver(&cx88_audio_pci_driver); -} - -/* - * module remove - */ -static void __exit cx88_audio_fini(void) -{ -	pci_unregister_driver(&cx88_audio_pci_driver); -} - -module_init(cx88_audio_init); -module_exit(cx88_audio_fini); +module_pci_driver(cx88_audio_pci_driver); diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index ad59dc9235a..e061c88b697 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -1012,7 +1012,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)  	set_tvaudio(core);  	// tell i2c chips -	call_all(core, core, s_std, norm); +	call_all(core, video, s_std, norm);  	/* The chroma_agc control should be inaccessible if the video format is SECAM */  	v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM); diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index f29e18c72f4..f991696a6c5 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -469,7 +469,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)  		dev->timeout = 10 * 1000 * 1000; /* 10 ms */  	} else {  		dev->driver_type = RC_DRIVER_SCANCODE; -		dev->allowed_protos = rc_type; +		rc_set_allowed_protocols(dev, rc_type);  	}  	ir->core = core; diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 2d3507eb489..74b7b8614c2 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -499,7 +499,7 @@ static int cx8802_init_common(struct cx8802_dev *dev)  	/* get irq */  	err = request_irq(dev->pci->irq, cx8802_irq, -			  IRQF_SHARED | IRQF_DISABLED, dev->core->name, dev); +			  IRQF_SHARED, dev->core->name, dev);  	if (err < 0) {  		printk(KERN_ERR "%s: can't get IRQ %d\n",  		       dev->core->name, dev->pci->irq); @@ -520,7 +520,6 @@ static void cx8802_fini_common(struct cx8802_dev *dev)  	/* unregister stuff */  	free_irq(dev->pci->irq, dev); -	pci_set_drvdata(dev->pci, NULL);  	/* free memory */  	btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); @@ -903,20 +902,8 @@ static struct pci_driver cx8802_pci_driver = {  	.remove   = cx8802_remove,  }; -static int __init cx8802_init(void) -{ -	printk(KERN_INFO "cx88/2: cx2388x MPEG-TS Driver Manager version %s loaded\n", -	       CX88_VERSION); -	return pci_register_driver(&cx8802_pci_driver); -} - -static void __exit cx8802_fini(void) -{ -	pci_unregister_driver(&cx8802_pci_driver); -} +module_pci_driver(cx8802_pci_driver); -module_init(cx8802_init); -module_exit(cx8802_fini);  EXPORT_SYMBOL(cx8802_buf_prepare);  EXPORT_SYMBOL(cx8802_buf_queue);  EXPORT_SYMBOL(cx8802_cancel_buffers); diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index ecf21d9f1f3..ed8cb9037b6 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -1738,7 +1738,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,  	/* get irq */  	err = request_irq(pci_dev->irq, cx8800_irq, -			  IRQF_SHARED | IRQF_DISABLED, core->name, dev); +			  IRQF_SHARED, core->name, dev);  	if (err < 0) {  		printk(KERN_ERR "%s/0: can't get IRQ %d\n",  		       core->name,pci_dev->irq); @@ -1922,7 +1922,6 @@ static void cx8800_finidev(struct pci_dev *pci_dev)  	free_irq(pci_dev->irq, dev);  	cx8800_unregister_video(dev); -	pci_set_drvdata(pci_dev, NULL);  	/* free memory */  	btcx_riscmem_free(dev->pci,&dev->vidq.stopper); @@ -2039,17 +2038,4 @@ static struct pci_driver cx8800_pci_driver = {  #endif  }; -static int __init cx8800_init(void) -{ -	printk(KERN_INFO "cx88/0: cx2388x v4l2 driver version %s loaded\n", -	       CX88_VERSION); -	return pci_register_driver(&cx8800_pci_driver); -} - -static void __exit cx8800_fini(void) -{ -	pci_unregister_driver(&cx8800_pci_driver); -} - -module_init(cx8800_init); -module_exit(cx8800_fini); +module_pci_driver(cx8800_pci_driver); diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 36e34522b9a..fb52bda8d45 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -876,10 +876,8 @@ static int dvb_input_attach(struct ddb_input *input)  			return -ENODEV;  		if (tuner_attach_tda18271(input) < 0)  			return -ENODEV; -		if (input->fe) { -			if (dvb_register_frontend(adap, input->fe) < 0) -				return -ENODEV; -		} +		if (dvb_register_frontend(adap, input->fe) < 0) +			return -ENODEV;  		if (input->fe2) {  			if (dvb_register_frontend(adap, input->fe2) < 0)  				return -ENODEV; @@ -1544,7 +1542,7 @@ static void ddb_unmap(struct ddb *dev)  static void ddb_remove(struct pci_dev *pdev)  { -	struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); +	struct ddb *dev = pci_get_drvdata(pdev);  	ddb_ports_detach(dev);  	ddb_i2c_release(dev); diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index ab797fe466d..e60ac35fc10 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -1178,7 +1178,6 @@ err_pci_release_regions:  err_pci_disable_device:  	pci_disable_device(pdev);  err_kfree: -	pci_set_drvdata(pdev, NULL);  	kfree(dev);  	return ret;  } @@ -1202,8 +1201,7 @@ static void dm1105_remove(struct pci_dev *pdev)  	dvb_dmxdev_release(&dev->dmxdev);  	dvb_dmx_release(dvbdemux);  	dvb_unregister_adapter(dvb_adapter); -	if (&dev->i2c_adap) -		i2c_del_adapter(&dev->i2c_adap); +	i2c_del_adapter(&dev->i2c_adap);  	dm1105_hw_exit(dev);  	synchronize_irq(pdev->irq); @@ -1211,7 +1209,6 @@ static void dm1105_remove(struct pci_dev *pdev)  	pci_iounmap(pdev, dev->io_mem);  	pci_release_regions(pdev);  	pci_disable_device(pdev); -	pci_set_drvdata(pdev, NULL);  	dm1105_devcount--;  	kfree(dev);  } diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c index e970cface70..39b52929755 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-main.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c @@ -145,11 +145,12 @@ static int snd_ivtv_init(struct v4l2_device *v4l2_dev)  	/* This is a no-op for us.  We'll use the itv->instance */  	/* (2) Create a card instance */ -	ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */ -			      SNDRV_DEFAULT_STR1, /* xid from end of shortname*/ -			      THIS_MODULE, 0, &sc); +	ret = snd_card_new(&itv->pdev->dev, +			   SNDRV_DEFAULT_IDX1, /* use first available id */ +			   SNDRV_DEFAULT_STR1, /* xid from end of shortname*/ +			   THIS_MODULE, 0, &sc);  	if (ret) { -		IVTV_ALSA_ERR("%s: snd_card_create() failed with err %d\n", +		IVTV_ALSA_ERR("%s: snd_card_new() failed with err %d\n",  			      __func__, ret);  		goto err_exit;  	} diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c index e1863dbf4ed..7a9b98bc208 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c @@ -159,6 +159,12 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)  	/* Instruct the CX2341[56] to start sending packets */  	snd_ivtv_lock(itvsc); + +	if (ivtv_init_on_first_open(itv)) { +		snd_ivtv_unlock(itvsc); +		return -ENXIO; +	} +  	s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];  	v4l2_fh_init(&item.fh, s->vdev); diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index c08ae3eb955..802642d2664 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -1261,7 +1261,7 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)  	/* Register IRQ */  	retval = request_irq(itv->pdev->irq, ivtv_irq_handler, -	     IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv); +	     IRQF_SHARED, itv->v4l2_dev.name, (void *)itv);  	if (retval) {  		IVTV_ERR("Failed to register irq %d\n", retval);  		goto free_i2c; diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c index 9caffd8aa99..e5ff6277ca8 100644 --- a/drivers/media/pci/ivtv/ivtv-fileops.c +++ b/drivers/media/pci/ivtv/ivtv-fileops.c @@ -894,7 +894,7 @@ int ivtv_v4l2_close(struct file *filp)  		/* Mark that the radio is no longer in use */  		clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);  		/* Switch tuner to TV */ -		ivtv_call_all(itv, core, s_std, itv->std); +		ivtv_call_all(itv, video, s_std, itv->std);  		/* Select correct audio input (i.e. TV tuner or Line in) */  		ivtv_audio_set_io(itv);  		if (itv->hw_flags & IVTV_HW_SAA711X) { diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 807b275a847..b3667a00db3 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -1090,7 +1090,7 @@ void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std)  		itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;  	/* Tuner */ -	ivtv_call_all(itv, core, s_std, itv->std); +	ivtv_call_all(itv, video, s_std, itv->std);  }  void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std) diff --git a/drivers/media/pci/mantis/mantis_pci.c b/drivers/media/pci/mantis/mantis_pci.c index a846036ea02..9e89e045213 100644 --- a/drivers/media/pci/mantis/mantis_pci.c +++ b/drivers/media/pci/mantis/mantis_pci.c @@ -143,7 +143,6 @@ fail1:  fail0:  	dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); -	pci_set_drvdata(pdev, NULL);  	return ret;  }  EXPORT_SYMBOL_GPL(mantis_pci_init); @@ -161,7 +160,6 @@ void mantis_pci_exit(struct mantis_pci *mantis)  	}  	pci_disable_device(pdev); -	pci_set_drvdata(pdev, NULL);  }  EXPORT_SYMBOL_GPL(mantis_pci_exit); diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 2381b05432e..54d5c821007 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1698,7 +1698,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)  	meye.mchip_irq = pcidev->irq;  	if (request_irq(meye.mchip_irq, meye_irq, -			IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) { +			IRQF_SHARED, "meye", meye_irq)) {  		v4l2_err(v4l2_dev, "request_irq failed\n");  		goto outreqirq;  	} diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index 37ebc42392a..970e8330852 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c @@ -1622,7 +1622,7 @@ static void ngene_unlink(struct ngene *dev)  void ngene_shutdown(struct pci_dev *pdev)  { -	struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); +	struct ngene *dev = pci_get_drvdata(pdev);  	if (!dev || !shutdown_workaround)  		return; @@ -1648,7 +1648,6 @@ void ngene_remove(struct pci_dev *pdev)  		cxd_detach(dev);  	ngene_stop(dev);  	ngene_release_buffers(dev); -	pci_set_drvdata(pdev, NULL);  	pci_disable_device(pdev);  } @@ -1702,6 +1701,5 @@ fail1:  	ngene_release_buffers(dev);  fail0:  	pci_disable_device(pci_dev); -	pci_set_drvdata(pci_dev, NULL);  	return stat;  } diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c index 49382850005..655d6854a8d 100644 --- a/drivers/media/pci/pluto2/pluto2.c +++ b/drivers/media/pci/pluto2/pluto2.c @@ -401,7 +401,7 @@ static int pluto_hw_init(struct pluto *pluto)  	/* set automatic LED control by FPGA */  	pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED); -	/* set data endianess */ +	/* set data endianness */  #ifdef __LITTLE_ENDIAN  	pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);  #else @@ -736,7 +736,6 @@ err_pci_release_regions:  err_pci_disable_device:  	pci_disable_device(pdev);  err_kfree: -	pci_set_drvdata(pdev, NULL);  	kfree(pluto);  	goto out;  } @@ -765,7 +764,6 @@ static void pluto2_remove(struct pci_dev *pdev)  	pci_iounmap(pdev, pluto->io_mem);  	pci_release_regions(pdev);  	pci_disable_device(pdev); -	pci_set_drvdata(pdev, NULL);  	kfree(pluto);  } diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c index 75ce14229e0..db887b0c37b 100644 --- a/drivers/media/pci/pt1/pt1.c +++ b/drivers/media/pci/pt1/pt1.c @@ -1076,7 +1076,6 @@ static void pt1_remove(struct pci_dev *pdev)  	pt1_update_power(pt1);  	pt1_cleanup_adapters(pt1);  	i2c_del_adapter(&pt1->i2c_adap); -	pci_set_drvdata(pdev, NULL);  	kfree(pt1);  	pci_iounmap(pdev, regs);  	pci_release_regions(pdev); @@ -1198,7 +1197,6 @@ err_i2c_del_adapter:  err_pt1_cleanup_adapters:  	pt1_cleanup_adapters(pt1);  err_kfree: -	pci_set_drvdata(pdev, NULL);  	kfree(pt1);  err_pci_iounmap:  	pci_iounmap(pdev, regs); diff --git a/drivers/media/pci/saa7134/Kconfig b/drivers/media/pci/saa7134/Kconfig index 15b90d6e913..18ae7554630 100644 --- a/drivers/media/pci/saa7134/Kconfig +++ b/drivers/media/pci/saa7134/Kconfig @@ -1,11 +1,12 @@  config VIDEO_SAA7134  	tristate "Philips SAA7134 support"  	depends on VIDEO_DEV && PCI && I2C -	select VIDEOBUF_DMA_SG +	select VIDEOBUF2_DMA_SG  	select VIDEO_TUNER  	select VIDEO_TVEEPROM  	select CRC32  	select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT +	select VIDEO_SAA6752HS if MEDIA_SUBDRV_AUTOSELECT  	---help---  	  This is a video4linux driver for Philips SAA713x based  	  TV cards. @@ -36,7 +37,7 @@ config VIDEO_SAA7134_RC  config VIDEO_SAA7134_DVB  	tristate "DVB/ATSC Support for saa7134 based TV cards"  	depends on VIDEO_SAA7134 && DVB_CORE -	select VIDEOBUF_DVB +	select VIDEOBUF2_DVB  	select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT  	select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT  	select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/pci/saa7134/Makefile b/drivers/media/pci/saa7134/Makefile index 35375480ed4..58de9b08568 100644 --- a/drivers/media/pci/saa7134/Makefile +++ b/drivers/media/pci/saa7134/Makefile @@ -4,7 +4,7 @@ saa7134-y +=	saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o  saa7134-y +=	saa7134-video.o  saa7134-$(CONFIG_VIDEO_SAA7134_RC) += saa7134-input.o -obj-$(CONFIG_VIDEO_SAA7134) +=  saa6752hs.o saa7134.o saa7134-empress.o +obj-$(CONFIG_VIDEO_SAA7134) +=  saa7134.o saa7134-empress.o  obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o diff --git a/drivers/media/pci/saa7134/saa6752hs.c b/drivers/media/pci/saa7134/saa6752hs.c deleted file mode 100644 index 8ac4b1f2322..00000000000 --- a/drivers/media/pci/saa7134/saa6752hs.c +++ /dev/null @@ -1,797 +0,0 @@ - /* -    saa6752hs - i2c-driver for the saa6752hs by Philips - -    Copyright (C) 2004 Andrew de Quincey - -    AC-3 support: - -    Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> - -    This program is free software; you can redistribute it and/or modify -    it under the terms of the GNU General Public License vs 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 Mvss Ave, Cambridge, MA 02139, USA. -  */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/timer.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/poll.h> -#include <linux/i2c.h> -#include <linux/types.h> -#include <linux/videodev2.h> -#include <media/v4l2-device.h> -#include <media/v4l2-ctrls.h> -#include <media/v4l2-common.h> -#include <linux/init.h> -#include <linux/crc32.h> - -#define MPEG_VIDEO_TARGET_BITRATE_MAX  27000 -#define MPEG_VIDEO_MAX_BITRATE_MAX     27000 -#define MPEG_TOTAL_TARGET_BITRATE_MAX  27000 -#define MPEG_PID_MAX ((1 << 14) - 1) - - -MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); -MODULE_AUTHOR("Andrew de Quincey"); -MODULE_LICENSE("GPL"); - -enum saa6752hs_videoformat { -	SAA6752HS_VF_D1 = 0,    /* standard D1 video format: 720x576 */ -	SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */ -	SAA6752HS_VF_1_2_D1 = 2,/* 1/2D1 video format: 352x576 */ -	SAA6752HS_VF_SIF = 3,   /* SIF video format: 352x288 */ -	SAA6752HS_VF_UNKNOWN, -}; - -struct saa6752hs_mpeg_params { -	/* transport streams */ -	__u16				ts_pid_pmt; -	__u16				ts_pid_audio; -	__u16				ts_pid_video; -	__u16				ts_pid_pcr; - -	/* audio */ -	enum v4l2_mpeg_audio_encoding    au_encoding; -	enum v4l2_mpeg_audio_l2_bitrate  au_l2_bitrate; -	enum v4l2_mpeg_audio_ac3_bitrate au_ac3_bitrate; - -	/* video */ -	enum v4l2_mpeg_video_aspect	vi_aspect; -	enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode; -	__u32 				vi_bitrate; -	__u32 				vi_bitrate_peak; -}; - -static const struct v4l2_format v4l2_format_table[] = -{ -	[SAA6752HS_VF_D1] = -		{ .fmt = { .pix = { .width = 720, .height = 576 }}}, -	[SAA6752HS_VF_2_3_D1] = -		{ .fmt = { .pix = { .width = 480, .height = 576 }}}, -	[SAA6752HS_VF_1_2_D1] = -		{ .fmt = { .pix = { .width = 352, .height = 576 }}}, -	[SAA6752HS_VF_SIF] = -		{ .fmt = { .pix = { .width = 352, .height = 288 }}}, -	[SAA6752HS_VF_UNKNOWN] = -		{ .fmt = { .pix = { .width = 0, .height = 0}}}, -}; - -struct saa6752hs_state { -	struct v4l2_subdev            sd; -	struct v4l2_ctrl_handler      hdl; -	struct { /* video bitrate mode control cluster */ -		struct v4l2_ctrl *video_bitrate_mode; -		struct v4l2_ctrl *video_bitrate; -		struct v4l2_ctrl *video_bitrate_peak; -	}; -	u32 			      revision; -	int 			      has_ac3; -	struct saa6752hs_mpeg_params  params; -	enum saa6752hs_videoformat    video_format; -	v4l2_std_id                   standard; -}; - -enum saa6752hs_command { -	SAA6752HS_COMMAND_RESET = 0, -	SAA6752HS_COMMAND_STOP = 1, -	SAA6752HS_COMMAND_START = 2, -	SAA6752HS_COMMAND_PAUSE = 3, -	SAA6752HS_COMMAND_RECONFIGURE = 4, -	SAA6752HS_COMMAND_SLEEP = 5, -	SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6, - -	SAA6752HS_COMMAND_MAX -}; - -static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd) -{ -	return container_of(sd, struct saa6752hs_state, sd); -} - -/* ---------------------------------------------------------------------- */ - -static u8 PAT[] = { -	0xc2, /* i2c register */ -	0x00, /* table number for encoder */ - -	0x47, /* sync */ -	0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */ -	0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */ - -	0x00, /* PSI pointer to start of table */ - -	0x00, /* tid(0) */ -	0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */ - -	0x00, 0x01, /* transport_stream_id(1) */ - -	0xc1, /* version_number(0), current_next_indicator(1) */ - -	0x00, 0x00, /* section_number(0), last_section_number(0) */ - -	0x00, 0x01, /* program_number(1) */ - -	0xe0, 0x00, /* PMT PID */ - -	0x00, 0x00, 0x00, 0x00 /* CRC32 */ -}; - -static u8 PMT[] = { -	0xc2, /* i2c register */ -	0x01, /* table number for encoder */ - -	0x47, /* sync */ -	0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */ -	0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */ - -	0x00, /* PSI pointer to start of table */ - -	0x02, /* tid(2) */ -	0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */ - -	0x00, 0x01, /* program_number(1) */ - -	0xc1, /* version_number(0), current_next_indicator(1) */ - -	0x00, 0x00, /* section_number(0), last_section_number(0) */ - -	0xe0, 0x00, /* PCR_PID */ - -	0xf0, 0x00, /* program_info_length(0) */ - -	0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */ -	0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */ - -	0x00, 0x00, 0x00, 0x00 /* CRC32 */ -}; - -static u8 PMT_AC3[] = { -	0xc2, /* i2c register */ -	0x01, /* table number for encoder(1) */ -	0x47, /* sync */ - -	0x40, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0) */ -	0x10, /* PMT PID (0x0010) */ -	0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */ - -	0x00, /* PSI pointer to start of table */ - -	0x02, /* TID (2) */ -	0xb0, 0x1a, /* section_syntax_indicator(1), section_length(26) */ - -	0x00, 0x01, /* program_number(1) */ - -	0xc1, /* version_number(0), current_next_indicator(1) */ - -	0x00, 0x00, /* section_number(0), last_section_number(0) */ - -	0xe1, 0x04, /* PCR_PID (0x0104) */ - -	0xf0, 0x00, /* program_info_length(0) */ - -	0x02, 0xe1, 0x00, 0xf0, 0x00, /* video stream type(2), pid */ -	0x06, 0xe1, 0x03, 0xf0, 0x03, /* audio stream type(6), pid */ -	0x6a, /* AC3 */ -	0x01, /* Descriptor_length(1) */ -	0x00, /* component_type_flag(0), bsid_flag(0), mainid_flag(0), asvc_flag(0), reserved flags(0) */ - -	0xED, 0xDE, 0x2D, 0xF3 /* CRC32 BE */ -}; - -static struct saa6752hs_mpeg_params param_defaults = -{ -	.ts_pid_pmt      = 16, -	.ts_pid_video    = 260, -	.ts_pid_audio    = 256, -	.ts_pid_pcr      = 259, - -	.vi_aspect       = V4L2_MPEG_VIDEO_ASPECT_4x3, -	.vi_bitrate      = 4000, -	.vi_bitrate_peak = 6000, -	.vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - -	.au_encoding     = V4L2_MPEG_AUDIO_ENCODING_LAYER_2, -	.au_l2_bitrate   = V4L2_MPEG_AUDIO_L2_BITRATE_256K, -	.au_ac3_bitrate  = V4L2_MPEG_AUDIO_AC3_BITRATE_256K, -}; - -/* ---------------------------------------------------------------------- */ - -static int saa6752hs_chip_command(struct i2c_client *client, -				  enum saa6752hs_command command) -{ -	unsigned char buf[3]; -	unsigned long timeout; -	int status = 0; - -	/* execute the command */ -	switch(command) { -	case SAA6752HS_COMMAND_RESET: -		buf[0] = 0x00; -		break; - -	case SAA6752HS_COMMAND_STOP: -		buf[0] = 0x03; -		break; - -	case SAA6752HS_COMMAND_START: -		buf[0] = 0x02; -		break; - -	case SAA6752HS_COMMAND_PAUSE: -		buf[0] = 0x04; -		break; - -	case SAA6752HS_COMMAND_RECONFIGURE: -		buf[0] = 0x05; -		break; - -	case SAA6752HS_COMMAND_SLEEP: -		buf[0] = 0x06; -		break; - -	case SAA6752HS_COMMAND_RECONFIGURE_FORCE: -		buf[0] = 0x07; -		break; - -	default: -		return -EINVAL; -	} - -	/* set it and wait for it to be so */ -	i2c_master_send(client, buf, 1); -	timeout = jiffies + HZ * 3; -	for (;;) { -		/* get the current status */ -		buf[0] = 0x10; -		i2c_master_send(client, buf, 1); -		i2c_master_recv(client, buf, 1); - -		if (!(buf[0] & 0x20)) -			break; -		if (time_after(jiffies,timeout)) { -			status = -ETIMEDOUT; -			break; -		} - -		msleep(10); -	} - -	/* delay a bit to let encoder settle */ -	msleep(50); - -	return status; -} - - -static inline void set_reg8(struct i2c_client *client, uint8_t reg, uint8_t val) -{ -	u8 buf[2]; - -	buf[0] = reg; -	buf[1] = val; -	i2c_master_send(client, buf, 2); -} - -static inline void set_reg16(struct i2c_client *client, uint8_t reg, uint16_t val) -{ -	u8 buf[3]; - -	buf[0] = reg; -	buf[1] = val >> 8; -	buf[2] = val & 0xff; -	i2c_master_send(client, buf, 3); -} - -static int saa6752hs_set_bitrate(struct i2c_client *client, -				 struct saa6752hs_state *h) -{ -	struct saa6752hs_mpeg_params *params = &h->params; -	int tot_bitrate; -	int is_384k; - -	/* set the bitrate mode */ -	set_reg8(client, 0x71, -		params->vi_bitrate_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); - -	/* set the video bitrate */ -	if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { -		/* set the target bitrate */ -		set_reg16(client, 0x80, params->vi_bitrate); - -		/* set the max bitrate */ -		set_reg16(client, 0x81, params->vi_bitrate_peak); -		tot_bitrate = params->vi_bitrate_peak; -	} else { -		/* set the target bitrate (no max bitrate for CBR) */ -		set_reg16(client, 0x81, params->vi_bitrate); -		tot_bitrate = params->vi_bitrate; -	} - -	/* set the audio encoding */ -	set_reg8(client, 0x93, -			params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3); - -	/* set the audio bitrate */ -	if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) -		is_384k = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate; -	else -		is_384k = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate; -	set_reg8(client, 0x94, is_384k); -	tot_bitrate += is_384k ? 384 : 256; - -	/* Note: the total max bitrate is determined by adding the video and audio -	   bitrates together and also adding an extra 768kbit/s to stay on the -	   safe side. If more control should be required, then an extra MPEG control -	   should be added. */ -	tot_bitrate += 768; -	if (tot_bitrate > MPEG_TOTAL_TARGET_BITRATE_MAX) -		tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; - -	/* set the total bitrate */ -	set_reg16(client, 0xb1, tot_bitrate); -	return 0; -} - -static int saa6752hs_try_ctrl(struct v4l2_ctrl *ctrl) -{ -	struct saa6752hs_state *h = -		container_of(ctrl->handler, struct saa6752hs_state, hdl); - -	switch (ctrl->id) { -	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: -		/* peak bitrate shall be >= normal bitrate */ -		if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && -		    h->video_bitrate_peak->val < h->video_bitrate->val) -			h->video_bitrate_peak->val = h->video_bitrate->val; -		break; -	} -	return 0; -} - -static int saa6752hs_s_ctrl(struct v4l2_ctrl *ctrl) -{ -	struct saa6752hs_state *h = -		container_of(ctrl->handler, struct saa6752hs_state, hdl); -	struct saa6752hs_mpeg_params *params = &h->params; - -	switch (ctrl->id) { -	case V4L2_CID_MPEG_STREAM_TYPE: -		break; -	case V4L2_CID_MPEG_STREAM_PID_PMT: -		params->ts_pid_pmt = ctrl->val; -		break; -	case V4L2_CID_MPEG_STREAM_PID_AUDIO: -		params->ts_pid_audio = ctrl->val; -		break; -	case V4L2_CID_MPEG_STREAM_PID_VIDEO: -		params->ts_pid_video = ctrl->val; -		break; -	case V4L2_CID_MPEG_STREAM_PID_PCR: -		params->ts_pid_pcr = ctrl->val; -		break; -	case V4L2_CID_MPEG_AUDIO_ENCODING: -		params->au_encoding = ctrl->val; -		break; -	case V4L2_CID_MPEG_AUDIO_L2_BITRATE: -		params->au_l2_bitrate = ctrl->val; -		break; -	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: -		params->au_ac3_bitrate = ctrl->val; -		break; -	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: -		break; -	case V4L2_CID_MPEG_VIDEO_ENCODING: -		break; -	case V4L2_CID_MPEG_VIDEO_ASPECT: -		params->vi_aspect = ctrl->val; -		break; -	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: -		params->vi_bitrate_mode = ctrl->val; -		params->vi_bitrate = h->video_bitrate->val / 1000; -		params->vi_bitrate_peak = h->video_bitrate_peak->val / 1000; -		v4l2_ctrl_activate(h->video_bitrate_peak, -				ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); -		break; -	default: -		return -EINVAL; -	} -	return 0; -} - -static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes) -{ -	unsigned char buf[9], buf2[4]; -	struct saa6752hs_state *h = to_state(sd); -	struct i2c_client *client = v4l2_get_subdevdata(sd); -	unsigned size; -	u32 crc; -	unsigned char localPAT[256]; -	unsigned char localPMT[256]; - -	/* Set video format - must be done first as it resets other settings */ -	set_reg8(client, 0x41, h->video_format); - -	/* Set number of lines in input signal */ -	set_reg8(client, 0x40, (h->standard & V4L2_STD_525_60) ? 1 : 0); - -	/* set bitrate */ -	saa6752hs_set_bitrate(client, h); - -	/* Set GOP structure {3, 13} */ -	set_reg16(client, 0x72, 0x030d); - -	/* Set minimum Q-scale {4} */ -	set_reg8(client, 0x82, 0x04); - -	/* Set maximum Q-scale {12} */ -	set_reg8(client, 0x83, 0x0c); - -	/* Set Output Protocol */ -	set_reg8(client, 0xd0, 0x81); - -	/* Set video output stream format {TS} */ -	set_reg8(client, 0xb0, 0x05); - -	/* Set leading null byte for TS */ -	set_reg16(client, 0xf6, leading_null_bytes); - -	/* compute PAT */ -	memcpy(localPAT, PAT, sizeof(PAT)); -	localPAT[17] = 0xe0 | ((h->params.ts_pid_pmt >> 8) & 0x0f); -	localPAT[18] = h->params.ts_pid_pmt & 0xff; -	crc = crc32_be(~0, &localPAT[7], sizeof(PAT) - 7 - 4); -	localPAT[sizeof(PAT) - 4] = (crc >> 24) & 0xFF; -	localPAT[sizeof(PAT) - 3] = (crc >> 16) & 0xFF; -	localPAT[sizeof(PAT) - 2] = (crc >> 8) & 0xFF; -	localPAT[sizeof(PAT) - 1] = crc & 0xFF; - -	/* compute PMT */ -	if (h->params.au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) { -		size = sizeof(PMT_AC3); -		memcpy(localPMT, PMT_AC3, size); -	} else { -		size = sizeof(PMT); -		memcpy(localPMT, PMT, size); -	} -	localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); -	localPMT[4] = h->params.ts_pid_pmt & 0xff; -	localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); -	localPMT[16] = h->params.ts_pid_pcr & 0xFF; -	localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F); -	localPMT[21] = h->params.ts_pid_video & 0xFF; -	localPMT[25] = 0xE0 | ((h->params.ts_pid_audio >> 8) & 0x0F); -	localPMT[26] = h->params.ts_pid_audio & 0xFF; -	crc = crc32_be(~0, &localPMT[7], size - 7 - 4); -	localPMT[size - 4] = (crc >> 24) & 0xFF; -	localPMT[size - 3] = (crc >> 16) & 0xFF; -	localPMT[size - 2] = (crc >> 8) & 0xFF; -	localPMT[size - 1] = crc & 0xFF; - -	/* Set Audio PID */ -	set_reg16(client, 0xc1, h->params.ts_pid_audio); - -	/* Set Video PID */ -	set_reg16(client, 0xc0, h->params.ts_pid_video); - -	/* Set PCR PID */ -	set_reg16(client, 0xc4, h->params.ts_pid_pcr); - -	/* Send SI tables */ -	i2c_master_send(client, localPAT, sizeof(PAT)); -	i2c_master_send(client, localPMT, size); - -	/* mute then unmute audio. This removes buzzing artefacts */ -	set_reg8(client, 0xa4, 1); -	set_reg8(client, 0xa4, 0); - -	/* start it going */ -	saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); - -	/* readout current state */ -	buf[0] = 0xE1; -	buf[1] = 0xA7; -	buf[2] = 0xFE; -	buf[3] = 0x82; -	buf[4] = 0xB0; -	i2c_master_send(client, buf, 5); -	i2c_master_recv(client, buf2, 4); - -	/* change aspect ratio */ -	buf[0] = 0xE0; -	buf[1] = 0xA7; -	buf[2] = 0xFE; -	buf[3] = 0x82; -	buf[4] = 0xB0; -	buf[5] = buf2[0]; -	switch (h->params.vi_aspect) { -	case V4L2_MPEG_VIDEO_ASPECT_16x9: -		buf[6] = buf2[1] | 0x40; -		break; -	case V4L2_MPEG_VIDEO_ASPECT_4x3: -	default: -		buf[6] = buf2[1] & 0xBF; -		break; -	} -	buf[7] = buf2[2]; -	buf[8] = buf2[3]; -	i2c_master_send(client, buf, 9); - -	return 0; -} - -static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) -{ -	struct saa6752hs_state *h = to_state(sd); - -	if (h->video_format == SAA6752HS_VF_UNKNOWN) -		h->video_format = SAA6752HS_VF_D1; -	f->width = v4l2_format_table[h->video_format].fmt.pix.width; -	f->height = v4l2_format_table[h->video_format].fmt.pix.height; -	f->code = V4L2_MBUS_FMT_FIXED; -	f->field = V4L2_FIELD_INTERLACED; -	f->colorspace = V4L2_COLORSPACE_SMPTE170M; -	return 0; -} - -static int saa6752hs_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) -{ -	int dist_352, dist_480, dist_720; - -	f->code = V4L2_MBUS_FMT_FIXED; - -	dist_352 = abs(f->width - 352); -	dist_480 = abs(f->width - 480); -	dist_720 = abs(f->width - 720); -	if (dist_720 < dist_480) { -		f->width = 720; -		f->height = 576; -	} else if (dist_480 < dist_352) { -		f->width = 480; -		f->height = 576; -	} else { -		f->width = 352; -		if (abs(f->height - 576) < abs(f->height - 288)) -			f->height = 576; -		else -			f->height = 288; -	} -	f->field = V4L2_FIELD_INTERLACED; -	f->colorspace = V4L2_COLORSPACE_SMPTE170M; -	return 0; -} - -static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) -{ -	struct saa6752hs_state *h = to_state(sd); - -	if (f->code != V4L2_MBUS_FMT_FIXED) -		return -EINVAL; - -	/* -	  FIXME: translate and round width/height into EMPRESS -	  subsample type: - -	  type   |   PAL   |  NTSC -	  --------------------------- -	  SIF    | 352x288 | 352x240 -	  1/2 D1 | 352x576 | 352x480 -	  2/3 D1 | 480x576 | 480x480 -	  D1     | 720x576 | 720x480 -	*/ - -	saa6752hs_try_mbus_fmt(sd, f); -	if (f->width == 720) -		h->video_format = SAA6752HS_VF_D1; -	else if (f->width == 480) -		h->video_format = SAA6752HS_VF_2_3_D1; -	else if (f->height == 576) -		h->video_format = SAA6752HS_VF_1_2_D1; -	else -		h->video_format = SAA6752HS_VF_SIF; -	return 0; -} - -static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std) -{ -	struct saa6752hs_state *h = to_state(sd); - -	h->standard = std; -	return 0; -} - -/* ----------------------------------------------------------------------- */ - -static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = { -	.try_ctrl = saa6752hs_try_ctrl, -	.s_ctrl = saa6752hs_s_ctrl, -}; - -static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { -	.init = saa6752hs_init, -	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls, -	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls, -	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls, -	.g_ctrl = v4l2_subdev_g_ctrl, -	.s_ctrl = v4l2_subdev_s_ctrl, -	.queryctrl = v4l2_subdev_queryctrl, -	.querymenu = v4l2_subdev_querymenu, -	.s_std = saa6752hs_s_std, -}; - -static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { -	.s_mbus_fmt = saa6752hs_s_mbus_fmt, -	.try_mbus_fmt = saa6752hs_try_mbus_fmt, -	.g_mbus_fmt = saa6752hs_g_mbus_fmt, -}; - -static const struct v4l2_subdev_ops saa6752hs_ops = { -	.core = &saa6752hs_core_ops, -	.video = &saa6752hs_video_ops, -}; - -static int saa6752hs_probe(struct i2c_client *client, -		const struct i2c_device_id *id) -{ -	struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL); -	struct v4l2_subdev *sd; -	struct v4l2_ctrl_handler *hdl; -	u8 addr = 0x13; -	u8 data[12]; - -	v4l_info(client, "chip found @ 0x%x (%s)\n", -			client->addr << 1, client->adapter->name); -	if (h == NULL) -		return -ENOMEM; -	sd = &h->sd; -	v4l2_i2c_subdev_init(sd, client, &saa6752hs_ops); - -	i2c_master_send(client, &addr, 1); -	i2c_master_recv(client, data, sizeof(data)); -	h->revision = (data[8] << 8) | data[9]; -	h->has_ac3 = 0; -	if (h->revision == 0x0206) { -		h->has_ac3 = 1; -		v4l_info(client, "supports AC-3\n"); -	} -	h->params = param_defaults; - -	hdl = &h->hdl; -	v4l2_ctrl_handler_init(hdl, 14); -	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_AUDIO_ENCODING, -		h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : -			V4L2_MPEG_AUDIO_ENCODING_LAYER_2, -		0x0d, V4L2_MPEG_AUDIO_ENCODING_LAYER_2); - -	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_AUDIO_L2_BITRATE, -		V4L2_MPEG_AUDIO_L2_BITRATE_384K, -		~((1 << V4L2_MPEG_AUDIO_L2_BITRATE_256K) | -		  (1 << V4L2_MPEG_AUDIO_L2_BITRATE_384K)), -		V4L2_MPEG_AUDIO_L2_BITRATE_256K); - -	if (h->has_ac3) -		v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops, -			V4L2_CID_MPEG_AUDIO_AC3_BITRATE, -			V4L2_MPEG_AUDIO_AC3_BITRATE_384K, -			~((1 << V4L2_MPEG_AUDIO_AC3_BITRATE_256K) | -			  (1 << V4L2_MPEG_AUDIO_AC3_BITRATE_384K)), -			V4L2_MPEG_AUDIO_AC3_BITRATE_256K); - -	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, -		V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, -		~(1 << V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000), -		V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000); - -	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_VIDEO_ENCODING, -		V4L2_MPEG_VIDEO_ENCODING_MPEG_2, -		~(1 << V4L2_MPEG_VIDEO_ENCODING_MPEG_2), -		V4L2_MPEG_VIDEO_ENCODING_MPEG_2); - -	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_VIDEO_ASPECT, -		V4L2_MPEG_VIDEO_ASPECT_16x9, 0x01, -		V4L2_MPEG_VIDEO_ASPECT_4x3); - -	h->video_bitrate_peak = v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, -		1000000, 27000000, 1000, 8000000); - -	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_STREAM_TYPE, -		V4L2_MPEG_STREAM_TYPE_MPEG2_TS, -		~(1 << V4L2_MPEG_STREAM_TYPE_MPEG2_TS), -		V4L2_MPEG_STREAM_TYPE_MPEG2_TS); - -	h->video_bitrate_mode = v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_VIDEO_BITRATE_MODE, -		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0, -		V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); -	h->video_bitrate = v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_VIDEO_BITRATE, 1000000, 27000000, 1000, 6000000); -	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_STREAM_PID_PMT, 0, (1 << 14) - 1, 1, 16); -	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_STREAM_PID_AUDIO, 0, (1 << 14) - 1, 1, 260); -	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_STREAM_PID_VIDEO, 0, (1 << 14) - 1, 1, 256); -	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops, -		V4L2_CID_MPEG_STREAM_PID_PCR, 0, (1 << 14) - 1, 1, 259); -	sd->ctrl_handler = hdl; -	if (hdl->error) { -		int err = hdl->error; - -		v4l2_ctrl_handler_free(hdl); -		kfree(h); -		return err; -	} -	v4l2_ctrl_cluster(3, &h->video_bitrate_mode); -	v4l2_ctrl_handler_setup(hdl); -	h->standard = 0; /* Assume 625 input lines */ -	return 0; -} - -static int saa6752hs_remove(struct i2c_client *client) -{ -	struct v4l2_subdev *sd = i2c_get_clientdata(client); - -	v4l2_device_unregister_subdev(sd); -	v4l2_ctrl_handler_free(&to_state(sd)->hdl); -	kfree(to_state(sd)); -	return 0; -} - -static const struct i2c_device_id saa6752hs_id[] = { -	{ "saa6752hs", 0 }, -	{ } -}; -MODULE_DEVICE_TABLE(i2c, saa6752hs_id); - -static struct i2c_driver saa6752hs_driver = { -	.driver = { -		.owner	= THIS_MODULE, -		.name	= "saa6752hs", -	}, -	.probe		= saa6752hs_probe, -	.remove		= saa6752hs_remove, -	.id_table	= saa6752hs_id, -}; - -module_i2c_driver(saa6752hs_driver); diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index dbcdfbf8aed..40569894c1c 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -27,6 +27,7 @@  #include <sound/pcm_params.h>  #include <sound/initval.h>  #include <linux/interrupt.h> +#include <linux/vmalloc.h>  #include "saa7134.h"  #include "saa7134-reg.h" @@ -274,6 +275,82 @@ static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream  	return err;  } +static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages) +{ +	struct saa7134_dmasound *dma = &dev->dmasound; +	struct page *pg; +	int i; + +	dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); +	if (NULL == dma->vaddr) { +		dprintk("vmalloc_32(%d pages) failed\n", nr_pages); +		return -ENOMEM; +	} + +	dprintk("vmalloc is at addr 0x%08lx, size=%d\n", +				(unsigned long)dma->vaddr, +				nr_pages << PAGE_SHIFT); + +	memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); +	dma->nr_pages = nr_pages; + +	dma->sglist = vzalloc(dma->nr_pages * sizeof(*dma->sglist)); +	if (NULL == dma->sglist) +		goto vzalloc_err; + +	sg_init_table(dma->sglist, dma->nr_pages); +	for (i = 0; i < dma->nr_pages; i++) { +		pg = vmalloc_to_page(dma->vaddr + i * PAGE_SIZE); +		if (NULL == pg) +			goto vmalloc_to_page_err; +		sg_set_page(&dma->sglist[i], pg, PAGE_SIZE, 0); +	} +	return 0; + +vmalloc_to_page_err: +	vfree(dma->sglist); +	dma->sglist = NULL; +vzalloc_err: +	vfree(dma->vaddr); +	dma->vaddr = NULL; +	return -ENOMEM; +} + +static int saa7134_alsa_dma_map(struct saa7134_dev *dev) +{ +	struct saa7134_dmasound *dma = &dev->dmasound; + +	dma->sglen = dma_map_sg(&dev->pci->dev, dma->sglist, +			dma->nr_pages, PCI_DMA_FROMDEVICE); + +	if (0 == dma->sglen) { +		pr_warn("%s: saa7134_alsa_map_sg failed\n", __func__); +		return -ENOMEM; +	} +	return 0; +} + +static int saa7134_alsa_dma_unmap(struct saa7134_dev *dev) +{ +	struct saa7134_dmasound *dma = &dev->dmasound; + +	if (!dma->sglen) +		return 0; + +	dma_unmap_sg(&dev->pci->dev, dma->sglist, dma->sglen, PCI_DMA_FROMDEVICE); +	dma->sglen = 0; +	return 0; +} + +static int saa7134_alsa_dma_free(struct saa7134_dmasound *dma) +{ +	vfree(dma->sglist); +	dma->sglist = NULL; +	vfree(dma->vaddr); +	dma->vaddr = NULL; +	return 0; +} +  /*   * DMA buffer initialization   * @@ -291,9 +368,8 @@ static int dsp_buffer_init(struct saa7134_dev *dev)  	BUG_ON(!dev->dmasound.bufsize); -	videobuf_dma_init(&dev->dmasound.dma); -	err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, -				       (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); +	err = saa7134_alsa_dma_init(dev, +			       (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);  	if (0 != err)  		return err;  	return 0; @@ -310,7 +386,7 @@ static int dsp_buffer_free(struct saa7134_dev *dev)  {  	BUG_ON(!dev->dmasound.blksize); -	videobuf_dma_free(&dev->dmasound.dma); +	saa7134_alsa_dma_free(&dev->dmasound);  	dev->dmasound.blocks  = 0;  	dev->dmasound.blksize = 0; @@ -632,7 +708,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,  	/* release the old buffer */  	if (substream->runtime->dma_area) {  		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); -		videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); +		saa7134_alsa_dma_unmap(dev);  		dsp_buffer_free(dev);  		substream->runtime->dma_area = NULL;  	} @@ -648,21 +724,22 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,  		return err;  	} -	if (0 != (err = videobuf_dma_map(&dev->pci->dev, &dev->dmasound.dma))) { +	err = saa7134_alsa_dma_map(dev); +	if (err) {  		dsp_buffer_free(dev);  		return err;  	} -	if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) { -		videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); +	err = saa7134_pgtable_alloc(dev->pci, &dev->dmasound.pt); +	if (err) { +		saa7134_alsa_dma_unmap(dev);  		dsp_buffer_free(dev);  		return err;  	} -	if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, -						dev->dmasound.dma.sglist, -						dev->dmasound.dma.sglen, -						0))) { +	err = saa7134_pgtable_build(dev->pci, &dev->dmasound.pt, +				dev->dmasound.sglist, dev->dmasound.sglen, 0); +	if (err) {  		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); -		videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); +		saa7134_alsa_dma_unmap(dev);  		dsp_buffer_free(dev);  		return err;  	} @@ -671,7 +748,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,  	   byte, but it doesn't work. So I allocate the DMA using the  	   V4L functions, and force ALSA to use that as the DMA area */ -	substream->runtime->dma_area = dev->dmasound.dma.vaddr; +	substream->runtime->dma_area = dev->dmasound.vaddr;  	substream->runtime->dma_bytes = dev->dmasound.bufsize;  	substream->runtime->dma_addr = 0; @@ -698,7 +775,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)  	if (substream->runtime->dma_area) {  		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); -		videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); +		saa7134_alsa_dma_unmap(dev);  		dsp_buffer_free(dev);  		substream->runtime->dma_area = NULL;  	} @@ -1072,8 +1149,8 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)  	if (!enable[devnum])  		return -ENODEV; -	err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, -			      sizeof(snd_card_saa7134_t), &card); +	err = snd_card_new(&dev->pci->dev, index[devnum], id[devnum], +			   THIS_MODULE, sizeof(snd_card_saa7134_t), &card);  	if (err < 0)  		return err; @@ -1096,7 +1173,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)  	err = request_irq(dev->pci->irq, saa7134_alsa_irq, -				IRQF_SHARED | IRQF_DISABLED, dev->name, +				IRQF_SHARED, dev->name,  				(void*) &dev->dmasound);  	if (err < 0) { @@ -1115,8 +1192,6 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)  	if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)  		goto __nodev; -	snd_card_set_dev(card, &chip->pci->dev); -  	/* End of "creation" */  	strcpy(card->shortname, "SAA7134"); diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index d45e7f6ff33..6e4bdb90aa9 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -2590,7 +2590,7 @@ struct saa7134_board saa7134_boards[] = {  		}},  	},  	[SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = { -		/* Michael Krufky <mkrufky@m1k.net> +		/* Michael Krufky <mkrufky@linuxtv.org>  		 * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder  		 * AFAIK, there is no analog demod, thus,  		 * no support for analog television. @@ -8045,8 +8045,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)  		break;  	} /* switch() */ -	/* initialize tuner */ -	if (TUNER_ABSENT != dev->tuner_type) { +	/* initialize tuner (don't do this when resuming) */ +	if (!dev->insuspend && TUNER_ABSENT != dev->tuner_type) {  		int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);  		/* Note: radio tuner address is always filled in, diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 45f0aca597a..be19a051a49 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -69,6 +69,10 @@ module_param_named(no_overlay, saa7134_no_overlay, int, 0444);  MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"  		" [some VIA/SIS chipsets are known to have problem with overlay]"); +bool saa7134_userptr; +module_param(saa7134_userptr, bool, 0644); +MODULE_PARM_DESC(saa7134_userptr, "enable page-aligned userptr support"); +  static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };  static unsigned int vbi_nr[]   = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };  static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; @@ -203,16 +207,16 @@ int saa7134_buffer_count(unsigned int size, unsigned int count)  int saa7134_buffer_startpage(struct saa7134_buf *buf)  { -	return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i; +	return saa7134_buffer_pages(vb2_plane_size(&buf->vb2, 0)) * buf->vb2.v4l2_buf.index;  }  unsigned long saa7134_buffer_base(struct saa7134_buf *buf)  {  	unsigned long base; -	struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); +	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);  	base  = saa7134_buffer_startpage(buf) * 4096; -	base += dma->sglist[0].offset; +	base += dma->sgl[0].offset;  	return base;  } @@ -237,14 +241,16 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,  			  unsigned int startpage)  {  	__le32        *ptr; -	unsigned int  i,p; +	unsigned int  i, p;  	BUG_ON(NULL == pt || NULL == pt->cpu);  	ptr = pt->cpu + startpage; -	for (i = 0; i < length; i++, list++) +	for (i = 0; i < length; i++, list = sg_next(list)) {  		for (p = 0; p * 4096 < list->length; p++, ptr++) -			*ptr = cpu_to_le32(sg_dma_address(list) - list->offset); +			*ptr = cpu_to_le32(sg_dma_address(list) + +						list->offset + p * 4096); +	}  	return 0;  } @@ -258,44 +264,31 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)  /* ------------------------------------------------------------------ */ -void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf) -{ -	struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); -	BUG_ON(in_interrupt()); - -	videobuf_waiton(q, &buf->vb, 0, 0); -	videobuf_dma_unmap(q->dev, dma); -	videobuf_dma_free(dma); -	buf->vb.state = VIDEOBUF_NEEDS_INIT; -} - -/* ------------------------------------------------------------------ */ -  int saa7134_buffer_queue(struct saa7134_dev *dev,  			 struct saa7134_dmaqueue *q,  			 struct saa7134_buf *buf)  {  	struct saa7134_buf *next = NULL; +	unsigned long flags; -	assert_spin_locked(&dev->slock); -	dprintk("buffer_queue %p\n",buf); +	spin_lock_irqsave(&dev->slock, flags); +	dprintk("buffer_queue %p\n", buf);  	if (NULL == q->curr) {  		if (!q->need_two) {  			q->curr = buf; -			buf->activate(dev,buf,NULL); +			buf->activate(dev, buf, NULL);  		} else if (list_empty(&q->queue)) { -			list_add_tail(&buf->vb.queue,&q->queue); -			buf->vb.state = VIDEOBUF_QUEUED; +			list_add_tail(&buf->entry, &q->queue);  		} else { -			next = list_entry(q->queue.next,struct saa7134_buf, -					  vb.queue); +			next = list_entry(q->queue.next, struct saa7134_buf, +					  entry);  			q->curr = buf; -			buf->activate(dev,buf,next); +			buf->activate(dev, buf, next);  		}  	} else { -		list_add_tail(&buf->vb.queue,&q->queue); -		buf->vb.state = VIDEOBUF_QUEUED; +		list_add_tail(&buf->entry, &q->queue);  	} +	spin_unlock_irqrestore(&dev->slock, flags);  	return 0;  } @@ -303,13 +296,12 @@ void saa7134_buffer_finish(struct saa7134_dev *dev,  			   struct saa7134_dmaqueue *q,  			   unsigned int state)  { -	assert_spin_locked(&dev->slock); -	dprintk("buffer_finish %p\n",q->curr); +	dprintk("buffer_finish %p\n", q->curr);  	/* finish current buffer */ -	q->curr->vb.state = state; -	v4l2_get_timestamp(&q->curr->vb.ts); -	wake_up(&q->curr->vb.done); +	v4l2_get_timestamp(&q->curr->vb2.v4l2_buf.timestamp); +	q->curr->vb2.v4l2_buf.sequence = q->seq_nr++; +	vb2_buffer_done(&q->curr->vb2, state);  	q->curr = NULL;  } @@ -323,36 +315,31 @@ void saa7134_buffer_next(struct saa7134_dev *dev,  	if (!list_empty(&q->queue)) {  		/* activate next one from queue */ -		buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue); +		buf = list_entry(q->queue.next, struct saa7134_buf, entry);  		dprintk("buffer_next %p [prev=%p/next=%p]\n", -			buf,q->queue.prev,q->queue.next); -		list_del(&buf->vb.queue); +			buf, q->queue.prev, q->queue.next); +		list_del(&buf->entry);  		if (!list_empty(&q->queue)) -			next = list_entry(q->queue.next,struct saa7134_buf, -					  vb.queue); +			next = list_entry(q->queue.next, struct saa7134_buf, entry);  		q->curr = buf; -		buf->activate(dev,buf,next); +		buf->activate(dev, buf, next);  		dprintk("buffer_next #2 prev=%p/next=%p\n", -			q->queue.prev,q->queue.next); +			q->queue.prev, q->queue.next);  	} else {  		/* nothing to do -- just stop DMA */ -		dprintk("buffer_next %p\n",NULL); +		dprintk("buffer_next %p\n", NULL);  		saa7134_set_dmabits(dev);  		del_timer(&q->timeout); - -		if (card_has_mpeg(dev)) -			if (dev->ts_started) -				saa7134_ts_stop(dev);  	}  }  void saa7134_buffer_timeout(unsigned long data)  { -	struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data; +	struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue *)data;  	struct saa7134_dev *dev = q->dev;  	unsigned long flags; -	spin_lock_irqsave(&dev->slock,flags); +	spin_lock_irqsave(&dev->slock, flags);  	/* try to reset the hardware (SWRST) */  	saa_writeb(SAA7134_REGION_ENABLE, 0x00); @@ -362,13 +349,33 @@ void saa7134_buffer_timeout(unsigned long data)  	/* flag current buffer as failed,  	   try to start over with the next one. */  	if (q->curr) { -		dprintk("timeout on %p\n",q->curr); -		saa7134_buffer_finish(dev,q,VIDEOBUF_ERROR); +		dprintk("timeout on %p\n", q->curr); +		saa7134_buffer_finish(dev, q, VB2_BUF_STATE_ERROR);  	} -	saa7134_buffer_next(dev,q); -	spin_unlock_irqrestore(&dev->slock,flags); +	saa7134_buffer_next(dev, q); +	spin_unlock_irqrestore(&dev->slock, flags);  } +void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q) +{ +	unsigned long flags; +	struct list_head *pos, *n; +	struct saa7134_buf *tmp; + +	spin_lock_irqsave(&dev->slock, flags); +	if (!list_empty(&q->queue)) { +		list_for_each_safe(pos, n, &q->queue) { +			 tmp = list_entry(pos, struct saa7134_buf, entry); +			 vb2_buffer_done(&tmp->vb2, VB2_BUF_STATE_ERROR); +			 list_del(pos); +			 tmp = NULL; +		} +	} +	spin_unlock_irqrestore(&dev->slock, flags); +	saa7134_buffer_timeout((unsigned long)q); /* also calls del_timer(&q->timeout) */ +} +EXPORT_SYMBOL_GPL(saa7134_stop_streaming); +  /* ------------------------------------------------------------------ */  int saa7134_set_dmabits(struct saa7134_dev *dev) @@ -388,12 +395,11 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)  		ctrl |= SAA7134_MAIN_CTRL_TE0;  		irq  |= SAA7134_IRQ1_INTE_RA0_1 |  			SAA7134_IRQ1_INTE_RA0_0; -		cap = dev->video_q.curr->vb.field; +		cap = dev->field;  	}  	/* video capture -- dma 1+2 (planar modes) */ -	if (dev->video_q.curr && -	    dev->video_q.curr->fmt->planar) { +	if (dev->video_q.curr && dev->fmt->planar) {  		ctrl |= SAA7134_MAIN_CTRL_TE4 |  			SAA7134_MAIN_CTRL_TE5;  	} @@ -751,6 +757,7 @@ static int saa7134_hwfini(struct saa7134_dev *dev)  	saa7134_input_fini(dev);  	saa7134_vbi_fini(dev);  	saa7134_tvaudio_fini(dev); +	saa7134_video_fini(dev);  	return 0;  } @@ -802,7 +809,6 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,  	*vfd = *template;  	vfd->v4l2_dev  = &dev->v4l2_dev;  	vfd->release = video_device_release; -	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); @@ -992,7 +998,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev,  	/* get irq */  	err = request_irq(pci_dev->irq, saa7134_irq, -			  IRQF_SHARED | IRQF_DISABLED, dev->name, dev); +			  IRQF_SHARED, dev->name, dev);  	if (err < 0) {  		printk(KERN_ERR "%s: can't get IRQ %d\n",  		       dev->name,pci_dev->irq); @@ -1008,13 +1014,13 @@ static int saa7134_initdev(struct pci_dev *pci_dev,  	/* load i2c helpers */  	if (card_is_empress(dev)) { -		struct v4l2_subdev *sd = +		dev->empress_sd =  			v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,  				"saa6752hs",  				saa7134_boards[dev->board].empress_addr, NULL); -		if (sd) -			sd->grp_id = GRP_EMPRESS; +		if (dev->empress_sd) +			dev->empress_sd->grp_id = GRP_EMPRESS;  	}  	if (saa7134_boards[dev->board].rds_addr) { @@ -1046,6 +1052,9 @@ static int saa7134_initdev(struct pci_dev *pci_dev,  		printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);  	dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); +	dev->video_dev->ctrl_handler = &dev->ctrl_handler; +	dev->video_dev->lock = &dev->lock; +	dev->video_dev->queue = &dev->video_vbq;  	err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,  				    video_nr[dev->nr]);  	if (err < 0) { @@ -1057,6 +1066,9 @@ static int saa7134_initdev(struct pci_dev *pci_dev,  	       dev->name, video_device_node_name(dev->video_dev));  	dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); +	dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; +	dev->vbi_dev->lock = &dev->lock; +	dev->vbi_dev->queue = &dev->vbi_vbq;  	err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,  				    vbi_nr[dev->nr]); @@ -1067,6 +1079,8 @@ static int saa7134_initdev(struct pci_dev *pci_dev,  	if (card_has_radio(dev)) {  		dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio"); +		dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; +		dev->radio_dev->lock = &dev->lock;  		err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,  					    radio_nr[dev->nr]);  		if (err < 0) @@ -1186,7 +1200,7 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev,  	if (!list_empty(&q->queue))  		next = list_entry(q->queue.next, struct saa7134_buf, -					  vb.queue); +					  entry);  	buf->activate(dev, buf, next);  	return 0; @@ -1357,10 +1371,3 @@ EXPORT_SYMBOL(saa7134_pgtable_free);  EXPORT_SYMBOL(saa7134_pgtable_build);  EXPORT_SYMBOL(saa7134_pgtable_alloc);  EXPORT_SYMBOL(saa7134_set_dmabits); - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index 4a08ae31df2..73ffbabf831 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -602,10 +602,10 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,  				struct tda1004x_config *cdec_conf,  				struct tda827x_config *tuner_conf)  { -	struct videobuf_dvb_frontend *fe0; +	struct vb2_dvb_frontend *fe0;  	/* Get the first frontend */ -	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); +	fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);  	if (!fe0)  		return -EINVAL; @@ -1215,29 +1215,38 @@ static int dvb_init(struct saa7134_dev *dev)  {  	int ret;  	int attach_xc3028 = 0; -	struct videobuf_dvb_frontend *fe0; +	struct vb2_dvb_frontend *fe0; +	struct vb2_queue *q;  	/* FIXME: add support for multi-frontend */  	mutex_init(&dev->frontends.lock);  	INIT_LIST_HEAD(&dev->frontends.felist);  	printk(KERN_INFO "%s() allocating 1 frontend\n", __func__); -	fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, 1); +	fe0 = vb2_dvb_alloc_frontend(&dev->frontends, 1);  	if (!fe0) {  		printk(KERN_ERR "%s() failed to alloc\n", __func__);  		return -ENOMEM;  	} -	/* init struct videobuf_dvb */ +	/* init struct vb2_dvb */  	dev->ts.nr_bufs    = 32;  	dev->ts.nr_packets = 32*4;  	fe0->dvb.name = dev->name; -	videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops, -			    &dev->pci->dev, &dev->slock, -			    V4L2_BUF_TYPE_VIDEO_CAPTURE, -			    V4L2_FIELD_ALTERNATE, -			    sizeof(struct saa7134_buf), -			    dev, NULL); +	q = &fe0->dvb.dvbq; +	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +	q->io_modes = VB2_MMAP | VB2_READ; +	q->drv_priv = &dev->ts_q; +	q->ops = &saa7134_ts_qops; +	q->mem_ops = &vb2_dma_sg_memops; +	q->buf_struct_size = sizeof(struct saa7134_buf); +	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; +	q->lock = &dev->lock; +	ret = vb2_queue_init(q); +	if (ret) { +		vb2_dvb_dealloc_frontends(&dev->frontends); +		return ret; +	}  	switch (dev->board) {  	case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: @@ -1876,7 +1885,7 @@ static int dvb_init(struct saa7134_dev *dev)  	fe0->dvb.frontend->callback = saa7134_tuner_callback;  	/* register everything else */ -	ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, +	ret = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,  					&dev->pci->dev, adapter_nr, 0);  	/* this sequence is necessary to make the tda1004x load its firmware @@ -1893,16 +1902,17 @@ static int dvb_init(struct saa7134_dev *dev)  	return ret;  detach_frontend: -	videobuf_dvb_dealloc_frontends(&dev->frontends); +	vb2_dvb_dealloc_frontends(&dev->frontends); +	vb2_queue_release(&fe0->dvb.dvbq);  	return -EINVAL;  }  static int dvb_fini(struct saa7134_dev *dev)  { -	struct videobuf_dvb_frontend *fe0; +	struct vb2_dvb_frontend *fe0;  	/* Get the first frontend */ -	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); +	fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);  	if (!fe0)  		return -EINVAL; @@ -1933,7 +1943,8 @@ static int dvb_fini(struct saa7134_dev *dev)  			}  		}  	} -	videobuf_dvb_unregister_bus(&dev->frontends); +	vb2_dvb_unregister_bus(&dev->frontends); +	vb2_queue_release(&fe0->dvb.dvbq);  	return 0;  } @@ -1955,10 +1966,3 @@ static void __exit dvb_unregister(void)  module_init(dvb_register);  module_exit(dvb_unregister); - -/* ------------------------------------------------------------------ */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 3022eb2a792..0006d6bf8c1 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -23,12 +23,12 @@  #include <linux/kernel.h>  #include <linux/delay.h> +#include <media/v4l2-common.h> +#include <media/v4l2-event.h> +  #include "saa7134-reg.h"  #include "saa7134.h" -#include <media/saa6752hs.h> -#include <media/v4l2-common.h> -  /* ------------------------------------------------------------------ */  MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); @@ -48,21 +48,16 @@ MODULE_PARM_DESC(debug,"enable debug messages");  /* ------------------------------------------------------------------ */ -static void ts_reset_encoder(struct saa7134_dev* dev) -{ -	if (!dev->empress_started) -		return; - -	saa_writeb(SAA7134_SPECIAL_MODE, 0x00); -	msleep(10); -	saa_writeb(SAA7134_SPECIAL_MODE, 0x01); -	msleep(100); -	dev->empress_started = 0; -} - -static int ts_init_encoder(struct saa7134_dev* dev) +static int start_streaming(struct vb2_queue *vq, unsigned int count)  { +	struct saa7134_dmaqueue *dmaq = vq->drv_priv; +	struct saa7134_dev *dev = dmaq->dev;  	u32 leading_null_bytes = 0; +	int err; + +	err = saa7134_ts_start_streaming(vq, count); +	if (err) +		return err;  	/* If more cards start to need this, then this  	   should probably be added to the card definitions. */ @@ -73,136 +68,43 @@ static int ts_init_encoder(struct saa7134_dev* dev)  		leading_null_bytes = 1;  		break;  	} -	ts_reset_encoder(dev);  	saa_call_all(dev, core, init, leading_null_bytes); -	dev->empress_started = 1; -	return 0; -} - -/* ------------------------------------------------------------------ */ - -static int ts_open(struct file *file) -{ -	struct video_device *vdev = video_devdata(file); -	struct saa7134_dev *dev = video_drvdata(file); -	int err; - -	dprintk("open dev=%s\n", video_device_node_name(vdev)); -	err = -EBUSY; -	if (!mutex_trylock(&dev->empress_tsq.vb_lock)) -		return err; -	if (atomic_read(&dev->empress_users)) -		goto done; -  	/* Unmute audio */  	saa_writeb(SAA7134_AUDIO_MUTE_CTRL, -		saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); - -	atomic_inc(&dev->empress_users); -	file->private_data = dev; -	err = 0; - -done: -	mutex_unlock(&dev->empress_tsq.vb_lock); -	return err; +			saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); +	dev->empress_started = 1; +	return 0;  } -static int ts_release(struct file *file) +static void stop_streaming(struct vb2_queue *vq)  { -	struct saa7134_dev *dev = file->private_data; - -	videobuf_stop(&dev->empress_tsq); -	videobuf_mmap_free(&dev->empress_tsq); - -	/* stop the encoder */ -	ts_reset_encoder(dev); +	struct saa7134_dmaqueue *dmaq = vq->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	saa7134_ts_stop_streaming(vq); +	saa_writeb(SAA7134_SPECIAL_MODE, 0x00); +	msleep(20); +	saa_writeb(SAA7134_SPECIAL_MODE, 0x01); +	msleep(100);  	/* Mute audio */  	saa_writeb(SAA7134_AUDIO_MUTE_CTRL, -		saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - -	atomic_dec(&dev->empress_users); - -	return 0; -} - -static ssize_t -ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ -	struct saa7134_dev *dev = file->private_data; - -	if (!dev->empress_started) -		ts_init_encoder(dev); - -	return videobuf_read_stream(&dev->empress_tsq, -				    data, count, ppos, 0, -				    file->f_flags & O_NONBLOCK); -} - -static unsigned int -ts_poll(struct file *file, struct poll_table_struct *wait) -{ -	struct saa7134_dev *dev = file->private_data; - -	return videobuf_poll_stream(file, &dev->empress_tsq, wait); -} - - -static int -ts_mmap(struct file *file, struct vm_area_struct * vma) -{ -	struct saa7134_dev *dev = file->private_data; - -	return videobuf_mmap_mapper(&dev->empress_tsq, vma); -} - -/* - * This function is _not_ called directly, but from - * video_generic_ioctl (and maybe others).  userspace - * copying is done already, arg is a kernel pointer. - */ - -static int empress_querycap(struct file *file, void  *priv, -					struct v4l2_capability *cap) -{ -	struct saa7134_dev *dev = file->private_data; - -	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_VIDEO_CAPTURE | -		V4L2_CAP_READWRITE | -		V4L2_CAP_STREAMING; -	return 0; -} - -static int empress_enum_input(struct file *file, void *priv, -					struct v4l2_input *i) -{ -	if (i->index != 0) -		return -EINVAL; - -	i->type = V4L2_INPUT_TYPE_CAMERA; -	strcpy(i->name, "CCIR656"); - -	return 0; -} - -static int empress_g_input(struct file *file, void *priv, unsigned int *i) -{ -	*i = 0; -	return 0; +			saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); +	dev->empress_started = 0;  } -static int empress_s_input(struct file *file, void *priv, unsigned int i) -{ -	if (i != 0) -		return -EINVAL; +static struct vb2_ops saa7134_empress_qops = { +	.queue_setup	= saa7134_ts_queue_setup, +	.buf_init	= saa7134_ts_buffer_init, +	.buf_prepare	= saa7134_ts_buffer_prepare, +	.buf_finish	= saa7134_ts_buffer_finish, +	.buf_queue	= saa7134_vb2_buffer_queue, +	.wait_prepare	= vb2_ops_wait_prepare, +	.wait_finish	= vb2_ops_wait_finish, +	.start_streaming = start_streaming, +	.stop_streaming = stop_streaming, +}; -	return 0; -} +/* ------------------------------------------------------------------ */  static int empress_enum_fmt_vid_cap(struct file *file, void  *priv,  					struct v4l2_fmtdesc *f) @@ -219,7 +121,7 @@ static int empress_enum_fmt_vid_cap(struct file *file, void  *priv,  static int empress_g_fmt_vid_cap(struct file *file, void *priv,  				struct v4l2_format *f)  { -	struct saa7134_dev *dev = file->private_data; +	struct saa7134_dev *dev = video_drvdata(file);  	struct v4l2_mbus_framefmt mbus_fmt;  	saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt); @@ -236,7 +138,7 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv,  static int empress_s_fmt_vid_cap(struct file *file, void *priv,  				struct v4l2_format *f)  { -	struct saa7134_dev *dev = file->private_data; +	struct saa7134_dev *dev = video_drvdata(file);  	struct v4l2_mbus_framefmt mbus_fmt;  	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); @@ -254,7 +156,7 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,  static int empress_try_fmt_vid_cap(struct file *file, void *priv,  				struct v4l2_format *f)  { -	struct saa7134_dev *dev = file->private_data; +	struct saa7134_dev *dev = video_drvdata(file);  	struct v4l2_mbus_framefmt mbus_fmt;  	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); @@ -269,209 +171,42 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv,  	return 0;  } -static int empress_reqbufs(struct file *file, void *priv, -					struct v4l2_requestbuffers *p) -{ -	struct saa7134_dev *dev = file->private_data; - -	return videobuf_reqbufs(&dev->empress_tsq, p); -} - -static int empress_querybuf(struct file *file, void *priv, -					struct v4l2_buffer *b) -{ -	struct saa7134_dev *dev = file->private_data; - -	return videobuf_querybuf(&dev->empress_tsq, b); -} - -static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ -	struct saa7134_dev *dev = file->private_data; - -	return videobuf_qbuf(&dev->empress_tsq, b); -} - -static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ -	struct saa7134_dev *dev = file->private_data; - -	return videobuf_dqbuf(&dev->empress_tsq, b, -				file->f_flags & O_NONBLOCK); -} - -static int empress_streamon(struct file *file, void *priv, -					enum v4l2_buf_type type) -{ -	struct saa7134_dev *dev = file->private_data; - -	return videobuf_streamon(&dev->empress_tsq); -} - -static int empress_streamoff(struct file *file, void *priv, -					enum v4l2_buf_type type) -{ -	struct saa7134_dev *dev = file->private_data; - -	return videobuf_streamoff(&dev->empress_tsq); -} - -static int empress_s_ext_ctrls(struct file *file, void *priv, -			       struct v4l2_ext_controls *ctrls) -{ -	struct saa7134_dev *dev = file->private_data; -	int err; - -	/* count == 0 is abused in saa6752hs.c, so that special -		case is handled here explicitly. */ -	if (ctrls->count == 0) -		return 0; - -	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) -		return -EINVAL; - -	err = saa_call_empress(dev, core, s_ext_ctrls, ctrls); -	ts_init_encoder(dev); - -	return err; -} - -static int empress_g_ext_ctrls(struct file *file, void *priv, -			       struct v4l2_ext_controls *ctrls) -{ -	struct saa7134_dev *dev = file->private_data; - -	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) -		return -EINVAL; -	return saa_call_empress(dev, core, g_ext_ctrls, ctrls); -} - -static int empress_g_ctrl(struct file *file, void *priv, -					struct v4l2_control *c) -{ -	struct saa7134_dev *dev = file->private_data; - -	return saa7134_g_ctrl_internal(dev, NULL, c); -} - -static int empress_s_ctrl(struct file *file, void *priv, -					struct v4l2_control *c) -{ -	struct saa7134_dev *dev = file->private_data; - -	return saa7134_s_ctrl_internal(dev, NULL, c); -} - -static int empress_queryctrl(struct file *file, void *priv, -					struct v4l2_queryctrl *c) -{ -	/* Must be sorted from low to high control ID! */ -	static const u32 user_ctrls[] = { -		V4L2_CID_USER_CLASS, -		V4L2_CID_BRIGHTNESS, -		V4L2_CID_CONTRAST, -		V4L2_CID_SATURATION, -		V4L2_CID_HUE, -		V4L2_CID_AUDIO_VOLUME, -		V4L2_CID_AUDIO_MUTE, -		V4L2_CID_HFLIP, -		0 -	}; - -	/* Must be sorted from low to high control ID! */ -	static const u32 mpeg_ctrls[] = { -		V4L2_CID_MPEG_CLASS, -		V4L2_CID_MPEG_STREAM_TYPE, -		V4L2_CID_MPEG_STREAM_PID_PMT, -		V4L2_CID_MPEG_STREAM_PID_AUDIO, -		V4L2_CID_MPEG_STREAM_PID_VIDEO, -		V4L2_CID_MPEG_STREAM_PID_PCR, -		V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, -		V4L2_CID_MPEG_AUDIO_ENCODING, -		V4L2_CID_MPEG_AUDIO_L2_BITRATE, -		V4L2_CID_MPEG_VIDEO_ENCODING, -		V4L2_CID_MPEG_VIDEO_ASPECT, -		V4L2_CID_MPEG_VIDEO_BITRATE_MODE, -		V4L2_CID_MPEG_VIDEO_BITRATE, -		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, -		0 -	}; -	static const u32 *ctrl_classes[] = { -		user_ctrls, -		mpeg_ctrls, -		NULL -	}; -	struct saa7134_dev *dev = file->private_data; - -	c->id = v4l2_ctrl_next(ctrl_classes, c->id); -	if (c->id == 0) -		return -EINVAL; -	if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS) -		return v4l2_ctrl_query_fill(c, 0, 0, 0, 0); -	if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG) -		return saa7134_queryctrl(file, priv, c); -	return saa_call_empress(dev, core, queryctrl, c); -} - -static int empress_querymenu(struct file *file, void *priv, -					struct v4l2_querymenu *c) -{ -	struct saa7134_dev *dev = file->private_data; - -	if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG) -		return -EINVAL; -	return saa_call_empress(dev, core, querymenu, c); -} - -static int empress_s_std(struct file *file, void *priv, v4l2_std_id id) -{ -	struct saa7134_dev *dev = file->private_data; - -	return saa7134_s_std_internal(dev, NULL, id); -} - -static int empress_g_std(struct file *file, void *priv, v4l2_std_id *id) -{ -	struct saa7134_dev *dev = file->private_data; - -	*id = dev->tvnorm->id; -	return 0; -} -  static const struct v4l2_file_operations ts_fops =  {  	.owner	  = THIS_MODULE, -	.open	  = ts_open, -	.release  = ts_release, -	.read	  = ts_read, -	.poll	  = ts_poll, -	.mmap	  = ts_mmap, -	.ioctl	  = video_ioctl2, +	.open	  = v4l2_fh_open, +	.release  = vb2_fop_release, +	.read	  = vb2_fop_read, +	.poll	  = vb2_fop_poll, +	.mmap	  = vb2_fop_mmap, +	.unlocked_ioctl = video_ioctl2,  };  static const struct v4l2_ioctl_ops ts_ioctl_ops = { -	.vidioc_querycap		= empress_querycap, +	.vidioc_querycap		= saa7134_querycap,  	.vidioc_enum_fmt_vid_cap	= empress_enum_fmt_vid_cap,  	.vidioc_try_fmt_vid_cap		= empress_try_fmt_vid_cap,  	.vidioc_s_fmt_vid_cap		= empress_s_fmt_vid_cap,  	.vidioc_g_fmt_vid_cap		= empress_g_fmt_vid_cap, -	.vidioc_reqbufs			= empress_reqbufs, -	.vidioc_querybuf		= empress_querybuf, -	.vidioc_qbuf			= empress_qbuf, -	.vidioc_dqbuf			= empress_dqbuf, -	.vidioc_streamon		= empress_streamon, -	.vidioc_streamoff		= empress_streamoff, -	.vidioc_s_ext_ctrls		= empress_s_ext_ctrls, -	.vidioc_g_ext_ctrls		= empress_g_ext_ctrls, -	.vidioc_enum_input		= empress_enum_input, -	.vidioc_g_input			= empress_g_input, -	.vidioc_s_input			= empress_s_input, -	.vidioc_queryctrl		= empress_queryctrl, -	.vidioc_querymenu		= empress_querymenu, -	.vidioc_g_ctrl			= empress_g_ctrl, -	.vidioc_s_ctrl			= empress_s_ctrl, -	.vidioc_s_std			= empress_s_std, -	.vidioc_g_std			= empress_g_std, +	.vidioc_reqbufs			= vb2_ioctl_reqbufs, +	.vidioc_querybuf		= vb2_ioctl_querybuf, +	.vidioc_qbuf			= vb2_ioctl_qbuf, +	.vidioc_dqbuf			= vb2_ioctl_dqbuf, +	.vidioc_streamon		= vb2_ioctl_streamon, +	.vidioc_streamoff		= vb2_ioctl_streamoff, +	.vidioc_g_frequency		= saa7134_g_frequency, +	.vidioc_s_frequency		= saa7134_s_frequency, +	.vidioc_g_tuner			= saa7134_g_tuner, +	.vidioc_s_tuner			= saa7134_s_tuner, +	.vidioc_enum_input		= saa7134_enum_input, +	.vidioc_g_input			= saa7134_g_input, +	.vidioc_s_input			= saa7134_s_input, +	.vidioc_s_std			= saa7134_s_std, +	.vidioc_g_std			= saa7134_g_std, +	.vidioc_querystd		= saa7134_querystd, +	.vidioc_log_status		= v4l2_ctrl_log_status, +	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event, +	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,  };  /* ----------------------------------------------------------- */ @@ -501,9 +236,27 @@ static void empress_signal_change(struct saa7134_dev *dev)  	schedule_work(&dev->empress_workqueue);  } +static bool empress_ctrl_filter(const struct v4l2_ctrl *ctrl) +{ +	switch (ctrl->id) { +	case V4L2_CID_BRIGHTNESS: +	case V4L2_CID_HUE: +	case V4L2_CID_CONTRAST: +	case V4L2_CID_SATURATION: +	case V4L2_CID_AUDIO_MUTE: +	case V4L2_CID_AUDIO_VOLUME: +	case V4L2_CID_PRIVATE_INVERT: +	case V4L2_CID_PRIVATE_AUTOMUTE: +		return true; +	default: +		return false; +	} +}  static int empress_init(struct saa7134_dev *dev)  { +	struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler; +	struct vb2_queue *q;  	int err;  	dprintk("%s: %s\n",dev->name,__func__); @@ -513,12 +266,43 @@ static int empress_init(struct saa7134_dev *dev)  	*(dev->empress_dev) = saa7134_empress_template;  	dev->empress_dev->v4l2_dev  = &dev->v4l2_dev;  	dev->empress_dev->release = video_device_release; +	dev->empress_dev->lock = &dev->lock;  	snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),  		 "%s empress (%s)", dev->name,  		 saa7134_boards[dev->board].name); +	set_bit(V4L2_FL_USE_FH_PRIO, &dev->empress_dev->flags); +	v4l2_ctrl_handler_init(hdl, 21); +	v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter); +	if (dev->empress_sd) +		v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL); +	if (hdl->error) { +		video_device_release(dev->empress_dev); +		return hdl->error; +	} +	dev->empress_dev->ctrl_handler = hdl;  	INIT_WORK(&dev->empress_workqueue, empress_signal_update); +	q = &dev->empress_vbq; +	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +	/* +	 * Do not add VB2_USERPTR: the saa7134 DMA engine cannot handle +	 * transfers that do not start at the beginning of a page. A USERPTR +	 * can start anywhere in a page, so USERPTR support is a no-go. +	 */ +	q->io_modes = VB2_MMAP | VB2_READ; +	q->drv_priv = &dev->ts_q; +	q->ops = &saa7134_empress_qops; +	q->gfp_flags = GFP_DMA32; +	q->mem_ops = &vb2_dma_sg_memops; +	q->buf_struct_size = sizeof(struct saa7134_buf); +	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; +	q->lock = &dev->lock; +	err = vb2_queue_init(q); +	if (err) +		return err; +	dev->empress_dev->queue = q; +  	video_set_drvdata(dev->empress_dev, dev);  	err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,  				    empress_nr[dev->nr]); @@ -532,13 +316,6 @@ static int empress_init(struct saa7134_dev *dev)  	printk(KERN_INFO "%s: registered device %s [mpeg]\n",  	       dev->name, video_device_node_name(dev->empress_dev)); -	videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, -			    &dev->pci->dev, &dev->slock, -			    V4L2_BUF_TYPE_VIDEO_CAPTURE, -			    V4L2_FIELD_ALTERNATE, -			    sizeof(struct saa7134_buf), -			    dev, NULL); -  	empress_signal_update(&dev->empress_workqueue);  	return 0;  } @@ -551,6 +328,8 @@ static int empress_fini(struct saa7134_dev *dev)  		return 0;  	flush_work(&dev->empress_workqueue);  	video_unregister_device(dev->empress_dev); +	vb2_queue_release(&dev->empress_vbq); +	v4l2_ctrl_handler_free(&dev->empress_ctrl_handler);  	dev->empress_dev = NULL;  	return 0;  } @@ -574,10 +353,3 @@ static void __exit empress_unregister(void)  module_init(empress_register);  module_exit(empress_unregister); - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index c68169d7580..f4da674e7f2 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -427,10 +427,3 @@ int saa7134_i2c_unregister(struct saa7134_dev *dev)  	i2c_del_adapter(&dev->i2c_adap);  	return 0;  } - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/saa7134/saa7134-reg.h b/drivers/media/pci/saa7134/saa7134-reg.h index e7e0af101fa..b6ea6f4f9b6 100644 --- a/drivers/media/pci/saa7134/saa7134-reg.h +++ b/drivers/media/pci/saa7134/saa7134-reg.h @@ -167,17 +167,22 @@  #define SAA7134_HSYNC_START                     0x106  #define SAA7134_HSYNC_STOP                      0x107  #define SAA7134_SYNC_CTRL                       0x108 +#define   SAA7134_SYNC_CTRL_AUFD                (1 << 7)  #define SAA7134_LUMA_CTRL                       0x109 +#define   SAA7134_LUMA_CTRL_LDEL                (1 << 5)  #define SAA7134_DEC_LUMA_BRIGHT                 0x10a  #define SAA7134_DEC_LUMA_CONTRAST               0x10b  #define SAA7134_DEC_CHROMA_SATURATION           0x10c  #define SAA7134_DEC_CHROMA_HUE                  0x10d  #define SAA7134_CHROMA_CTRL1                    0x10e +#define   SAA7134_CHROMA_CTRL1_AUTO0            (1 << 1) +#define   SAA7134_CHROMA_CTRL1_FCTC             (1 << 2)  #define SAA7134_CHROMA_GAIN                     0x10f  #define SAA7134_CHROMA_CTRL2                    0x110  #define SAA7134_MODE_DELAY_CTRL                 0x111  #define SAA7134_ANALOG_ADC                      0x114 +#define   SAA7134_ANALOG_ADC_AUTO1              (1 << 2)  #define SAA7134_VGATE_START                     0x115  #define SAA7134_VGATE_STOP                      0x116  #define SAA7134_MISC_VGATE_MSB                  0x117 @@ -369,10 +374,3 @@  #define SAA7135_DSP_RWCLEAR_RERR		    1  #define SAA7133_I2S_AUDIO_CONTROL               0x591 -/* ------------------------------------------------------------------ */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ - diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 2e3f4b412d8..bd25323bd94 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -39,26 +39,29 @@ MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");  	printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)  /* ------------------------------------------------------------------ */ -  static int buffer_activate(struct saa7134_dev *dev,  			   struct saa7134_buf *buf,  			   struct saa7134_buf *next)  {  	dprintk("buffer_activate [%p]",buf); -	buf->vb.state = VIDEOBUF_ACTIVE;  	buf->top_seen = 0; +	if (!dev->ts_started) +		dev->ts_field = V4L2_FIELD_TOP; +  	if (NULL == next)  		next = buf; -	if (V4L2_FIELD_TOP == buf->vb.field) { +	if (V4L2_FIELD_TOP == dev->ts_field) {  		dprintk("- [top]     buf=%p next=%p\n",buf,next);  		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));  		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next)); +		dev->ts_field = V4L2_FIELD_BOTTOM;  	} else {  		dprintk("- [bottom]  buf=%p next=%p\n",buf,next);  		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));  		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); +		dev->ts_field = V4L2_FIELD_TOP;  	}  	/* start DMA */ @@ -72,96 +75,123 @@ static int buffer_activate(struct saa7134_dev *dev,  	return 0;  } -static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, -		enum v4l2_field field) +int saa7134_ts_buffer_init(struct vb2_buffer *vb2)  { -	struct saa7134_dev *dev = q->priv_data; -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); + +	dmaq->curr = NULL; +	buf->activate = buffer_activate; + +	return 0; +} +EXPORT_SYMBOL_GPL(saa7134_ts_buffer_init); + +int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2) +{ +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); +	struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0);  	unsigned int lines, llength, size; -	int err; +	int ret; -	dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); +	dprintk("buffer_prepare [%p]\n", buf);  	llength = TS_PACKET_SIZE;  	lines = dev->ts.nr_packets;  	size = lines * llength; -	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) +	if (vb2_plane_size(vb2, 0) < size)  		return -EINVAL; -	if (buf->vb.size != size) { -		saa7134_dma_free(q,buf); -	} - -	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - -		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - -		dprintk("buffer_prepare: needs_init\n"); - -		buf->vb.width  = llength; -		buf->vb.height = lines; -		buf->vb.size   = size; -		buf->pt        = &dev->ts.pt_ts; - -		err = videobuf_iolock(q,&buf->vb,NULL); -		if (err) -			goto oops; -		err = saa7134_pgtable_build(dev->pci,buf->pt, -					    dma->sglist, -					    dma->sglen, -					    saa7134_buffer_startpage(buf)); -		if (err) -			goto oops; -	} - -	buf->vb.state = VIDEOBUF_PREPARED; -	buf->activate = buffer_activate; -	buf->vb.field = field; -	return 0; +	vb2_set_plane_payload(vb2, 0, size); +	vb2->v4l2_buf.field = dev->field; - oops: -	saa7134_dma_free(q,buf); -	return err; +	ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); +	if (!ret) +		return -EIO; +	return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, +				    saa7134_buffer_startpage(buf));  } +EXPORT_SYMBOL_GPL(saa7134_ts_buffer_prepare); -static int -buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) +void saa7134_ts_buffer_finish(struct vb2_buffer *vb2)  { -	struct saa7134_dev *dev = q->priv_data; +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); +	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); -	*size = TS_PACKET_SIZE * dev->ts.nr_packets; -	if (0 == *count) -		*count = dev->ts.nr_bufs; -	*count = saa7134_buffer_count(*size,*count); +	dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); +} +EXPORT_SYMBOL_GPL(saa7134_ts_buffer_finish); +int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, +			   unsigned int *nbuffers, unsigned int *nplanes, +			   unsigned int sizes[], void *alloc_ctxs[]) +{ +	struct saa7134_dmaqueue *dmaq = q->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	int size = TS_PACKET_SIZE * dev->ts.nr_packets; + +	if (0 == *nbuffers) +		*nbuffers = dev->ts.nr_bufs; +	*nbuffers = saa7134_buffer_count(size, *nbuffers); +	if (*nbuffers < 3) +		*nbuffers = 3; +	*nplanes = 1; +	sizes[0] = size;  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_ts_queue_setup); -static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) +int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count)  { -	struct saa7134_dev *dev = q->priv_data; -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); - -	saa7134_buffer_queue(dev,&dev->ts_q,buf); +	struct saa7134_dmaqueue *dmaq = vq->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; + +	/* +	 * Planar video capture and TS share the same DMA channel, +	 * so only one can be active at a time. +	 */ +	if (vb2_is_busy(&dev->video_vbq) && dev->fmt->planar) { +		struct saa7134_buf *buf, *tmp; + +		list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) { +			list_del(&buf->entry); +			vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED); +		} +		if (dmaq->curr) { +			vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED); +			dmaq->curr = NULL; +		} +		return -EBUSY; +	} +	dmaq->seq_nr = 0; +	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_ts_start_streaming); -static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) +void saa7134_ts_stop_streaming(struct vb2_queue *vq)  { -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); -	struct saa7134_dev *dev = q->priv_data; - -	if (dev->ts_started) -		saa7134_ts_stop(dev); +	struct saa7134_dmaqueue *dmaq = vq->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; -	saa7134_dma_free(q,buf); +	saa7134_ts_stop(dev); +	saa7134_stop_streaming(dev, dmaq);  } - -struct videobuf_queue_ops saa7134_ts_qops = { -	.buf_setup    = buffer_setup, -	.buf_prepare  = buffer_prepare, -	.buf_queue    = buffer_queue, -	.buf_release  = buffer_release, +EXPORT_SYMBOL_GPL(saa7134_ts_stop_streaming); + +struct vb2_ops saa7134_ts_qops = { +	.queue_setup	= saa7134_ts_queue_setup, +	.buf_init	= saa7134_ts_buffer_init, +	.buf_prepare	= saa7134_ts_buffer_prepare, +	.buf_finish	= saa7134_ts_buffer_finish, +	.buf_queue	= saa7134_vb2_buffer_queue, +	.wait_prepare	= vb2_ops_wait_prepare, +	.wait_finish	= vb2_ops_wait_finish, +	.stop_streaming = saa7134_ts_stop_streaming,  };  EXPORT_SYMBOL_GPL(saa7134_ts_qops); @@ -213,7 +243,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev)  	dev->ts_q.dev              = dev;  	dev->ts_q.need_two         = 1;  	dev->ts_started            = 0; -	saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); +	saa7134_pgtable_alloc(dev->pci, &dev->ts_q.pt);  	/* init TS hw */  	saa7134_ts_init_hw(dev); @@ -226,7 +256,8 @@ int saa7134_ts_stop(struct saa7134_dev *dev)  {  	dprintk("TS stop\n"); -	BUG_ON(!dev->ts_started); +	if (!dev->ts_started) +		return 0;  	/* Stop TS stream */  	switch (saa7134_boards[dev->board].ts_type) { @@ -247,7 +278,8 @@ int saa7134_ts_start(struct saa7134_dev *dev)  {  	dprintk("TS start\n"); -	BUG_ON(dev->ts_started); +	if (WARN_ON(dev->ts_started)) +		return 0;  	/* dma: setup channel 5 (= TS) */  	saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); @@ -259,7 +291,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)  	saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);  	saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |  					  SAA7134_RS_CONTROL_ME | -					  (dev->ts.pt_ts.dma >> 12)); +					  (dev->ts_q.pt.dma >> 12));  	/* reset hardware TS buffers */  	saa_writeb(SAA7134_TS_SERIAL1, 0x00); @@ -293,7 +325,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)  int saa7134_ts_fini(struct saa7134_dev *dev)  { -	saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); +	saa7134_pgtable_free(dev->pci, &dev->ts_q.pt);  	return 0;  } @@ -303,25 +335,18 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)  	spin_lock(&dev->slock);  	if (dev->ts_q.curr) { -		field = dev->ts_q.curr->vb.field; -		if (field == V4L2_FIELD_TOP) { +		field = dev->ts_field; +		if (field != V4L2_FIELD_TOP) {  			if ((status & 0x100000) != 0x000000)  				goto done;  		} else {  			if ((status & 0x100000) != 0x100000)  				goto done;  		} -		saa7134_buffer_finish(dev,&dev->ts_q,VIDEOBUF_DONE); +		saa7134_buffer_finish(dev, &dev->ts_q, VB2_BUF_STATE_DONE);  	}  	saa7134_buffer_next(dev,&dev->ts_q);   done:  	spin_unlock(&dev->slock);  } - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index 0f34e09d98d..3afbcb70b51 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -1079,10 +1079,3 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)  EXPORT_SYMBOL(saa_dsp_writel);  EXPORT_SYMBOL(saa7134_tvaudio_setmute); - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index e9aa94b807f..c06dbe17a87 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -67,10 +67,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,  	saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task),   0x00);  	saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00); -	saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width   & 0xff); -	saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width   >> 8); -	saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height  & 0xff); -	saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height  >> 8); +	saa_writeb(SAA7134_VBI_H_LEN1(task), dev->vbi_hlen & 0xff); +	saa_writeb(SAA7134_VBI_H_LEN2(task), dev->vbi_hlen >> 8); +	saa_writeb(SAA7134_VBI_V_LEN1(task), dev->vbi_vlen & 0xff); +	saa_writeb(SAA7134_VBI_V_LEN2(task), dev->vbi_vlen >> 8);  	saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);  } @@ -81,14 +81,14 @@ static int buffer_activate(struct saa7134_dev *dev,  			   struct saa7134_buf *buf,  			   struct saa7134_buf *next)  { -	unsigned long control,base; +	struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv; +	unsigned long control, base; -	dprintk("buffer_activate [%p]\n",buf); -	buf->vb.state = VIDEOBUF_ACTIVE; +	dprintk("buffer_activate [%p]\n", buf);  	buf->top_seen = 0; -	task_init(dev,buf,TASK_A); -	task_init(dev,buf,TASK_B); +	task_init(dev, buf, TASK_A); +	task_init(dev, buf, TASK_B);  	saa_writeb(SAA7134_OFMT_DATA_A, 0x06);  	saa_writeb(SAA7134_OFMT_DATA_B, 0x06); @@ -96,110 +96,99 @@ static int buffer_activate(struct saa7134_dev *dev,  	base    = saa7134_buffer_base(buf);  	control = SAA7134_RS_CONTROL_BURST_16 |  		SAA7134_RS_CONTROL_ME | -		(buf->pt->dma >> 12); -	saa_writel(SAA7134_RS_BA1(2),base); -	saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2); -	saa_writel(SAA7134_RS_PITCH(2),buf->vb.width); -	saa_writel(SAA7134_RS_CONTROL(2),control); -	saa_writel(SAA7134_RS_BA1(3),base); -	saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2); -	saa_writel(SAA7134_RS_PITCH(3),buf->vb.width); -	saa_writel(SAA7134_RS_CONTROL(3),control); +		(dmaq->pt.dma >> 12); +	saa_writel(SAA7134_RS_BA1(2), base); +	saa_writel(SAA7134_RS_BA2(2), base + dev->vbi_hlen * dev->vbi_vlen); +	saa_writel(SAA7134_RS_PITCH(2), dev->vbi_hlen); +	saa_writel(SAA7134_RS_CONTROL(2), control); +	saa_writel(SAA7134_RS_BA1(3), base); +	saa_writel(SAA7134_RS_BA2(3), base + dev->vbi_hlen * dev->vbi_vlen); +	saa_writel(SAA7134_RS_PITCH(3), dev->vbi_hlen); +	saa_writel(SAA7134_RS_CONTROL(3), control);  	/* start DMA */  	saa7134_set_dmabits(dev); -	mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT); +	mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT);  	return 0;  } -static int buffer_prepare(struct videobuf_queue *q, -			  struct videobuf_buffer *vb, -			  enum v4l2_field field) +static int buffer_prepare(struct vb2_buffer *vb2)  { -	struct saa7134_fh *fh   = q->priv_data; -	struct saa7134_dev *dev = fh->dev; -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); -	struct saa7134_tvnorm *norm = dev->tvnorm; -	unsigned int lines, llength, size; -	int err; - -	lines   = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1; -	if (lines > VBI_LINE_COUNT) -		lines = VBI_LINE_COUNT; -	llength = VBI_LINE_LENGTH; -	size = lines * llength * 2; -	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); +	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); +	unsigned int size; +	int ret; + +	if (dma->sgl->offset) { +		pr_err("The buffer is not page-aligned\n");  		return -EINVAL; - -	if (buf->vb.size != size) -		saa7134_dma_free(q,buf); - -	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { -		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - -		buf->vb.width  = llength; -		buf->vb.height = lines; -		buf->vb.size   = size; -		buf->pt        = &fh->pt_vbi; - -		err = videobuf_iolock(q,&buf->vb,NULL); -		if (err) -			goto oops; -		err = saa7134_pgtable_build(dev->pci,buf->pt, -					    dma->sglist, -					    dma->sglen, -					    saa7134_buffer_startpage(buf)); -		if (err) -			goto oops;  	} -	buf->vb.state = VIDEOBUF_PREPARED; -	buf->activate = buffer_activate; -	buf->vb.field = field; -	return 0; +	size = dev->vbi_hlen * dev->vbi_vlen * 2; +	if (vb2_plane_size(vb2, 0) < size) +		return -EINVAL; + +	vb2_set_plane_payload(vb2, 0, size); - oops: -	saa7134_dma_free(q,buf); -	return err; +	ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); +	if (!ret) +		return -EIO; +	return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, +				    saa7134_buffer_startpage(buf));  } -static int -buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, +			   unsigned int *nbuffers, unsigned int *nplanes, +			   unsigned int sizes[], void *alloc_ctxs[])  { -	struct saa7134_fh *fh   = q->priv_data; -	struct saa7134_dev *dev = fh->dev; -	int llength,lines; - -	lines   = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1; -	llength = VBI_LINE_LENGTH; -	*size = lines * llength * 2; -	if (0 == *count) -		*count = vbibufs; -	*count = saa7134_buffer_count(*size,*count); +	struct saa7134_dmaqueue *dmaq = q->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	unsigned int size; + +	dev->vbi_vlen = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 + 1; +	if (dev->vbi_vlen > VBI_LINE_COUNT) +		dev->vbi_vlen = VBI_LINE_COUNT; +	dev->vbi_hlen = VBI_LINE_LENGTH; +	size = dev->vbi_hlen * dev->vbi_vlen * 2; + +	*nbuffers = saa7134_buffer_count(size, *nbuffers); +	*nplanes = 1; +	sizes[0] = size;  	return 0;  } -static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) +static int buffer_init(struct vb2_buffer *vb2)  { -	struct saa7134_fh *fh = q->priv_data; -	struct saa7134_dev *dev = fh->dev; -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); -	saa7134_buffer_queue(dev,&dev->vbi_q,buf); +	dmaq->curr = NULL; +	buf->activate = buffer_activate; +	return 0;  } -static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) +static void buffer_finish(struct vb2_buffer *vb2)  { -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); +	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); -	saa7134_dma_free(q,buf); +	dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);  } -struct videobuf_queue_ops saa7134_vbi_qops = { -	.buf_setup    = buffer_setup, -	.buf_prepare  = buffer_prepare, -	.buf_queue    = buffer_queue, -	.buf_release  = buffer_release, +struct vb2_ops saa7134_vbi_qops = { +	.queue_setup	= queue_setup, +	.buf_init	= buffer_init, +	.buf_prepare	= buffer_prepare, +	.buf_finish	= buffer_finish, +	.buf_queue	= saa7134_vb2_buffer_queue, +	.wait_prepare	= vb2_ops_wait_prepare, +	.wait_finish	= vb2_ops_wait_finish, +	.start_streaming = saa7134_vb2_start_streaming, +	.stop_streaming = saa7134_vb2_stop_streaming,  };  /* ------------------------------------------------------------------ */ @@ -229,7 +218,6 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)  {  	spin_lock(&dev->slock);  	if (dev->vbi_q.curr) { -		dev->vbi_fieldcount++;  		/* make sure we have seen both fields */  		if ((status & 0x10) == 0x00) {  			dev->vbi_q.curr->top_seen = 1; @@ -238,18 +226,10 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)  		if (!dev->vbi_q.curr->top_seen)  			goto done; -		dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount; -		saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE); +		saa7134_buffer_finish(dev, &dev->vbi_q, VB2_BUF_STATE_DONE);  	} -	saa7134_buffer_next(dev,&dev->vbi_q); +	saa7134_buffer_next(dev, &dev->vbi_q);   done:  	spin_unlock(&dev->slock);  } - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index e12bbd8c3f0..d3759998076 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -27,11 +27,13 @@  #include <linux/slab.h>  #include <linux/sort.h> -#include "saa7134-reg.h" -#include "saa7134.h"  #include <media/v4l2-common.h> +#include <media/v4l2-event.h>  #include <media/saa6588.h> +#include "saa7134-reg.h" +#include "saa7134.h" +  /* ------------------------------------------------------------------ */  unsigned int video_debug; @@ -369,117 +371,6 @@ static struct saa7134_tvnorm tvnorms[] = {  };  #define TVNORMS ARRAY_SIZE(tvnorms) -#define V4L2_CID_PRIVATE_INVERT      (V4L2_CID_PRIVATE_BASE + 0) -#define V4L2_CID_PRIVATE_Y_ODD       (V4L2_CID_PRIVATE_BASE + 1) -#define V4L2_CID_PRIVATE_Y_EVEN      (V4L2_CID_PRIVATE_BASE + 2) -#define V4L2_CID_PRIVATE_AUTOMUTE    (V4L2_CID_PRIVATE_BASE + 3) -#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 4) - -static const struct v4l2_queryctrl no_ctrl = { -	.name  = "42", -	.flags = V4L2_CTRL_FLAG_DISABLED, -}; -static const struct v4l2_queryctrl video_ctrls[] = { -	/* --- video --- */ -	{ -		.id            = V4L2_CID_BRIGHTNESS, -		.name          = "Brightness", -		.minimum       = 0, -		.maximum       = 255, -		.step          = 1, -		.default_value = 128, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_CONTRAST, -		.name          = "Contrast", -		.minimum       = 0, -		.maximum       = 127, -		.step          = 1, -		.default_value = 68, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_SATURATION, -		.name          = "Saturation", -		.minimum       = 0, -		.maximum       = 127, -		.step          = 1, -		.default_value = 64, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_HUE, -		.name          = "Hue", -		.minimum       = -128, -		.maximum       = 127, -		.step          = 1, -		.default_value = 0, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_HFLIP, -		.name          = "Mirror", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	}, -	/* --- 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       = -15, -		.maximum       = 15, -		.step          = 1, -		.default_value = 0, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	}, -	/* --- private --- */ -	{ -		.id            = V4L2_CID_PRIVATE_INVERT, -		.name          = "Invert", -		.minimum       = 0, -		.maximum       = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_PRIVATE_Y_ODD, -		.name          = "y offset odd field", -		.minimum       = 0, -		.maximum       = 128, -		.step          = 1, -		.default_value = 0, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_PRIVATE_Y_EVEN, -		.name          = "y offset even field", -		.minimum       = 0, -		.maximum       = 128, -		.step          = 1, -		.default_value = 0, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	},{ -		.id            = V4L2_CID_PRIVATE_AUTOMUTE, -		.name          = "automute", -		.minimum       = 0, -		.maximum       = 1, -		.default_value = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	} -}; -static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls); - -static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id) -{ -	unsigned int i; - -	for (i = 0; i < CTRLS; i++) -		if (video_ctrls[i].id == id) -			return video_ctrls+i; -	return NULL; -} -  static struct saa7134_format* format_by_fourcc(unsigned int fourcc)  {  	unsigned int i; @@ -490,52 +381,6 @@ static struct saa7134_format* format_by_fourcc(unsigned int fourcc)  	return NULL;  } -/* ----------------------------------------------------------------------- */ -/* resource management                                                     */ - -static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit) -{ -	if (fh->resources & bit) -		/* have it already allocated */ -		return 1; - -	/* is it free? */ -	mutex_lock(&dev->lock); -	if (dev->resources & bit) { -		/* no, someone else uses it */ -		mutex_unlock(&dev->lock); -		return 0; -	} -	/* it's free, grab it */ -	fh->resources  |= bit; -	dev->resources |= bit; -	dprintk("res: get %d\n",bit); -	mutex_unlock(&dev->lock); -	return 1; -} - -static int res_check(struct saa7134_fh *fh, unsigned int bit) -{ -	return (fh->resources & bit); -} - -static int res_locked(struct saa7134_dev *dev, unsigned int bit) -{ -	return (dev->resources & bit); -} - -static -void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) -{ -	BUG_ON((fh->resources & bits) != bits); - -	mutex_lock(&dev->lock); -	fh->resources  &= ~bits; -	dev->resources &= ~bits; -	dprintk("res: put %d\n",bits); -	mutex_unlock(&dev->lock); -} -  /* ------------------------------------------------------------------ */  static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) @@ -571,19 +416,26 @@ static void video_mux(struct saa7134_dev *dev, int input)  static void saa7134_set_decoder(struct saa7134_dev *dev)  { -	int luma_control, sync_control, mux; +	int luma_control, sync_control, chroma_ctrl1, mux;  	struct saa7134_tvnorm *norm = dev->tvnorm;  	mux = card_in(dev, dev->ctl_input).vmux;  	luma_control = norm->luma_control;  	sync_control = norm->sync_control; +	chroma_ctrl1 = norm->chroma_ctrl1;  	if (mux > 5)  		luma_control |= 0x80; /* svideo */  	if (noninterlaced || dev->nosignal)  		sync_control |= 0x20; +	/* switch on auto standard detection */ +	sync_control |= SAA7134_SYNC_CTRL_AUFD; +	chroma_ctrl1 |= SAA7134_CHROMA_CTRL1_AUTO0; +	chroma_ctrl1 &= ~SAA7134_CHROMA_CTRL1_FCTC; +	luma_control &= ~SAA7134_LUMA_CTRL_LDEL; +  	/* setup video decoder */  	saa_writeb(SAA7134_INCR_DELAY,            0x08);  	saa_writeb(SAA7134_ANALOG_IN_CTRL1,       0xc0 | mux); @@ -606,7 +458,7 @@ static void saa7134_set_decoder(struct saa7134_dev *dev)  		dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);  	saa_writeb(SAA7134_DEC_CHROMA_HUE,        dev->ctl_hue); -	saa_writeb(SAA7134_CHROMA_CTRL1,          norm->chroma_ctrl1); +	saa_writeb(SAA7134_CHROMA_CTRL1,          chroma_ctrl1);  	saa_writeb(SAA7134_CHROMA_GAIN,           norm->chroma_gain);  	saa_writeb(SAA7134_CHROMA_CTRL2,          norm->chroma_ctrl2); @@ -625,10 +477,10 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)  	saa7134_set_decoder(dev);  	if (card_in(dev, dev->ctl_input).tv) -		saa_call_all(dev, core, s_std, dev->tvnorm->id); +		saa_call_all(dev, video, s_std, dev->tvnorm->id);  	/* Set the correct norm for the saa6752hs. This function  	   does nothing if there is no saa6752hs. */ -	saa_call_empress(dev, core, s_std, dev->tvnorm->id); +	saa_call_empress(dev, video, s_std, dev->tvnorm->id);  }  static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) @@ -868,7 +720,7 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win, bool  	return 0;  } -static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh) +static int start_preview(struct saa7134_dev *dev)  {  	unsigned long base,control,bpl;  	int err; @@ -923,7 +775,7 @@ static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)  	return 0;  } -static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh) +static int stop_preview(struct saa7134_dev *dev)  {  	dev->ovenable = 0;  	saa7134_set_dmabits(dev); @@ -936,35 +788,35 @@ static int buffer_activate(struct saa7134_dev *dev,  			   struct saa7134_buf *buf,  			   struct saa7134_buf *next)  { +	struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv;  	unsigned long base,control,bpl;  	unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */  	dprintk("buffer_activate buf=%p\n",buf); -	buf->vb.state = VIDEOBUF_ACTIVE;  	buf->top_seen = 0; -	set_size(dev,TASK_A,buf->vb.width,buf->vb.height, -		 V4L2_FIELD_HAS_BOTH(buf->vb.field)); -	if (buf->fmt->yuv) +	set_size(dev, TASK_A, dev->width, dev->height, +		 V4L2_FIELD_HAS_BOTH(dev->field)); +	if (dev->fmt->yuv)  		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);  	else  		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01); -	saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm); +	saa_writeb(SAA7134_OFMT_VIDEO_A, dev->fmt->pm);  	/* DMA: setup channel 0 (= Video Task A0) */  	base  = saa7134_buffer_base(buf); -	if (buf->fmt->planar) -		bpl = buf->vb.width; +	if (dev->fmt->planar) +		bpl = dev->width;  	else -		bpl = (buf->vb.width * buf->fmt->depth) / 8; +		bpl = (dev->width * dev->fmt->depth) / 8;  	control = SAA7134_RS_CONTROL_BURST_16 |  		SAA7134_RS_CONTROL_ME | -		(buf->pt->dma >> 12); -	if (buf->fmt->bswap) +		(dmaq->pt.dma >> 12); +	if (dev->fmt->bswap)  		control |= SAA7134_RS_CONTROL_BSWAP; -	if (buf->fmt->wswap) +	if (dev->fmt->wswap)  		control |= SAA7134_RS_CONTROL_WSWAP; -	if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) { +	if (V4L2_FIELD_HAS_BOTH(dev->field)) {  		/* interlaced */  		saa_writel(SAA7134_RS_BA1(0),base);  		saa_writel(SAA7134_RS_BA2(0),base+bpl); @@ -977,17 +829,17 @@ static int buffer_activate(struct saa7134_dev *dev,  	}  	saa_writel(SAA7134_RS_CONTROL(0),control); -	if (buf->fmt->planar) { +	if (dev->fmt->planar) {  		/* DMA: setup channel 4+5 (= planar task A) */ -		bpl_uv   = bpl >> buf->fmt->hshift; -		lines_uv = buf->vb.height >> buf->fmt->vshift; -		base2    = base + bpl * buf->vb.height; +		bpl_uv   = bpl >> dev->fmt->hshift; +		lines_uv = dev->height >> dev->fmt->vshift; +		base2    = base + bpl * dev->height;  		base3    = base2 + bpl_uv * lines_uv; -		if (buf->fmt->uvswap) +		if (dev->fmt->uvswap)  			tmp = base2, base2 = base3, base3 = tmp;  		dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",  			bpl_uv,lines_uv,base2,base3); -		if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) { +		if (V4L2_FIELD_HAS_BOTH(dev->field)) {  			/* interlaced */  			saa_writel(SAA7134_RS_BA1(4),base2);  			saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv); @@ -1010,239 +862,208 @@ static int buffer_activate(struct saa7134_dev *dev,  	/* start DMA */  	saa7134_set_dmabits(dev); -	mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT); +	mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT); +	return 0; +} + +static int buffer_init(struct vb2_buffer *vb2) +{ +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); + +	dmaq->curr = NULL; +	buf->activate = buffer_activate;  	return 0;  } -static int buffer_prepare(struct videobuf_queue *q, -			  struct videobuf_buffer *vb, -			  enum v4l2_field field) +static int buffer_prepare(struct vb2_buffer *vb2)  { -	struct saa7134_fh *fh = q->priv_data; -	struct saa7134_dev *dev = fh->dev; -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); +	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);  	unsigned int size; -	int err; +	int ret; -	/* sanity checks */ -	if (NULL == dev->fmt) -		return -EINVAL; -	if (dev->width    < 48 || -	    dev->height   < 32 || -	    dev->width/4  > dev->crop_current.width  || -	    dev->height/4 > dev->crop_current.height || -	    dev->width    > dev->crop_bounds.width  || -	    dev->height   > dev->crop_bounds.height) +	if (dma->sgl->offset) { +		pr_err("The buffer is not page-aligned\n");  		return -EINVAL; +	}  	size = (dev->width * dev->height * dev->fmt->depth) >> 3; -	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) +	if (vb2_plane_size(vb2, 0) < size)  		return -EINVAL; -	dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n", -		vb->i, dev->width, dev->height, size, v4l2_field_names[field], -		dev->fmt->name); -	if (buf->vb.width  != dev->width  || -	    buf->vb.height != dev->height || -	    buf->vb.size   != size       || -	    buf->vb.field  != field      || -	    buf->fmt       != dev->fmt) { -		saa7134_dma_free(q,buf); -	} +	vb2_set_plane_payload(vb2, 0, size); +	vb2->v4l2_buf.field = dev->field; -	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { -		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - -		buf->vb.width  = dev->width; -		buf->vb.height = dev->height; -		buf->vb.size   = size; -		buf->vb.field  = field; -		buf->fmt       = dev->fmt; -		buf->pt        = &fh->pt_cap; -		dev->video_q.curr = NULL; - -		err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); -		if (err) -			goto oops; -		err = saa7134_pgtable_build(dev->pci,buf->pt, -					    dma->sglist, -					    dma->sglen, -					    saa7134_buffer_startpage(buf)); -		if (err) -			goto oops; -	} -	buf->vb.state = VIDEOBUF_PREPARED; -	buf->activate = buffer_activate; -	return 0; - - oops: -	saa7134_dma_free(q,buf); -	return err; +	ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); +	if (!ret) +		return -EIO; +	return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, +				    saa7134_buffer_startpage(buf));  } -static int -buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) +static void buffer_finish(struct vb2_buffer *vb2)  { -	struct saa7134_fh *fh = q->priv_data; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); +	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); -	*size = dev->fmt->depth * dev->width * dev->height >> 3; -	if (0 == *count) -		*count = gbuffers; -	*count = saa7134_buffer_count(*size,*count); -	return 0; +	dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);  } -static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, +			   unsigned int *nbuffers, unsigned int *nplanes, +			   unsigned int sizes[], void *alloc_ctxs[])  { -	struct saa7134_fh *fh = q->priv_data; -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); +	struct saa7134_dmaqueue *dmaq = q->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	int size = dev->fmt->depth * dev->width * dev->height >> 3; + +	if (dev->width    < 48 || +	    dev->height   < 32 || +	    dev->width/4  > dev->crop_current.width  || +	    dev->height/4 > dev->crop_current.height || +	    dev->width    > dev->crop_bounds.width  || +	    dev->height   > dev->crop_bounds.height) +		return -EINVAL; -	saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf); +	*nbuffers = saa7134_buffer_count(size, *nbuffers); +	*nplanes = 1; +	sizes[0] = size; +	return 0;  } -static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) +/* + * move buffer to hardware queue + */ +void saa7134_vb2_buffer_queue(struct vb2_buffer *vb)  { -	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); +	struct saa7134_dmaqueue *dmaq = vb->vb2_queue->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; +	struct saa7134_buf *buf = container_of(vb, struct saa7134_buf, vb2); -	saa7134_dma_free(q,buf); +	saa7134_buffer_queue(dev, dmaq, buf);  } +EXPORT_SYMBOL_GPL(saa7134_vb2_buffer_queue); -static struct videobuf_queue_ops video_qops = { -	.buf_setup    = buffer_setup, -	.buf_prepare  = buffer_prepare, -	.buf_queue    = buffer_queue, -	.buf_release  = buffer_release, -}; - -/* ------------------------------------------------------------------ */ - -int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c) +int saa7134_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)  { -	const struct v4l2_queryctrl* ctrl; +	struct saa7134_dmaqueue *dmaq = vq->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; -	ctrl = ctrl_by_id(c->id); -	if (NULL == ctrl) -		return -EINVAL; -	switch (c->id) { -	case V4L2_CID_BRIGHTNESS: -		c->value = dev->ctl_bright; -		break; -	case V4L2_CID_HUE: -		c->value = dev->ctl_hue; -		break; -	case V4L2_CID_CONTRAST: -		c->value = dev->ctl_contrast; -		break; -	case V4L2_CID_SATURATION: -		c->value = dev->ctl_saturation; -		break; -	case V4L2_CID_AUDIO_MUTE: -		c->value = dev->ctl_mute; -		break; -	case V4L2_CID_AUDIO_VOLUME: -		c->value = dev->ctl_volume; -		break; -	case V4L2_CID_PRIVATE_INVERT: -		c->value = dev->ctl_invert; -		break; -	case V4L2_CID_HFLIP: -		c->value = dev->ctl_mirror; -		break; -	case V4L2_CID_PRIVATE_Y_EVEN: -		c->value = dev->ctl_y_even; -		break; -	case V4L2_CID_PRIVATE_Y_ODD: -		c->value = dev->ctl_y_odd; -		break; -	case V4L2_CID_PRIVATE_AUTOMUTE: -		c->value = dev->ctl_automute; -		break; -	default: -		return -EINVAL; +	/* +	 * Planar video capture and TS share the same DMA channel, +	 * so only one can be active at a time. +	 */ +	if (card_is_empress(dev) && vb2_is_busy(&dev->empress_vbq) && +	    dmaq == &dev->video_q && dev->fmt->planar) { +		struct saa7134_buf *buf, *tmp; + +		list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) { +			list_del(&buf->entry); +			vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED); +		} +		if (dmaq->curr) { +			vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED); +			dmaq->curr = NULL; +		} +		return -EBUSY;  	} + +	/* The SAA7134 has a 1K FIFO; the datasheet suggests that when +	 * configured conservatively, there's 22 usec of buffering for video. +	 * We therefore request a DMA latency of 20 usec, giving us 2 usec of +	 * margin in case the FIFO is configured differently to the datasheet. +	 * Unfortunately, I lack register-level documentation to check the +	 * Linux FIFO setup and confirm the perfect value. +	 */ +	if ((dmaq == &dev->video_q && !vb2_is_streaming(&dev->vbi_vbq)) || +	    (dmaq == &dev->vbi_q && !vb2_is_streaming(&dev->video_vbq))) +		pm_qos_add_request(&dev->qos_request, +			PM_QOS_CPU_DMA_LATENCY, 20); +	dmaq->seq_nr = 0; +  	return 0;  } -EXPORT_SYMBOL_GPL(saa7134_g_ctrl_internal); -static int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) +void saa7134_vb2_stop_streaming(struct vb2_queue *vq)  { -	struct saa7134_fh *fh = priv; +	struct saa7134_dmaqueue *dmaq = vq->drv_priv; +	struct saa7134_dev *dev = dmaq->dev; + +	saa7134_stop_streaming(dev, dmaq); -	return saa7134_g_ctrl_internal(fh->dev, fh, c); +	if ((dmaq == &dev->video_q && !vb2_is_streaming(&dev->vbi_vbq)) || +	    (dmaq == &dev->vbi_q && !vb2_is_streaming(&dev->video_vbq))) +		pm_qos_remove_request(&dev->qos_request);  } -int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, struct v4l2_control *c) +static struct vb2_ops vb2_qops = { +	.queue_setup	= queue_setup, +	.buf_init	= buffer_init, +	.buf_prepare	= buffer_prepare, +	.buf_finish	= buffer_finish, +	.buf_queue	= saa7134_vb2_buffer_queue, +	.wait_prepare	= vb2_ops_wait_prepare, +	.wait_finish	= vb2_ops_wait_finish, +	.start_streaming = saa7134_vb2_start_streaming, +	.stop_streaming = saa7134_vb2_stop_streaming, +}; + +/* ------------------------------------------------------------------ */ + +static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl)  { -	const struct v4l2_queryctrl* ctrl; +	struct saa7134_dev *dev = container_of(ctrl->handler, struct saa7134_dev, ctrl_handler);  	unsigned long flags;  	int restart_overlay = 0; -	int err; - -	err = -EINVAL; -	mutex_lock(&dev->lock); - -	ctrl = ctrl_by_id(c->id); -	if (NULL == ctrl) -		goto error; - -	dprintk("set_control name=%s val=%d\n",ctrl->name,c->value); -	switch (ctrl->type) { -	case V4L2_CTRL_TYPE_BOOLEAN: -	case V4L2_CTRL_TYPE_MENU: -	case V4L2_CTRL_TYPE_INTEGER: -		if (c->value < ctrl->minimum) -			c->value = ctrl->minimum; -		if (c->value > ctrl->maximum) -			c->value = ctrl->maximum; -		break; -	default: -		/* nothing */; -	} -	switch (c->id) { +	switch (ctrl->id) {  	case V4L2_CID_BRIGHTNESS: -		dev->ctl_bright = c->value; -		saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright); +		dev->ctl_bright = ctrl->val; +		saa_writeb(SAA7134_DEC_LUMA_BRIGHT, ctrl->val);  		break;  	case V4L2_CID_HUE: -		dev->ctl_hue = c->value; -		saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue); +		dev->ctl_hue = ctrl->val; +		saa_writeb(SAA7134_DEC_CHROMA_HUE, ctrl->val);  		break;  	case V4L2_CID_CONTRAST: -		dev->ctl_contrast = c->value; +		dev->ctl_contrast = ctrl->val;  		saa_writeb(SAA7134_DEC_LUMA_CONTRAST,  			   dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);  		break;  	case V4L2_CID_SATURATION: -		dev->ctl_saturation = c->value; +		dev->ctl_saturation = ctrl->val;  		saa_writeb(SAA7134_DEC_CHROMA_SATURATION,  			   dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);  		break;  	case V4L2_CID_AUDIO_MUTE: -		dev->ctl_mute = c->value; +		dev->ctl_mute = ctrl->val;  		saa7134_tvaudio_setmute(dev);  		break;  	case V4L2_CID_AUDIO_VOLUME: -		dev->ctl_volume = c->value; +		dev->ctl_volume = ctrl->val;  		saa7134_tvaudio_setvolume(dev,dev->ctl_volume);  		break;  	case V4L2_CID_PRIVATE_INVERT: -		dev->ctl_invert = c->value; +		dev->ctl_invert = ctrl->val;  		saa_writeb(SAA7134_DEC_LUMA_CONTRAST,  			   dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);  		saa_writeb(SAA7134_DEC_CHROMA_SATURATION,  			   dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);  		break;  	case V4L2_CID_HFLIP: -		dev->ctl_mirror = c->value; +		dev->ctl_mirror = ctrl->val;  		restart_overlay = 1;  		break;  	case V4L2_CID_PRIVATE_Y_EVEN: -		dev->ctl_y_even = c->value; +		dev->ctl_y_even = ctrl->val;  		restart_overlay = 1;  		break;  	case V4L2_CID_PRIVATE_Y_ODD: -		dev->ctl_y_odd = c->value; +		dev->ctl_y_odd = ctrl->val;  		restart_overlay = 1;  		break;  	case V4L2_CID_PRIVATE_AUTOMUTE: @@ -1252,7 +1073,7 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, str  		tda9887_cfg.tuner = TUNER_TDA9887;  		tda9887_cfg.priv = &dev->tda9887_conf; -		dev->ctl_automute = c->value; +		dev->ctl_automute = ctrl->val;  		if (dev->tda9887_conf) {  			if (dev->ctl_automute)  				dev->tda9887_conf |= TDA9887_AUTOMUTE; @@ -1264,210 +1085,70 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, str  		break;  	}  	default: -		goto error; +		return -EINVAL;  	} -	if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) { -		spin_lock_irqsave(&dev->slock,flags); -		stop_preview(dev,fh); -		start_preview(dev,fh); -		spin_unlock_irqrestore(&dev->slock,flags); +	if (restart_overlay && dev->overlay_owner) { +		spin_lock_irqsave(&dev->slock, flags); +		stop_preview(dev); +		start_preview(dev); +		spin_unlock_irqrestore(&dev->slock, flags);  	} -	err = 0; - -error: -	mutex_unlock(&dev->lock); -	return err; -} -EXPORT_SYMBOL_GPL(saa7134_s_ctrl_internal); - -static int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c) -{ -	struct saa7134_fh *fh = f; - -	return saa7134_s_ctrl_internal(fh->dev, fh, c); +	return 0;  }  /* ------------------------------------------------------------------ */ -static struct videobuf_queue *saa7134_queue(struct file *file) -{ -	struct video_device *vdev = video_devdata(file); -	struct saa7134_fh *fh = file->private_data; -	struct videobuf_queue *q = NULL; - -	switch (vdev->vfl_type) { -	case VFL_TYPE_GRABBER: -		q = &fh->cap; -		break; -	case VFL_TYPE_VBI: -		q = &fh->vbi; -		break; -	default: -		BUG(); -	} -	return q; -} - -static int saa7134_resource(struct file *file) +static inline struct vb2_queue *saa7134_queue(struct file *file)  { -	struct video_device *vdev = video_devdata(file); - -	if (vdev->vfl_type == VFL_TYPE_GRABBER) -		return RESOURCE_VIDEO; - -	if (vdev->vfl_type == VFL_TYPE_VBI) -		return RESOURCE_VBI; - -	BUG(); -	return 0; +	return video_devdata(file)->queue;  }  static int video_open(struct file *file)  {  	struct video_device *vdev = video_devdata(file);  	struct saa7134_dev *dev = video_drvdata(file); -	struct saa7134_fh *fh; - -	/* allocate + initialize per filehandle data */ -	fh = kzalloc(sizeof(*fh),GFP_KERNEL); -	if (NULL == fh) -		return -ENOMEM; - -	v4l2_fh_init(&fh->fh, vdev); -	file->private_data = fh; -	fh->dev      = dev; - -	videobuf_queue_sg_init(&fh->cap, &video_qops, -			    &dev->pci->dev, &dev->slock, -			    V4L2_BUF_TYPE_VIDEO_CAPTURE, -			    V4L2_FIELD_INTERLACED, -			    sizeof(struct saa7134_buf), -			    fh, NULL); -	videobuf_queue_sg_init(&fh->vbi, &saa7134_vbi_qops, -			    &dev->pci->dev, &dev->slock, -			    V4L2_BUF_TYPE_VBI_CAPTURE, -			    V4L2_FIELD_SEQ_TB, -			    sizeof(struct saa7134_buf), -			    fh, NULL); -	saa7134_pgtable_alloc(dev->pci,&fh->pt_cap); -	saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi); +	int ret = v4l2_fh_open(file); + +	if (ret < 0) +		return ret; +	mutex_lock(&dev->lock);  	if (vdev->vfl_type == VFL_TYPE_RADIO) {  		/* switch to radio mode */ -		saa7134_tvaudio_setinput(dev,&card(dev).radio); +		saa7134_tvaudio_setinput(dev, &card(dev).radio);  		saa_call_all(dev, tuner, s_radio);  	} else {  		/* switch to video/vbi mode */ -		video_mux(dev,dev->ctl_input); +		video_mux(dev, dev->ctl_input);  	} -	v4l2_fh_add(&fh->fh); +	mutex_unlock(&dev->lock);  	return 0;  } -static ssize_t -video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ -	struct video_device *vdev = video_devdata(file); -	struct saa7134_fh *fh = file->private_data; - -	switch (vdev->vfl_type) { -	case VFL_TYPE_GRABBER: -		if (res_locked(fh->dev,RESOURCE_VIDEO)) -			return -EBUSY; -		return videobuf_read_one(saa7134_queue(file), -					 data, count, ppos, -					 file->f_flags & O_NONBLOCK); -	case VFL_TYPE_VBI: -		if (!res_get(fh->dev,fh,RESOURCE_VBI)) -			return -EBUSY; -		return videobuf_read_stream(saa7134_queue(file), -					    data, count, ppos, 1, -					    file->f_flags & O_NONBLOCK); -		break; -	default: -		BUG(); -		return 0; -	} -} - -static unsigned int -video_poll(struct file *file, struct poll_table_struct *wait) -{ -	struct video_device *vdev = video_devdata(file); -	struct saa7134_fh *fh = file->private_data; -	struct videobuf_buffer *buf = NULL; -	unsigned int rc = 0; - -	if (vdev->vfl_type == VFL_TYPE_VBI) -		return videobuf_poll_stream(file, &fh->vbi, wait); - -	if (res_check(fh,RESOURCE_VIDEO)) { -		mutex_lock(&fh->cap.vb_lock); -		if (!list_empty(&fh->cap.stream)) -			buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); -	} else { -		mutex_lock(&fh->cap.vb_lock); -		if (UNSET == fh->cap.read_off) { -			/* need to capture a new frame */ -			if (res_locked(fh->dev,RESOURCE_VIDEO)) -				goto err; -			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) -				goto err; -			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); -			fh->cap.read_off = 0; -		} -		buf = fh->cap.read_buf; -	} - -	if (!buf) -		goto err; - -	poll_wait(file, &buf->done, wait); -	if (buf->state == VIDEOBUF_DONE || -	    buf->state == VIDEOBUF_ERROR) -		rc = POLLIN|POLLRDNORM; -	mutex_unlock(&fh->cap.vb_lock); -	return rc; - -err: -	mutex_unlock(&fh->cap.vb_lock); -	return POLLERR; -} -  static int video_release(struct file *file)  {  	struct video_device *vdev = video_devdata(file); -	struct saa7134_fh  *fh  = file->private_data; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file); +	struct v4l2_fh *fh = file->private_data;  	struct saa6588_command cmd;  	unsigned long flags; +	mutex_lock(&dev->lock);  	saa7134_tvaudio_close(dev);  	/* turn off overlay */ -	if (res_check(fh, RESOURCE_OVERLAY)) { +	if (fh == dev->overlay_owner) {  		spin_lock_irqsave(&dev->slock,flags); -		stop_preview(dev,fh); +		stop_preview(dev);  		spin_unlock_irqrestore(&dev->slock,flags); -		res_free(dev,fh,RESOURCE_OVERLAY); +		dev->overlay_owner = NULL;  	} -	/* stop video capture */ -	if (res_check(fh, RESOURCE_VIDEO)) { -		videobuf_streamoff(&fh->cap); -		res_free(dev,fh,RESOURCE_VIDEO); -	} -	if (fh->cap.read_buf) { -		buffer_release(&fh->cap,fh->cap.read_buf); -		kfree(fh->cap.read_buf); -	} - -	/* stop vbi capture */ -	if (res_check(fh, RESOURCE_VBI)) { -		videobuf_stop(&fh->vbi); -		res_free(dev,fh,RESOURCE_VBI); -	} +	if (vdev->vfl_type == VFL_TYPE_RADIO) +		v4l2_fh_release(file); +	else +		_vb2_fop_release(file, NULL);  	/* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/  	saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0); @@ -1478,54 +1159,44 @@ static int video_release(struct file *file)  	saa_call_all(dev, core, s_power, 0);  	if (vdev->vfl_type == VFL_TYPE_RADIO)  		saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); +	mutex_unlock(&dev->lock); -	/* free stuff */ -	videobuf_mmap_free(&fh->cap); -	videobuf_mmap_free(&fh->vbi); -	saa7134_pgtable_free(dev->pci,&fh->pt_cap); -	saa7134_pgtable_free(dev->pci,&fh->pt_vbi); - -	v4l2_fh_del(&fh->fh); -	v4l2_fh_exit(&fh->fh); -	file->private_data = NULL; -	kfree(fh);  	return 0;  } -static int video_mmap(struct file *file, struct vm_area_struct * vma) -{ -	return videobuf_mmap_mapper(saa7134_queue(file), vma); -} -  static ssize_t radio_read(struct file *file, char __user *data,  			 size_t count, loff_t *ppos)  { -	struct saa7134_fh *fh = file->private_data; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	struct saa6588_command cmd;  	cmd.block_count = count/3; +	cmd.nonblocking = file->f_flags & O_NONBLOCK;  	cmd.buffer = data;  	cmd.instance = file;  	cmd.result = -ENODEV; +	mutex_lock(&dev->lock);  	saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd); +	mutex_unlock(&dev->lock);  	return cmd.result;  }  static unsigned int radio_poll(struct file *file, poll_table *wait)  { -	struct saa7134_fh *fh = file->private_data; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	struct saa6588_command cmd; +	unsigned int rc = v4l2_ctrl_poll(file, wait);  	cmd.instance = file;  	cmd.event_list = wait; -	cmd.result = -ENODEV; +	cmd.result = 0; +	mutex_lock(&dev->lock);  	saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); +	mutex_unlock(&dev->lock); -	return cmd.result; +	return rc | cmd.result;  }  /* ------------------------------------------------------------------ */ @@ -1533,8 +1204,7 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)  static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,  						struct v4l2_format *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	struct saa7134_tvnorm *norm = dev->tvnorm;  	memset(&f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved)); @@ -1554,12 +1224,11 @@ static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,  static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,  				struct v4l2_format *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	f->fmt.pix.width        = dev->width;  	f->fmt.pix.height       = dev->height; -	f->fmt.pix.field        = fh->cap.field; +	f->fmt.pix.field        = dev->field;  	f->fmt.pix.pixelformat  = dev->fmt->fourcc;  	f->fmt.pix.bytesperline =  		(f->fmt.pix.width * dev->fmt->depth) >> 3; @@ -1573,8 +1242,7 @@ static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,  static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,  				struct v4l2_format *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	struct v4l2_clip __user *clips = f->fmt.win.clips;  	u32 clipcount = f->fmt.win.clipcount;  	int err = 0; @@ -1584,7 +1252,6 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,  		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");  		return -EINVAL;  	} -	mutex_lock(&dev->lock);  	f->fmt.win = dev->win;  	f->fmt.win.clips = clips;  	if (clips == NULL) @@ -1598,7 +1265,6 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,  					sizeof(struct v4l2_rect)))  			err = -EFAULT;  	} -	mutex_unlock(&dev->lock);  	return err;  } @@ -1606,8 +1272,7 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,  static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,  						struct v4l2_format *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	struct saa7134_format *fmt;  	enum v4l2_field field;  	unsigned int maxw, maxh; @@ -1658,8 +1323,7 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,  static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv,  						struct v4l2_format *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	if (saa7134_no_overlay > 0) {  		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); @@ -1674,26 +1338,24 @@ static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv,  static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,  					struct v4l2_format *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	int err;  	err = saa7134_try_fmt_vid_cap(file, priv, f);  	if (0 != err)  		return err; -	dev->fmt       = format_by_fourcc(f->fmt.pix.pixelformat); -	dev->width     = f->fmt.pix.width; -	dev->height    = f->fmt.pix.height; -	fh->cap.field = f->fmt.pix.field; +	dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); +	dev->width = f->fmt.pix.width; +	dev->height = f->fmt.pix.height; +	dev->field = f->fmt.pix.field;  	return 0;  }  static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,  					struct v4l2_format *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	int err;  	unsigned long flags; @@ -1707,48 +1369,26 @@ static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,  	if (0 != err)  		return err; -	mutex_lock(&dev->lock); -  	dev->win    = f->fmt.win;  	dev->nclips = f->fmt.win.clipcount;  	if (copy_from_user(dev->clips, f->fmt.win.clips, -			   sizeof(struct v4l2_clip) * dev->nclips)) { -		mutex_unlock(&dev->lock); +			   sizeof(struct v4l2_clip) * dev->nclips))  		return -EFAULT; -	} -	if (res_check(fh, RESOURCE_OVERLAY)) { +	if (priv == dev->overlay_owner) {  		spin_lock_irqsave(&dev->slock, flags); -		stop_preview(dev, fh); -		start_preview(dev, fh); +		stop_preview(dev); +		start_preview(dev);  		spin_unlock_irqrestore(&dev->slock, flags);  	} -	mutex_unlock(&dev->lock); -	return 0; -} - -int saa7134_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) && -	    (c->id <  V4L2_CID_PRIVATE_BASE || -	     c->id >= V4L2_CID_PRIVATE_LASTP1)) -		return -EINVAL; -	ctrl = ctrl_by_id(c->id); -	*c = (NULL != ctrl) ? *ctrl : no_ctrl;  	return 0;  } -EXPORT_SYMBOL_GPL(saa7134_queryctrl); -static int saa7134_enum_input(struct file *file, void *priv, -					struct v4l2_input *i) +int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	unsigned int n;  	n = i->index; @@ -1768,43 +1408,41 @@ static int saa7134_enum_input(struct file *file, void *priv,  		if (0 != (v1 & 0x40))  			i->status |= V4L2_IN_ST_NO_H_LOCK;  		if (0 != (v2 & 0x40)) -			i->status |= V4L2_IN_ST_NO_SYNC; +			i->status |= V4L2_IN_ST_NO_SIGNAL;  		if (0 != (v2 & 0x0e))  			i->status |= V4L2_IN_ST_MACROVISION;  	}  	i->std = SAA7134_NORMS;  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_enum_input); -static int saa7134_g_input(struct file *file, void *priv, unsigned int *i) +int saa7134_g_input(struct file *file, void *priv, unsigned int *i)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	*i = dev->ctl_input;  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_g_input); -static int saa7134_s_input(struct file *file, void *priv, unsigned int i) +int saa7134_s_input(struct file *file, void *priv, unsigned int i)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	if (i >= SAA7134_INPUT_MAX)  		return -EINVAL;  	if (NULL == card_in(dev, i).name)  		return -EINVAL; -	mutex_lock(&dev->lock);  	video_mux(dev, i); -	mutex_unlock(&dev->lock);  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_s_input); -static int saa7134_querycap(struct file *file, void  *priv, +int saa7134_querycap(struct file *file, void *priv,  					struct v4l2_capability *cap)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	struct video_device *vdev = video_devdata(file);  	u32 radio_caps, video_caps, vbi_caps; @@ -1824,7 +1462,7 @@ static int saa7134_querycap(struct file *file, void  *priv,  		radio_caps |= V4L2_CAP_RDS_CAPTURE;  	video_caps = V4L2_CAP_VIDEO_CAPTURE; -	if (saa7134_no_overlay <= 0) +	if (saa7134_no_overlay <= 0 && !is_empress(file))  		video_caps |= V4L2_CAP_VIDEO_OVERLAY;  	vbi_caps = V4L2_CAP_VBI_CAPTURE; @@ -1850,14 +1488,17 @@ static int saa7134_querycap(struct file *file, void  *priv,  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_querycap); -int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id id) +int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id)  { +	struct saa7134_dev *dev = video_drvdata(file); +	struct v4l2_fh *fh = priv;  	unsigned long flags;  	unsigned int i;  	v4l2_std_id fixup; -	if (!fh && res_locked(dev, RESOURCE_OVERLAY)) { +	if (is_empress(file) && dev->overlay_owner) {  		/* Don't change the std from the mpeg device  		   if overlay is active. */  		return -EBUSY; @@ -1896,47 +1537,66 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_  	id = tvnorms[i].id; -	mutex_lock(&dev->lock); -	if (fh && res_check(fh, RESOURCE_OVERLAY)) { +	if (!is_empress(file) && fh == dev->overlay_owner) {  		spin_lock_irqsave(&dev->slock, flags); -		stop_preview(dev, fh); +		stop_preview(dev);  		spin_unlock_irqrestore(&dev->slock, flags);  		set_tvnorm(dev, &tvnorms[i]);  		spin_lock_irqsave(&dev->slock, flags); -		start_preview(dev, fh); +		start_preview(dev);  		spin_unlock_irqrestore(&dev->slock, flags);  	} else  		set_tvnorm(dev, &tvnorms[i]);  	saa7134_tvaudio_do_scan(dev); -	mutex_unlock(&dev->lock);  	return 0;  } -EXPORT_SYMBOL_GPL(saa7134_s_std_internal); +EXPORT_SYMBOL_GPL(saa7134_s_std); -static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id) +int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id)  { -	struct saa7134_fh *fh = priv; +	struct saa7134_dev *dev = video_drvdata(file); -	return saa7134_s_std_internal(fh->dev, fh, id); +	*id = dev->tvnorm->id; +	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_g_std); -static int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id) +static v4l2_std_id saa7134_read_std(struct saa7134_dev *dev)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	static v4l2_std_id stds[] = { +		V4L2_STD_UNKNOWN, +		V4L2_STD_NTSC, +		V4L2_STD_PAL, +		V4L2_STD_SECAM }; -	*id = dev->tvnorm->id; +	v4l2_std_id result = 0; + +	u8 st1 = saa_readb(SAA7134_STATUS_VIDEO1); +	u8 st2 = saa_readb(SAA7134_STATUS_VIDEO2); + +	if (!(st2 & 0x1)) /* RDCAP == 0 */ +		result = V4L2_STD_UNKNOWN; +	else +		result = stds[st1 & 0x03]; + +	return result; +} + +int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std) +{ +	struct saa7134_dev *dev = video_drvdata(file); +	*std &= saa7134_read_std(dev);  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_querystd);  static int saa7134_cropcap(struct file *file, void *priv,  					struct v4l2_cropcap *cap)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&  	    cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) @@ -1958,8 +1618,7 @@ static int saa7134_cropcap(struct file *file, void *priv,  static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop)  { -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&  	    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) @@ -1970,22 +1629,17 @@ static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop)  static int saa7134_s_crop(struct file *file, void *f, const struct v4l2_crop *crop)  { -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	struct v4l2_rect *b = &dev->crop_bounds;  	struct v4l2_rect *c = &dev->crop_current;  	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&  	    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)  		return -EINVAL; -	if (crop->c.height < 0) -		return -EINVAL; -	if (crop->c.width < 0) -		return -EINVAL; -	if (res_locked(fh->dev, RESOURCE_OVERLAY)) +	if (dev->overlay_owner)  		return -EBUSY; -	if (res_locked(fh->dev, RESOURCE_VIDEO)) +	if (vb2_is_streaming(&dev->video_vbq))  		return -EBUSY;  	*c = crop->c; @@ -2005,11 +1659,10 @@ static int saa7134_s_crop(struct file *file, void *f, const struct v4l2_crop *cr  	return 0;  } -static int saa7134_g_tuner(struct file *file, void *priv, +int saa7134_g_tuner(struct file *file, void *priv,  					struct v4l2_tuner *t)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	int n;  	if (0 != t->index) @@ -2036,12 +1689,12 @@ static int saa7134_g_tuner(struct file *file, void *priv,  		t->signal = 0xffff;  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_g_tuner); -static int saa7134_s_tuner(struct file *file, void *priv, +int saa7134_s_tuner(struct file *file, void *priv,  					const struct v4l2_tuner *t)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	int rx, mode;  	if (0 != t->index) @@ -2057,12 +1710,12 @@ static int saa7134_s_tuner(struct file *file, void *priv,  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_s_tuner); -static int saa7134_g_frequency(struct file *file, void *priv, +int saa7134_g_frequency(struct file *file, void *priv,  					struct v4l2_frequency *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	if (0 != f->tuner)  		return -EINVAL; @@ -2071,23 +1724,22 @@ static int saa7134_g_frequency(struct file *file, void *priv,  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_g_frequency); -static int saa7134_s_frequency(struct file *file, void *priv, +int saa7134_s_frequency(struct file *file, void *priv,  					const struct v4l2_frequency *f)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	if (0 != f->tuner)  		return -EINVAL; -	mutex_lock(&dev->lock);  	saa_call_all(dev, tuner, s_frequency, f);  	saa7134_tvaudio_do_scan(dev); -	mutex_unlock(&dev->lock);  	return 0;  } +EXPORT_SYMBOL_GPL(saa7134_s_frequency);  static int saa7134_enum_fmt_vid_cap(struct file *file, void  *priv,  					struct v4l2_fmtdesc *f) @@ -2125,8 +1777,7 @@ static int saa7134_enum_fmt_vid_overlay(struct file *file, void  *priv,  static int saa7134_g_fbuf(struct file *file, void *f,  				struct v4l2_framebuffer *fb)  { -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	*fb = dev->ovbuf;  	fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; @@ -2137,8 +1788,7 @@ static int saa7134_g_fbuf(struct file *file, void *f,  static int saa7134_s_fbuf(struct file *file, void *f,  					const struct v4l2_framebuffer *fb)  { -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	struct saa7134_format *fmt;  	if (!capable(CAP_SYS_ADMIN) && @@ -2159,10 +1809,9 @@ static int saa7134_s_fbuf(struct file *file, void *f,  	return 0;  } -static int saa7134_overlay(struct file *file, void *f, unsigned int on) +static int saa7134_overlay(struct file *file, void *priv, unsigned int on)  { -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	unsigned long flags;  	if (on) { @@ -2171,93 +1820,29 @@ static int saa7134_overlay(struct file *file, void *f, unsigned int on)  			return -EINVAL;  		} -		if (!res_get(dev, fh, RESOURCE_OVERLAY)) +		if (dev->overlay_owner && priv != dev->overlay_owner)  			return -EBUSY; +		dev->overlay_owner = priv;  		spin_lock_irqsave(&dev->slock, flags); -		start_preview(dev, fh); +		start_preview(dev);  		spin_unlock_irqrestore(&dev->slock, flags);  	}  	if (!on) { -		if (!res_check(fh, RESOURCE_OVERLAY)) +		if (priv != dev->overlay_owner)  			return -EINVAL;  		spin_lock_irqsave(&dev->slock, flags); -		stop_preview(dev, fh); +		stop_preview(dev);  		spin_unlock_irqrestore(&dev->slock, flags); -		res_free(dev, fh, RESOURCE_OVERLAY); +		dev->overlay_owner = NULL;  	}  	return 0;  } -static int saa7134_reqbufs(struct file *file, void *priv, -					struct v4l2_requestbuffers *p) -{ -	return videobuf_reqbufs(saa7134_queue(file), p); -} - -static int saa7134_querybuf(struct file *file, void *priv, -					struct v4l2_buffer *b) -{ -	return videobuf_querybuf(saa7134_queue(file), b); -} - -static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ -	return videobuf_qbuf(saa7134_queue(file), b); -} - -static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ -	return videobuf_dqbuf(saa7134_queue(file), b, -				file->f_flags & O_NONBLOCK); -} - -static int saa7134_streamon(struct file *file, void *priv, -					enum v4l2_buf_type type) -{ -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; -	int res = saa7134_resource(file); - -	if (!res_get(dev, fh, res)) -		return -EBUSY; - -	/* The SAA7134 has a 1K FIFO; the datasheet suggests that when -	 * configured conservatively, there's 22 usec of buffering for video. -	 * We therefore request a DMA latency of 20 usec, giving us 2 usec of -	 * margin in case the FIFO is configured differently to the datasheet. -	 * Unfortunately, I lack register-level documentation to check the -	 * Linux FIFO setup and confirm the perfect value. -	 */ -	pm_qos_add_request(&dev->qos_request, -			   PM_QOS_CPU_DMA_LATENCY, -			   20); - -	return videobuf_streamon(saa7134_queue(file)); -} - -static int saa7134_streamoff(struct file *file, void *priv, -					enum v4l2_buf_type type) -{ -	int err; -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; -	int res = saa7134_resource(file); - -	pm_qos_remove_request(&dev->qos_request); - -	err = videobuf_streamoff(saa7134_queue(file)); -	if (err < 0) -		return err; -	res_free(dev, fh, res); -	return 0; -} -  #ifdef CONFIG_VIDEO_ADV_DEBUG  static int vidioc_g_register (struct file *file, void *priv,  			      struct v4l2_dbg_register *reg)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	reg->val = saa_readb(reg->reg & 0xffffff);  	reg->size = 1; @@ -2267,8 +1852,7 @@ static int vidioc_g_register (struct file *file, void *priv,  static int vidioc_s_register (struct file *file, void *priv,  				const struct v4l2_dbg_register *reg)  { -	struct saa7134_fh *fh = priv; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	saa_writeb(reg->reg & 0xffffff, reg->val);  	return 0; @@ -2278,8 +1862,7 @@ static int vidioc_s_register (struct file *file, void *priv,  static int radio_g_tuner(struct file *file, void *priv,  					struct v4l2_tuner *t)  { -	struct saa7134_fh *fh = file->private_data; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	if (0 != t->index)  		return -EINVAL; @@ -2298,8 +1881,7 @@ static int radio_g_tuner(struct file *file, void *priv,  static int radio_s_tuner(struct file *file, void *priv,  					const struct v4l2_tuner *t)  { -	struct saa7134_fh *fh = file->private_data; -	struct saa7134_dev *dev = fh->dev; +	struct saa7134_dev *dev = video_drvdata(file);  	if (0 != t->index)  		return -EINVAL; @@ -2308,59 +1890,15 @@ static int radio_s_tuner(struct file *file, void *priv,  	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_input(struct file *filp, void *priv, unsigned int *i) -{ -	*i = 0; -	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) -{ -	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_ctrl; -	return 0; -} -  static const struct v4l2_file_operations video_fops =  {  	.owner	  = THIS_MODULE,  	.open	  = video_open,  	.release  = video_release, -	.read	  = video_read, -	.poll     = video_poll, -	.mmap	  = video_mmap, -	.ioctl	  = video_ioctl2, +	.read	  = vb2_fop_read, +	.poll     = vb2_fop_poll, +	.mmap	  = vb2_fop_mmap, +	.unlocked_ioctl	  = video_ioctl2,  };  static const struct v4l2_ioctl_ops video_ioctl_ops = { @@ -2377,20 +1915,18 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {  	.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_cropcap			= saa7134_cropcap, -	.vidioc_reqbufs			= saa7134_reqbufs, -	.vidioc_querybuf		= saa7134_querybuf, -	.vidioc_qbuf			= saa7134_qbuf, -	.vidioc_dqbuf			= saa7134_dqbuf, +	.vidioc_reqbufs			= vb2_ioctl_reqbufs, +	.vidioc_querybuf		= vb2_ioctl_querybuf, +	.vidioc_qbuf			= vb2_ioctl_qbuf, +	.vidioc_dqbuf			= vb2_ioctl_dqbuf,  	.vidioc_s_std			= saa7134_s_std,  	.vidioc_g_std			= saa7134_g_std, +	.vidioc_querystd		= saa7134_querystd,  	.vidioc_enum_input		= saa7134_enum_input,  	.vidioc_g_input			= saa7134_g_input,  	.vidioc_s_input			= saa7134_s_input, -	.vidioc_queryctrl		= saa7134_queryctrl, -	.vidioc_g_ctrl			= saa7134_g_ctrl, -	.vidioc_s_ctrl			= saa7134_s_ctrl, -	.vidioc_streamon		= saa7134_streamon, -	.vidioc_streamoff		= saa7134_streamoff, +	.vidioc_streamon		= vb2_ioctl_streamon, +	.vidioc_streamoff		= vb2_ioctl_streamoff,  	.vidioc_g_tuner			= saa7134_g_tuner,  	.vidioc_s_tuner			= saa7134_s_tuner,  	.vidioc_g_crop			= saa7134_g_crop, @@ -2404,6 +1940,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {  	.vidioc_g_register              = vidioc_g_register,  	.vidioc_s_register              = vidioc_s_register,  #endif +	.vidioc_log_status		= v4l2_ctrl_log_status, +	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event, +	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,  };  static const struct v4l2_file_operations radio_fops = { @@ -2411,23 +1950,18 @@ static const struct v4l2_file_operations radio_fops = {  	.open	  = video_open,  	.read     = radio_read,  	.release  = video_release, -	.ioctl	  = video_ioctl2, +	.unlocked_ioctl	= video_ioctl2,  	.poll     = radio_poll,  };  static const struct v4l2_ioctl_ops radio_ioctl_ops = {  	.vidioc_querycap	= saa7134_querycap,  	.vidioc_g_tuner		= radio_g_tuner, -	.vidioc_enum_input	= radio_enum_input,  	.vidioc_s_tuner		= radio_s_tuner, -	.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		= saa7134_g_ctrl, -	.vidioc_s_ctrl		= saa7134_s_ctrl,  	.vidioc_g_frequency	= saa7134_g_frequency,  	.vidioc_s_frequency	= saa7134_s_frequency, +	.vidioc_subscribe_event	= v4l2_ctrl_subscribe_event, +	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,  };  /* ----------------------------------------------------------- */ @@ -2446,8 +1980,57 @@ struct video_device saa7134_radio_template = {  	.ioctl_ops 		= &radio_ioctl_ops,  }; +static const struct v4l2_ctrl_ops saa7134_ctrl_ops = { +	.s_ctrl = saa7134_s_ctrl, +}; + +static const struct v4l2_ctrl_config saa7134_ctrl_invert = { +	.ops = &saa7134_ctrl_ops, +	.id = V4L2_CID_PRIVATE_INVERT, +	.name = "Invert", +	.type = V4L2_CTRL_TYPE_BOOLEAN, +	.min = 0, +	.max = 1, +	.step = 1, +}; + +static const struct v4l2_ctrl_config saa7134_ctrl_y_odd = { +	.ops = &saa7134_ctrl_ops, +	.id = V4L2_CID_PRIVATE_Y_ODD, +	.name = "Y Offset Odd Field", +	.type = V4L2_CTRL_TYPE_INTEGER, +	.min = 0, +	.max = 128, +	.step = 1, +}; + +static const struct v4l2_ctrl_config saa7134_ctrl_y_even = { +	.ops = &saa7134_ctrl_ops, +	.id = V4L2_CID_PRIVATE_Y_EVEN, +	.name = "Y Offset Even Field", +	.type = V4L2_CTRL_TYPE_INTEGER, +	.min = 0, +	.max = 128, +	.step = 1, +}; + +static const struct v4l2_ctrl_config saa7134_ctrl_automute = { +	.ops = &saa7134_ctrl_ops, +	.id = V4L2_CID_PRIVATE_AUTOMUTE, +	.name = "Automute", +	.type = V4L2_CTRL_TYPE_BOOLEAN, +	.min = 0, +	.max = 1, +	.step = 1, +	.def = 1, +}; +  int saa7134_video_init1(struct saa7134_dev *dev)  { +	struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; +	struct vb2_queue *q; +	int ret; +  	/* sanitycheck insmod options */  	if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)  		gbuffers = 2; @@ -2455,17 +2038,38 @@ int saa7134_video_init1(struct saa7134_dev *dev)  		gbufsize = gbufsize_max;  	gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; -	/* put some sensible defaults into the data structures ... */ -	dev->ctl_bright     = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value; -	dev->ctl_contrast   = ctrl_by_id(V4L2_CID_CONTRAST)->default_value; -	dev->ctl_hue        = ctrl_by_id(V4L2_CID_HUE)->default_value; -	dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value; -	dev->ctl_volume     = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value; -	dev->ctl_mute       = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value; -	dev->ctl_invert     = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value; -	dev->ctl_automute   = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value; - -	if (dev->tda9887_conf && dev->ctl_automute) +	v4l2_ctrl_handler_init(hdl, 11); +	v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops, +			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); +	v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops, +			V4L2_CID_CONTRAST, 0, 127, 1, 68); +	v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops, +			V4L2_CID_SATURATION, 0, 127, 1, 64); +	v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops, +			V4L2_CID_HUE, -128, 127, 1, 0); +	v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops, +			V4L2_CID_HFLIP, 0, 1, 1, 0); +	v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops, +			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); +	v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops, +			V4L2_CID_AUDIO_VOLUME, -15, 15, 1, 0); +	v4l2_ctrl_new_custom(hdl, &saa7134_ctrl_invert, NULL); +	v4l2_ctrl_new_custom(hdl, &saa7134_ctrl_y_odd, NULL); +	v4l2_ctrl_new_custom(hdl, &saa7134_ctrl_y_even, NULL); +	v4l2_ctrl_new_custom(hdl, &saa7134_ctrl_automute, NULL); +	if (hdl->error) +		return hdl->error; +	if (card_has_radio(dev)) { +		hdl = &dev->radio_ctrl_handler; +		v4l2_ctrl_handler_init(hdl, 2); +		v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, +				v4l2_ctrl_radio_filter); +		if (hdl->error) +			return hdl->error; +	} +	dev->ctl_mute       = 1; + +	if (dev->tda9887_conf && saa7134_ctrl_automute.def)  		dev->tda9887_conf |= TDA9887_AUTOMUTE;  	dev->automute       = 0; @@ -2477,6 +2081,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)  	dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);  	dev->width    = 720;  	dev->height   = 576; +	dev->field = V4L2_FIELD_INTERLACED;  	dev->win.w.width = dev->width;  	dev->win.w.height = dev->height;  	dev->win.field = V4L2_FIELD_INTERLACED; @@ -2488,9 +2093,63 @@ int saa7134_video_init1(struct saa7134_dev *dev)  	if (saa7134_boards[dev->board].video_out)  		saa7134_videoport_init(dev); +	q = &dev->video_vbq; +	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +	/* +	 * Do not add VB2_USERPTR unless explicitly requested: the saa7134 DMA +	 * engine cannot handle transfers that do not start at the beginning +	 * of a page. A user-provided pointer can start anywhere in a page, so +	 * USERPTR support is a no-go unless the application knows about these +	 * limitations and has special support for this. +	 */ +	q->io_modes = VB2_MMAP | VB2_READ; +	if (saa7134_userptr) +		q->io_modes |= VB2_USERPTR; +	q->drv_priv = &dev->video_q; +	q->ops = &vb2_qops; +	q->gfp_flags = GFP_DMA32; +	q->mem_ops = &vb2_dma_sg_memops; +	q->buf_struct_size = sizeof(struct saa7134_buf); +	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; +	q->lock = &dev->lock; +	ret = vb2_queue_init(q); +	if (ret) +		return ret; +	saa7134_pgtable_alloc(dev->pci, &dev->video_q.pt); + +	q = &dev->vbi_vbq; +	q->type = V4L2_BUF_TYPE_VBI_CAPTURE; +	/* Don't add VB2_USERPTR, see comment above */ +	q->io_modes = VB2_MMAP | VB2_READ; +	if (saa7134_userptr) +		q->io_modes |= VB2_USERPTR; +	q->drv_priv = &dev->vbi_q; +	q->ops = &saa7134_vbi_qops; +	q->gfp_flags = GFP_DMA32; +	q->mem_ops = &vb2_dma_sg_memops; +	q->buf_struct_size = sizeof(struct saa7134_buf); +	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; +	q->lock = &dev->lock; +	ret = vb2_queue_init(q); +	if (ret) +		return ret; +	saa7134_pgtable_alloc(dev->pci, &dev->vbi_q.pt); +  	return 0;  } +void saa7134_video_fini(struct saa7134_dev *dev) +{ +	/* free stuff */ +	vb2_queue_release(&dev->video_vbq); +	saa7134_pgtable_free(dev->pci, &dev->video_q.pt); +	vb2_queue_release(&dev->vbi_vbq); +	saa7134_pgtable_free(dev->pci, &dev->vbi_q.pt); +	v4l2_ctrl_handler_free(&dev->ctrl_handler); +	if (card_has_radio(dev)) +		v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); +} +  int saa7134_videoport_init(struct saa7134_dev *dev)  {  	/* enable video output */ @@ -2532,6 +2191,7 @@ int saa7134_video_init2(struct saa7134_dev *dev)  	/* init video hw */  	set_tvnorm(dev,&tvnorms[0]);  	video_mux(dev,0); +	v4l2_ctrl_handler_setup(&dev->ctrl_handler);  	saa7134_tvaudio_setmute(dev);  	saa7134_tvaudio_setvolume(dev,dev->ctl_volume);  	return 0; @@ -2577,8 +2237,7 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)  	spin_lock(&dev->slock);  	if (dev->video_q.curr) { -		dev->video_fieldcount++; -		field = dev->video_q.curr->vb.field; +		field = dev->field;  		if (V4L2_FIELD_HAS_BOTH(field)) {  			/* make sure we have seen both fields */  			if ((status & 0x10) == 0x00) { @@ -2594,18 +2253,10 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)  			if ((status & 0x10) != 0x00)  				goto done;  		} -		dev->video_q.curr->vb.field_count = dev->video_fieldcount; -		saa7134_buffer_finish(dev,&dev->video_q,VIDEOBUF_DONE); +		saa7134_buffer_finish(dev, &dev->video_q, VB2_BUF_STATE_DONE);  	} -	saa7134_buffer_next(dev,&dev->video_q); +	saa7134_buffer_next(dev, &dev->video_q);   done:  	spin_unlock(&dev->slock);  } - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 8d1453a4801..e47edd4b57c 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -37,14 +37,15 @@  #include <media/v4l2-ioctl.h>  #include <media/v4l2-device.h>  #include <media/v4l2-fh.h> +#include <media/v4l2-ctrls.h>  #include <media/tuner.h>  #include <media/rc-core.h>  #include <media/ir-kbd-i2c.h> -#include <media/videobuf-dma-sg.h> +#include <media/videobuf2-dma-sg.h>  #include <sound/core.h>  #include <sound/pcm.h>  #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB) -#include <media/videobuf-dvb.h> +#include <media/videobuf2-dvb.h>  #endif  #include "tda8290.h" @@ -410,12 +411,18 @@ struct saa7134_board {  #define card(dev)             (saa7134_boards[dev->board])  #define card_in(dev,n)        (saa7134_boards[dev->board].inputs[n]) +#define V4L2_CID_PRIVATE_INVERT      (V4L2_CID_USER_SAA7134_BASE + 0) +#define V4L2_CID_PRIVATE_Y_ODD       (V4L2_CID_USER_SAA7134_BASE + 1) +#define V4L2_CID_PRIVATE_Y_EVEN      (V4L2_CID_USER_SAA7134_BASE + 2) +#define V4L2_CID_PRIVATE_AUTOMUTE    (V4L2_CID_USER_SAA7134_BASE + 3) +  /* ----------------------------------------------------------- */  /* device / file handle status                                 */  #define RESOURCE_OVERLAY       1  #define RESOURCE_VIDEO         2  #define RESOURCE_VBI           4 +#define RESOURCE_EMPRESS       8  #define INTERLACE_AUTO         0  #define INTERLACE_ON           1 @@ -446,17 +453,15 @@ struct saa7134_thread {  /* buffer for one video/vbi/ts frame */  struct saa7134_buf {  	/* common v4l buffer stuff -- must be first */ -	struct videobuf_buffer vb; +	struct vb2_buffer vb2;  	/* saa7134 specific */ -	struct saa7134_format   *fmt;  	unsigned int            top_seen;  	int (*activate)(struct saa7134_dev *dev,  			struct saa7134_buf *buf,  			struct saa7134_buf *next); -	/* page tables */ -	struct saa7134_pgtable  *pt; +	struct list_head	entry;  };  struct saa7134_dmaqueue { @@ -465,21 +470,8 @@ struct saa7134_dmaqueue {  	struct list_head           queue;  	struct timer_list          timeout;  	unsigned int               need_two; -}; - -/* video filehandle status */ -struct saa7134_fh { -	struct v4l2_fh             fh; -	struct saa7134_dev         *dev; -	unsigned int               resources; - -	/* video capture */ -	struct videobuf_queue      cap; -	struct saa7134_pgtable     pt_cap; - -	/* vbi capture */ -	struct videobuf_queue      vbi; -	struct saa7134_pgtable     pt_vbi; +	unsigned int               seq_nr; +	struct saa7134_pgtable     pt;  };  /* dmasound dsp status */ @@ -505,7 +497,10 @@ struct saa7134_dmasound {  	unsigned int               blksize;  	unsigned int               bufsize;  	struct saa7134_pgtable     pt; -	struct videobuf_dmabuf     dma; +	void			   *vaddr; +	struct scatterlist	   *sglist; +	int                        sglen; +	int                        nr_pages;  	unsigned int               dma_blk;  	unsigned int               read_offset;  	unsigned int               read_count; @@ -516,7 +511,6 @@ struct saa7134_dmasound {  /* ts/mpeg status */  struct saa7134_ts {  	/* TS capture */ -	struct saa7134_pgtable     pt_ts;  	int                        nr_packets;  	int                        nr_bufs;  }; @@ -585,20 +579,39 @@ struct saa7134_dev {  	struct v4l2_window         win;  	struct v4l2_clip           clips[8];  	unsigned int               nclips; +	struct v4l2_fh		   *overlay_owner;  	/* video+ts+vbi capture */  	struct saa7134_dmaqueue    video_q; +	struct vb2_queue           video_vbq;  	struct saa7134_dmaqueue    vbi_q; -	unsigned int               video_fieldcount; -	unsigned int               vbi_fieldcount; +	struct vb2_queue           vbi_vbq; +	enum v4l2_field		   field;  	struct saa7134_format      *fmt;  	unsigned int               width, height; +	unsigned int               vbi_hlen, vbi_vlen;  	struct pm_qos_request	   qos_request; +	/* SAA7134_MPEG_* */ +	struct saa7134_ts          ts; +	struct saa7134_dmaqueue    ts_q; +	enum v4l2_field		   ts_field; +	int                        ts_started; +	struct saa7134_mpeg_ops    *mops; + +	/* SAA7134_MPEG_EMPRESS only */ +	struct video_device        *empress_dev; +	struct v4l2_subdev	   *empress_sd; +	struct vb2_queue           empress_vbq; +	struct work_struct         empress_workqueue; +	int                        empress_started; +	struct v4l2_ctrl_handler   empress_ctrl_handler; +  	/* various v4l controls */  	struct saa7134_tvnorm      *tvnorm;              /* video */  	struct saa7134_tvaudio     *tvaudio; +	struct v4l2_ctrl_handler   ctrl_handler;  	unsigned int               ctl_input;  	int                        ctl_bright;  	int                        ctl_contrast; @@ -626,26 +639,14 @@ struct saa7134_dev {  	int                        last_carrier;  	int                        nosignal;  	unsigned int               insuspend; +	struct v4l2_ctrl_handler   radio_ctrl_handler;  	/* I2C keyboard data */  	struct IR_i2c_init_data    init_data; -	/* SAA7134_MPEG_* */ -	struct saa7134_ts          ts; -	struct saa7134_dmaqueue    ts_q; -	int                        ts_started; -	struct saa7134_mpeg_ops    *mops; - -	/* SAA7134_MPEG_EMPRESS only */ -	struct video_device        *empress_dev; -	struct videobuf_queue      empress_tsq; -	atomic_t 		   empress_users; -	struct work_struct         empress_workqueue; -	int                        empress_started; -  #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)  	/* SAA7134_MPEG_DVB only */ -	struct videobuf_dvb_frontends frontends; +	struct vb2_dvb_frontends frontends;  	int (*original_demod_sleep)(struct dvb_frontend *fe);  	int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);  	int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); @@ -699,12 +700,21 @@ struct saa7134_dev {  	_rc;								\  }) +static inline bool is_empress(struct file *file) +{ +	struct video_device *vdev = video_devdata(file); +	struct saa7134_dev *dev = video_get_drvdata(vdev); + +	return vdev->queue == &dev->empress_vbq; +} +  /* ----------------------------------------------------------- */  /* saa7134-core.c                                              */  extern struct list_head  saa7134_devlist;  extern struct mutex saa7134_devlist_lock;  extern int saa7134_no_overlay; +extern bool saa7134_userptr;  void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);  void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value); @@ -727,7 +737,7 @@ void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,  			   unsigned int state);  void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);  void saa7134_buffer_timeout(unsigned long data); -void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf); +void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);  int saa7134_set_dmabits(struct saa7134_dev *dev); @@ -761,10 +771,26 @@ extern unsigned int video_debug;  extern struct video_device saa7134_video_template;  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); +void saa7134_vb2_buffer_queue(struct vb2_buffer *vb); +int saa7134_vb2_start_streaming(struct vb2_queue *vq, unsigned int count); +void saa7134_vb2_stop_streaming(struct vb2_queue *vq); + +int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id); +int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id); +int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std); +int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i); +int saa7134_g_input(struct file *file, void *priv, unsigned int *i); +int saa7134_s_input(struct file *file, void *priv, unsigned int i); +int saa7134_querycap(struct file *file, void  *priv, +					struct v4l2_capability *cap); +int saa7134_g_tuner(struct file *file, void *priv, +					struct v4l2_tuner *t); +int saa7134_s_tuner(struct file *file, void *priv, +					const struct v4l2_tuner *t); +int saa7134_g_frequency(struct file *file, void *priv, +					struct v4l2_frequency *f); +int saa7134_s_frequency(struct file *file, void *priv, +					const struct v4l2_frequency *f);  int saa7134_videoport_init(struct saa7134_dev *dev);  void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); @@ -773,6 +799,7 @@ int saa7134_video_init1(struct saa7134_dev *dev);  int saa7134_video_init2(struct saa7134_dev *dev);  void saa7134_irq_video_signalchange(struct saa7134_dev *dev);  void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status); +void saa7134_video_fini(struct saa7134_dev *dev);  /* ----------------------------------------------------------- */ @@ -780,7 +807,16 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);  #define TS_PACKET_SIZE 188 /* TS packets 188 bytes */ -extern struct videobuf_queue_ops saa7134_ts_qops; +int saa7134_ts_buffer_init(struct vb2_buffer *vb2); +int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2); +void saa7134_ts_buffer_finish(struct vb2_buffer *vb2); +int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, +			   unsigned int *nbuffers, unsigned int *nplanes, +			   unsigned int sizes[], void *alloc_ctxs[]); +int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count); +void saa7134_ts_stop_streaming(struct vb2_queue *vq); + +extern struct vb2_ops saa7134_ts_qops;  int saa7134_ts_init1(struct saa7134_dev *dev);  int saa7134_ts_fini(struct saa7134_dev *dev); @@ -797,7 +833,7 @@ int saa7134_ts_stop(struct saa7134_dev *dev);  /* ----------------------------------------------------------- */  /* saa7134-vbi.c                                               */ -extern struct videobuf_queue_ops saa7134_vbi_qops; +extern struct vb2_ops saa7134_vbi_qops;  extern struct video_device saa7134_vbi_template;  int saa7134_vbi_init1(struct saa7134_dev *dev); diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index 33abe332d17..c4c8fce8f2b 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c @@ -357,7 +357,7 @@ static int mxb_init_done(struct saa7146_dev* dev)  	tea6420_route(mxb, 6);  	/* select video mode in saa7111a */ -	saa7111a_call(mxb, core, s_std, std); +	saa7111a_call(mxb, video, s_std, std);  	/* select tuner-output on saa7111a */  	i = 0; @@ -379,8 +379,8 @@ static int mxb_init_done(struct saa7146_dev* dev)  	/* These two gpio calls set the GPIO pins that control the tda9820 */  	saa7146_write(dev, GPIO_CTRL, 0x00404050);  	saa7111a_call(mxb, core, s_gpio, 1); -	saa7111a_call(mxb, core, s_std, std); -	tuner_call(mxb, core, s_std, std); +	saa7111a_call(mxb, video, s_std, std); +	tuner_call(mxb, video, s_std, std);  	/* switch to tuner-channel on tea6415c */  	tea6415c_call(mxb, video, s_routing, 3, 17, 0); @@ -771,9 +771,9 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa  		/* These two gpio calls set the GPIO pins that control the tda9820 */  		saa7146_write(dev, GPIO_CTRL, 0x00404050);  		saa7111a_call(mxb, core, s_gpio, 0); -		saa7111a_call(mxb, core, s_std, std); +		saa7111a_call(mxb, video, s_std, std);  		if (mxb->cur_input == 0) -			tuner_call(mxb, core, s_std, std); +			tuner_call(mxb, video, s_std, std);  	} else {  		v4l2_std_id std = V4L2_STD_PAL_BG; @@ -783,9 +783,9 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa  		/* These two gpio calls set the GPIO pins that control the tda9820 */  		saa7146_write(dev, GPIO_CTRL, 0x00404050);  		saa7111a_call(mxb, core, s_gpio, 1); -		saa7111a_call(mxb, core, s_std, std); +		saa7111a_call(mxb, video, s_std, std);  		if (mxb->cur_input == 0) -			tuner_call(mxb, core, s_std, std); +			tuner_call(mxb, video, s_std, std);  	}  	return 0;  } diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index d37ee37aaef..1bf06970ca3 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -1232,7 +1232,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev,  	}  	err = request_irq(pci_dev->irq, saa7164_irq, -		IRQF_SHARED | IRQF_DISABLED, dev->name, dev); +		IRQF_SHARED, dev->name, dev);  	if (err < 0) {  		printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,  			pci_dev->irq); @@ -1354,9 +1354,11 @@ static int saa7164_initdev(struct pci_dev *pci_dev,  		if (fw_debug) {  			dev->kthread = kthread_run(saa7164_thread_function, dev,  				"saa7164 debug"); -			if (!dev->kthread) +			if (IS_ERR(dev->kthread)) { +				dev->kthread = NULL;  				printk(KERN_ERR "%s() Failed to create "  					"debug kernel thread\n", __func__); +			}  		}  	} /* != BOARD_UNKNOWN */ @@ -1439,7 +1441,6 @@ static void saa7164_finidev(struct pci_dev *pci_dev)  	/* unregister stuff */  	free_irq(pci_dev->irq, dev); -	pci_set_drvdata(pci_dev, NULL);  	mutex_lock(&devlist);  	list_del(&dev->devlist); diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index 77edc113e48..d2abd3b5c2b 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c @@ -327,7 +327,7 @@ static void buffer_queue(struct vb2_buffer *vb)  	}  	spin_unlock(&vip->lock);  } -static int buffer_finish(struct vb2_buffer *vb) +static void buffer_finish(struct vb2_buffer *vb)  {  	struct sta2x11_vip *vip = vb2_get_drv_priv(vb->vb2_queue);  	struct vip_buffer *vip_buf = to_vip_buffer(vb); @@ -337,9 +337,8 @@ static int buffer_finish(struct vb2_buffer *vb)  	list_del_init(&vip_buf->list);  	spin_unlock(&vip->lock); -	vip_active_buf_next(vip); - -	return 0; +	if (vb2_is_streaming(vb->vb2_queue)) +		vip_active_buf_next(vip);  }  static int start_streaming(struct vb2_queue *vq, unsigned int count) @@ -358,7 +357,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)  }  /* abort streaming and wait for last buffer */ -static int stop_streaming(struct vb2_queue *vq) +static void stop_streaming(struct vb2_queue *vq)  {  	struct sta2x11_vip *vip = vb2_get_drv_priv(vq);  	struct vip_buffer *vip_buf, *node; @@ -375,7 +374,6 @@ static int stop_streaming(struct vb2_queue *vq)  		list_del(&vip_buf->list);  	}  	spin_unlock(&vip->lock); -	return 0;  }  static struct vb2_ops vip_video_qops = { @@ -446,7 +444,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)  	int status;  	if (V4L2_STD_ALL == std) { -		v4l2_subdev_call(vip->decoder, core, s_std, std); +		v4l2_subdev_call(vip->decoder, video, s_std, std);  		ssleep(2);  		v4l2_subdev_call(vip->decoder, video, querystd, &newstd);  		v4l2_subdev_call(vip->decoder, video, g_input_status, &status); @@ -469,7 +467,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)  			vip->format = formats_50[0];  	} -	return v4l2_subdev_call(vip->decoder, core, s_std, std); +	return v4l2_subdev_call(vip->decoder, video, s_std, std);  }  /** @@ -1303,7 +1301,7 @@ static int sta2x11_vip_resume(struct pci_dev *pdev)  #endif -static DEFINE_PCI_DEVICE_TABLE(sta2x11_vip_pci_tbl) = { +static const struct pci_device_id sta2x11_vip_pci_tbl[] = {  	{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)},  	{0,}  }; diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c index 301029ca453..9544cfc0660 100644 --- a/drivers/media/pci/ttpci/av7110_av.c +++ b/drivers/media/pci/ttpci/av7110_av.c @@ -958,8 +958,10 @@ static unsigned int dvb_video_poll(struct file *file, poll_table *wait)  		if (av7110->playing) {  			if (FREE_COND)  				mask |= (POLLOUT | POLLWRNORM); -			} else /* if not playing: may play if asked for */ -				mask |= (POLLOUT | POLLWRNORM); +		} else { +			/* if not playing: may play if asked for */ +			mask |= (POLLOUT | POLLWRNORM); +		}  	}  	return mask; diff --git a/drivers/media/pci/ttpci/av7110_hw.c b/drivers/media/pci/ttpci/av7110_hw.c index f1cbfe52698..300bd3c9473 100644 --- a/drivers/media/pci/ttpci/av7110_hw.c +++ b/drivers/media/pci/ttpci/av7110_hw.c @@ -22,7 +22,7 @@   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   * Or, point your browser to http://www.gnu.org/copyleft/gpl.html   * - * the project's page is at http://www.linuxtv.org/  + * the project's page is at http://www.linuxtv.org/   */  /* for debugging ARM communication: */ @@ -40,6 +40,14 @@  #define _NOHANDSHAKE +/* + * Max transfer size done by av7110_fw_cmd() + * + * The maximum size passed to this function is 6 bytes. The buffer also + * uses two additional ones for type and size. So, 8 bytes is enough. + */ +#define MAX_XFER_SIZE  8 +  /****************************************************************************   * DEBI functions   ****************************************************************************/ @@ -488,11 +496,18 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)  int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)  {  	va_list args; -	u16 buf[num + 2]; +	u16 buf[MAX_XFER_SIZE];  	int i, ret;  //	dprintk(4, "%p\n", av7110); +	if (2 + num > ARRAY_SIZE(buf)) { +		printk(KERN_WARNING +		       "%s: %s len=%d is too big!\n", +		       KBUILD_MODNAME, __func__, num); +		return -EINVAL; +	} +  	buf[0] = ((type << 8) | com);  	buf[1] = num; diff --git a/drivers/media/pci/zoran/Kconfig b/drivers/media/pci/zoran/Kconfig index 26ca8702e33..39ec35bd21a 100644 --- a/drivers/media/pci/zoran/Kconfig +++ b/drivers/media/pci/zoran/Kconfig @@ -1,6 +1,7 @@  config VIDEO_ZORAN  	tristate "Zoran ZR36057/36067 Video For Linux"  	depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS +	depends on !ALPHA  	help  	  Say Y for support for MJPEG capture cards based on the Zoran  	  36057/36067 PCI controller chipset. This includes the Iomega diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c index 923d59a321f..cec5b7553f2 100644 --- a/drivers/media/pci/zoran/zoran_card.c +++ b/drivers/media/pci/zoran/zoran_card.c @@ -1293,7 +1293,7 @@ static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	}  	result = request_irq(zr->pci_dev->irq, zoran_irq, -			     IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr); +			     IRQF_SHARED, ZR_DEVNAME(zr), zr);  	if (result < 0) {  		if (result == -EINVAL) {  			dprintk(1, diff --git a/drivers/media/pci/zoran/zoran_device.c b/drivers/media/pci/zoran/zoran_device.c index 519164c572c..bf34b93f23e 100644 --- a/drivers/media/pci/zoran/zoran_device.c +++ b/drivers/media/pci/zoran/zoran_device.c @@ -1572,7 +1572,7 @@ zoran_init_hardware (struct zoran *zr)  	}  	decoder_call(zr, core, init, 0); -	decoder_call(zr, core, s_std, zr->norm); +	decoder_call(zr, video, s_std, zr->norm);  	decoder_call(zr, video, s_routing,  		zr->card.input[zr->input].muxsel, 0, 0); diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index e7e9840c6c3..099d5fbebb7 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c @@ -1469,7 +1469,7 @@ zoran_set_norm (struct zoran *zr,  	if (on)  		zr36057_overlay(zr, 0); -	decoder_call(zr, core, s_std, norm); +	decoder_call(zr, video, s_std, norm);  	encoder_call(zr, video, s_std_output, norm);  	if (on)  | 
