Re: [PULL] http://www.kernellabs.com/hg/~stoth/cx23885-mpx

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

 



Hi Steven,

Em 31-07-2010 13:31, Steven Toth escreveu:
> Mauro,
> 
> Please pull from http://www.kernellabs.com/hg/~stoth/cx23885-mpx
> 
>    -  cx23885: prepare the cx23885 makefile for alsa support
>    -  cx23885: merge mijhail's header changes for alsa
>    -  cx23885: ALSA support
>    -  cx23885: core changes requireed for ALSA
>    -  cx23885: add definitions for HVR1500 to support audio
>    -  cx23885: correct the contrast, saturation and hue controls
>    -  cx23885: hooks the alsa changes into the video subsystem
>    -  cx23885: convert call clients into subdevices
>    -  cx23885: replaced spinlock with mutex
>    -  cx23885: minor function renaming to ensure uniformity
>    -  cx23885: setup the dma mapping for raw audio support
>    -  cx23885: mute the audio during channel change
>    -  cx23885: add two additional defines to simplify VBI register
> bitmap handling
>    -  cx23885: initial support for VBI with the cx23885
>    -  cx23885: initialize VBI support in the core, add IRQ support,
> register vbi device
>    -  cx23885: minor printk cleanups and device registration
>    -  cx25840: enable raw cc processing only for the cx23885 hardware
>    -  cx23885: vbi line window adjustments
>    -  cx23885: add vbi buffer formatting, window changes and video core changes
>    -  cx23885: Ensure the VBI pixel format is established correctly.
>    -  cx23885: convert from snd_card_new() to snd_card_create()
>    -  cx23885: ensure video is streaming before allowing vbi to stream
>    -  cx23885: vbi related codingstyle cleanups
>    -  cx23885: removal of VBI and earlier VBI printk debugging
>    -  cx23885: removal of redundant code, this is no longer required.
>    -  cx23885: remove channel dump diagnostics when a vbi buffer times out.
>    -  cx23885: Ensure VBI buffers timeout quickly - bugfix for vbi
> hangs during streaming.
>    -  cx23885: coding style violation cleanups
>    -  cx23885: Convert a mutex back to a spinlock
>    -  cx23885: Name an internal i2c part and declare a bitfield by name
>    -  cx25840: Enable support for non-tuner LR1/LR2 audio inputs
>    -  cx23885: Allow the audio mux config to be specified on a per input basis.
>    -  cx23885: remove a line of debug
>    -  cx23885: Enable audio line in support from the back panel
>    -  cx25840: Ensure AUDIO6 and AUDIO7 trigger line-in baseband use.
>    -  cx23885: Initial support for the MPX-885 mini-card
>    -  cx23885: fixes related to maximum number of inputs and range checking
>    -  cx23885: add generic functions for dealing with audio input selection
>    -  cx23885: hook the audio selection functions into the main driver
>    -  cx23885: v4l2 api compliance, set the audioset field correctly
>    -  cx23885: Removed a spurious function cx23885_set_scale().
>    -  cx23885: Avoid stopping the risc engine during buffer timeout.
>    -  cx23885: Avoid incorrect error handling and reporting
>    -  cx23885: Stop the risc video fifo before reconfiguring it.
> 
>  b/linux/drivers/media/video/cx23885/cx23885-alsa.c |  542 +++++++++
>  linux/Documentation/video4linux/CARDLIST.cx23885   |    1
>  linux/drivers/media/video/cx23885/Makefile         |    2
>  linux/drivers/media/video/cx23885/cx23885-alsa.c   |   28
>  linux/drivers/media/video/cx23885/cx23885-cards.c  |   53
>  linux/drivers/media/video/cx23885/cx23885-core.c   |  127 +-
>  linux/drivers/media/video/cx23885/cx23885-i2c.c    |    1
>  linux/drivers/media/video/cx23885/cx23885-reg.h    |    3
>  linux/drivers/media/video/cx23885/cx23885-vbi.c    |   96 +
>  linux/drivers/media/video/cx23885/cx23885-video.c  |  556 ++++++----
>  linux/drivers/media/video/cx23885/cx23885.h        |   65 +
>  linux/drivers/media/video/cx25840/cx25840-audio.c  |    9
>  linux/drivers/media/video/cx25840/cx25840-core.c   |   21
>  13 files changed, 1257 insertions(+), 247 deletions(-)
> 
> A pretty large patch set which adds a number of important features to
> the cx23885 driver.

It is always a good idea to not wait for a large patch set when submitting,
as waiting for a long time to merge increase the chances of conflicts.
That's the case of this changeset. It breaks compilation due to an API change
at the videobuf-dma-sg:

drivers/media/video/cx23885/cx23885-alsa.c: In function ‘dsp_buffer_free’:
drivers/media/video/cx23885/cx23885-alsa.c:199: error: implicit declaration of function ‘videobuf_sg_dma_unmap’
drivers/media/video/cx23885/cx23885-alsa.c: In function ‘snd_cx23885_hw_params’:
drivers/media/video/cx23885/cx23885-alsa.c:329: error: implicit declaration of function ‘videobuf_sg_dma_map’
drivers/media/video/cx23885/cx23885-alsa.c:348: error: ‘struct videobuf_dmabuf’ has no member named ‘vmalloc’

I suspect it is caused by commit fecfedeb27ab9497cbdd2c6:
Author: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
Date:   Tue May 11 10:36:31 2010 -0300

    V4L/DVB: Remove videobuf_sg_alloc abuse
    
    The cx88 and cx25821 drivers abuse videobuf_buffer to handle audio data.
    Remove the abuse by creating private audio buffer structures with a
    videobuf_dmabuf field.
    
    Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>


I also had to solve a few trivial conflicts against awalls pull request, 
that also submitted a large sets of change due to IR and had to move the
Makefile changes to the end - to avoid bisect issues.If you want, I may
send you a quilt tree with the fixed patches.

> Some early patches for the HVR1500 with add support for analog audio
> (very rough, much rework on these).
> The University of California sponsored work for the HVR1800 and
> HVR1850 and raw video and raw audio and VBI support.
> The Belac Group sponsored changes related to the MPX cx23885 8 input
> design, adding raw video and audio support.
> Mencoder now works correctly with the raw video and audio portions of
> the driver.
> GStreamer now works correctly using the v4l interfaces from the
> driver, live video and audio viewing are now possible.
> NTSC-ZZ-VBI now works correctly for RAW VBI decoding (although TVTime
> still refuses to work correctly - tvtime bug)

I have a few other comments. In order to make simpler for me to comment, I
just folded everything into one single diff, as enclosed.

Cheers,
Mauro.
 
> diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
> index 87c4634..30309f0 100644
> --- a/Documentation/video4linux/CARDLIST.cx23885
> +++ b/Documentation/video4linux/CARDLIST.cx23885
> @@ -27,3 +27,4 @@
>   26 -> Hauppauge WinTV-HVR1290                             [0070:8551]
>   27 -> Mygica X8558 PRO DMB-TH                             [14f1:8578]
>   28 -> LEADTEK WinFast PxTV1200                            [107d:6f22]
> + 29 -> MPX-885
> diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
> index e2ee95f..ed739f9 100644
> --- a/drivers/media/video/cx23885/Makefile
> +++ b/drivers/media/video/cx23885/Makefile
> @@ -2,7 +2,7 @@ cx23885-objs	:= cx23885-cards.o cx23885-video.o cx23885-vbi.o \
>  		    cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
>  		    cx23885-ioctl.o cx23885-ir.o cx23885-av.o cx23885-input.o \
>  		    cx23888-ir.o netup-init.o cimax2.o netup-eeprom.o \
> -		    cx23885-f300.o
> +		    cx23885-f300.o cx23885-alsa.o
>  
>  obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
>  
> diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
> index e76ce87..d07eedf 100644
> --- a/drivers/media/video/cx23885/cx23885-cards.c
> +++ b/drivers/media/video/cx23885/cx23885-cards.c
> @@ -95,12 +95,14 @@ struct cx23885_board cx23885_boards[] = {
>  			.vmux   =	CX25840_VIN7_CH3 |
>  					CX25840_VIN5_CH2 |
>  					CX25840_VIN2_CH1,
> +			.amux   = CX25840_AUDIO8,
>  			.gpio0  = 0,
>  		}, {
>  			.type   = CX23885_VMUX_COMPOSITE1,
>  			.vmux   =	CX25840_VIN7_CH3 |
>  					CX25840_VIN4_CH2 |
>  					CX25840_VIN6_CH1,
> +			.amux   = CX25840_AUDIO7,
>  			.gpio0  = 0,
>  		}, {
>  			.type   = CX23885_VMUX_SVIDEO,
> @@ -108,6 +110,7 @@ struct cx23885_board cx23885_boards[] = {
>  					CX25840_VIN4_CH2 |
>  					CX25840_VIN8_CH1 |
>  					CX25840_SVIDEO_ON,
> +			.amux   = CX25840_AUDIO7,
>  			.gpio0  = 0,
>  		} },
>  	},
> @@ -142,7 +145,30 @@ struct cx23885_board cx23885_boards[] = {
>  	},
>  	[CX23885_BOARD_HAUPPAUGE_HVR1500] = {
>  		.name		= "Hauppauge WinTV-HVR1500",
> +		.porta		= CX23885_ANALOG_VIDEO,
>  		.portc		= CX23885_MPEG_DVB,
> +		.tuner_type	= TUNER_XC2028,
> +		.tuner_addr	= 0x61, /* 0xc2 >> 1 */
> +		.input          = {{
> +			.type   = CX23885_VMUX_TELEVISION,
> +			.vmux   =	CX25840_VIN7_CH3 |
> +					CX25840_VIN5_CH2 |
> +					CX25840_VIN2_CH1,
> +			.gpio0  = 0,
> +		}, {
> +			.type   = CX23885_VMUX_COMPOSITE1,
> +			.vmux   =	CX25840_VIN7_CH3 |
> +					CX25840_VIN4_CH2 |
> +					CX25840_VIN6_CH1,
> +			.gpio0  = 0,
> +		}, {
> +			.type   = CX23885_VMUX_SVIDEO,
> +			.vmux   =	CX25840_VIN7_CH3 |
> +					CX25840_VIN4_CH2 |
> +					CX25840_VIN8_CH1 |
> +					CX25840_SVIDEO_ON,
> +			.gpio0  = 0,
> +		} },
>  	},
>  	[CX23885_BOARD_HAUPPAUGE_HVR1200] = {
>  		.name		= "Hauppauge WinTV-HVR1200",
> @@ -309,6 +335,31 @@ struct cx23885_board cx23885_boards[] = {
>  				  CX25840_COMPONENT_ON,
>  		} },
>  	},
> +	[CX23885_BOARD_MPX885] = {
> +		.name		= "MPX-885",
> +		.porta		= CX23885_ANALOG_VIDEO,
> +		.input          = {{
> +			.type   = CX23885_VMUX_COMPOSITE1,
> +			.vmux   = CX25840_COMPOSITE1,
> +			.amux   = CX25840_AUDIO6,
> +			.gpio0  = 0,
> +		}, {
> +			.type   = CX23885_VMUX_COMPOSITE2,
> +			.vmux   = CX25840_COMPOSITE2,
> +			.amux   = CX25840_AUDIO6,
> +			.gpio0  = 0,
> +		}, {
> +			.type   = CX23885_VMUX_COMPOSITE3,
> +			.vmux   = CX25840_COMPOSITE3,
> +			.amux   = CX25840_AUDIO7,
> +			.gpio0  = 0,
> +		}, {
> +			.type   = CX23885_VMUX_COMPOSITE4,
> +			.vmux   = CX25840_COMPOSITE4,
> +			.amux   = CX25840_AUDIO7,
> +			.gpio0  = 0,
> +		} },
> +	},
>  };
>  const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
>  
> @@ -1245,6 +1296,8 @@ void cx23885_card_setup(struct cx23885_dev *dev)
>  	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
>  	case CX23885_BOARD_HAUPPAUGE_HVR1290:
>  	case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
> +	case CX23885_BOARD_HAUPPAUGE_HVR1500:
> +	case CX23885_BOARD_MPX885:
>  		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
>  				&dev->i2c_bus[2].i2c_adap,
>  				"cx25840", "cx25840", 0x88 >> 1, NULL);
> diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
> index f6b62e7..6118b56 100644
> --- a/drivers/media/video/cx23885/cx23885-core.c
> +++ b/drivers/media/video/cx23885/cx23885-core.c
> @@ -51,7 +51,7 @@ MODULE_PARM_DESC(card, "card type");
>  
>  #define dprintk(level, fmt, arg...)\
>  	do { if (debug >= level)\
> -		printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
> +		printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
>  	} while (0)
>  
>  static unsigned int cx23885_devcount;
> @@ -152,12 +152,12 @@ static struct sram_channel cx23885_sram_channels[] = {
>  		.cnt2_reg	= DMA5_CNT2,
>  	},
>  	[SRAM_CH07] = {
> -		.name		= "ch7",
> -		.cmds_start	= 0x0,
> -		.ctrl_start	= 0x0,
> -		.cdt		= 0x0,
> -		.fifo_start	= 0x0,
> -		.fifo_size	= 0x0,
> +		.name		= "TV Audio",
> +		.cmds_start	= 0x10190,
> +		.ctrl_start	= 0x10480,
> +		.cdt		= 0x10a00,
> +		.fifo_start	= 0x7000,
> +		.fifo_size	= 0x1000,
>  		.ptr1_reg	= DMA6_PTR1,
>  		.ptr2_reg	= DMA6_PTR2,
>  		.cnt1_reg	= DMA6_CNT1,
> @@ -203,12 +203,12 @@ static struct sram_channel cx23887_sram_channels[] = {
>  		.cnt2_reg	= DMA1_CNT2,
>  	},
>  	[SRAM_CH02] = {
> -		.name		= "ch2",
> -		.cmds_start	= 0x0,
> -		.ctrl_start	= 0x0,
> -		.cdt		= 0x0,
> -		.fifo_start	= 0x0,
> -		.fifo_size	= 0x0,
> +		.name		= "VID A (VBI)",
> +		.cmds_start	= 0x10050,
> +		.ctrl_start	= 0x105F0,
> +		.cdt		= 0x10810,
> +		.fifo_start	= 0x3000,
> +		.fifo_size	= 0x1000,
>  		.ptr1_reg	= DMA2_PTR1,
>  		.ptr2_reg	= DMA2_PTR2,
>  		.cnt1_reg	= DMA2_CNT1,
> @@ -263,12 +263,12 @@ static struct sram_channel cx23887_sram_channels[] = {
>  		.cnt2_reg	= DMA5_CNT2,
>  	},
>  	[SRAM_CH07] = {
> -		.name		= "ch7",
> -		.cmds_start	= 0x0,
> -		.ctrl_start	= 0x0,
> -		.cdt		= 0x0,
> -		.fifo_start	= 0x0,
> -		.fifo_size	= 0x0,
> +		.name		= "TV Audio",
> +		.cmds_start	= 0x10190,
> +		.ctrl_start	= 0x106B0,
> +		.cdt		= 0x10930,
> +		.fifo_start	= 0x7000,
> +		.fifo_size	= 0x1000,
>  		.ptr1_reg	= DMA6_PTR1,
>  		.ptr2_reg	= DMA6_PTR2,
>  		.cnt1_reg	= DMA6_CNT1,
> @@ -1069,10 +1069,10 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
>  static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
>  			       unsigned int offset, u32 sync_line,
>  			       unsigned int bpl, unsigned int padding,
> -			       unsigned int lines)
> +			       unsigned int lines,  unsigned int lpi)
>  {
>  	struct scatterlist *sg;
> -	unsigned int line, todo;
> +	unsigned int line, todo, sol;
>  
>  	/* sync instruction */
>  	if (sync_line != NO_SYNC_LINE)
> @@ -1085,16 +1085,22 @@ static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
>  			offset -= sg_dma_len(sg);
>  			sg++;
>  		}
> +
> +		if (lpi && line > 0 && !(line % lpi))
> +			sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
> +		else
> +			sol = RISC_SOL;
> +
>  		if (bpl <= sg_dma_len(sg)-offset) {
>  			/* fits into current chunk */
> -			*(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
> +			*(rp++) = cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl);
>  			*(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
>  			*(rp++) = cpu_to_le32(0); /* bits 63-32 */
>  			offset += bpl;
>  		} else {
>  			/* scanline needs to be split */
>  			todo = bpl;
> -			*(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|
> +			*(rp++) = cpu_to_le32(RISC_WRITE|sol|
>  					    (sg_dma_len(sg)-offset));
>  			*(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
>  			*(rp++) = cpu_to_le32(0); /* bits 63-32 */
> @@ -1151,10 +1157,10 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  	rp = risc->cpu;
>  	if (UNSET != top_offset)
>  		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
> -					bpl, padding, lines);
> +					bpl, padding, lines, 0);
>  	if (UNSET != bottom_offset)
>  		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
> -					bpl, padding, lines);
> +					bpl, padding, lines, 0);
>  
>  	/* save pointer to jmp instruction address */
>  	risc->jmp = rp;
> @@ -1162,11 +1168,11 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  	return 0;
>  }
>  
> -static int cx23885_risc_databuffer(struct pci_dev *pci,
> +int cx23885_risc_databuffer(struct pci_dev *pci,
>  				   struct btcx_riscmem *risc,
>  				   struct scatterlist *sglist,
>  				   unsigned int bpl,
> -				   unsigned int lines)
> +				   unsigned int lines, unsigned int lpi)
>  {
>  	u32 instructions;
>  	__le32 *rp;
> @@ -1186,7 +1192,55 @@ static int cx23885_risc_databuffer(struct pci_dev *pci,
>  
>  	/* write risc instructions */
>  	rp = risc->cpu;
> -	rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
> +	rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
> +		lines, lpi);
> +
> +	/* save pointer to jmp instruction address */
> +	risc->jmp = rp;
> +	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
> +	return 0;
> +}
> +
> +int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
> +			struct scatterlist *sglist, unsigned int top_offset,
> +			unsigned int bottom_offset, unsigned int bpl,
> +			unsigned int padding, unsigned int lines)
> +{
> +	u32 instructions, fields;
> +	__le32 *rp;
> +	int rc;
> +
> +	fields = 0;
> +	if (UNSET != top_offset)
> +		fields++;
> +	if (UNSET != bottom_offset)
> +		fields++;
> +
> +	/* estimate risc mem: worst case is one write per page border +
> +	   one write per scan line + syncs + jump (all 2 dwords).  Padding
> +	   can cause next bpl to start close to a page border.  First DMA
> +	   region may be smaller than PAGE_SIZE */
> +	/* write and jump need and extra dword */
> +	instructions  = fields * (1 + ((bpl + padding) * lines)
> +		/ PAGE_SIZE + lines);
> +	instructions += 2;
> +	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
> +	if (rc < 0)
> +		return rc;
> +	/* write risc instructions */
> +	rp = risc->cpu;
> +
> +	/* Sync to line 6, so US CC line 21 will appear in line '12'
> +	 * in the userland vbi payload */
> +	if (UNSET != top_offset)
> +		rp = cx23885_risc_field(rp, sglist, top_offset, 6,
> +					bpl, padding, lines, 0);
> +
> +	if (UNSET != bottom_offset)
> +		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207,
> +					bpl, padding, lines, 0);
> +
> +
>  
>  	/* save pointer to jmp instruction address */
>  	risc->jmp = rp;
> @@ -1194,6 +1248,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci,
>  	return 0;
>  }
>  
> +
>  int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
>  				u32 reg, u32 mask, u32 value)
>  {
> @@ -1504,7 +1559,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
>  			goto fail;
>  		cx23885_risc_databuffer(dev->pci, &buf->risc,
>  					videobuf_to_dma(&buf->vb)->sglist,
> -					buf->vb.width, buf->vb.height);
> +					buf->vb.width, buf->vb.height, 0);
>  	}
>  	buf->vb.state = VIDEOBUF_PREPARED;
>  	return 0;
> @@ -1728,15 +1783,19 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
>  	struct cx23885_tsport *ts2 = &dev->ts2;
>  	u32 pci_status, pci_mask;
>  	u32 vida_status, vida_mask;
> +	u32 audint_status, audint_mask;
>  	u32 ts1_status, ts1_mask;
>  	u32 ts2_status, ts2_mask;
>  	int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0;
> +	int audint_count = 0;
>  	bool subdev_handled;
>  
>  	pci_status = cx_read(PCI_INT_STAT);
>  	pci_mask = cx23885_irq_get_mask(dev);
>  	vida_status = cx_read(VID_A_INT_STAT);
>  	vida_mask = cx_read(VID_A_INT_MSK);
> +	audint_status = cx_read(AUDIO_INT_INT_STAT);
> +	audint_mask = cx_read(AUDIO_INT_INT_MSK);
>  	ts1_status = cx_read(VID_B_INT_STAT);
>  	ts1_mask = cx_read(VID_B_INT_MSK);
>  	ts2_status = cx_read(VID_C_INT_STAT);
> @@ -1746,12 +1805,15 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
>  		goto out;
>  
>  	vida_count = cx_read(VID_A_GPCNT);
> +	audint_count = cx_read(AUD_INT_A_GPCNT);
>  	ts1_count = cx_read(ts1->reg_gpcnt);
>  	ts2_count = cx_read(ts2->reg_gpcnt);
>  	dprintk(7, "pci_status: 0x%08x  pci_mask: 0x%08x\n",
>  		pci_status, pci_mask);
>  	dprintk(7, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n",
>  		vida_status, vida_mask, vida_count);
> +	dprintk(7, "audint_status: 0x%08x audint_mask: 0x%08x count: 0x%x\n",
> +		audint_status, audint_mask, audint_count);
>  	dprintk(7, "ts1_status: 0x%08x  ts1_mask: 0x%08x count: 0x%x\n",
>  		ts1_status, ts1_mask, ts1_count);
>  	dprintk(7, "ts2_status: 0x%08x  ts2_mask: 0x%08x count: 0x%x\n",
> @@ -1849,6 +1911,9 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
>  	if (vida_status)
>  		handled += cx23885_video_irq(dev, vida_status);
>  
> +	if (audint_status)
> +		handled += cx23885_audio_irq(dev, audint_status, audint_mask);
> +
>  	if (pci_status & PCI_MSK_IR) {
>  		subdev_handled = false;
>  		v4l2_subdev_call(dev->sd_ir, core, interrupt_service_routine,
> diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
> index 1a39148..46027ee 100644
> --- a/drivers/media/video/cx23885/cx23885-i2c.c
> +++ b/drivers/media/video/cx23885/cx23885-i2c.c
> @@ -297,6 +297,7 @@ static char *i2c_devs[128] = {
>  	[0x32 >> 1] = "cx24227",
>  	[0x88 >> 1] = "cx25837",
>  	[0x84 >> 1] = "tda8295",
> +	[0x98 >> 1] = "flatiron",
>  	[0xa0 >> 1] = "eeprom",
>  	[0xc0 >> 1] = "tuner/mt2131/tda8275",
>  	[0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028",
> diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
> index a28772d..0c648ac 100644
> --- a/drivers/media/video/cx23885/cx23885-reg.h
> +++ b/drivers/media/video/cx23885/cx23885-reg.h
> @@ -203,6 +203,7 @@ Channel manager Data Structure entry = 20 DWORD
>  #define SD2_BIAS_CTRL	0x0000000A
>  #define AMP_BIAS_CTRL	0x0000000C
>  #define CH_PWR_CTRL1	0x0000000E
> +#define FLD_CH_SEL      (1 << 3)
>  #define CH_PWR_CTRL2	0x0000000F
>  #define DSM_STATUS1	0x00000010
>  #define DSM_STATUS2	0x00000011
> @@ -271,7 +272,9 @@ Channel manager Data Structure entry = 20 DWORD
>  #define VID_BC_MSK_OPC_ERR (1 << 16)
>  #define VID_BC_MSK_SYNC    (1 << 12)
>  #define VID_BC_MSK_OF      (1 <<  8)
> +#define VID_BC_MSK_VBI_RISCI2 (1 <<  5)
>  #define VID_BC_MSK_RISCI2  (1 <<  4)
> +#define VID_BC_MSK_VBI_RISCI1 (1 <<  1)
>  #define VID_BC_MSK_RISCI1   1
>  
>  #define VID_C_INT_MSK	0x00040040
> diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c
> index c0b6038..d2b25d9 100644
> --- a/drivers/media/video/cx23885/cx23885-vbi.c
> +++ b/drivers/media/video/cx23885/cx23885-vbi.c
> @@ -41,6 +41,12 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
>  
>  /* ------------------------------------------------------------------ */
>  
> +#define VBI_LINE_LENGTH 1440
> +#define NTSC_VBI_START_LINE 10        /* line 10 - 21 */
> +#define NTSC_VBI_END_LINE   21
> +#define NTSC_VBI_LINES      (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1)
> +
> +
>  int cx23885_vbi_fmt(struct file *file, void *priv,
>  	struct v4l2_format *f)
>  {
> @@ -49,28 +55,71 @@ int cx23885_vbi_fmt(struct file *file, void *priv,
>  
>  	if (dev->tvnorm & V4L2_STD_525_60) {
>  		/* ntsc */
> -		f->fmt.vbi.sampling_rate = 28636363;
> +		f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
> +		f->fmt.vbi.sampling_rate = 27000000;
> +		f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
> +		f->fmt.vbi.offset = 0;
> +		f->fmt.vbi.flags = 0;
>  		f->fmt.vbi.start[0] = 10;
> -		f->fmt.vbi.start[1] = 273;
> -
> +		f->fmt.vbi.count[0] = 17;
> +		f->fmt.vbi.start[1] = 263 + 10 + 1;
> +		f->fmt.vbi.count[1] = 17;
>  	} else if (dev->tvnorm & V4L2_STD_625_50) {
>  		/* pal */
>  		f->fmt.vbi.sampling_rate = 35468950;

I suspect that the sampling rate is wrong here. If PAL/SECAM with 625 lines are
not supported yet, better to just prevent VBI from work with 625 lines.

>  		f->fmt.vbi.start[0] = 7 - 1;
>  		f->fmt.vbi.start[1] = 319 - 1;
>  	}
> +
>  	return 0;
>  }
>  
> +/* We're given the Video Interrupt status register.
> + * The cx23885_video_irq() func has already validated
> + * the potential error bits, we just need to
> + * deal with vbi payload and return indication if
> + * we actually processed any payload.
> + */
> +int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status)
> +{
> +	u32 count;
> +	int handled = 0;
> +
> +	if (status & VID_BC_MSK_VBI_RISCI1) {
> +		dprintk(1, "%s() VID_BC_MSK_VBI_RISCI1\n", __func__);
> +		spin_lock(&dev->slock);
> +		count = cx_read(VID_A_GPCNT);
> +		cx23885_video_wakeup(dev, &dev->vbiq, count);
> +		spin_unlock(&dev->slock);
> +		handled++;
> +	}
> +
> +	if (status & VID_BC_MSK_VBI_RISCI2) {
> +		dprintk(1, "%s() VID_BC_MSK_VBI_RISCI2\n", __func__);
> +		dprintk(2, "stopper vbi\n");
> +		spin_lock(&dev->slock);
> +		cx23885_restart_vbi_queue(dev, &dev->vbiq);
> +		spin_unlock(&dev->slock);
> +		handled++;
> +	}
> +
> +	return handled;
> +}
> +
>  static int cx23885_start_vbi_dma(struct cx23885_dev    *dev,
>  			 struct cx23885_dmaqueue *q,
>  			 struct cx23885_buffer   *buf)
>  {
> +	dprintk(1, "%s()\n", __func__);
> +
>  	/* setup fifo + format */
>  	cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02],
>  				buf->vb.width, buf->risc.dma);
>  
>  	/* reset counter */
> +	cx_write(VID_A_GPCNT_CTL, 3);
> +	cx_write(VID_A_VBI_CTRL, 3);
> +	cx_write(VBI_A_GPCNT_CTL, 3);
>  	q->count = 1;
>  
>  	/* enable irqs */
> @@ -79,13 +128,13 @@ static int cx23885_start_vbi_dma(struct cx23885_dev    *dev,
>  
>  	/* start dma */
>  	cx_set(DEV_CNTRL2, (1<<5));
> -	cx_set(VID_A_DMA_CTL, 0x00000022);
> +	cx_set(VID_A_DMA_CTL, 0x22); /* FIFO and RISC enable */
>  
>  	return 0;
>  }
>  
>  
> -static int cx23885_restart_vbi_queue(struct cx23885_dev    *dev,
> +int cx23885_restart_vbi_queue(struct cx23885_dev *dev,
>  			     struct cx23885_dmaqueue *q)
>  {
>  	struct cx23885_buffer *buf;
> @@ -102,7 +151,7 @@ static int cx23885_restart_vbi_queue(struct cx23885_dev    *dev,
>  		buf = list_entry(item, struct cx23885_buffer, vb.queue);
>  		buf->count = q->count++;
>  	}
> -	mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
> +	mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30));
>  	return 0;
>  }
>  
> @@ -113,8 +162,7 @@ void cx23885_vbi_timeout(unsigned long data)
>  	struct cx23885_buffer *buf;
>  	unsigned long flags;
>  
> -	cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH02]);
> -
> +	/* Stop the VBI engine */
>  	cx_clear(VID_A_DMA_CTL, 0x22);
>  
>  	spin_lock_irqsave(&dev->slock, flags);
> @@ -132,7 +180,7 @@ void cx23885_vbi_timeout(unsigned long data)
>  }
>  
>  /* ------------------------------------------------------------------ */
> -#define VBI_LINE_LENGTH 2048
> +#define VBI_LINE_LENGTH 1440
>  #define VBI_LINE_COUNT 17
>  
>  static int
> @@ -173,7 +221,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
>  		rc = videobuf_iolock(q, &buf->vb, NULL);
>  		if (0 != rc)
>  			goto fail;
> -		cx23885_risc_buffer(dev->pci, &buf->risc,
> +		cx23885_risc_vbibuffer(dev->pci, &buf->risc,
>  				 dma->sglist,
>  				 0, buf->vb.width * buf->vb.height,
>  				 buf->vb.width, 0,
> @@ -207,7 +255,7 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
>  		cx23885_start_vbi_dma(dev, q, buf);
>  		buf->vb.state = VIDEOBUF_ACTIVE;
>  		buf->count    = q->count++;
> -		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
> +		mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30));
>  		dprintk(2, "[%p/%d] vbi_queue - first active\n",
>  			buf, buf->vb.i);
>  
> diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
> index da66e5f..b7f01bd 100644
> --- a/drivers/media/video/cx23885/cx23885-video.c
> +++ b/drivers/media/video/cx23885/cx23885-video.c
> @@ -38,6 +38,8 @@
>  #include "cx23885-ioctl.h"
>  #include "tuner-xc2028.h"
>  
> +#include <media/cx25840.h>
> +
>  MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
>  MODULE_AUTHOR("Steven Toth <stoth@xxxxxxxxxxx>");
>  MODULE_LICENSE("GPL");
> @@ -70,66 +72,20 @@ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
>  
>  #define dprintk(level, fmt, arg...)\
>  	do { if (video_debug >= level)\
> -		printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
> +		printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
>  	} while (0)
>  
>  /* ------------------------------------------------------------------- */
>  /* static data                                                         */
>  
>  #define FORMAT_FLAGS_PACKED       0x01
> -
>  static struct cx23885_fmt formats[] = {
>  	{
> -		.name     = "8 bpp, gray",
> -		.fourcc   = V4L2_PIX_FMT_GREY,
> -		.depth    = 8,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
> -		.name     = "15 bpp RGB, le",
> -		.fourcc   = V4L2_PIX_FMT_RGB555,
> -		.depth    = 16,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
> -		.name     = "15 bpp RGB, be",
> -		.fourcc   = V4L2_PIX_FMT_RGB555X,
> -		.depth    = 16,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
> -		.name     = "16 bpp RGB, le",
> -		.fourcc   = V4L2_PIX_FMT_RGB565,
> -		.depth    = 16,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
> -		.name     = "16 bpp RGB, be",
> -		.fourcc   = V4L2_PIX_FMT_RGB565X,
> -		.depth    = 16,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
> -		.name     = "24 bpp RGB, le",
> -		.fourcc   = V4L2_PIX_FMT_BGR24,
> -		.depth    = 24,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
> -		.name     = "32 bpp RGB, le",
> -		.fourcc   = V4L2_PIX_FMT_BGR32,
> -		.depth    = 32,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
> -		.name     = "32 bpp RGB, be",
> -		.fourcc   = V4L2_PIX_FMT_RGB32,
> -		.depth    = 32,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
>  		.name     = "4:2:2, packed, YUYV",
>  		.fourcc   = V4L2_PIX_FMT_YUYV,
>  		.depth    = 16,
>  		.flags    = FORMAT_FLAGS_PACKED,
> -	}, {
> -		.name     = "4:2:2, packed, UYVY",
> -		.fourcc   = V4L2_PIX_FMT_UYVY,
> -		.depth    = 16,
> -		.flags    = FORMAT_FLAGS_PACKED,
> -	},
> +	}

Hmm... why did you remove the other standards? This looks like a regression to me.

>  };
>  
>  static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc)
> @@ -140,7 +96,12 @@ static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc)
>  		if (formats[i].fourcc == fourcc)
>  			return formats+i;
>  
> -	printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
> +	printk(KERN_ERR "%s(%c%c%c%c) NOT FOUND\n", __func__,
> +		(fourcc & 0xff),
> +		((fourcc >> 8) & 0xff),
> +		((fourcc >> 16) & 0xff),
> +		((fourcc >> 24) & 0xff)
> +		);
>  	return NULL;
>  }
>  
> @@ -172,7 +133,7 @@ static struct cx23885_ctrl cx23885_ctls[] = {
>  			.id            = V4L2_CID_CONTRAST,
>  			.name          = "Contrast",
>  			.minimum       = 0,
> -			.maximum       = 0xff,
> +			.maximum       = 0x7f,
>  			.step          = 1,
>  			.default_value = 0x3f,
>  			.type          = V4L2_CTRL_TYPE_INTEGER,
> @@ -185,10 +146,10 @@ static struct cx23885_ctrl cx23885_ctls[] = {
>  		.v = {
>  			.id            = V4L2_CID_HUE,
>  			.name          = "Hue",
> -			.minimum       = 0,
> -			.maximum       = 0xff,
> +			.minimum       = -127,
> +			.maximum       = 128,
>  			.step          = 1,
> -			.default_value = 0x7f,
> +			.default_value = 0x0,
>  			.type          = V4L2_CTRL_TYPE_INTEGER,
>  		},
>  		.off                   = 128,
> @@ -203,9 +164,9 @@ static struct cx23885_ctrl cx23885_ctls[] = {
>  			.id            = V4L2_CID_SATURATION,
>  			.name          = "Saturation",
>  			.minimum       = 0,
> -			.maximum       = 0xff,
> +			.maximum       = 0x7f,
>  			.step          = 1,
> -			.default_value = 0x7f,
> +			.default_value = 0x3f,
>  			.type          = V4L2_CTRL_TYPE_INTEGER,
>  		},
>  		.off                   = 0,
> @@ -259,8 +220,8 @@ static const u32 *ctrl_classes[] = {
>  	NULL
>  };
>  
> -static void cx23885_video_wakeup(struct cx23885_dev *dev,
> -		 struct cx23885_dmaqueue *q, u32 count)
> +void cx23885_video_wakeup(struct cx23885_dev *dev,
> +	struct cx23885_dmaqueue *q, u32 count)
>  {
>  	struct cx23885_buffer *buf;
>  	int bc;
> @@ -394,6 +355,71 @@ static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
>  	mutex_unlock(&dev->lock);
>  }
>  
> +static int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data)
> +{
> +	/* 8 bit registers, 8 bit values */
> +	u8 buf[] = { reg, data };
> +
> +	struct i2c_msg msg = { .addr = 0x98 >> 1,
> +		.flags = 0, .buf = buf, .len = 2 };
> +
> +	return i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg, 1);
> +}
> +
> +static u8 cx23885_flatiron_read(struct cx23885_dev *dev, u8 reg)
> +{
> +	/* 8 bit registers, 8 bit values */
> +	int ret;
> +	u8 b0[] = { reg };
> +	u8 b1[] = { 0 };
> +
> +	struct i2c_msg msg[] = {
> +		{ .addr = 0x98 >> 1, .flags = 0, .buf = b0, .len = 1 },
> +		{ .addr = 0x98 >> 1, .flags = I2C_M_RD, .buf = b1, .len = 1 }
> +	};
> +
> +	ret = i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg[0], 2);
> +	if (ret != 2)
> +		printk(KERN_ERR "%s() error\n", __func__);
> +
> +	return b1[0];
> +}
> +
> +static void cx23885_flatiron_dump(struct cx23885_dev *dev)
> +{
> +	int i;
> +	dprintk(1, "Flatiron dump\n");
> +	for (i = 0; i < 0x24; i++) {
> +		dprintk(1, "FI[%02x] = %02x\n", i,
> +			cx23885_flatiron_read(dev, i));
> +	}
> +}
> +
> +static int cx23885_flatiron_mux(struct cx23885_dev *dev, int input)
> +{
> +	u8 val;
> +	dprintk(1, "%s(input = %d)\n", __func__, input);
> +
> +	if (input == 1)
> +		val = cx23885_flatiron_read(dev, CH_PWR_CTRL1) & ~FLD_CH_SEL;
> +	else if (input == 2)
> +		val = cx23885_flatiron_read(dev, CH_PWR_CTRL1) | FLD_CH_SEL;
> +	else
> +		return -EINVAL;
> +
> +	val |= 0x20; /* Enable clock to delta-sigma and dec filter */
> +
> +	cx23885_flatiron_write(dev, CH_PWR_CTRL1, val);
> +
> +	/* Wake up */
> +	cx23885_flatiron_write(dev, CH_PWR_CTRL2, 0);
> +
> +	if (video_debug)
> +		cx23885_flatiron_dump(dev);
> +
> +	return 0;
> +}
> +
>  static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
>  {
>  	dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
> @@ -414,27 +440,59 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
>  	v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
>  			INPUT(input)->vmux, 0, 0);
>  
> +	if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) ||
> +		(dev->board == CX23885_BOARD_MPX885)) {
> +		/* Configure audio routing */
> +		v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
> +			INPUT(input)->amux, 0, 0);
> +
> +		if (INPUT(input)->amux == CX25840_AUDIO7)
> +			cx23885_flatiron_mux(dev, 1);
> +		else if (INPUT(input)->amux == CX25840_AUDIO6)
> +			cx23885_flatiron_mux(dev, 2);
> +	}
> +
>  	return 0;
>  }
>  
> -/* ------------------------------------------------------------------ */
> -static int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width,
> -	unsigned int height, enum v4l2_field field)
> +static int cx23885_audio_mux(struct cx23885_dev *dev, unsigned int input)
>  {
> -	dprintk(1, "%s()\n", __func__);
> +	dprintk(1, "%s(input=%d)\n", __func__, input);
> +
> +	/* The baseband video core of the cx23885 has two audio inputs.
> +	 * LR1 and LR2. In almost every single case so far only HVR1xxx
> +	 * cards we've only ever supported LR1. Time to support LR2,
> +	 * which is available via the optional white breakout header on
> +	 * the board.
> +	 * We'll use a could of existing enums in the card struct to allow
> +	 * devs to specify which baseband input they need, or just default
> +	 * to what we've always used.
> +	 */
> +	if (INPUT(input)->amux == CX25840_AUDIO7)
> +		cx23885_flatiron_mux(dev, 1);
> +	else if (INPUT(input)->amux == CX25840_AUDIO6)
> +		cx23885_flatiron_mux(dev, 2);
> +	else {
> +		/* Not specifically defined, assume the default. */
> +		cx23885_flatiron_mux(dev, 1);
> +	}
> +
>  	return 0;
>  }
>  
> +/* ------------------------------------------------------------------ */
>  static int cx23885_start_video_dma(struct cx23885_dev *dev,
>  			   struct cx23885_dmaqueue *q,
>  			   struct cx23885_buffer *buf)
>  {
>  	dprintk(1, "%s()\n", __func__);
>  
> +	/* Stop the dma/fifo before we tamper with it's risc programs */
> +	cx_clear(VID_A_DMA_CTL, 0x11);
> +
>  	/* setup fifo + format */
>  	cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01],
>  				buf->bpl, buf->risc.dma);
> -	cx23885_set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field);
>  
>  	/* reset counter */
>  	cx_write(VID_A_GPCNT_CTL, 3);
> @@ -751,7 +809,7 @@ static int video_open(struct file *file)
>  	fh->type     = type;
>  	fh->width    = 320;
>  	fh->height   = 240;
> -	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
> +	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_YUYV);
>  
>  	videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops,
>  			    &dev->pci->dev, &dev->slock,
> @@ -760,6 +818,14 @@ static int video_open(struct file *file)
>  			    sizeof(struct cx23885_buffer),
>  			    fh);
>  
> +	videobuf_queue_sg_init(&fh->vbiq, &cx23885_vbi_qops,
> +		&dev->pci->dev, &dev->slock,
> +		V4L2_BUF_TYPE_VBI_CAPTURE,
> +		V4L2_FIELD_SEQ_TB,
> +		sizeof(struct cx23885_buffer),
> +		fh);
> +
> +
>  	dprintk(1, "post videobuf_queue_init()\n");
>  
>  	unlock_kernel();
> @@ -857,6 +923,8 @@ static int video_release(struct file *file)
>  	}
>  
>  	videobuf_mmap_free(&fh->vidq);
> +	videobuf_mmap_free(&fh->vbiq);
> +
>  	file->private_data = NULL;
>  	kfree(fh);
>  
> @@ -889,8 +957,9 @@ static int cx23885_get_control(struct cx23885_dev *dev,
>  static int cx23885_set_control(struct cx23885_dev *dev,
>  	struct v4l2_control *ctl)
>  {
> -	dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)"
> -		" (disabled - no action)\n", __func__);
> +	dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)\n", __func__);
> +	call_all(dev, core, s_ctrl, ctl);
> +
>  	return 0;
>  }
>  
> @@ -1094,13 +1163,22 @@ static int vidioc_streamon(struct file *file, void *priv,
>  	struct cx23885_dev *dev = fh->dev;
>  	dprintk(1, "%s()\n", __func__);
>  
> -	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
> +	if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
> +		(fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
>  		return -EINVAL;
>  	if (unlikely(i != fh->type))
>  		return -EINVAL;
>  
>  	if (unlikely(!res_get(dev, fh, get_resource(fh))))
>  		return -EBUSY;
> +
> +	/* Don't start VBI streaming unless vida streaming
> +	 * has already started.
> +	 */
> +	if ((fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) &&
> +		((cx_read(VID_A_DMA_CTL) & 0x11) == 0))
> +		return -EINVAL;
> +
>  	return videobuf_streamon(get_queue(fh));
>  }
>  
> @@ -1111,7 +1189,8 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
>  	int err, res;
>  	dprintk(1, "%s()\n", __func__);
>  
> -	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> +	if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
> +		(fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
>  		return -EINVAL;
>  	if (i != fh->type)
>  		return -EINVAL;
> @@ -1154,7 +1233,7 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
>  	dprintk(1, "%s()\n", __func__);
>  
>  	n = i->index;
> -	if (n >= 4)
> +	if (n >= MAX_CX23885_INPUT)
>  		return -EINVAL;
>  
>  	if (0 == INPUT(n)->type)
> @@ -1168,6 +1247,11 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
>  		(CX23885_VMUX_CABLE == INPUT(n)->type))
>  		i->type = V4L2_INPUT_TYPE_TUNER;
>  		i->std = CX23885_NORMS;
> +
> +	/* Two selectable audio inputs for non-tv inputs */
> +	if (INPUT(n)->type != CX23885_VMUX_TELEVISION)
> +		i->audioset = 0x3;
> +
>  	return 0;
>  }
>  
> @@ -1194,13 +1278,20 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
>  
>  	dprintk(1, "%s(%d)\n", __func__, i);
>  
> -	if (i >= 4) {
> +	if (i >= MAX_CX23885_INPUT) {
>  		dprintk(1, "%s() -EINVAL\n", __func__);
>  		return -EINVAL;
>  	}
>  
> +	if (INPUT(i)->type == 0)
> +		return -EINVAL;
> +
>  	mutex_lock(&dev->lock);
>  	cx23885_video_mux(dev, i);
> +
> +	/* By default establish the default audio input for the card also */
> +	/* Caller is free to use VIDIOC_S_AUDIO to override afterwards */
> +	cx23885_audio_mux(dev, i);
>  	mutex_unlock(&dev->lock);
>  	return 0;
>  }
> @@ -1220,6 +1311,64 @@ static int vidioc_log_status(struct file *file, void *priv)
>  	return 0;
>  }
>  
> +static int cx23885_query_audinput(struct file *file, void *priv,
> +	struct v4l2_audio *i)
> +{
> +	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
> +	static const char *iname[] = {
> +		[0] = "Baseband L/R 1",
> +		[1] = "Baseband L/R 2",
> +	};
> +	unsigned int n;
> +	dprintk(1, "%s()\n", __func__);
> +
> +	n = i->index;
> +	if (n >= 2)
> +		return -EINVAL;
> +
> +	memset(i, 0, sizeof(*i));
> +	i->index = n;
> +	strcpy(i->name, iname[n]);
> +	i->capability  = V4L2_AUDCAP_STEREO;
> +	i->mode  = V4L2_AUDMODE_AVL;
> +	return 0;
> +
> +}
> +
> +static int vidioc_enum_audinput(struct file *file, void *priv,
> +				struct v4l2_audio *i)
> +{
> +	return cx23885_query_audinput(file, priv, i);
> +}
> +
> +static int vidioc_g_audinput(struct file *file, void *priv,
> +	struct v4l2_audio *i)
> +{
> +	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
> +
> +	i->index = dev->audinput;
> +	dprintk(1, "%s(input=%d)\n", __func__, i->index);
> +
> +	return cx23885_query_audinput(file, priv, i);
> +}
> +
> +static int vidioc_s_audinput(struct file *file, void *priv,
> +	struct v4l2_audio *i)
> +{
> +	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
> +	if (i->index >= 2)
> +		return -EINVAL;
> +
> +	dprintk(1, "%s(%d)\n", __func__, i->index);
> +
> +	dev->audinput = i->index;
> +
> +	/* Skip the audio defaults from the cards struct, caller wants
> +	 * directly touch the audio mux hardware. */
> +	cx23885_flatiron_mux(dev, dev->audinput + 1);
> +	return 0;
> +}
> +
>  static int vidioc_queryctrl(struct file *file, void *priv,
>  				struct v4l2_queryctrl *qctrl)
>  {
> @@ -1255,11 +1404,11 @@ static int vidioc_g_tuner(struct file *file, void *priv,
>  	if (0 != t->index)
>  		return -EINVAL;
>  
> +	memset(t, 0, sizeof(*t));

There's no need. video_ioctl2 should already cleanup the return parameters.

>  	strcpy(t->name, "Television");
> -	t->type       = V4L2_TUNER_ANALOG_TV;
> -	t->capability = V4L2_TUNER_CAP_NORM;
> -	t->rangehigh  = 0xffffffffUL;
> -	t->signal = 0xffff ; /* LOCKED */
> +
> +	call_all(dev, tuner, g_tuner, t);
> +
>  	return 0;
>  }
>  
> @@ -1272,6 +1421,9 @@ static int vidioc_s_tuner(struct file *file, void *priv,
>  		return -EINVAL;
>  	if (0 != t->index)
>  		return -EINVAL;
> +	/* Update the A/V core */
> +	call_all(dev, tuner, s_tuner, t);
> +
>  	return 0;
>  }
>  
> @@ -1295,18 +1447,30 @@ static int vidioc_g_frequency(struct file *file, void *priv,
>  
>  static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
>  {
> +	struct v4l2_control ctrl;
> +
>  	if (unlikely(UNSET == dev->tuner_type))
>  		return -EINVAL;
>  	if (unlikely(f->tuner != 0))
>  		return -EINVAL;
>  
> +
>  	mutex_lock(&dev->lock);
>  	dev->freq = f->frequency;
>  
> +	/* I need to mute audio here */
> +	ctrl.id = V4L2_CID_AUDIO_MUTE;
> +	ctrl.value = 1;
> +	cx23885_set_control(dev, &ctrl);
> +
>  	call_all(dev, tuner, s_frequency, f);
>  
>  	/* When changing channels it is required to reset TVAUDIO */
> -	msleep(10);
> +	msleep(100);
> +
> +	/* I need to unmute audio here */
> +	ctrl.value = 0;
> +	cx23885_set_control(dev, &ctrl);
>  
>  	mutex_unlock(&dev->lock);
>  
> @@ -1337,9 +1501,7 @@ static void cx23885_vid_timeout(unsigned long data)
>  	struct cx23885_buffer *buf;
>  	unsigned long flags;
>  
> -	cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]);
> -
> -	cx_clear(VID_A_DMA_CTL, 0x11);
> +	dprintk(1, "%s()\n", __func__);
>  
>  	spin_lock_irqsave(&dev->slock, flags);
>  	while (!list_empty(&q->active)) {
> @@ -1348,7 +1510,7 @@ static void cx23885_vid_timeout(unsigned long data)
>  		list_del(&buf->vb.queue);
>  		buf->vb.state = VIDEOBUF_ERROR;
>  		wake_up(&buf->vb.done);
> -		printk(KERN_ERR "%s/0: [%p/%d] timeout - dma=0x%08lx\n",
> +		printk(KERN_ERR "%s: [%p/%d] timeout - dma=0x%08lx\n",
>  			dev->name, buf, buf->vb.i,
>  			(unsigned long)buf->risc.dma);
>  	}
> @@ -1361,30 +1523,46 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
>  	u32 mask, count;
>  	int handled = 0;
>  
> -	mask   = cx_read(VID_A_INT_MSK);
> +	mask = cx_read(VID_A_INT_MSK);
>  	if (0 == (status & mask))
>  		return handled;
> +
>  	cx_write(VID_A_INT_STAT, status);
>  
> -	dprintk(2, "%s() status = 0x%08x\n", __func__, status);
> -	/* risc op code error */
> -	if (status & (1 << 16)) {
> -		printk(KERN_WARNING "%s/0: video risc op code error\n",
> -			dev->name);
> -		cx_clear(VID_A_DMA_CTL, 0x11);
> -		cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]);
> +	/* risc op code error, fifo overflow or line sync detection error */
> +	if ((status & VID_BC_MSK_OPC_ERR) ||
> +		(status & VID_BC_MSK_SYNC) ||
> +		(status & VID_BC_MSK_OF)) {
> +
> +		if (status & VID_BC_MSK_OPC_ERR) {
> +			dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n",
> +				VID_BC_MSK_OPC_ERR);
> +			printk(KERN_WARNING "%s: video risc op code error\n",
> +				dev->name);
> +			cx23885_sram_channel_dump(dev,
> +				&dev->sram_channels[SRAM_CH01]);
> +		}
> +
> +		if (status & VID_BC_MSK_SYNC)
> +			dprintk(7, " (VID_BC_MSK_SYNC 0x%08x) "
> +				"video lines miss-match\n",
> +				VID_BC_MSK_SYNC);
> +
> +		if (status & VID_BC_MSK_OF)
> +			dprintk(7, " (VID_BC_MSK_OF 0x%08x) fifo overflow\n",
> +				VID_BC_MSK_OF);
> +
>  	}
>  
> -	/* risc1 y */
> -	if (status & 0x01) {
> +	/* Video */
> +	if (status & VID_BC_MSK_RISCI1) {
>  		spin_lock(&dev->slock);
>  		count = cx_read(VID_A_GPCNT);
>  		cx23885_video_wakeup(dev, &dev->vidq, count);
>  		spin_unlock(&dev->slock);
>  		handled++;
>  	}
> -	/* risc2 y */
> -	if (status & 0x10) {
> +	if (status & VID_BC_MSK_RISCI2) {
>  		dprintk(2, "stopper video\n");
>  		spin_lock(&dev->slock);
>  		cx23885_restart_video_queue(dev, &dev->vidq);
> @@ -1392,6 +1570,9 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
>  		handled++;
>  	}
>  
> +	/* Allow the VBI framework to process it's payload */
> +	handled += cx23885_vbi_irq(dev, status);
> +
>  	return handled;
>  }
>  
> @@ -1443,6 +1624,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
>  	.vidioc_g_register    = cx23885_g_register,
>  	.vidioc_s_register    = cx23885_s_register,
>  #endif
> +	.vidioc_enumaudio     = vidioc_enum_audinput,
> +	.vidioc_g_audio       = vidioc_g_audinput,
> +	.vidioc_s_audio       = vidioc_s_audinput,
>  };
>  
>  static struct video_device cx23885_vbi_template;
> @@ -1467,6 +1651,14 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
>  	dprintk(1, "%s()\n", __func__);
>  	cx23885_irq_remove(dev, 0x01);
>  
> +	if (dev->vbi_dev) {
> +		if (video_is_registered(dev->vbi_dev))
> +			video_unregister_device(dev->vbi_dev);
> +		else
> +			video_device_release(dev->vbi_dev);
> +		dev->vbi_dev = NULL;
> +		btcx_riscmem_free(dev->pci, &dev->vbiq.stopper);
> +	}
>  	if (dev->video_dev) {
>  		if (video_is_registered(dev->video_dev))
>  			video_unregister_device(dev->video_dev);
> @@ -1476,6 +1668,9 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
>  
>  		btcx_riscmem_free(dev->pci, &dev->vidq.stopper);
>  	}
> +
> +	if (dev->audio_dev)
> +		cx23885_audio_unregister(dev);
>  }
>  
>  int cx23885_video_register(struct cx23885_dev *dev)
> @@ -1502,6 +1697,13 @@ int cx23885_video_register(struct cx23885_dev *dev)
>  		VID_A_DMA_CTL, 0x11, 0x00);
>  
>  	/* Don't enable VBI yet */
> +	INIT_LIST_HEAD(&dev->vbiq.active);
> +	INIT_LIST_HEAD(&dev->vbiq.queued);
> +	dev->vbiq.timeout.function = cx23885_vbi_timeout;
> +	dev->vbiq.timeout.data = (unsigned long)dev;
> +	init_timer(&dev->vbiq.timeout);
> +	cx23885_risc_stopper(dev->pci, &dev->vbiq.stopper,
> +		VID_A_DMA_CTL, 0x22, 0x00);
>  
>  	cx23885_irq_add_enable(dev, 0x01);
>  
> @@ -1515,7 +1717,8 @@ int cx23885_video_register(struct cx23885_dev *dev)
>  		else
>  			sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
>  				&dev->i2c_bus[1].i2c_adap,
> -				"tuner", "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
> +				"tuner", "tuner", 0,
> +				v4l2_i2c_tuner_addrs(ADDRS_TV));
>  		if (sd) {
>  			struct tuner_setup tun_setup;
>  
> @@ -1527,7 +1730,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) {
>  				struct xc2028_ctrl ctrl = {
>  					.fname = XC2028_DEFAULT_FIRMWARE,
>  					.max_len = 64
> @@ -1541,8 +1745,7 @@ int cx23885_video_register(struct cx23885_dev *dev)
>  		}
>  	}
>  
> -
> -	/* register v4l devices */
> +	/* register Video device */
>  	dev->video_dev = cx23885_vdev_init(dev, dev->pci,
>  		&cx23885_video_template, "video");
>  	err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,
> @@ -1552,13 +1755,32 @@ int cx23885_video_register(struct cx23885_dev *dev)
>  			dev->name);
>  		goto fail_unreg;
>  	}
> -	printk(KERN_INFO "%s/0: registered device %s [v4l2]\n",
> +	printk(KERN_INFO "%s: registered device %s [v4l2]\n",
>  	       dev->name, video_device_node_name(dev->video_dev));
> +
> +	/* register VBI device */
> +	dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
> +		&cx23885_vbi_template, "vbi");
> +	err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
> +				    vbi_nr[dev->nr]);
> +	if (err < 0) {
> +		printk(KERN_INFO "%s: can't register vbi device\n",
> +			dev->name);
> +		goto fail_unreg;
> +	}
> +	printk(KERN_INFO "%s: registered device %s\n",
> +	       dev->name, video_device_node_name(dev->vbi_dev));
> +
> +
> +	/* Register ALSA audio device */
> +	dev->audio_dev = cx23885_audio_register(dev);
> +
>  	/* initial device configuration */
>  	mutex_lock(&dev->lock);
>  	cx23885_set_tvnorm(dev, dev->tvnorm);
>  	init_controls(dev);
>  	cx23885_video_mux(dev, 0);
> +	cx23885_audio_mux(dev, 0);
>  	mutex_unlock(&dev->lock);
>  
>  	return 0;
> diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
> index ed94b17..d3468d6 100644
> --- a/drivers/media/video/cx23885/cx23885.h
> +++ b/drivers/media/video/cx23885/cx23885.h
> @@ -84,6 +84,7 @@
>  #define CX23885_BOARD_HAUPPAUGE_HVR1290        26
>  #define CX23885_BOARD_MYGICA_X8558PRO          27
>  #define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
> +#define CX23885_BOARD_MPX885                   29
>  
>  #define GPIO_0 0x00000001
>  #define GPIO_1 0x00000002
> @@ -190,6 +191,7 @@ struct cx23885_buffer {
>  struct cx23885_input {
>  	enum cx23885_itype type;
>  	unsigned int    vmux;
> +	unsigned int    amux;
>  	u32             gpio0, gpio1, gpio2, gpio3;
>  };
>  
> @@ -314,6 +316,28 @@ struct cx23885_kernel_ir {
>  	struct ir_dev_props	props;
>  };
>  
> +struct cx23885_audio_dev {
> +	struct cx23885_dev	*dev;
> +
> +	struct pci_dev		*pci;
> +
> +	struct snd_card		*card;
> +
> +	spinlock_t		lock;
> +
> +	atomic_t                count;
> +
> +	unsigned int		dma_size;
> +	unsigned int		period_size;
> +	unsigned int		num_periods;
> +
> +	struct videobuf_dmabuf	*dma_risc;
> +
> +	struct cx23885_buffer	*buf;
> +
> +	struct snd_pcm_substream *substream;
> +};
> +
>  struct cx23885_dev {
>  	atomic_t                   refcount;
>  	struct v4l2_device 	   v4l2_dev;
> @@ -358,6 +382,7 @@ struct cx23885_dev {
>  	/* Analog video */
>  	u32                        resources;
>  	unsigned int               input;
> +	unsigned int               audinput; /* Selectable audio input */
>  	u32                        tvaudio;
>  	v4l2_std_id                tvnorm;
>  	unsigned int               tuner_type;
> @@ -395,6 +420,9 @@ struct cx23885_dev {
>  	atomic_t                   v4l_reader_count;
>  	struct cx23885_tvnorm      encodernorm;
>  
> +	/* Analog raw audio */
> +	struct cx23885_audio_dev   *audio_dev;
> +
>  };
>  
>  static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
> @@ -473,6 +501,12 @@ extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  	unsigned int top_offset, unsigned int bottom_offset,
>  	unsigned int bpl, unsigned int padding, unsigned int lines);
>  
> +extern int cx23885_risc_vbibuffer(struct pci_dev *pci,
> +	struct btcx_riscmem *risc,
> +	struct scatterlist *sglist,
> +	unsigned int top_offset, unsigned int bottom_offset,
> +	unsigned int bpl, unsigned int padding, unsigned int lines);
> +
>  void cx23885_cancel_buffers(struct cx23885_tsport *port);
>  
>  extern int cx23885_restart_queue(struct cx23885_tsport *port,
> @@ -528,6 +562,8 @@ extern void cx23885_free_buffer(struct videobuf_queue *q,
>  extern int cx23885_video_register(struct cx23885_dev *dev);
>  extern void cx23885_video_unregister(struct cx23885_dev *dev);
>  extern int cx23885_video_irq(struct cx23885_dev *dev, u32 status);
> +extern void cx23885_video_wakeup(struct cx23885_dev *dev,
> +	struct cx23885_dmaqueue *q, u32 count);
>  
>  /* ----------------------------------------------------------- */
>  /* cx23885-vbi.c                                               */
> @@ -535,6 +571,9 @@ extern int cx23885_vbi_fmt(struct file *file, void *priv,
>  	struct v4l2_format *f);
>  extern void cx23885_vbi_timeout(unsigned long data);
>  extern struct videobuf_queue_ops cx23885_vbi_qops;
> +extern int cx23885_restart_vbi_queue(struct cx23885_dev *dev,
> +	struct cx23885_dmaqueue *q);
> +extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status);
>  
>  /* cx23885-i2c.c                                                */
>  extern int cx23885_i2c_register(struct cx23885_i2c *bus);
> @@ -558,6 +597,18 @@ extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
>  extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
>  extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
>  
> +/* ----------------------------------------------------------- */
> +/* cx23885-alsa.c                                             */
> +extern struct cx23885_audio_dev *cx23885_audio_register(
> +	struct cx23885_dev *dev);
> +extern void cx23885_audio_unregister(struct cx23885_dev *dev);
> +extern int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask);
> +extern int cx23885_risc_databuffer(struct pci_dev *pci,
> +				   struct btcx_riscmem *risc,
> +				   struct scatterlist *sglist,
> +				   unsigned int bpl,
> +				   unsigned int lines,
> +				   unsigned int lpi);
>  
>  /* ----------------------------------------------------------- */
>  /* tv norms                                                    */
> diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
> index 45608d5..e25c012 100644
> --- a/drivers/media/video/cx25840/cx25840-audio.c
> +++ b/drivers/media/video/cx25840/cx25840-audio.c
> @@ -514,7 +514,14 @@ static void set_volume(struct i2c_client *client, int volume)
>  	}
>  
>  	/* PATH1_VOLUME */
> -	cx25840_write(client, 0x8d4, 228 - (vol * 2));
> +	if (is_cx2388x(state)) {
> +		/* for cx23885 volume doesn't work,
> +		 * the calculation always results in
> +		 * e4 regardless.
> +		 */
> +		cx25840_write(client, 0x8d4, volume);
> +	} else
> +		cx25840_write(client, 0x8d4, 228 - (vol * 2));
>  }
>  

If I understood well, from Andy's comments, the 228 - (vol * 2) formula is only there to make
ivtv driver happy. If ivtv expects a different scale for whatever reason, the scale logic
should be at ivtv, and not at cx25840.


>  static int get_bass(struct i2c_client *client)
> diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
> index 9fab0b1..eca8656 100644
> --- a/drivers/media/video/cx25840/cx25840-core.c
> +++ b/drivers/media/video/cx25840/cx25840-core.c
> @@ -703,6 +703,13 @@ static void cx231xx_initialize(struct i2c_client *client)
>  
>  	/* start microcontroller */
>  	cx25840_and_or(client, 0x803, ~0x10, 0x10);
> +
> +	/* CC raw enable */
> +	cx25840_write(client, 0x404, 0x0b);
> +
> +	/* CC on */
> +	cx25840_write(client, 0x42f, 0x66);
> +	cx25840_write4(client, 0x474, 0x1e1e601a);
>  }
>  
>  /* ----------------------------------------------------------------------- */
> @@ -1065,6 +1072,18 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
>  		cx25840_write(client, 0x919, 0x01);
>  	}
>  
> +	if (is_cx2388x(state) && ((aud_input == CX25840_AUDIO7) ||
> +		(aud_input == CX25840_AUDIO6))) {
> +		/* Configure audio from LR1 or LR2 input */
> +		cx25840_write4(client, 0x910, 0);
> +		cx25840_write4(client, 0x8d0, 0x63073);
> +	} else
> +	if (is_cx2388x(state) && (aud_input == CX25840_AUDIO8)) {
> +		/* Configure audio from tuner/sif input */
> +		cx25840_write4(client, 0x910, 0x12b000c9);
> +		cx25840_write4(client, 0x8d0, 0x1f063870);
> +	}
> +
>  	return 0;
>  }
>  

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


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