From 12d5d5907229c21d604c49091d380756a4226593 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 27 Jun 2008 23:48:18 -0400 Subject: cx23885: Bugfix for concurrent use of /dev/video0 and /dev/video1 From: Steven Toth With the HVR1800, trying to use video0 and video1 simultaneously caused buffer corruption in the PCIe bridge. This fix reallocates video1 buffer locations to avoid the issue. Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index a1902d59e..94070ebbf 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -105,8 +105,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH03] = { .name = "TS1 B", .cmds_start = 0x100A0, - .ctrl_start = 0x10780, - .cdt = 0x10400, + .ctrl_start = 0x10670, + .cdt = 0x10810, .fifo_start = 0x5000, .fifo_size = 0x1000, .ptr1_reg = DMA3_PTR1, -- cgit v1.2.3 From de1a48f03fb92ffdc82696c4c733ab095f2cda00 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 27 Jun 2008 23:52:45 -0400 Subject: cx23885: Ensure PAD_CTRL is always reset to a sensible default From: Steven Toth PAD_CTRL controls TS1 and TS2 input and output states, if the register became corrupt the driver was never able to recover. Signed-off-by: Steven Toth Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 94070ebbf..3f5571ee6 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -461,6 +461,7 @@ static void cx23885_reset(struct cx23885_dev *dev) cx_write(AUDIO_INT_INT_STAT, 0xffffffff); cx_write(AUDIO_EXT_INT_STAT, 0xffffffff); cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); + cx_write(PAD_CTRL, 0x00500300); mdelay(100); -- cgit v1.2.3 From 53eff196a31c492f2635343c8d0389145125fc67 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 27 Jun 2008 23:58:35 -0400 Subject: cx23885: Bugfix - DVB Transport cards using DVB port VIDB/TS1 did not stream. From: Steven Toth Certain DVB cards that have demodulators on TS1/VIDB were not streaming packets. This ensure the pin directions on PAD_CTRL are set correctly, solving the issue. Signed-off-by: Steven Toth Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-core.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 3f5571ee6..41e927ff9 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -1085,7 +1085,21 @@ static int cx23885_start_dma(struct cx23885_tsport *port, cx_write(port->reg_gpcnt_ctl, 3); q->count = 1; - if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { + /* Set VIDB pins to input */ + if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { + reg = cx_read(PAD_CTRL); + reg &= ~0x3; /* Clear TS1_OE & TS1_SOP_OE */ + cx_write(PAD_CTRL, reg); + } + + /* Set VIDC pins to input */ + if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { + reg = cx_read(PAD_CTRL); + reg &= ~0x4; /* Clear TS2_SOP_OE */ + cx_write(PAD_CTRL, reg); + } + + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { reg = cx_read(PAD_CTRL); reg = reg & ~0x1; /* Clear TS1_OE */ @@ -1135,7 +1149,7 @@ static int cx23885_stop_dma(struct cx23885_tsport *port) cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { reg = cx_read(PAD_CTRL); -- cgit v1.2.3 From a14a52dcbc9e8093154f6309a9ea98221e9db948 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 30 Jun 2008 19:54:34 -0400 Subject: cx23885: Minor cleanup to the debuging output for a specific register. From: Steven Toth Don't display the register when it's not appropriate for the specific port. Signed-off-by: Steven Toth Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 41e927ff9..7789649f8 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -1012,8 +1012,9 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__, port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); - dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, - port->reg_src_sel, cx_read(port->reg_src_sel)); + if (port->reg_src_sel) + dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, + port->reg_src_sel, cx_read(port->reg_src_sel)); dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__, port->reg_lngth, cx_read(port->reg_lngth)); dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__, -- cgit v1.2.3 From e4b4beeee4577a06e48f44169a3b4617a62391e0 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 30 Jun 2008 19:58:38 -0400 Subject: cx23885: Ensure the second transport port is enabled for streaming. From: Steven Toth It was previously disabled pending a bugfix, which has since been resolved. Signed-off-by: Steven Toth Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-cards.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index 7171e344a..476c33d29 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -146,9 +146,7 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = { .name = "DViCO FusionHDTV7 Dual Express", -#if 0 .portb = CX23885_MPEG_DVB, -#endif .portc = CX23885_MPEG_DVB, }, }; -- cgit v1.2.3 From bd1974db7aad57ce9931e4717afa1c5a7633a0d5 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 30 Jun 2008 20:23:50 -0400 Subject: cx23885: FusionHDTV7 Dual Express toggle reset. From: Steven Toth Ensure the tuners and demods are brought in and out of reset during driver startup. Signed-off-by: Steven Toth Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-cards.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index 476c33d29..ba69f2b9a 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -437,6 +437,19 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(20); cx_set(GP0_IO, 0x00050005); break; + case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + /* GPIO-0 xc5000 tuner reset i2c bus 0 */ + /* GPIO-1 s5h1409 demod reset i2c bus 0 */ + /* GPIO-2 xc5000 tuner reset i2c bus 1 */ + /* GPIO-3 s5h1409 demod reset i2c bus 0 */ + + /* Put the parts into reset and back */ + cx_set(GP0_IO, 0x000f0000); + mdelay(20); + cx_clear(GP0_IO, 0x0000000f); + mdelay(20); + cx_set(GP0_IO, 0x000f000f); + break; } } -- cgit v1.2.3 From bf0ba42500218953501a1bef8f3a1f5cc5237457 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 30 Jun 2008 21:17:05 -0400 Subject: cx23885: Add DViCO HDTV7 Dual Express tuner callback support. From: Steven Toth Ensure the correct tuner gets reset on demand. Signed-off-by: Steven Toth Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-cards.c | 40 ++++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index ba69f2b9a..ee01ff8bf 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -327,25 +327,41 @@ int cx23885_tuner_callback(void *priv, int command, int arg) { struct cx23885_i2c *bus = priv; struct cx23885_dev *dev = bus->dev; + u32 bitmask = 0; + + if (command != 0) { + printk(KERN_ERR "%s(): Unknown command 0x%x.\n", + __func__, command); + return -EINVAL; + } switch(dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - if(command == 0) { /* Tuner Reset Command from xc5000 */ - /* Drive the tuner into reset and out */ - cx_clear(GP0_IO, 0x00000004); - mdelay(200); - cx_set(GP0_IO, 0x00000004); - return 0; - } - else { - printk(KERN_ERR - "%s(): Unknow command.\n", __func__); - return -EINVAL; + /* Tuner Reset Command from xc5000 */ + if (command == 0) + bitmask = 0x04; + break; + case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + if (command == 0) { + + /* Two identical tuners on two different i2c buses, + * we need to reset the correct gpio. */ + if (bus->nr == 0) + bitmask = 0x01; + else if (bus->nr == 1) + bitmask = 0x04; } break; } - return 0; /* Should never be here */ + if (bitmask) { + /* Drive the tuner into reset and back out */ + cx_clear(GP0_IO, bitmask); + mdelay(200); + cx_set(GP0_IO, bitmask); + } + + return 0; } void cx23885_gpio_setup(struct cx23885_dev *dev) -- cgit v1.2.3 From 74da344e1653dc088e77c18c7608de0a8f1384bd Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 1 Jul 2008 09:43:27 -0400 Subject: cx23885: Reallocated the sram to avoid concurrent VIDB/C issues. From: Steven Toth This may be cx23885 chip specific and may not work on the cx23887. Analog and mpeg encoder streaming are still to be tested. Signed-off-by: Steven Toth Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 7789649f8..6b71eaf51 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -81,8 +81,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH01] = { .name = "VID A", .cmds_start = 0x10000, - .ctrl_start = 0x105b0, - .cdt = 0x107b0, + .ctrl_start = 0x10380, + .cdt = 0x104c0, .fifo_start = 0x40, .fifo_size = 0x2800, .ptr1_reg = DMA1_PTR1, @@ -105,8 +105,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH03] = { .name = "TS1 B", .cmds_start = 0x100A0, - .ctrl_start = 0x10670, - .cdt = 0x10810, + .ctrl_start = 0x10400, + .cdt = 0x10580, .fifo_start = 0x5000, .fifo_size = 0x1000, .ptr1_reg = DMA3_PTR1, @@ -141,8 +141,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH06] = { .name = "TS2 C", .cmds_start = 0x10140, - .ctrl_start = 0x10680, - .cdt = 0x108d0, + .ctrl_start = 0x10440, + .cdt = 0x105e0, .fifo_start = 0x6000, .fifo_size = 0x1000, .ptr1_reg = DMA5_PTR1, @@ -1045,6 +1045,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port, dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, buf->vb.width, buf->vb.height, buf->vb.field); + /* Stop the fifo and risc engine for this port */ + cx_clear(port->reg_dma_ctl, port->dma_ctl_val); + /* setup fifo + format */ cx23885_sram_channel_setup(dev, &dev->sram_channels[ port->sram_chno ], -- cgit v1.2.3 From 44fb701496d8cb2343f6b3339278778d3d752b84 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 1 Jul 2008 20:18:00 -0400 Subject: cx23885: SRAM changes for the 885 and 887 silicon parts. From: Steven Toth In a previous patch I merged both memory maps into a single struct, believing that they could be combined. We've since found problems with streaming multiple channels on the 885. I'm restoring the multiple memory map structs - in line with the windows driver. Signed-off-by: Steven Toth Signed-off-by: <> --- linux/drivers/media/video/cx23885/cx23885-core.c | 116 ++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 6b71eaf51..14e14f884 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -77,7 +77,7 @@ LIST_HEAD(cx23885_devlist); * 0x00010ea0 0x00010xxx Free */ -static struct sram_channel cx23887_sram_channels[] = { +static struct sram_channel cx23885_sram_channels[] = { [SRAM_CH01] = { .name = "VID A", .cmds_start = 0x10000, @@ -188,6 +188,117 @@ static struct sram_channel cx23887_sram_channels[] = { }, }; +static struct sram_channel cx23887_sram_channels[] = { + [SRAM_CH01] = { + .name = "VID A", + .cmds_start = 0x10000, + .ctrl_start = 0x105b0, + .cdt = 0x107b0, + .fifo_start = 0x40, + .fifo_size = 0x2800, + .ptr1_reg = DMA1_PTR1, + .ptr2_reg = DMA1_PTR2, + .cnt1_reg = DMA1_CNT1, + .cnt2_reg = DMA1_CNT2, + }, + [SRAM_CH02] = { + .name = "ch2", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA2_PTR1, + .ptr2_reg = DMA2_PTR2, + .cnt1_reg = DMA2_CNT1, + .cnt2_reg = DMA2_CNT2, + }, + [SRAM_CH03] = { + .name = "TS1 B", + .cmds_start = 0x100A0, + .ctrl_start = 0x10630, + .cdt = 0x10870, + .fifo_start = 0x5000, + .fifo_size = 0x1000, + .ptr1_reg = DMA3_PTR1, + .ptr2_reg = DMA3_PTR2, + .cnt1_reg = DMA3_CNT1, + .cnt2_reg = DMA3_CNT2, + }, + [SRAM_CH04] = { + .name = "ch4", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA4_PTR1, + .ptr2_reg = DMA4_PTR2, + .cnt1_reg = DMA4_CNT1, + .cnt2_reg = DMA4_CNT2, + }, + [SRAM_CH05] = { + .name = "ch5", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA5_PTR1, + .ptr2_reg = DMA5_PTR2, + .cnt1_reg = DMA5_CNT1, + .cnt2_reg = DMA5_CNT2, + }, + [SRAM_CH06] = { + .name = "TS2 C", + .cmds_start = 0x10140, + .ctrl_start = 0x10670, + .cdt = 0x108d0, + .fifo_start = 0x6000, + .fifo_size = 0x1000, + .ptr1_reg = DMA5_PTR1, + .ptr2_reg = DMA5_PTR2, + .cnt1_reg = DMA5_CNT1, + .cnt2_reg = DMA5_CNT2, + }, + [SRAM_CH07] = { + .name = "ch7", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA6_PTR1, + .ptr2_reg = DMA6_PTR2, + .cnt1_reg = DMA6_CNT1, + .cnt2_reg = DMA6_CNT2, + }, + [SRAM_CH08] = { + .name = "ch8", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA7_PTR1, + .ptr2_reg = DMA7_PTR2, + .cnt1_reg = DMA7_CNT1, + .cnt2_reg = DMA7_CNT2, + }, + [SRAM_CH09] = { + .name = "ch9", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA8_PTR1, + .ptr2_reg = DMA8_PTR2, + .cnt1_reg = DMA8_CNT1, + .cnt2_reg = DMA8_CNT2, + }, +}; + static int cx23885_risc_decode(u32 risc) { static char *instr[16] = { @@ -627,7 +738,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) atomic_inc(&dev->refcount); dev->nr = cx23885_devcount++; - dev->sram_channels = cx23887_sram_channels; sprintf(dev->name, "cx23885[%d]", dev->nr); mutex_lock(&devlist); @@ -639,11 +749,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->bridge = CX23885_BRIDGE_887; /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 25000000; + dev->sram_channels = cx23887_sram_channels; } else if(dev->pci->device == 0x8852) { dev->bridge = CX23885_BRIDGE_885; /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 28000000; + dev->sram_channels = cx23885_sram_channels; } else BUG(); -- cgit v1.2.3 From 2630aac5242db6717a663b0541d3191c516ddbeb Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 7 Jul 2008 17:20:58 -0400 Subject: add support for MaxLinear MxL5007T silicon tuner From: Michael Krufky Signed-off-by: Michael Krufky Signed-off-by: Asaf Fishov Signed-off-by: Charles Kim --- linux/drivers/media/common/tuners/Kconfig | 7 + linux/drivers/media/common/tuners/Makefile | 1 + linux/drivers/media/common/tuners/mxl5007t.c | 1039 ++++++++++++++++++++++++++ linux/drivers/media/common/tuners/mxl5007t.h | 105 +++ 4 files changed, 1152 insertions(+) create mode 100644 linux/drivers/media/common/tuners/mxl5007t.c create mode 100644 linux/drivers/media/common/tuners/mxl5007t.h (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/Kconfig b/linux/drivers/media/common/tuners/Kconfig index 850d5689b..8d93ba857 100644 --- a/linux/drivers/media/common/tuners/Kconfig +++ b/linux/drivers/media/common/tuners/Kconfig @@ -162,4 +162,11 @@ config MEDIA_TUNER_MXL5005S help A driver for the silicon tuner MXL5005S from MaxLinear. +config MEDIA_TUNER_MXL5007T + tristate "MaxLinear MxL5007T silicon tuner" + depends on VIDEO_MEDIA && I2C + default m if DVB_FE_CUSTOMISE + help + A driver for the silicon tuner MxL5007T from MaxLinear. + endif # MEDIA_TUNER_CUSTOMIZE diff --git a/linux/drivers/media/common/tuners/Makefile b/linux/drivers/media/common/tuners/Makefile index 55f7e6706..4dfbe5b82 100644 --- a/linux/drivers/media/common/tuners/Makefile +++ b/linux/drivers/media/common/tuners/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o +obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c new file mode 100644 index 000000000..82e77329d --- /dev/null +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -0,0 +1,1039 @@ +/* + * mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner + * + * Copyright (C) 2008 Michael Krufky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include "compat.h" +#include +#include "tuner-i2c.h" +#include "mxl5007t.h" + +static DEFINE_MUTEX(mxl5007t_list_mutex); +static LIST_HEAD(hybrid_tuner_instance_list); + +static int mxl5007t_debug; +module_param_named(debug, mxl5007t_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debug level"); + +/* ------------------------------------------------------------------------- */ + +#define mxl_printk(kern, fmt, arg...) \ + printk(kern "%s: " fmt "\n", __func__, ##arg) + +#define mxl_err(fmt, arg...) \ + mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg) + +#define mxl_warn(fmt, arg...) \ + mxl_printk(KERN_WARNING, fmt, ##arg) + +#define mxl_info(fmt, arg...) \ + mxl_printk(KERN_INFO, fmt, ##arg) + +#define mxl_debug(fmt, arg...) \ +({ \ + if (mxl5007t_debug) \ + mxl_printk(KERN_DEBUG, fmt, ##arg); \ +}) + +#define mxl_fail(ret) \ +({ \ + int __ret; \ + __ret = (ret < 0); \ + if (__ret) \ + mxl_printk(KERN_ERR, "error %d on line %d", \ + ret, __LINE__); \ + __ret; \ +}) + +/* ------------------------------------------------------------------------- */ + +#define MHz 1000000 + +enum mxl5007t_mode { + MxL_MODE_OTA_DVBT_ATSC = 0, + MxL_MODE_OTA_NTSC_PAL_GH = 1, + MxL_MODE_OTA_PAL_IB = 2, + MxL_MODE_OTA_PAL_D_SECAM_KL = 3, + MxL_MODE_OTA_ISDBT = 4, + MxL_MODE_CABLE_DIGITAL = 0x10, + MxL_MODE_CABLE_NTSC_PAL_GH = 0x11, + MxL_MODE_CABLE_PAL_IB = 0x12, + MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13, + MxL_MODE_CABLE_SCTE40 = 0x14, +}; + +enum mxl5007t_chip_version { + MxL_UNKNOWN_ID = 0x00, + MxL_5007_V1_F1 = 0x11, + MxL_5007_V1_F2 = 0x12, + MxL_5007_V2_100_F1 = 0x21, + MxL_5007_V2_100_F2 = 0x22, + MxL_5007_V2_200_F1 = 0x23, + MxL_5007_V2_200_F2 = 0x24, +}; + +struct reg_pair_t { + u8 reg; + u8 val; +}; + +/* ------------------------------------------------------------------------- */ + +static struct reg_pair_t init_tab[] = { + { 0x0b, 0x44 }, /* XTAL */ + { 0x0c, 0x60 }, /* IF */ + { 0x10, 0x00 }, /* MISC */ + { 0x12, 0xca }, /* IDAC */ + { 0x16, 0x90 }, /* MODE */ + { 0x32, 0x38 }, /* MODE Analog/Digital */ + { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ + { 0x2c, 0x34 }, /* OVERRIDE */ + { 0x4d, 0x40 }, /* OVERRIDE */ + { 0x7f, 0x02 }, /* OVERRIDE */ + { 0x9a, 0x52 }, /* OVERRIDE */ + { 0x48, 0x5a }, /* OVERRIDE */ + { 0x76, 0x1a }, /* OVERRIDE */ + { 0x6a, 0x48 }, /* OVERRIDE */ + { 0x64, 0x28 }, /* OVERRIDE */ + { 0x66, 0xe6 }, /* OVERRIDE */ + { 0x35, 0x0e }, /* OVERRIDE */ + { 0x7e, 0x01 }, /* OVERRIDE */ + { 0x83, 0x00 }, /* OVERRIDE */ + { 0x04, 0x0b }, /* OVERRIDE */ + { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ + { 0, 0 } +}; + +static struct reg_pair_t init_tab_cable[] = { + { 0x0b, 0x44 }, /* XTAL */ + { 0x0c, 0x60 }, /* IF */ + { 0x10, 0x00 }, /* MISC */ + { 0x12, 0xca }, /* IDAC */ + { 0x16, 0x90 }, /* MODE */ + { 0x32, 0x38 }, /* MODE A/D */ + { 0x71, 0x3f }, /* TOP1 */ + { 0x72, 0x3f }, /* TOP2 */ + { 0x74, 0x3f }, /* TOP3 */ + { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ + { 0x2c, 0x34 }, /* OVERRIDE */ + { 0x4d, 0x40 }, /* OVERRIDE */ + { 0x7f, 0x02 }, /* OVERRIDE */ + { 0x9a, 0x52 }, /* OVERRIDE */ + { 0x48, 0x5a }, /* OVERRIDE */ + { 0x76, 0x1a }, /* OVERRIDE */ + { 0x6a, 0x48 }, /* OVERRIDE */ + { 0x64, 0x28 }, /* OVERRIDE */ + { 0x66, 0xe6 }, /* OVERRIDE */ + { 0x35, 0x0e }, /* OVERRIDE */ + { 0x7e, 0x01 }, /* OVERRIDE */ + { 0x04, 0x0b }, /* OVERRIDE */ + { 0x68, 0xb4 }, /* OVERRIDE */ + { 0x36, 0x00 }, /* OVERRIDE */ + { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ + { 0, 0 } +}; + +/* ------------------------------------------------------------------------- */ + +static struct reg_pair_t reg_pair_rftune[] = { + { 0x11, 0x00 }, /* abort tune */ + { 0x13, 0x15 }, + { 0x14, 0x40 }, + { 0x15, 0x0e }, + { 0x11, 0x02 }, /* start tune */ + { 0, 0 } +}; + +/* ------------------------------------------------------------------------- */ + +struct mxl5007t_state { + struct list_head hybrid_tuner_instance_list; + struct tuner_i2c_props i2c_props; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + struct mutex lock; +#else + struct semaphore lock; +#endif + + struct mxl5007t_config *config; + + enum mxl5007t_chip_version chip_id; + + struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)]; + struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)]; + struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)]; + + u32 frequency; + u32 bandwidth; +}; + +/* ------------------------------------------------------------------------- */ + +/* called by _init and _rftun to manipulate the register arrays */ + +static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val) +{ + unsigned int i = 0; + + while (reg_pair[i].reg || reg_pair[i].val) { + if (reg_pair[i].reg == reg) { + reg_pair[i].val &= ~mask; + reg_pair[i].val |= val; + } + i++; + + } + return; +} + +static void copy_reg_bits(struct reg_pair_t *reg_pair1, + struct reg_pair_t *reg_pair2) +{ + unsigned int i, j; + + i = j = 0; + + while (reg_pair1[i].reg || reg_pair1[i].val) { + while (reg_pair2[j].reg || reg_pair2[j].reg) { + if (reg_pair1[i].reg != reg_pair2[j].reg) { + j++; + continue; + } + reg_pair2[j].val = reg_pair1[i].val; + break; + } + i++; + } + return; +} + +/* ------------------------------------------------------------------------- */ + +static void mxl5007t_set_mode_bits(struct mxl5007t_state *state, + enum mxl5007t_mode mode, + s32 if_diff_out_level) +{ + switch (mode) { + case MxL_MODE_OTA_DVBT_ATSC: + set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); + set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e); + break; + case MxL_MODE_OTA_ISDBT: + set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); + set_reg_bits(state->tab_init, 0x35, 0xff, 0x12); + break; + case MxL_MODE_OTA_NTSC_PAL_GH: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + break; + case MxL_MODE_OTA_PAL_IB: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + break; + case MxL_MODE_OTA_PAL_D_SECAM_KL: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + break; + case MxL_MODE_CABLE_DIGITAL: + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_NTSC_PAL_GH: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_PAL_IB: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_PAL_D_SECAM_KL: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_SCTE40: + set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08); + set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + default: + mxl_fail(-EINVAL); + } + return; +} + +static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, + enum mxl5007t_if_freq if_freq, + int invert_if) +{ + u8 val; + + switch (if_freq) { + case MxL_IF_4_MHZ: + val = 0x00; + break; + case MxL_IF_4_5_MHZ: + val = 0x20; + break; + case MxL_IF_4_57_MHZ: + val = 0x30; + break; + case MxL_IF_5_MHZ: + val = 0x40; + break; + case MxL_IF_5_38_MHZ: + val = 0x50; + break; + case MxL_IF_6_MHZ: + val = 0x60; + break; + case MxL_IF_6_28_MHZ: + val = 0x70; + break; + case MxL_IF_9_1915_MHZ: + val = 0x80; + break; + case MxL_IF_35_25_MHZ: + val = 0x90; + break; + case MxL_IF_36_15_MHZ: + val = 0xa0; + break; + case MxL_IF_44_MHZ: + val = 0xb0; + break; + default: + mxl_fail(-EINVAL); + return; + } + set_reg_bits(state->tab_init, 0x0c, 0xf0, val); + + /* set inverted IF or normal IF */ + set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00); + + return; +} + +static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state, + enum mxl5007t_xtal_freq xtal_freq) +{ + u8 val; + + switch (xtal_freq) { + case MxL_XTAL_16_MHZ: + val = 0x00; /* select xtal freq & Ref Freq */ + break; + case MxL_XTAL_20_MHZ: + val = 0x11; + break; + case MxL_XTAL_20_25_MHZ: + val = 0x22; + break; + case MxL_XTAL_20_48_MHZ: + val = 0x33; + break; + case MxL_XTAL_24_MHZ: + val = 0x44; + break; + case MxL_XTAL_25_MHZ: + val = 0x55; + break; + case MxL_XTAL_25_14_MHZ: + val = 0x66; + break; + case MxL_XTAL_27_MHZ: + val = 0x77; + break; + case MxL_XTAL_28_8_MHZ: + val = 0x88; + break; + case MxL_XTAL_32_MHZ: + val = 0x99; + break; + case MxL_XTAL_40_MHZ: + val = 0xaa; + break; + case MxL_XTAL_44_MHZ: + val = 0xbb; + break; + case MxL_XTAL_48_MHZ: + val = 0xcc; + break; + case MxL_XTAL_49_3811_MHZ: + val = 0xdd; + break; + default: + mxl_fail(-EINVAL); + return; + } + set_reg_bits(state->tab_init, 0x0b, 0xff, val); + + return; +} + +static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state, + enum mxl5007t_mode mode) +{ + struct mxl5007t_config *cfg = state->config; + + memcpy(&state->tab_init, &init_tab, sizeof(init_tab)); + memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable)); + + mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level); + mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if); + mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz); + + set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6); + + set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3); + + set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp); + + /* set IDAC to automatic mode control by AGC */ + set_reg_bits(state->tab_init, 0x12, 0x80, 0x00); + + if (mode >= MxL_MODE_CABLE_DIGITAL) { + copy_reg_bits(state->tab_init, state->tab_init_cable); + return state->tab_init_cable; + } else + return state->tab_init; +} + +/* ------------------------------------------------------------------------- */ + +enum mxl5007t_bw_mhz { + MxL_BW_6MHz = 6, + MxL_BW_7MHz = 7, + MxL_BW_8MHz = 8, +}; + +static void mxl5007t_set_bw_bits(struct mxl5007t_state *state, + enum mxl5007t_bw_mhz bw) +{ + u8 val; + + switch (bw) { + case MxL_BW_6MHz: + val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A, + * and DIG_MODEINDEX_CSF */ + break; + case MxL_BW_7MHz: + val = 0x21; + break; + case MxL_BW_8MHz: + val = 0x3f; + break; + default: + mxl_fail(-EINVAL); + return; + } + set_reg_bits(state->tab_rftune, 0x13, 0x3f, val); + + return; +} + +static struct +reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state, + u32 rf_freq, enum mxl5007t_bw_mhz bw) +{ + u32 dig_rf_freq = 0; + u32 temp; + u32 frac_divider = 1000000; + unsigned int i; + + memcpy(&state->tab_rftune, ®_pair_rftune, sizeof(reg_pair_rftune)); + + mxl5007t_set_bw_bits(state, bw); + + /* Convert RF frequency into 16 bits => + * 10 bit integer (MHz) + 6 bit fraction */ + dig_rf_freq = rf_freq / MHz; + + temp = rf_freq % MHz; + + for (i = 0; i < 6; i++) { + dig_rf_freq <<= 1; + frac_divider /= 2; + if (temp > frac_divider) { + temp -= frac_divider; + dig_rf_freq++; + } + } + + /* add to have shift center point by 7.8124 kHz */ + if (temp > 7812) + dig_rf_freq++; + + set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq); + set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8)); + + return state->tab_rftune; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val) +{ + u8 buf[] = { reg, val }; + struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0, + .buf = buf, .len = 2 }; + int ret; + + ret = i2c_transfer(state->i2c_props.adap, &msg, 1); + if (ret != 1) { + mxl_err("failed!"); + return -EREMOTEIO; + } + return 0; +} + +static int mxl5007t_write_regs(struct mxl5007t_state *state, + struct reg_pair_t *reg_pair) +{ + unsigned int i = 0; + int ret = 0; + + while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) { + ret = mxl5007t_write_reg(state, + reg_pair[i].reg, reg_pair[i].val); + i++; + } + return ret; +} + +static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val) +{ + struct i2c_msg msg[] = { + { .addr = state->i2c_props.addr, .flags = 0, + .buf = ®, .len = 1 }, + { .addr = state->i2c_props.addr, .flags = I2C_M_RD, + .buf = val, .len = 1 }, + }; + int ret; + + ret = i2c_transfer(state->i2c_props.adap, msg, 2); + if (ret != 2) { + mxl_err("failed!"); + return -EREMOTEIO; + } + return 0; +} + +static int mxl5007t_soft_reset(struct mxl5007t_state *state) +{ + u8 d = 0xff; + struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0, + .buf = &d, .len = 1 }; + + int ret = i2c_transfer(state->i2c_props.adap, &msg, 1); + + if (ret != 1) { + mxl_err("failed!"); + return -EREMOTEIO; + } + return 0; +} + +static int mxl5007t_tuner_init(struct mxl5007t_state *state, + enum mxl5007t_mode mode) +{ + struct reg_pair_t *init_regs; + int ret; + + ret = mxl5007t_soft_reset(state); + if (mxl_fail(ret)) + goto fail; + + /* calculate initialization reg array */ + init_regs = mxl5007t_calc_init_regs(state, mode); + + ret = mxl5007t_write_regs(state, init_regs); + if (mxl_fail(ret)) + goto fail; + mdelay(1); + + ret = mxl5007t_write_reg(state, 0x2c, 0x35); + mxl_fail(ret); +fail: + return ret; +} + +static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz, + enum mxl5007t_bw_mhz bw) +{ + struct reg_pair_t *rf_tune_regs; + int ret; + + /* calculate channel change reg array */ + rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw); + + ret = mxl5007t_write_regs(state, rf_tune_regs); + if (mxl_fail(ret)) + goto fail; + msleep(3); +fail: + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_synth_lock_status(struct mxl5007t_state *state, + int *rf_locked, int *ref_locked) +{ + u8 d; + int ret; + + *rf_locked = 0; + *ref_locked = 0; + + ret = mxl5007t_read_reg(state, 0xcf, &d); + if (mxl_fail(ret)) + goto fail; + + if ((d & 0x0c) == 0x0c) + *rf_locked = 1; + + if ((d & 0x03) == 0x03) + *ref_locked = 1; +fail: + return ret; +} + +static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state, + s32 *rf_input_level) +{ + u8 d1, d2; + int ret; + + ret = mxl5007t_read_reg(state, 0xb7, &d1); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_read_reg(state, 0xbf, &d2); + if (mxl_fail(ret)) + goto fail; + + d2 = d2 >> 4; + if (d2 > 7) + d2 += 0xf0; + + *rf_input_level = (s32)(d1 + d2 - 113); +fail: + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) +{ + struct mxl5007t_state *state = fe->tuner_priv; + int rf_locked, ref_locked; + s32 rf_input_level; + int ret; + + mutex_lock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked); + if (mxl_fail(ret)) + goto fail; + mxl_debug("%s%s", rf_locked ? "rf locked " : "", + ref_locked ? "ref locked" : ""); + + ret = mxl5007t_check_rf_input_power(state, &rf_input_level); + if (mxl_fail(ret)) + goto fail; + mxl_debug("rf input power: %d", rf_input_level); +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mutex_unlock(&state->lock); + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct mxl5007t_state *state = fe->tuner_priv; + enum mxl5007t_bw_mhz bw; + enum mxl5007t_mode mode; + int ret; + u32 freq = params->frequency; + + if (fe->ops.info.type == FE_ATSC) { + switch (params->u.vsb.modulation) { + case VSB_8: + case VSB_16: + mode = MxL_MODE_OTA_DVBT_ATSC; + break; + case QAM_64: + case QAM_256: + mode = MxL_MODE_CABLE_DIGITAL; + break; + default: + mxl_err("modulation not set!"); + return -EINVAL; + } + bw = MxL_BW_6MHz; + } else if (fe->ops.info.type == FE_OFDM) { + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + bw = MxL_BW_6MHz; + break; + case BANDWIDTH_7_MHZ: + bw = MxL_BW_7MHz; + break; + case BANDWIDTH_8_MHZ: + bw = MxL_BW_8MHz; + break; + default: + mxl_err("bandwidth not set!"); + return -EINVAL; + } + mode = MxL_MODE_OTA_DVBT_ATSC; + } else { + mxl_err("modulation type not supported!"); + return -EINVAL; + } + + mutex_lock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_tuner_init(state, mode); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_tuner_rf_tune(state, freq, bw); + if (mxl_fail(ret)) + goto fail; + + state->frequency = freq; + state->bandwidth = (fe->ops.info.type == FE_OFDM) ? + params->u.ofdm.bandwidth : 0; +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mutex_unlock(&state->lock); + return ret; +} + +static int mxl5007t_set_analog_params(struct dvb_frontend *fe, + struct analog_parameters *params) +{ + struct mxl5007t_state *state = fe->tuner_priv; + enum mxl5007t_bw_mhz bw = 0; /* FIXME */ + enum mxl5007t_mode cbl_mode; + enum mxl5007t_mode ota_mode; + char *mode_name; + int ret; + u32 freq = params->frequency * 62500; + +#if 0 + if (params->mode == V4L2_TUNER_RADIO) { + freq = freq / 1000; + mode_name = "fm"; + } else +#else +#define cable 1 +#endif + if (params->std & V4L2_STD_MN) { + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + mode_name = "MN"; + } else if (params->std & V4L2_STD_B) { + cbl_mode = MxL_MODE_CABLE_PAL_IB; + ota_mode = MxL_MODE_OTA_PAL_IB; + mode_name = "B"; + } else if (params->std & V4L2_STD_GH) { + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + mode_name = "GH"; + } else if (params->std & V4L2_STD_PAL_I) { + cbl_mode = MxL_MODE_CABLE_PAL_IB; + ota_mode = MxL_MODE_OTA_PAL_IB; + mode_name = "I"; + } else if (params->std & V4L2_STD_DK) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "DK"; + } else if (params->std & V4L2_STD_SECAM_L) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "L"; + } else if (params->std & V4L2_STD_SECAM_LC) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "L'"; + } else { + mode_name = "xx"; + /* FIXME */ + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + } + mxl_debug("setting mxl5007 to system %s", mode_name); + + mutex_lock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_tuner_rf_tune(state, freq, bw); + if (mxl_fail(ret)) + goto fail; + + state->frequency = freq; + state->bandwidth = 0; +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mutex_unlock(&state->lock); + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_init(struct dvb_frontend *fe) +{ + struct mxl5007t_state *state = fe->tuner_priv; + //int ret; + + mutex_lock(&state->lock); + /* do init */ +//fail: + mutex_unlock(&state->lock); + + return 0;//ret; +} + +static int mxl5007t_sleep(struct dvb_frontend *fe) +{ + struct mxl5007t_state *state = fe->tuner_priv; + //int ret; + + mutex_lock(&state->lock); + /* do standby */ +//fail: + mutex_unlock(&state->lock); + + return 0;//ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct mxl5007t_state *state = fe->tuner_priv; + *frequency = state->frequency; + return 0; +} + +static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct mxl5007t_state *state = fe->tuner_priv; + *bandwidth = state->bandwidth; + return 0; +} + +static int mxl5007t_release(struct dvb_frontend *fe) +{ + struct mxl5007t_state *state = fe->tuner_priv; + + mutex_lock(&mxl5007t_list_mutex); + + if (state) + hybrid_tuner_release_state(state); + + mutex_unlock(&mxl5007t_list_mutex); + + fe->tuner_priv = NULL; + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static struct dvb_tuner_ops mxl5007t_tuner_ops = { + .info = { + .name = "MaxLinear MxL5007T", +#if 0 + .frequency_min = , + .frequency_max = , + .frequency_step = , +#endif + }, + .init = mxl5007t_init, + .sleep = mxl5007t_sleep, + .set_params = mxl5007t_set_params, + .set_analog_params = mxl5007t_set_analog_params, + .get_status = mxl5007t_get_status, + .get_frequency = mxl5007t_get_frequency, + .get_bandwidth = mxl5007t_get_bandwidth, + .release = mxl5007t_release, +}; + +static int mxl5007t_get_chip_id(struct mxl5007t_state *state) +{ + char *name; + int ret; + u8 id; + + ret = mxl5007t_read_reg(state, 0xd3, &id); + if (mxl_fail(ret)) + goto fail; + + switch (id) { + case MxL_5007_V1_F1: + name = "MxL5007.v1.f1"; + break; + case MxL_5007_V1_F2: + name = "MxL5007.v1.f2"; + break; + case MxL_5007_V2_100_F1: + name = "MxL5007.v2.100.f1"; + break; + case MxL_5007_V2_100_F2: + name = "MxL5007.v2.100.f2"; + break; + case MxL_5007_V2_200_F1: + name = "MxL5007.v2.200.f1"; + break; + case MxL_5007_V2_200_F2: + name = "MxL5007.v2.200.f2"; + break; + default: +#if 0 + ret = -EINVAL; + goto fail; +#else + name = "MxL5007T"; + id = MxL_UNKNOWN_ID; +#endif + } + state->chip_id = id; + mxl_info("%s detected @ %d-%04x", name, + i2c_adapter_id(state->i2c_props.adap), + state->i2c_props.addr); + return 0; +fail: + mxl_warn("unable to identify device @ %d-%04x", + i2c_adapter_id(state->i2c_props.adap), + state->i2c_props.addr); + + state->chip_id = MxL_UNKNOWN_ID; + return ret; +} + +struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 addr, + struct mxl5007t_config *cfg) +{ + struct mxl5007t_state *state = NULL; + int instance, ret; + + mutex_lock(&mxl5007t_list_mutex); + instance = hybrid_tuner_request_state(struct mxl5007t_state, state, + hybrid_tuner_instance_list, + i2c, addr, "mxl5007"); + switch (instance) { + case 0: + goto fail; + break; + case 1: + /* new tuner instance */ + state->config = cfg; + + mutex_init(&state->lock); + + mutex_lock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_get_chip_id(state); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mutex_unlock(&state->lock); + + /* check return value of mxl5007t_get_chip_id */ + if (mxl_fail(ret)) + goto fail; + break; + default: + /* existing tuner instance */ + break; + } + fe->tuner_priv = state; + mutex_unlock(&mxl5007t_list_mutex); + + memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + return fe; +fail: + mutex_unlock(&mxl5007t_list_mutex); + + mxl5007t_release(fe); + return NULL; +} +EXPORT_SYMBOL_GPL(mxl5007t_attach); +MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver"); +MODULE_AUTHOR("Michael Krufky "); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/linux/drivers/media/common/tuners/mxl5007t.h b/linux/drivers/media/common/tuners/mxl5007t.h new file mode 100644 index 000000000..a1ee3628b --- /dev/null +++ b/linux/drivers/media/common/tuners/mxl5007t.h @@ -0,0 +1,105 @@ +/* + * mxl5007t.h - driver for the MaxLinear MxL5007T silicon tuner + * + * Copyright (C) 2008 Michael Krufky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MXL5007T_H__ +#define __MXL5007T_H__ + +#include "dvb_frontend.h" + +/* ------------------------------------------------------------------------- */ + +enum mxl5007t_if_freq { + MxL_IF_4_MHZ, /* 4000000 */ + MxL_IF_4_5_MHZ, /* 4500000 */ + MxL_IF_4_57_MHZ, /* 4570000 */ + MxL_IF_5_MHZ, /* 5000000 */ + MxL_IF_5_38_MHZ, /* 5380000 */ + MxL_IF_6_MHZ, /* 6000000 */ + MxL_IF_6_28_MHZ, /* 6280000 */ + MxL_IF_9_1915_MHZ, /* 9191500 */ + MxL_IF_35_25_MHZ, /* 35250000 */ + MxL_IF_36_15_MHZ, /* 36150000 */ + MxL_IF_44_MHZ, /* 44000000 */ +}; + +enum mxl5007t_xtal_freq { + MxL_XTAL_16_MHZ, /* 16000000 */ + MxL_XTAL_20_MHZ, /* 20000000 */ + MxL_XTAL_20_25_MHZ, /* 20250000 */ + MxL_XTAL_20_48_MHZ, /* 20480000 */ + MxL_XTAL_24_MHZ, /* 24000000 */ + MxL_XTAL_25_MHZ, /* 25000000 */ + MxL_XTAL_25_14_MHZ, /* 25140000 */ + MxL_XTAL_27_MHZ, /* 27000000 */ + MxL_XTAL_28_8_MHZ, /* 28800000 */ + MxL_XTAL_32_MHZ, /* 32000000 */ + MxL_XTAL_40_MHZ, /* 40000000 */ + MxL_XTAL_44_MHZ, /* 44000000 */ + MxL_XTAL_48_MHZ, /* 48000000 */ + MxL_XTAL_49_3811_MHZ, /* 49381100 */ +}; + +enum mxl5007t_clkout_amp { + MxL_CLKOUT_AMP_0_94V = 0, + MxL_CLKOUT_AMP_0_53V = 1, + MxL_CLKOUT_AMP_0_37V = 2, + MxL_CLKOUT_AMP_0_28V = 3, + MxL_CLKOUT_AMP_0_23V = 4, + MxL_CLKOUT_AMP_0_20V = 5, + MxL_CLKOUT_AMP_0_17V = 6, + MxL_CLKOUT_AMP_0_15V = 7, +}; + +struct mxl5007t_config { + s32 if_diff_out_level; + enum mxl5007t_clkout_amp clk_out_amp; + enum mxl5007t_xtal_freq xtal_freq_hz; + enum mxl5007t_if_freq if_freq_hz; + unsigned int invert_if:1; + unsigned int loop_thru_enable:1; + unsigned int clk_out_enable:1; +}; + +#define CONFIG_MEDIA_TUNER_MXL5007T +#if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE)) +extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 addr, + struct mxl5007t_config *cfg); +#else +static inline struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + u8 addr, + struct mxl5007t_config *cfg) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif /* __MXL5007T_H__ */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ + -- cgit v1.2.3 From 91d1655f34d7ffd36e3e68c6bdbf365cbc6d0ddc Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 12 Jul 2008 17:22:38 -0400 Subject: mxl5007t: enable _init and _sleep power management functionality From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/mxl5007t.c | 42 ++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index 82e77329d..fc6aec1bd 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -842,27 +842,53 @@ fail: static int mxl5007t_init(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; - //int ret; + int ret; + u8 d; mutex_lock(&state->lock); - /* do init */ -//fail: + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_read_reg(state, 0x05, &d); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_write_reg(state, 0x05, d | 0x01); + mxl_fail(ret); +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + mutex_unlock(&state->lock); - return 0;//ret; + return ret; } static int mxl5007t_sleep(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; - //int ret; + int ret; + u8 d; mutex_lock(&state->lock); - /* do standby */ -//fail: + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_read_reg(state, 0x05, &d); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); + mxl_fail(ret); +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + mutex_unlock(&state->lock); - return 0;//ret; + return ret; } /* ------------------------------------------------------------------------- */ -- cgit v1.2.3 From bd3a5b6d784b2cc99e76226249a850e6f568bf78 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 8 Jul 2008 23:23:08 -0400 Subject: au0828: add support for new revision of HVR950Q From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/video/au0828/Kconfig | 1 + linux/drivers/media/video/au0828/au0828-cards.c | 12 ++++++++++++ linux/drivers/media/video/au0828/au0828-cards.h | 1 + linux/drivers/media/video/au0828/au0828-dvb.c | 15 +++++++++++++++ 4 files changed, 29 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/au0828/Kconfig b/linux/drivers/media/video/au0828/Kconfig index 52b249158..ed9a50f18 100644 --- a/linux/drivers/media/video/au0828/Kconfig +++ b/linux/drivers/media/video/au0828/Kconfig @@ -6,6 +6,7 @@ config VIDEO_AU0828 select VIDEO_TVEEPROM select DVB_AU8522 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE ---help--- This is a video4linux driver for Auvitek's USB device. diff --git a/linux/drivers/media/video/au0828/au0828-cards.c b/linux/drivers/media/video/au0828/au0828-cards.c index 898e12395..443e59009 100644 --- a/linux/drivers/media/video/au0828/au0828-cards.c +++ b/linux/drivers/media/video/au0828/au0828-cards.c @@ -32,6 +32,9 @@ struct au0828_board au0828_boards[] = { [AU0828_BOARD_HAUPPAUGE_HVR950Q] = { .name = "Hauppauge HVR950Q", }, + [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = { + .name = "Hauppauge HVR950Q rev xxF8", + }, [AU0828_BOARD_DVICO_FUSIONHDTV7] = { .name = "DViCO FusionHDTV USB", }, @@ -49,6 +52,7 @@ int au0828_tuner_callback(void *priv, int command, int arg) switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: case AU0828_BOARD_DVICO_FUSIONHDTV7: if (command == 0) { /* Tuner Reset Command from xc5000 */ @@ -110,6 +114,7 @@ void au0828_card_setup(struct au0828_dev *dev) switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: if (dev->i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xa0); break; @@ -128,6 +133,7 @@ void au0828_gpio_setup(struct au0828_dev *dev) switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: /* GPIO's * 4 - CS5340 * 5 - AU8522 Demodulator @@ -193,6 +199,12 @@ struct usb_device_id au0828_usb_id_table [] = { .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { USB_DEVICE(0x0fd9, 0x0008), .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x2040, 0x7201), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, + { USB_DEVICE(0x2040, 0x7211), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, + { USB_DEVICE(0x2040, 0x7281), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, { }, }; diff --git a/linux/drivers/media/video/au0828/au0828-cards.h b/linux/drivers/media/video/au0828/au0828-cards.h index e26f54a96..c37f5fd0f 100644 --- a/linux/drivers/media/video/au0828/au0828-cards.h +++ b/linux/drivers/media/video/au0828/au0828-cards.h @@ -23,3 +23,4 @@ #define AU0828_BOARD_HAUPPAUGE_HVR950Q 1 #define AU0828_BOARD_HAUPPAUGE_HVR850 2 #define AU0828_BOARD_DVICO_FUSIONHDTV7 3 +#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4 diff --git a/linux/drivers/media/video/au0828/au0828-dvb.c b/linux/drivers/media/video/au0828/au0828-dvb.c index 0a835354f..4c1dfdd8d 100644 --- a/linux/drivers/media/video/au0828/au0828-dvb.c +++ b/linux/drivers/media/video/au0828/au0828-dvb.c @@ -29,6 +29,7 @@ #include "au0828.h" #include "au8522.h" #include "xc5000.h" +#include "mxl5007t.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -46,6 +47,11 @@ static struct xc5000_config hauppauge_hvr950q_tunerconfig = { .tuner_callback = au0828_tuner_callback }; +static struct mxl5007t_config mxl5007t_hvr950q_config = { + .xtal_freq_hz = MxL_XTAL_24_MHZ, + .if_freq_hz = MxL_IF_6_MHZ, +}; + /*-------------------------------------------------------------------*/ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static void urb_completion(struct urb *purb, struct pt_regs *regs) @@ -347,6 +353,15 @@ int au0828_dvb_register(struct au0828_dev *dev) &dev->i2c_adap, &hauppauge_hvr950q_tunerconfig, dev); break; + case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: + dvb->frontend = dvb_attach(au8522_attach, + &hauppauge_hvr950q_config, + &dev->i2c_adap); + if (dvb->frontend != NULL) + dvb_attach(mxl5007t_attach, dvb->frontend, + &dev->i2c_adap, 0x60, + &mxl5007t_hvr950q_config); + break; default: printk(KERN_WARNING "The frontend of your DVB/ATSC card " "isn't supported yet\n"); -- cgit v1.2.3 From d7e45e064b4731c936279a3734f2decbd32c1234 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Jul 2008 10:47:00 -0300 Subject: add dvb-t support for terratec cinergy hybrid T usb xs From: reinhard schwab This patch adds dvbt support for the terratec cinergy hybrid T usb xsstick. Thanks to Devin Heitmueller and Mauro Chehab for guiding me. Signed-off-by: Reinhard Schwab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 4 ++++ linux/drivers/media/video/em28xx/em28xx-dvb.c | 9 +++++++++ 2 files changed, 13 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index aa11618ef..4874c68d1 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -247,6 +247,7 @@ struct em28xx_board em28xx_boards[] = { .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .decoder = EM28XX_TVP5150, + .has_dvb = 1, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -640,6 +641,9 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: ctl->demod = XC3028_FE_ZARLINK456; break; + case EM2880_BOARD_TERRATEC_HYBRID_XS: + ctl->demod = XC3028_FE_ZARLINK456; + break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: /* djh - Not sure which demod we need here */ ctl->demod = XC3028_FE_DEFAULT; diff --git a/linux/drivers/media/video/em28xx/em28xx-dvb.c b/linux/drivers/media/video/em28xx/em28xx-dvb.c index adf2a6552..80f85f38e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-dvb.c +++ b/linux/drivers/media/video/em28xx/em28xx-dvb.c @@ -442,6 +442,15 @@ static int dvb_init(struct em28xx *dev) } break; #endif + case EM2880_BOARD_TERRATEC_HYBRID_XS: + dvb->frontend = dvb_attach(zl10353_attach, + &em28xx_zl10353_with_xc3028, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" " isn't supported yet\n", -- cgit v1.2.3 From 6c80285db2bbd7b7261fc1c10941787223acb3f4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Jul 2008 17:43:27 +0000 Subject: s2255drv Sensoray 2255 driver fixes From: Dean Anderson This patch fixes timer issues in driver disconnect. It also removes the restriction of one user per channel at a time. Thanks to Oliver Neukum and Mauro Chehab for finding these issues. Locking of video stream partly based on saa7134 driver. Signed-off-by: Dean Anderson Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/s2255drv.c | 111 ++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 46 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c index f13235e31..97820ee4a 100644 --- a/linux/drivers/media/video/s2255drv.c +++ b/linux/drivers/media/video/s2255drv.c @@ -186,6 +186,7 @@ struct s2255_dmaqueue { #define S2255_FW_LOADED_DSPWAIT 1 #define S2255_FW_SUCCESS 2 #define S2255_FW_FAILED 3 +#define S2255_FW_DISCONNECTING 4 struct s2255_fw { int fw_loaded; @@ -265,7 +266,6 @@ struct s2255_buffer { struct s2255_fh { struct s2255_dev *dev; - unsigned int resources; const struct s2255_fmt *fmt; unsigned int width; unsigned int height; @@ -275,14 +275,9 @@ struct s2255_fh { /* mode below is the desired mode. mode in s2255_dev is the current mode that was last set */ struct s2255_mode mode; + int resources[MAX_CHANNELS]; }; -/* - * TODO: fixme S2255_MAX_USERS. Do not limit open driver handles. - * Limit V4L to one stream at a time. - */ -#define S2255_MAX_USERS 1 - #define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */ #define S2255_MAJOR_VERSION 1 #define S2255_MINOR_VERSION 13 @@ -478,10 +473,9 @@ static void s2255_timer(unsigned long user_data) dprintk(100, "s2255 timer\n"); if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { printk(KERN_ERR "s2255: can't submit urb\n"); - if (data->fw) { - release_firmware(data->fw); - data->fw = NULL; - } + atomic_set(&data->fw_state, S2255_FW_FAILED); + /* wake up anything waiting for the firmware */ + wake_up(&data->wait_fw); return; } } @@ -511,13 +505,18 @@ static void s2255_fwchunk_complete(struct urb *urb) struct usb_device *udev = urb->dev; int len; dprintk(100, "udev %p urb %p", udev, urb); - /* TODO: fixme. reflect change in status */ if (urb->status) { dev_err(&udev->dev, "URB failed with status %d", urb->status); + atomic_set(&data->fw_state, S2255_FW_FAILED); + /* wake up anything waiting for the firmware */ + wake_up(&data->wait_fw); return; } if (data->fw_urb == NULL) { - dev_err(&udev->dev, "early disconncect\n"); + dev_err(&udev->dev, "s2255 disconnected\n"); + atomic_set(&data->fw_state, S2255_FW_FAILED); + /* wake up anything waiting for the firmware */ + wake_up(&data->wait_fw); return; } #define CHUNK_SIZE 512 @@ -791,7 +790,8 @@ static int res_get(struct s2255_dev *dev, struct s2255_fh *fh) } /* it's free, grab it */ dev->resources[fh->channel] = 1; - dprintk(1, "res: get\n"); + fh->resources[fh->channel] = 1; + dprintk(1, "s2255: res: get\n"); mutex_unlock(&dev->lock); return 1; } @@ -801,9 +801,18 @@ static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh) return dev->resources[fh->channel]; } +static int res_check(struct s2255_fh *fh) +{ + return fh->resources[fh->channel]; +} + + static void res_free(struct s2255_dev *dev, struct s2255_fh *fh) { + mutex_lock(&dev->lock); dev->resources[fh->channel] = 0; + fh->resources[fh->channel] = 0; + mutex_unlock(&dev->lock); dprintk(1, "res: put\n"); } @@ -1234,7 +1243,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) } if (!res_get(dev, fh)) { - dev_err(&dev->udev->dev, "res get busy\n"); + dev_err(&dev->udev->dev, "s2255: stream busy\n"); return -EBUSY; } @@ -1290,8 +1299,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) } s2255_stop_acquire(dev, fh->channel); res = videobuf_streamoff(&fh->vb_vidq); + if (res < 0) + return res; res_free(dev, fh); - return res; + return 0; } static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) @@ -1464,12 +1475,7 @@ static int s2255_open(struct inode *inode, struct file *file) mutex_lock(&dev->open_lock); dev->users[cur_channel]++; - if (dev->users[cur_channel] > S2255_MAX_USERS) { - dev->users[cur_channel]--; - mutex_unlock(&dev->open_lock); - printk(KERN_INFO "s2255drv: too many open handles!\n"); - return -EBUSY; - } + dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]); if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_FAILED) { err("2255 firmware load failed. retrying.\n"); @@ -1480,7 +1486,8 @@ static int s2255_open(struct inode *inode, struct file *file) msecs_to_jiffies(S2255_LOAD_TIMEOUT)); if (atomic_read(&dev->fw_data->fw_state) != S2255_FW_SUCCESS) { - printk(KERN_INFO "2255 FW load failed after 2 tries\n"); + printk(KERN_INFO "2255 FW load failed.\n"); + dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); return -EFAULT; } @@ -1496,6 +1503,7 @@ static int s2255_open(struct inode *inode, struct file *file) != S2255_FW_SUCCESS) { printk(KERN_INFO "2255 firmware not loaded" "try again\n"); + dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); return -EBUSY; } @@ -1504,6 +1512,7 @@ static int s2255_open(struct inode *inode, struct file *file) /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (NULL == fh) { + dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); return -ENOMEM; } @@ -1563,44 +1572,48 @@ static void s2255_destroy(struct kref *kref) printk(KERN_ERR "s2255drv: kref problem\n"); return; } + + /* + * Wake up any firmware load waiting (only done in .open, + * which holds the open_lock mutex) + */ + atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); + wake_up(&dev->fw_data->wait_fw); + /* prevent s2255_disconnect from racing s2255_open */ mutex_lock(&dev->open_lock); s2255_exit_v4l(dev); - /* device unregistered so no longer possible to open. open_mutex - can be unlocked */ + /* + * device unregistered so no longer possible to open. open_mutex + * can be unlocked and timers deleted afterwards. + */ mutex_unlock(&dev->open_lock); /* board shutdown stops the read pipe if it is running */ s2255_board_shutdown(dev); /* make sure firmware still not trying to load */ + del_timer(&dev->timer); /* only started in .probe and .open */ + if (dev->fw_data->fw_urb) { dprintk(2, "kill fw_urb\n"); usb_kill_urb(dev->fw_data->fw_urb); usb_free_urb(dev->fw_data->fw_urb); dev->fw_data->fw_urb = NULL; } + /* - * TODO: fixme(above, below): potentially leaving timers alive. - * do not ignore timeout below if - * it occurs. + * delete the dsp_wait timer, which sets the firmware + * state on completion. This is done before fw_data + * is freed below. */ - /* make sure we aren't waiting for the DSP */ - if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_LOADED_DSPWAIT) { - /* if we are, wait for the wakeup for fw_success or timeout */ - wait_event_timeout(dev->fw_data->wait_fw, - (atomic_read(&dev->fw_data->fw_state) - == S2255_FW_SUCCESS), - msecs_to_jiffies(S2255_LOAD_TIMEOUT)); - } + del_timer(&dev->fw_data->dsp_wait); /* only started in .open */ - if (dev->fw_data) { - if (dev->fw_data->fw) - release_firmware(dev->fw_data->fw); - kfree(dev->fw_data->pfw_data); - kfree(dev->fw_data); - } + if (dev->fw_data->fw) + release_firmware(dev->fw_data->fw); + kfree(dev->fw_data->pfw_data); + kfree(dev->fw_data); usb_put_dev(dev->udev); dprintk(1, "%s", __func__); @@ -1617,17 +1630,23 @@ static int s2255_close(struct inode *inode, struct file *file) mutex_lock(&dev->open_lock); - if (dev->b_acquire[fh->channel]) - s2255_stop_acquire(dev, fh->channel); - res_free(dev, fh); + /* turn off stream */ + if (res_check(fh)) { + if (dev->b_acquire[fh->channel]) + s2255_stop_acquire(dev, fh->channel); + videobuf_streamoff(&fh->vb_vidq); + res_free(dev, fh); + } + videobuf_mmap_free(&fh->vb_vidq); - kfree(fh); dev->users[fh->channel]--; + mutex_unlock(&dev->open_lock); kref_put(&dev->kref, s2255_destroy); dprintk(1, "s2255: close called (minor=%d, users=%d)\n", minor, dev->users[fh->channel]); + kfree(fh); return 0; } -- cgit v1.2.3 From 864de2be6bbbffb01707d727382eda327967d167 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Jul 2008 15:28:36 +0000 Subject: stkwebcam: Always reuse last queued buffer From: Jaime Velasco Juan This change keeps the video stream going on when the application is slow queuing buffers, instead of spamming dmesg and hanging. Fixes a problem with aMSN reported by Samed Beyribey Signed-off-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/stk-webcam.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index 5daa2294d..c5f766653 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -446,18 +446,19 @@ static void stk_isoc_handler(struct urb *urb) fb->v4lbuf.bytesused = 0; fill = fb->buffer; } else if (fb->v4lbuf.bytesused == dev->frame_size) { - list_move_tail(dev->sio_avail.next, - &dev->sio_full); - wake_up(&dev->wait_frame); - if (list_empty(&dev->sio_avail)) { - (void) (printk_ratelimit() && - STK_ERROR("No buffer available\n")); - goto resubmit; + if (list_is_singular(&dev->sio_avail)) { + /* Always reuse the last buffer */ + fb->v4lbuf.bytesused = 0; + fill = fb->buffer; + } else { + list_move_tail(dev->sio_avail.next, + &dev->sio_full); + wake_up(&dev->wait_frame); + fb = list_first_entry(&dev->sio_avail, + struct stk_sio_buffer, list); + fb->v4lbuf.bytesused = 0; + fill = fb->buffer; } - fb = list_first_entry(&dev->sio_avail, - struct stk_sio_buffer, list); - fb->v4lbuf.bytesused = 0; - fill = fb->buffer; } } else { framelen -= 4; -- cgit v1.2.3 From 4588ddfb9948cdad490f96d59ee8a4c2d9be86a2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Jul 2008 11:04:33 -0300 Subject: Add support for the ATI TV Wonder HD 600 From: Devin Heitmueller em28xx-cards.c em28xx-dvb.c em28xx.h - Add support for the ATI TV Wonder HD 600, based on a 94 email exchange and USB traces provided by Ronnie Bailey Thanks to Ronnie Bailey for testing the changes Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 50 +++++++++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx-dvb.c | 2 + linux/drivers/media/video/em28xx/em28xx.h | 1 + 3 files changed, 53 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 4874c68d1..9510ac044 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -241,6 +241,52 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { + .name = "AMD ATI TV Wonder HD 600", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { + .name = "AMD ATI TV Wonder HD 600", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, [EM2880_BOARD_TERRATEC_HYBRID_XS] = { .name = "Terratec Hybrid XS", .vchannels = 3, @@ -494,6 +540,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, { USB_DEVICE(0x0ccd, 0x0047), .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, + { USB_DEVICE(0x0438, 0xb002), + .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -609,6 +657,7 @@ void em28xx_pre_card_setup(struct em28xx *dev) case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: + case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); msleep(50); @@ -650,6 +699,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: + case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: /* FIXME: Better to specify the needed IF */ ctl->demod = XC3028_FE_DEFAULT; break; diff --git a/linux/drivers/media/video/em28xx/em28xx-dvb.c b/linux/drivers/media/video/em28xx/em28xx-dvb.c index 80f85f38e..7edec4618 100644 --- a/linux/drivers/media/video/em28xx/em28xx-dvb.c +++ b/linux/drivers/media/video/em28xx/em28xx-dvb.c @@ -6,6 +6,7 @@ (c) 2008 Devin Heitmueller - Fixes for the driver to properly work with HVR-950 - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick + - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 (c) 2008 Aidan Thornton @@ -412,6 +413,7 @@ static int dvb_init(struct em28xx *dev) switch (dev->model) { case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: + case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 6db96db0f..8c97635c2 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -59,6 +59,7 @@ #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 +#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From 2bf5145e5bbfe9c7756ba4ccc0d22f4cccdf2ebb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Jul 2008 00:29:46 +0000 Subject: mt20xx: test below 0 on unsigned lo1a and lo2a From: roel kluin lo1a and lo2a are unsigned ints so these tests won't work. Signed-off-by: Roel Kluin Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/mt20xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/mt20xx.c b/linux/drivers/media/common/tuners/mt20xx.c index 9d9f1cf11..2669cd0bf 100644 --- a/linux/drivers/media/common/tuners/mt20xx.c +++ b/linux/drivers/media/common/tuners/mt20xx.c @@ -149,7 +149,8 @@ static int mt2032_compute_freq(struct dvb_frontend *fe, tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", rfin,lo2,lo2n,lo2a,lo2num,lo2freq); - if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { + if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 || + lo2n > 30) { tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", lo1a, lo1n, lo2a,lo2n); return(-1); -- cgit v1.2.3 From ccac3f9c17e7032132a869467215973380721525 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 Jul 2008 19:33:48 +0000 Subject: make cx25840_debug static From: Adrian Bunk cx25840_debug can now become static. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx25840/cx25840-core.c | 2 +- linux/drivers/media/video/cx25840/cx25840-core.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index ecd498c70..7b48e0285 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -51,7 +51,7 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -int cx25840_debug; +static int cx25840_debug; module_param_named(debug,cx25840_debug, int, 0644); diff --git a/linux/drivers/media/video/cx25840/cx25840-core.h b/linux/drivers/media/video/cx25840/cx25840-core.h index f81a9a959..cd549b119 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.h +++ b/linux/drivers/media/video/cx25840/cx25840-core.h @@ -25,8 +25,6 @@ #include #include -extern int cx25840_debug; - /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is present in Hauppauge PVR-150 (and possibly PVR-500) cards that have certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The -- cgit v1.2.3 From 934a0ff7b293a5df5f8f33f3361ec53dd9efeda1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 Jul 2008 19:33:42 +0000 Subject: usb/anysee.c: make struct anysee_usb_mutex static From: Adrian Bunk This patch makes the needlessly global struct anysee_usb_mutex static. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/anysee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/dvb-usb/anysee.c b/linux/drivers/media/dvb/dvb-usb/anysee.c index adfd4fc82..2f408d2e1 100644 --- a/linux/drivers/media/dvb/dvb-usb/anysee.c +++ b/linux/drivers/media/dvb/dvb-usb/anysee.c @@ -43,7 +43,7 @@ module_param_named(debug, dvb_usb_anysee_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -struct mutex anysee_usb_mutex; +static struct mutex anysee_usb_mutex; static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen) -- cgit v1.2.3 From 54c5a432d5b1ee850dfddf8ffbb85e2c6f3ba5b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Jul 2008 11:30:03 -0300 Subject: saa7134: Copy tuner data earlier in init to avoid overwriting manual tuner type From: Simon Arlott When saa7134_board_init2 runs, it immediately overwrites the current value (set earlier from module parameter) of tuner_type with the static values, and then does autodetection. This patch moves the tuner_addr copy to earlier in saa7134_initdev and removes the tuner_type copy from saa7134_board_init2. Autodetection could still potentially change to the wrong tuner type, but it is now possible to override the default type for the card again. My card's tuner is configured with autodetection from eeprom, so I don't need to manually set the tuner. I've checked that the autodetection still works for my card. Reviewed-by: Hermann Pitton Cc: Brian Marete Signed-off-by: Simon Arlott Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-cards.c | 3 --- linux/drivers/media/video/saa7134/saa7134-core.c | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 8ec09c97e..dfe4f7169 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -5956,9 +5956,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) unsigned char buf; int board; - dev->tuner_type = saa7134_boards[dev->board].tuner_type; - dev->tuner_addr = saa7134_boards[dev->board].tuner_addr; - switch (dev->board) { case SAA7134_BOARD_BMK_MPEX_NOTUNER: case SAA7134_BOARD_BMK_MPEX_TUNER: diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 254a04717..e791bbd64 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -1006,11 +1006,12 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, dev->board = SAA7134_BOARD_UNKNOWN; } dev->autodetected = card[dev->nr] != dev->board; - dev->tuner_type = saa7134_boards[dev->board].tuner_type; + dev->tuner_type = saa7134_boards[dev->board].tuner_type; + dev->tuner_addr = saa7134_boards[dev->board].tuner_addr; dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; if (UNSET != tuner[dev->nr]) dev->tuner_type = tuner[dev->nr]; - printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", + printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", dev->name,pci_dev->subsystem_vendor, pci_dev->subsystem_device,saa7134_boards[dev->board].name, dev->board, dev->autodetected ? -- cgit v1.2.3 From fd6f88cc2d6fc72838895f49a7713c733ef2c510 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Jul 2008 11:42:29 -0300 Subject: uvcvideo: Make the auto-exposure menu control V4L2 compliant From: Laurent Pinchart V4L2 and UVC enumerate the auto-exposure settings in a different order. This patch fixes the auto-exposure menu declaration to match the V4L2 spec. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/uvc/uvc_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/uvc/uvc_ctrl.c b/linux/drivers/media/video/uvc/uvc_ctrl.c index 3ae955126..f54d06a8a 100644 --- a/linux/drivers/media/video/uvc/uvc_ctrl.c +++ b/linux/drivers/media/video/uvc/uvc_ctrl.c @@ -195,8 +195,8 @@ static struct uvc_menu_info power_line_frequency_controls[] = { }; static struct uvc_menu_info exposure_auto_controls[] = { - { 1, "Manual Mode" }, { 2, "Auto Mode" }, + { 1, "Manual Mode" }, { 4, "Shutter Priority Mode" }, { 8, "Aperture Priority Mode" }, }; -- cgit v1.2.3 From 48592db52742b5ad934b4f7c97e0dd6d90d8478b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Jul 2008 10:37:37 +0000 Subject: uvcvideo: Return sensible min and max values when querying a boolean control. From: Laurent Pinchart Although the V4L2 spec states that the minimum and maximum fields may not be valid for control types other than V4L2_CTRL_TYPE_INTEGER, it makes sense to set the bounds to 0 and 1 for boolean controls instead of returning uninitialized values. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/uvc/uvc_ctrl.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/uvc/uvc_ctrl.c b/linux/drivers/media/video/uvc/uvc_ctrl.c index f54d06a8a..626f4ad7e 100644 --- a/linux/drivers/media/video/uvc/uvc_ctrl.c +++ b/linux/drivers/media/video/uvc/uvc_ctrl.c @@ -592,6 +592,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, if (ctrl == NULL) return -EINVAL; + memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); v4l2_ctrl->id = mapping->id; v4l2_ctrl->type = mapping->v4l2_type; strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); @@ -608,7 +609,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); } - if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { + switch (mapping->v4l2_type) { + case V4L2_CTRL_TYPE_MENU: v4l2_ctrl->minimum = 0; v4l2_ctrl->maximum = mapping->menu_count - 1; v4l2_ctrl->step = 1; @@ -622,6 +624,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, } return 0; + + case V4L2_CTRL_TYPE_BOOLEAN: + v4l2_ctrl->minimum = 0; + v4l2_ctrl->maximum = 1; + v4l2_ctrl->step = 1; + return 0; + + default: + break; } if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { -- cgit v1.2.3 From a577023c8a7e4d47643aa89117d98d958dfb343f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 14 Jul 2008 12:51:03 +0000 Subject: zr36067: Rework device memory allocation From: Jean Delvare Allocate zoran devices dynamically. Currently, the zr36067 driver stores the device structures in a global array, with room for 4 devices. This makes the bss section very large (90 kB!), and given that most users, I suspect, have only one zoran device, this is a waste of kernel memory. Allocating the memory dynamically lets us use only the amount of memory we need. Before: text data bss dec hex filename 64754 9230 90224 164208 28170 drivers/media/video/zr36067.o After: text data bss dec hex filename 64866 9230 112 74208 121e0 drivers/media/video/zr36067.o Signed-off-by: Jean Delvare Acked-by: Ronald Bultje Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/zoran_card.c | 36 ++++++++++++++++++++------------ linux/drivers/media/video/zoran_card.h | 2 +- linux/drivers/media/video/zoran_driver.c | 4 ++-- 3 files changed, 26 insertions(+), 16 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/zoran_card.c b/linux/drivers/media/video/zoran_card.c index cc45ae5cd..4ffe998ba 100644 --- a/linux/drivers/media/video/zoran_card.c +++ b/linux/drivers/media/video/zoran_card.c @@ -162,7 +162,7 @@ static struct pci_device_id zr36067_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); int zoran_num; /* number of Buzs in use */ -struct zoran zoran[BUZ_MAX]; +struct zoran *zoran[BUZ_MAX]; /* videocodec bus functions ZR36060 */ static u32 @@ -1165,7 +1165,7 @@ static void zoran_release (struct zoran *zr) { if (!zr->initialized) - return; + goto exit_free; /* unregister videocodec bus */ if (zr->codec) { struct videocodec_master *master = zr->codec->master_data; @@ -1193,6 +1193,8 @@ zoran_release (struct zoran *zr) iounmap(zr->zr36057_mem); pci_disable_device(zr->pci_dev); video_unregister_device(zr->video_dev); +exit_free: + kfree(zr); } void @@ -1270,8 +1272,14 @@ find_zr36057 (void) while (zoran_num < BUZ_MAX && (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) { card_num = card[zoran_num]; - zr = &zoran[zoran_num]; - memset(zr, 0, sizeof(struct zoran)); // Just in case if previous cycle failed + zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); + if (!zr) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - kzalloc failed\n", + ZORAN_NAME); + continue; + } zr->pci_dev = dev; //zr->zr36057_mem = NULL; zr->id = zoran_num; @@ -1279,7 +1287,7 @@ find_zr36057 (void) spin_lock_init(&zr->spinlock); mutex_init(&zr->resource_lock); if (pci_enable_device(dev)) - continue; + goto zr_free_mem; zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); @@ -1295,7 +1303,7 @@ find_zr36057 (void) KERN_ERR "%s: find_zr36057() - no card specified, please use the card=X insmod option\n", ZR_DEVNAME(zr)); - continue; + goto zr_free_mem; } } else { int i; @@ -1334,7 +1342,7 @@ find_zr36057 (void) KERN_ERR "%s: find_zr36057() - unknown card\n", ZR_DEVNAME(zr)); - continue; + goto zr_free_mem; } } } @@ -1344,7 +1352,7 @@ find_zr36057 (void) KERN_ERR "%s: find_zr36057() - invalid cardnum %d\n", ZR_DEVNAME(zr), card_num); - continue; + goto zr_free_mem; } /* even though we make this a non pointer and thus @@ -1362,7 +1370,7 @@ find_zr36057 (void) KERN_ERR "%s: find_zr36057() - ioremap failed\n", ZR_DEVNAME(zr)); - continue; + goto zr_free_mem; } result = request_irq(zr->pci_dev->irq, @@ -1531,7 +1539,7 @@ find_zr36057 (void) } /* Success so keep the pci_dev referenced */ pci_dev_get(zr->pci_dev); - zoran_num++; + zoran[zoran_num++] = zr; continue; // Init errors @@ -1550,6 +1558,8 @@ find_zr36057 (void) free_irq(zr->pci_dev->irq, zr); zr_unmap: iounmap(zr->zr36057_mem); + zr_free_mem: + kfree(zr); continue; } if (dev) /* Clean up ref count on early exit */ @@ -1621,7 +1631,7 @@ init_dc10_cards (void) /* take care of Natoma chipset and a revision 1 zr36057 */ for (i = 0; i < zoran_num; i++) { - struct zoran *zr = &zoran[i]; + struct zoran *zr = zoran[i]; if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { zr->jpg_buffers.need_contiguous = 1; @@ -1633,7 +1643,7 @@ init_dc10_cards (void) if (zr36057_init(zr) < 0) { for (i = 0; i < zoran_num; i++) - zoran_release(&zoran[i]); + zoran_release(zoran[i]); return -EIO; } zoran_proc_init(zr); @@ -1648,7 +1658,7 @@ unload_dc10_cards (void) int i; for (i = 0; i < zoran_num; i++) - zoran_release(&zoran[i]); + zoran_release(zoran[i]); } module_init(init_dc10_cards); diff --git a/linux/drivers/media/video/zoran_card.h b/linux/drivers/media/video/zoran_card.h index 1b5c4171c..e4dc9d29b 100644 --- a/linux/drivers/media/video/zoran_card.h +++ b/linux/drivers/media/video/zoran_card.h @@ -41,7 +41,7 @@ extern int zr36067_debug; /* Anybody who uses more than four? */ #define BUZ_MAX 4 extern int zoran_num; -extern struct zoran zoran[BUZ_MAX]; +extern struct zoran *zoran[BUZ_MAX]; extern struct video_device zoran_template; diff --git a/linux/drivers/media/video/zoran_driver.c b/linux/drivers/media/video/zoran_driver.c index 989a6f7e0..433b469d6 100644 --- a/linux/drivers/media/video/zoran_driver.c +++ b/linux/drivers/media/video/zoran_driver.c @@ -1278,8 +1278,8 @@ zoran_open (struct inode *inode, /* find the device */ for (i = 0; i < zoran_num; i++) { - if (zoran[i].video_dev->minor == minor) { - zr = &zoran[i]; + if (zoran[i]->video_dev->minor == minor) { + zr = zoran[i]; break; } } -- cgit v1.2.3 From c88b19f6bfbf00c91ea3a890bc66a7560c6cda44 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 14 Jul 2008 12:28:59 +0000 Subject: zr36067: Load the avs6eyes chip drivers automatically From: Martin Samuelsson This enables the avs6eyes to load the bt866 and ks0127 drivers automatically. Signed-off-by: Martin Samuelsson Acked-by: Ronald Bultje Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/zoran_card.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/zoran_card.c b/linux/drivers/media/video/zoran_card.c index 4ffe998ba..6678c6de9 100644 --- a/linux/drivers/media/video/zoran_card.c +++ b/linux/drivers/media/video/zoran_card.c @@ -356,9 +356,15 @@ i2cid_to_modulename (u16 i2c_id) case I2C_DRIVERID_BT856: name = "bt856"; break; + case I2C_DRIVERID_BT866: + name = "bt866"; + break; case I2C_DRIVERID_VPX3220: name = "vpx3220"; break; + case I2C_DRIVERID_KS0127: + name = "ks0127"; + break; } return name; -- cgit v1.2.3 From 75a2c8ca0d26f57dfa9e0b8cc67ebbd63046a4a2 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Tue, 22 Jul 2008 12:09:33 +0200 Subject: gspca_sonixb sn9c103 + ov7630 autoexposure and cleanup From: Hans de Goede Andoni Zubimendi has been doing some testing with his sn9c103 cam with ov7630 sensor, and with this patch the exposure setting and autoexposure now work. This patch also removes some special cases in the shared ov6650 / ov7630 code which now are handled the same for both sensors and it adds a new special case which stops us from changing the hsync / vsync polarity settings from their default on the ov7630 (which we were doing as a side-effect of using the ov6650 exposure code for the ov7630). Last this patch removes the superficial difference between the OV7630 and OV7630_3 sensors. Signed-off-by: Andoni Zubimendi Signed-off-by: Hans de Goede --- linux/drivers/media/video/gspca/sonixb.c | 174 +++++++++++++++---------------- 1 file changed, 82 insertions(+), 92 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index 76a0677ed..5b510ebf2 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -44,6 +44,7 @@ struct sd { unsigned char brightness; unsigned char autogain; unsigned char autogain_ignore_frames; + unsigned char frames_to_drop; unsigned char freq; /* light freq filter setting */ unsigned char saturation; unsigned char hue; @@ -54,13 +55,13 @@ struct sd { #define SENSOR_HV7131R 0 #define SENSOR_OV6650 1 #define SENSOR_OV7630 2 -#define SENSOR_OV7630_3 3 -#define SENSOR_PAS106 4 -#define SENSOR_PAS202 5 -#define SENSOR_TAS5110 6 -#define SENSOR_TAS5130CXX 7 +#define SENSOR_PAS106 3 +#define SENSOR_PAS202 4 +#define SENSOR_TAS5110 5 +#define SENSOR_TAS5130CXX 6 char sensor_has_gain; __u8 sensor_addr; + __u8 reg11; }; #define COMP2 0x8f @@ -354,7 +355,7 @@ static const __u8 initOv7630_3[] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ }; -static const __u8 ov7630_sensor_init_com[][8] = { +static const __u8 ov7630_sensor_init[][8] = { {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ @@ -375,17 +376,6 @@ static const __u8 ov7630_sensor_init_com[][8] = { {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, }; -static const __u8 ov7630_sensor_init[][8] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */ - {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */ - {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ -}; -static const __u8 ov7630_sensor_init_3[][8] = { - {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10}, -}; static const __u8 initPas106[] = { 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, @@ -575,7 +565,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_OV6650: - case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2cOV[] = {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; @@ -668,7 +657,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev) case SENSOR_OV6650: gain >>= 1; /* fall thru */ - case SENSOR_OV7630_3: { + case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[1] = sd->sensor_addr; @@ -723,7 +712,7 @@ static void setexposure(struct gspca_dev *gspca_dev) break; } case SENSOR_OV6650: - case SENSOR_OV7630_3: { + case SENSOR_OV7630: { /* The ov6650 / ov7630 have 2 registers which both influence exposure, register 11, whose low nibble sets the nr off fps according to: fps = 30 / (low_nibble + 1) @@ -738,16 +727,20 @@ static void setexposure(struct gspca_dev *gspca_dev) The code maps our 0 - 510 ms exposure ctrl to these 2 registers, trying to keep fps as high as possible. */ - __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; - int reg10, reg11; + __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}; + int reg10, reg11, reg10_max; + /* ov6645 datasheet says reg10_max is 9a, but that uses tline * 2 * reg10 as formula for calculating texpo, the ov6650 probably uses the same formula as the 7730 which uses tline * 4 * reg10, which explains why the reg10max we've found experimentally for the ov6650 is exactly half that of the ov6645. The ov7630 datasheet says the max is 0x41. */ - const int reg10_max = (sd->sensor == SENSOR_OV6650) - ? 0x4d : 0x41; + if (sd->sensor == SENSOR_OV6650) { + reg10_max = 0x4d; + i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */ + } else + reg10_max = 0x41; reg11 = (60 * sd->exposure + 999) / 1000; if (reg11 < 1) @@ -768,20 +761,23 @@ static void setexposure(struct gspca_dev *gspca_dev) else if (reg10 > reg10_max) reg10 = reg10_max; + /* In 640x480, if the reg11 has less than 3, the image is + unstable (not enough bandwidth). */ + if (gspca_dev->width == 640 && reg11 < 3) + reg11 = 3; + /* Write reg 10 and reg11 low nibble */ i2c[1] = sd->sensor_addr; i2c[3] = reg10; i2c[4] |= reg11 - 1; - if (sd->sensor == SENSOR_OV7630_3) { - __u8 reg76 = reg10 & 0x03; - __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00, - 0x00, 0x00, 0x00, 0x10}; - reg10 >>= 2; - i2c_reg76[3] = reg76; - if (i2c_w(gspca_dev, i2c_reg76) < 0) - PDEBUG(D_ERR, "i2c error exposure"); - } - if (i2c_w(gspca_dev, i2c) < 0) + + /* If register 11 didn't change, don't change it */ + if (sd->reg11 == reg11 ) + i2c[0] = 0xa0; + + if (i2c_w(gspca_dev, i2c) == 0) + sd->reg11 = reg11; + else PDEBUG(D_ERR, "i2c error exposure"); break; } @@ -794,11 +790,11 @@ static void setfreq(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_OV6650: - case SENSOR_OV7630_3: { + case SENSOR_OV7630: { /* Framerate adjust register for artificial light 50 hz flicker - compensation, identical to ov6630 0x2b register, see ov6630 - datasheet. - 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ + compensation, for the ov6650 this is identical to ov6630 + 0x2b register, see ov6630 datasheet. + 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; switch (sd->freq) { default: @@ -825,7 +821,6 @@ static void setsaturation(struct gspca_dev *gspca_dev) switch (sd->sensor) { /* case SENSOR_OV6650: */ - case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[1] = sd->sensor_addr; @@ -846,7 +841,6 @@ static void sethue(struct gspca_dev *gspca_dev) switch (sd->sensor) { /* case SENSOR_OV6650: */ - case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[1] = sd->sensor_addr; @@ -866,7 +860,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) switch (sd->sensor) { /* case SENSOR_OV6650: */ - case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[1] = sd->sensor_addr; @@ -916,8 +909,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->fr_h_sz = 12; /* default size of the frame header */ sd->sd_desc.nctrls = 2; /* default nb of ctrls */ - sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ - product = id->idProduct; /* switch (id->idVendor) { */ /* case 0x0c45: * Sonix */ @@ -948,17 +939,14 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x6019: /* SN9C101 */ case 0x602c: /* SN9C102 */ case 0x602e: /* SN9C102 */ - sd->sensor = SENSOR_OV7630; - sd->sensor_addr = 0x21; - break; case 0x60b0: /* SN9C103 */ - sd->sensor = SENSOR_OV7630_3; + sd->sensor = SENSOR_OV7630; sd->sensor_addr = 0x21; - sd->fr_h_sz = 18; /* size of frame header */ sd->sensor_has_gain = 1; - sd->sd_desc.nctrls = 8; + sd->sd_desc.nctrls = 5; sd->sd_desc.dq_callback = do_autogain; - sd->autogain = 0; + if (product == 0x60b0) + sd->fr_h_sz = 18; /* size of frame header */ break; case 0x6024: /* SN9C102 */ case 0x6025: /* SN9C102 */ @@ -984,7 +972,7 @@ static int sd_config(struct gspca_dev *gspca_dev, if (!sif) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - if (sd->sensor == SENSOR_OV7630_3) { + if (product == 0x60b0) { /* SN9C103 with OV7630 */ /* We only have 320x240 & 640x480 */ cam->cam_mode++; cam->nmodes--; @@ -996,12 +984,15 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; + sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; sd->contrast = CONTRAST_DEF; sd->saturation = SATURATION_DEF; sd->hue = HUE_DEF; - if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ + + if (product == 0x60b0) /* SN9C103 with OV7630 */ reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); + return 0; } @@ -1035,7 +1026,7 @@ static void pas106_i2cinit(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int mode, l; + int mode, l = 0x1f; const __u8 *sn9c10x; __u8 reg01, reg17; __u8 reg17_19[3]; @@ -1055,13 +1046,11 @@ static void sd_start(struct gspca_dev *gspca_dev) reg17_19[2] = 0x20; break; case SENSOR_OV7630: - sn9c10x = initOv7630; - reg17_19[0] = 0x68; - reg17_19[1] = (mode << 4) | COMP2; - reg17_19[2] = MCK_INIT1; - break; - case SENSOR_OV7630_3: - sn9c10x = initOv7630_3; + if (sd->fr_h_sz == 18) { /* SN9C103 */ + sn9c10x = initOv7630_3; + l = sizeof initOv7630_3; + } else + sn9c10x = initOv7630; reg17_19[0] = 0x68; reg17_19[1] = (mode << 4) | COMP2; reg17_19[2] = MCK_INIT1; @@ -1092,30 +1081,22 @@ static void sd_start(struct gspca_dev *gspca_dev) reg17_19[2] = mode ? 0x23 : 0x43; break; } - switch (sd->sensor) { - case SENSOR_OV7630: + + /* Special case for SN9C101/2 with OV 7630 */ + /* HDG: is this really necessary we overwrite the values immediately + afterwards with the ones from the template ?? */ + if (sd->sensor == SENSOR_OV7630 && sd->fr_h_sz == 12) { reg01 = 0x06; reg17 = 0x29; - l = sizeof initOv7630; - break; - case SENSOR_OV7630_3: - reg01 = 0x44; - reg17 = 0x68; - l = sizeof initOv7630_3; - break; - default: + } else { reg01 = sn9c10x[0]; reg17 = sn9c10x[0x17 - 1]; - l = 0x1f; - break; } /* reg 0x01 bit 2 video transfert on */ reg_w(gspca_dev, 0x01, ®01, 1); /* reg 0x17 SensorClk enable inv Clk 0x60 */ reg_w(gspca_dev, 0x17, ®17, 1); -/*fixme: for ov7630 102 - reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */ /* Set the registers from the template */ reg_w_big(gspca_dev, 0x01, sn9c10x, l); switch (sd->sensor) { @@ -1128,17 +1109,13 @@ static void sd_start(struct gspca_dev *gspca_dev) sizeof ov6650_sensor_init); break; case SENSOR_OV7630: - i2c_w_vector(gspca_dev, ov7630_sensor_init_com, - sizeof ov7630_sensor_init_com); - msleep(200); i2c_w_vector(gspca_dev, ov7630_sensor_init, sizeof ov7630_sensor_init); - break; - case SENSOR_OV7630_3: - i2c_w_vector(gspca_dev, ov7630_sensor_init_com, - sizeof ov7630_sensor_init_com); - msleep(200); - i2c_w(gspca_dev, ov7630_sensor_init_3[mode]); + if (sd->fr_h_sz == 18) { /* SN9C103 */ + const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00, + 0x00, 0x00, 0x10 }; + i2c_w(gspca_dev, i2c); + } break; case SENSOR_PAS106: pas106_i2cinit(gspca_dev); @@ -1178,6 +1155,8 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x18, ®17_19[1], 2); msleep(20); + sd->reg11 = -1; + setgain(gspca_dev); setbrightness(gspca_dev); setexposure(gspca_dev); @@ -1186,6 +1165,7 @@ static void sd_start(struct gspca_dev *gspca_dev) sethue(gspca_dev); setcontrast(gspca_dev); + sd->frames_to_drop = 0; sd->autogain_ignore_frames = 0; atomic_set(&sd->avg_lum, -1); } @@ -1231,21 +1211,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, && data[3 + i] == 0xc4 && data[4 + i] == 0xc4 && data[5 + i] == 0x96) { /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, 0); + int lum = -1; + int pkt_type = LAST_PACKET; + if (len - i < sd->fr_h_sz) { - atomic_set(&sd->avg_lum, -1); PDEBUG(D_STREAM, "packet too short to" " get avg brightness"); } else if (sd->fr_h_sz == 12) { - atomic_set(&sd->avg_lum, - data[i + 8] + - (data[i + 9] << 8)); + lum = data[i + 8] + (data[i + 9] << 8); } else { - atomic_set(&sd->avg_lum, - data[i + 9] + - (data[i + 10] << 8)); + lum = data[i + 9] + + (data[i + 10] << 8); } + if (lum == 0) { + lum = -1; + sd->frames_to_drop = 2; + } + atomic_set(&sd->avg_lum, lum); + + if (sd->frames_to_drop) { + sd->frames_to_drop--; + pkt_type = DISCARD_PACKET; + } + + frame = gspca_frame_add(gspca_dev, pkt_type, + frame, data, 0); data += i + sd->fr_h_sz; len -= i + sd->fr_h_sz; gspca_frame_add(gspca_dev, FIRST_PACKET, -- cgit v1.2.3 From e356bb63e6e5be00ec1eada0da9960088c15c564 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Tue, 22 Jul 2008 12:13:21 +0200 Subject: gspca_sonixb remove non working ovXXXX contrast, hue and saturation ctrls From: Hans de Goede gspca_sonixb remove non working ovXXXX contrast, hue and saturation ctrls Signed-off-by: Hans de Goede --- linux/drivers/media/video/gspca/sonixb.c | 171 ------------------------------- 1 file changed, 171 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index 5b510ebf2..ff33621b5 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -46,9 +46,6 @@ struct sd { unsigned char autogain_ignore_frames; unsigned char frames_to_drop; unsigned char freq; /* light freq filter setting */ - unsigned char saturation; - unsigned char hue; - unsigned char contrast; unsigned char fr_h_sz; /* size of frame header */ char sensor; /* Type of image sensor chip */ @@ -93,12 +90,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); -static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { { @@ -175,48 +166,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setfreq, .get = sd_getfreq, }, - { - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 1, -#define SATURATION_DEF 127 - .default_value = SATURATION_DEF, - }, - .set = sd_setsaturation, - .get = sd_getsaturation, - }, - { - { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = 0, - .maximum = 255, - .step = 1, -#define HUE_DEF 127 - .default_value = HUE_DEF, - }, - .set = sd_sethue, - .get = sd_gethue, - }, - { - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 1, -#define CONTRAST_DEF 127 - .default_value = CONTRAST_DEF, - }, - .set = sd_setcontrast, - .get = sd_getcontrast, - }, }; static struct v4l2_pix_format vga_mode[] = { @@ -815,66 +764,6 @@ static void setfreq(struct gspca_dev *gspca_dev) } } -static void setsaturation(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { -/* case SENSOR_OV6650: */ - case SENSOR_OV7630: { - __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[1] = sd->sensor_addr; - i2c[3] = sd->saturation & 0xf0; - if (i2c_w(gspca_dev, i2c) < 0) - PDEBUG(D_ERR, "i2c error setsaturation"); - else - PDEBUG(D_CONF, "saturation set to: %d", - (int)sd->saturation); - break; - } - } -} - -static void sethue(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { -/* case SENSOR_OV6650: */ - case SENSOR_OV7630: { - __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[1] = sd->sensor_addr; - i2c[3] = 0x20 | (sd->hue >> 3); - if (i2c_w(gspca_dev, i2c) < 0) - PDEBUG(D_ERR, "i2c error setsaturation"); - else - PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue); - break; - } - } -} - -static void setcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { -/* case SENSOR_OV6650: */ - case SENSOR_OV7630: { - __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[1] = sd->sensor_addr; - i2c[3] = 0x20 | (sd->contrast >> 3); - if (i2c_w(gspca_dev, i2c) < 0) - PDEBUG(D_ERR, "i2c error setcontrast"); - else - PDEBUG(D_CONF, "contrast set to: %d", - (int)sd->contrast); - break; - } - } -} - - static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -986,9 +875,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->exposure = EXPOSURE_DEF; sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; - sd->contrast = CONTRAST_DEF; - sd->saturation = SATURATION_DEF; - sd->hue = HUE_DEF; if (product == 0x60b0) /* SN9C103 with OV7630 */ reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); @@ -1161,9 +1047,6 @@ static void sd_start(struct gspca_dev *gspca_dev) setbrightness(gspca_dev); setexposure(gspca_dev); setfreq(gspca_dev); - setsaturation(gspca_dev); - sethue(gspca_dev); - setcontrast(gspca_dev); sd->frames_to_drop = 0; sd->autogain_ignore_frames = 0; @@ -1350,60 +1233,6 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->saturation = val; - if (gspca_dev->streaming) - setsaturation(gspca_dev); - return 0; -} - -static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->saturation; - return 0; -} - -static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->hue = val; - if (gspca_dev->streaming) - sethue(gspca_dev); - return 0; -} - -static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->hue; - return 0; -} - -static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->contrast = val; - if (gspca_dev->streaming) - setcontrast(gspca_dev); - return 0; -} - -static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->contrast; - return 0; -} - static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { -- cgit v1.2.3 From ed2a63fee50e44cb3232a0d1b3a84c13ca7dfb96 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Tue, 22 Jul 2008 13:39:24 +0200 Subject: gspca_sonixb remove some no longer needed sn9c103+ov7630 special cases From: Andoni Zubimendi gspca_sonixb remove some no longer needed sn9c103+ov7630 special cases Signed-off-by: Andoni Zubimendi Signed-off-by: Hans de Goede --- linux/drivers/media/video/gspca/sonixb.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index ff33621b5..aaf93e2d6 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -198,8 +198,6 @@ static struct v4l2_pix_format sif_mode[] = { .priv = 0}, }; -static const __u8 probe_ov7630[] = {0x08, 0x44}; - static const __u8 initHv7131[] = { 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -861,11 +859,6 @@ static int sd_config(struct gspca_dev *gspca_dev, if (!sif) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - if (product == 0x60b0) { /* SN9C103 with OV7630 */ - /* We only have 320x240 & 640x480 */ - cam->cam_mode++; - cam->nmodes--; - } } else { cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); @@ -876,9 +869,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; - if (product == 0x60b0) /* SN9C103 with OV7630 */ - reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); - return 0; } -- cgit v1.2.3 From 6663286ec924d58968a88f5cb07ba47bf5bb41b2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 22 Jul 2008 20:50:31 +0200 Subject: tveeprom/ivtv: fix usage of has_ir field From: Hans Verkuil has_ir was set to and compared to -1 in several cases, even though it is an u32. ivtv also contained a FIXME for an old kernel that could be removed. Thanks to Roel Kluin for creating an initial patch for this. Although I chose a different solution here it did help in pointing out the problem. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-driver.c | 5 ++--- linux/drivers/media/video/tveeprom.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index c0b98a83b..efdb59193 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -465,9 +465,8 @@ static void ivtv_process_eeprom(struct ivtv *itv) if (itv->options.radio == -1) itv->options.radio = (tv.has_radio != 0); /* only enable newi2c if an IR blaster is present */ - /* FIXME: for 2.6.20 the test against 2 should be removed */ - if (itv->options.newi2c == -1 && tv.has_ir != -1 && tv.has_ir != 2) { - itv->options.newi2c = (tv.has_ir & 2) ? 1 : 0; + if (itv->options.newi2c == -1 && tv.has_ir) { + itv->options.newi2c = (tv.has_ir & 4) ? 1 : 0; if (itv->options.newi2c) { IVTV_INFO("Reopen i2c bus for IR-blaster support\n"); exit_ivtv_i2c(itv); diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c index dc0bd9fda..54c44ee8f 100644 --- a/linux/drivers/media/video/tveeprom.c +++ b/linux/drivers/media/video/tveeprom.c @@ -484,7 +484,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, tvee->has_radio = eeprom_data[i+len-1]; /* old style tag, don't know how to detect IR presence, mark as unknown. */ - tvee->has_ir = -1; + tvee->has_ir = 0; tvee->model = eeprom_data[i+8] + (eeprom_data[i+9] << 8); @@ -604,7 +604,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, case 0x0f: /* tag 'IRInfo' */ - tvee->has_ir = eeprom_data[i+1]; + tvee->has_ir = 1 | (eeprom_data[i+1] << 1); break; /* case 0x10: tag 'VBIInfo' */ @@ -704,14 +704,14 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, tveeprom_info("decoder processor is %s (idx %d)\n", STRM(decoderIC, tvee->decoder_processor), tvee->decoder_processor); - if (tvee->has_ir == -1) - tveeprom_info("has %sradio\n", - tvee->has_radio ? "" : "no "); - else + if (tvee->has_ir) tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n", tvee->has_radio ? "" : "no ", - (tvee->has_ir & 1) ? "" : "no ", - (tvee->has_ir & 2) ? "" : "no "); + (tvee->has_ir & 2) ? "" : "no ", + (tvee->has_ir & 4) ? "" : "no "); + else + tveeprom_info("has %sradio\n", + tvee->has_radio ? "" : "no "); } EXPORT_SYMBOL(tveeprom_hauppauge_analog); -- cgit v1.2.3 From c241933ee2723ed8ac2f3e493a3abfa9a8aa35fa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 23 Jul 2008 10:09:15 +0200 Subject: v4l: remove obsolete audiochip.h From: Hans Verkuil Converted the last users of audiochip.h to the v4l2-chip-ident.h header and remove the now unused audiochip.h header. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx23885/cx23885-video.c | 2 +- linux/drivers/media/video/cx88/cx88-cards.c | 2 +- linux/drivers/media/video/cx88/cx88-video.c | 4 +- linux/drivers/media/video/cx88/cx88.h | 4 +- linux/drivers/media/video/em28xx/em28xx-cards.c | 4 +- linux/drivers/media/video/tveeprom.c | 104 +++++++++++---------- .../drivers/media/video/usbvision/usbvision-core.c | 1 - .../media/video/usbvision/usbvision-video.c | 1 - 8 files changed, 61 insertions(+), 61 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index b3d0902e1..6cb578434 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -1790,7 +1790,7 @@ int cx23885_video_register(struct cx23885_dev *dev) if (TUNER_ABSENT != core->tuner_type) request_module("tuner"); - if (cx23885_boards[dev->board].audio_chip == AUDIO_CHIP_WM8775) + if (cx23885_boards[dev->board].audio_chip == V4L2_IDENT_WM8775) request_module("wm8775"); #endif diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index 9329dbf6a..871ba1992 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -1381,7 +1381,7 @@ static const struct cx88_board cx88_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, - .audio_chip = AUDIO_CHIP_WM8775, + .audio_chip = V4L2_IDENT_WM8775, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index f26232345..8469f9d59 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -449,7 +449,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) the initialization. Some boards may use different routes for different inputs. HVR-1300 surely does */ if (core->board.audio_chip && - core->board.audio_chip == AUDIO_CHIP_WM8775) { + core->board.audio_chip == V4L2_IDENT_WM8775) { struct v4l2_routing route; route.input = INPUT(input).audioroute; @@ -2141,7 +2141,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* load and configure helper modules */ - if (core->board.audio_chip == AUDIO_CHIP_WM8775) + if (core->board.audio_chip == V4L2_IDENT_WM8775) request_module("wm8775"); switch (core->boardnr) { diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index 3e4b80617..751176e7a 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -29,8 +29,8 @@ #include #include #include +#include #include -#include #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) #include #endif @@ -253,7 +253,7 @@ struct cx88_board { struct cx88_input input[MAX_CX88_INPUT]; struct cx88_input radio; enum cx88_board_type mpeg; - enum audiochip audio_chip; + unsigned int audio_chip; }; struct cx88_subid { diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 871d81242..aa11618ef 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -33,8 +33,8 @@ #include #include #include -#include #include +#include #include "em28xx.h" @@ -837,7 +837,7 @@ void em28xx_card_setup(struct em28xx *dev) dev->tuner_type = tv.tuner_type; - if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { + if (tv.audio_processor == V4L2_IDENT_MSPX4XX) { dev->i2s_speed = 2048000; dev->has_msp34xx = 1; } diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c index dc0bd9fda..345d4351a 100644 --- a/linux/drivers/media/video/tveeprom.c +++ b/linux/drivers/media/video/tveeprom.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include "compat.h" MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); @@ -262,70 +262,72 @@ hauppauge_tuner[] = { TUNER_ABSENT, "MaxLinear MXL5005_v2"}, { TUNER_PHILIPS_TDA8290, "Philips 18271_8295"}, /* 150-159 */ - { TUNER_ABSENT, "Xceive XC5000"}, + { TUNER_ABSENT, "Xceive XC5000"}, }; +/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are + * internal to a video chip, i.e. not a separate audio chip. */ static struct HAUPPAUGE_AUDIOIC { - enum audiochip id; + u32 id; char *name; } audioIC[] = { /* 0-4 */ - {AUDIO_CHIP_NONE, "None"}, - {AUDIO_CHIP_TEA6300, "TEA6300"}, - {AUDIO_CHIP_TEA6300, "TEA6320"}, - {AUDIO_CHIP_TDA985X, "TDA9850"}, - {AUDIO_CHIP_MSP34XX, "MSP3400C"}, + { V4L2_IDENT_NONE, "None" }, + { V4L2_IDENT_UNKNOWN, "TEA6300" }, + { V4L2_IDENT_UNKNOWN, "TEA6320" }, + { V4L2_IDENT_UNKNOWN, "TDA9850" }, + { V4L2_IDENT_MSPX4XX, "MSP3400C" }, /* 5-9 */ - {AUDIO_CHIP_MSP34XX, "MSP3410D"}, - {AUDIO_CHIP_MSP34XX, "MSP3415"}, - {AUDIO_CHIP_MSP34XX, "MSP3430"}, - {AUDIO_CHIP_MSP34XX, "MSP3438"}, - {AUDIO_CHIP_UNKNOWN, "CS5331"}, + { V4L2_IDENT_MSPX4XX, "MSP3410D" }, + { V4L2_IDENT_MSPX4XX, "MSP3415" }, + { V4L2_IDENT_MSPX4XX, "MSP3430" }, + { V4L2_IDENT_MSPX4XX, "MSP3438" }, + { V4L2_IDENT_UNKNOWN, "CS5331" }, /* 10-14 */ - {AUDIO_CHIP_MSP34XX, "MSP3435"}, - {AUDIO_CHIP_MSP34XX, "MSP3440"}, - {AUDIO_CHIP_MSP34XX, "MSP3445"}, - {AUDIO_CHIP_MSP34XX, "MSP3411"}, - {AUDIO_CHIP_MSP34XX, "MSP3416"}, + { V4L2_IDENT_MSPX4XX, "MSP3435" }, + { V4L2_IDENT_MSPX4XX, "MSP3440" }, + { V4L2_IDENT_MSPX4XX, "MSP3445" }, + { V4L2_IDENT_MSPX4XX, "MSP3411" }, + { V4L2_IDENT_MSPX4XX, "MSP3416" }, /* 15-19 */ - {AUDIO_CHIP_MSP34XX, "MSP3425"}, - {AUDIO_CHIP_MSP34XX, "MSP3451"}, - {AUDIO_CHIP_MSP34XX, "MSP3418"}, - {AUDIO_CHIP_UNKNOWN, "Type 0x12"}, - {AUDIO_CHIP_UNKNOWN, "OKI7716"}, + { V4L2_IDENT_MSPX4XX, "MSP3425" }, + { V4L2_IDENT_MSPX4XX, "MSP3451" }, + { V4L2_IDENT_MSPX4XX, "MSP3418" }, + { V4L2_IDENT_UNKNOWN, "Type 0x12" }, + { V4L2_IDENT_UNKNOWN, "OKI7716" }, /* 20-24 */ - {AUDIO_CHIP_MSP34XX, "MSP4410"}, - {AUDIO_CHIP_MSP34XX, "MSP4420"}, - {AUDIO_CHIP_MSP34XX, "MSP4440"}, - {AUDIO_CHIP_MSP34XX, "MSP4450"}, - {AUDIO_CHIP_MSP34XX, "MSP4408"}, + { V4L2_IDENT_MSPX4XX, "MSP4410" }, + { V4L2_IDENT_MSPX4XX, "MSP4420" }, + { V4L2_IDENT_MSPX4XX, "MSP4440" }, + { V4L2_IDENT_MSPX4XX, "MSP4450" }, + { V4L2_IDENT_MSPX4XX, "MSP4408" }, /* 25-29 */ - {AUDIO_CHIP_MSP34XX, "MSP4418"}, - {AUDIO_CHIP_MSP34XX, "MSP4428"}, - {AUDIO_CHIP_MSP34XX, "MSP4448"}, - {AUDIO_CHIP_MSP34XX, "MSP4458"}, - {AUDIO_CHIP_MSP34XX, "Type 0x1d"}, + { V4L2_IDENT_MSPX4XX, "MSP4418" }, + { V4L2_IDENT_MSPX4XX, "MSP4428" }, + { V4L2_IDENT_MSPX4XX, "MSP4448" }, + { V4L2_IDENT_MSPX4XX, "MSP4458" }, + { V4L2_IDENT_MSPX4XX, "Type 0x1d" }, /* 30-34 */ - {AUDIO_CHIP_INTERNAL, "CX880"}, - {AUDIO_CHIP_INTERNAL, "CX881"}, - {AUDIO_CHIP_INTERNAL, "CX883"}, - {AUDIO_CHIP_INTERNAL, "CX882"}, - {AUDIO_CHIP_INTERNAL, "CX25840"}, + { V4L2_IDENT_AMBIGUOUS, "CX880" }, + { V4L2_IDENT_AMBIGUOUS, "CX881" }, + { V4L2_IDENT_AMBIGUOUS, "CX883" }, + { V4L2_IDENT_AMBIGUOUS, "CX882" }, + { V4L2_IDENT_AMBIGUOUS, "CX25840" }, /* 35-39 */ - {AUDIO_CHIP_INTERNAL, "CX25841"}, - {AUDIO_CHIP_INTERNAL, "CX25842"}, - {AUDIO_CHIP_INTERNAL, "CX25843"}, - {AUDIO_CHIP_INTERNAL, "CX23418"}, - {AUDIO_CHIP_INTERNAL, "CX23885"}, + { V4L2_IDENT_AMBIGUOUS, "CX25841" }, + { V4L2_IDENT_AMBIGUOUS, "CX25842" }, + { V4L2_IDENT_AMBIGUOUS, "CX25843" }, + { V4L2_IDENT_AMBIGUOUS, "CX23418" }, + { V4L2_IDENT_AMBIGUOUS, "CX23885" }, /* 40-44 */ - {AUDIO_CHIP_INTERNAL, "CX23888"}, - {AUDIO_CHIP_INTERNAL, "SAA7131"}, - {AUDIO_CHIP_INTERNAL, "CX23887"}, - {AUDIO_CHIP_INTERNAL, "SAA7164"}, - {AUDIO_CHIP_INTERNAL, "AU8522"}, + { V4L2_IDENT_AMBIGUOUS, "CX23888" }, + { V4L2_IDENT_AMBIGUOUS, "SAA7131" }, + { V4L2_IDENT_AMBIGUOUS, "CX23887" }, + { V4L2_IDENT_AMBIGUOUS, "SAA7164" }, + { V4L2_IDENT_AMBIGUOUS, "AU8522" }, }; /* This list is supplied by Hauppauge. Thanks! */ @@ -510,7 +512,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, if (audioic < ARRAY_SIZE(audioIC)) tvee->audio_processor = audioIC[audioic].id; else - tvee->audio_processor = AUDIO_CHIP_UNKNOWN; + tvee->audio_processor = V4L2_IDENT_UNKNOWN; break; /* case 0x03: tag 'EEInfo' */ @@ -543,7 +545,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, if (audioic < ARRAY_SIZE(audioIC)) tvee->audio_processor = audioIC[audioic].id; else - tvee->audio_processor = AUDIO_CHIP_UNKNOWN; + tvee->audio_processor = V4L2_IDENT_UNKNOWN; break; @@ -691,7 +693,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, t_fmt_name2[6], t_fmt_name2[7], t_format2); if (audioic < 0) { tveeprom_info("audio processor is unknown (no idx)\n"); - tvee->audio_processor = AUDIO_CHIP_UNKNOWN; + tvee->audio_processor = V4L2_IDENT_UNKNOWN; } else { if (audioic < ARRAY_SIZE(audioIC)) tveeprom_info("audio processor is %s (idx %d)\n", diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c index bf464540c..4c391727e 100644 --- a/linux/drivers/media/video/usbvision/usbvision-core.c +++ b/linux/drivers/media/video/usbvision/usbvision-core.c @@ -43,7 +43,6 @@ #include #include #include -#include #include diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 56cd685d3..5984c7562 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -67,7 +67,6 @@ #include #include #include -#include #include -- cgit v1.2.3 From 6b9a288b7689b76db669d5fb192a5190fcafbcc8 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Wed, 23 Jul 2008 12:04:39 +0200 Subject: gspca_sonixb remove one more no longer needed special case from the code From: Hans de Goede gspca_sonixb remove one more no longer needed special case from the code Signed-off-by: Hans de Goede --- linux/drivers/media/video/gspca/sonixb.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index aaf93e2d6..74b8f0409 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -904,7 +904,6 @@ static void sd_start(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int mode, l = 0x1f; const __u8 *sn9c10x; - __u8 reg01, reg17; __u8 reg17_19[3]; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; @@ -958,21 +957,10 @@ static void sd_start(struct gspca_dev *gspca_dev) break; } - /* Special case for SN9C101/2 with OV 7630 */ - /* HDG: is this really necessary we overwrite the values immediately - afterwards with the ones from the template ?? */ - if (sd->sensor == SENSOR_OV7630 && sd->fr_h_sz == 12) { - reg01 = 0x06; - reg17 = 0x29; - } else { - reg01 = sn9c10x[0]; - reg17 = sn9c10x[0x17 - 1]; - } - /* reg 0x01 bit 2 video transfert on */ - reg_w(gspca_dev, 0x01, ®01, 1); + reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); /* reg 0x17 SensorClk enable inv Clk 0x60 */ - reg_w(gspca_dev, 0x17, ®17, 1); + reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); /* Set the registers from the template */ reg_w_big(gspca_dev, 0x01, sn9c10x, l); switch (sd->sensor) { -- cgit v1.2.3 From d3749e64c4be27a3230d2a602c928d10eb2dd815 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 23 Jul 2008 19:28:23 -0400 Subject: cx18: Fix 32 kHz audio sample output rate for analog tuner SIF input From: Andy Walls cx18: Fix 32 kHz audio sample output rate for analog tuner SIF input so it works. The AUX_PLL VCO was being operated at 196.6 MHz out of the spec'ed 200-600 MHz range. Fixed the multipler and post dividers to operate the VCO within specification and added comments on how magic numbers are derived. Thanks to Hans Verkuil for pointing out this interesting problem to solve. Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-audio.c | 41 ++++++++++++++++++-------- 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx18/cx18-av-audio.c b/linux/drivers/media/video/cx18/cx18-av-audio.c index c40a286de..7245d37ef 100644 --- a/linux/drivers/media/video/cx18/cx18-av-audio.c +++ b/linux/drivers/media/video/cx18/cx18-av-audio.c @@ -30,7 +30,6 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) if (freq != 32000 && freq != 44100 && freq != 48000) return -EINVAL; - /* common for all inputs and rates */ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ cx18_av_write(cx, 0x127, 0x50); @@ -38,15 +37,20 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) switch (freq) { case 32000: /* VID_PLL and AUX_PLL */ - cx18_av_write4(cx, 0x108, 0x1006040f); + cx18_av_write4(cx, 0x108, 0x1408040f); /* AUX_PLL_FRAC */ - cx18_av_write4(cx, 0x110, 0x01bb39ee); + /* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */ + cx18_av_write4(cx, 0x110, 0x012a0863); - /* src3/4/6_ctl = 0x0801f77f */ + /* src3/4/6_ctl */ + /* 0x1.f77f = (4 * 15734.26) / 32000 */ cx18_av_write4(cx, 0x900, 0x0801f77f); cx18_av_write4(cx, 0x904, 0x0801f77f); cx18_av_write4(cx, 0x90c, 0x0801f77f); + + /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ + cx18_av_write(cx, 0x127, 0x54); break; case 44100: @@ -54,9 +58,11 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1009040f); /* AUX_PLL_FRAC */ + /* 0x9.7635eb * 28,636,363 / 0x10 = 44100 * 384 */ cx18_av_write4(cx, 0x110, 0x00ec6bd6); - /* src3/4/6_ctl = 0x08016d59 */ + /* src3/4/6_ctl */ + /* 0x1.6d59 = (4 * 15734.26) / 44100 */ cx18_av_write4(cx, 0x900, 0x08016d59); cx18_av_write4(cx, 0x904, 0x08016d59); cx18_av_write4(cx, 0x90c, 0x08016d59); @@ -67,9 +73,11 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x100a040f); /* AUX_PLL_FRAC */ + /* 0xa.4c6b728 * 28,636,363 / 0x10 = 48000 * 384 */ cx18_av_write4(cx, 0x110, 0x0098d6e5); - /* src3/4/6_ctl = 0x08014faa */ + /* src3/4/6_ctl */ + /* 0x1.4faa = (4 * 15734.26) / 48000 */ cx18_av_write4(cx, 0x900, 0x08014faa); cx18_av_write4(cx, 0x904, 0x08014faa); cx18_av_write4(cx, 0x90c, 0x08014faa); @@ -82,12 +90,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1e08040f); /* AUX_PLL_FRAC */ + /* 0x8.9504348 * 28,636,363 / 0x1e = 32000 * 256 */ cx18_av_write4(cx, 0x110, 0x012a0869); - /* src1_ctl = 0x08010000 */ + /* src1_ctl */ + /* 0x1.0000 = 32000/32000 */ cx18_av_write4(cx, 0x8f8, 0x08010000); - /* src3/4/6_ctl = 0x08020000 */ + /* src3/4/6_ctl */ + /* 0x2.0000 = 2 * (32000/32000) */ cx18_av_write4(cx, 0x900, 0x08020000); cx18_av_write4(cx, 0x904, 0x08020000); cx18_av_write4(cx, 0x90c, 0x08020000); @@ -101,12 +112,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1809040f); /* AUX_PLL_FRAC */ + /* 0x9.76346B * 28,636,363 / 0x18 = 44100 * 256 */ cx18_av_write4(cx, 0x110, 0x00ec6bd6); - /* src1_ctl = 0x08010000 */ + /* src1_ctl */ + /* 0x1.60cd = 44100/32000 */ cx18_av_write4(cx, 0x8f8, 0x080160cd); - /* src3/4/6_ctl = 0x08020000 */ + /* src3/4/6_ctl */ + /* 0x1.7385 = 2 * (32000/44100) */ cx18_av_write4(cx, 0x900, 0x08017385); cx18_av_write4(cx, 0x904, 0x08017385); cx18_av_write4(cx, 0x90c, 0x08017385); @@ -117,12 +131,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x180a040f); /* AUX_PLL_FRAC */ + /* 0xa.4c6b728 * 28,636,363 / 0x18 = 48000 * 256 */ cx18_av_write4(cx, 0x110, 0x0098d6e5); - /* src1_ctl = 0x08010000 */ + /* src1_ctl */ + /* 0x1.8000 = 48000/32000 */ cx18_av_write4(cx, 0x8f8, 0x08018000); - /* src3/4/6_ctl = 0x08020000 */ + /* src3/4/6_ctl */ + /* 0x1.5555 = 2 * (32000/48000) */ cx18_av_write4(cx, 0x900, 0x08015555); cx18_av_write4(cx, 0x904, 0x08015555); cx18_av_write4(cx, 0x90c, 0x08015555); -- cgit v1.2.3 From 75e626f6a8de25ae7225cf0510c96d1fac4f23aa Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 25 Jul 2008 14:03:08 -0400 Subject: cx18: Lock the aux PLL to the video pixle rate for analog captures From: Andy Walls cx18: Lock the aux PLL to the video pixel rate for analog captures. The datasheet for the CX25840 says this is important for MPEG encoding applications. To ensure the PLL locking was correct, also fixed the aux PLL's multiplier to be computed based on a precise crystal freq of 4.5 MHz/286 * 455/2 * 8 = 28636363.6363... instead of the imporperly rounded 28636363. Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-av-audio.c | 80 ++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx18/cx18-av-audio.c b/linux/drivers/media/video/cx18/cx18-av-audio.c index 7245d37ef..0b5583788 100644 --- a/linux/drivers/media/video/cx18/cx18-av-audio.c +++ b/linux/drivers/media/video/cx18/cx18-av-audio.c @@ -51,6 +51,16 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ cx18_av_write(cx, 0x127, 0x54); + + /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */ + cx18_av_write4(cx, 0x12c, 0x11202fff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = + * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa10d2ef8); break; case 44100: @@ -58,14 +68,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1009040f); /* AUX_PLL_FRAC */ - /* 0x9.7635eb * 28,636,363 / 0x10 = 44100 * 384 */ - cx18_av_write4(cx, 0x110, 0x00ec6bd6); + /* 0x9.7635e7 * 28,636,363.63 / 0x10 = 44100 * 384 */ + cx18_av_write4(cx, 0x110, 0x00ec6bce); /* src3/4/6_ctl */ /* 0x1.6d59 = (4 * 15734.26) / 44100 */ cx18_av_write4(cx, 0x900, 0x08016d59); cx18_av_write4(cx, 0x904, 0x08016d59); cx18_av_write4(cx, 0x90c, 0x08016d59); + + /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */ + cx18_av_write4(cx, 0x12c, 0x112092ff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = + * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa11d4bf8); break; case 48000: @@ -73,14 +93,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x100a040f); /* AUX_PLL_FRAC */ - /* 0xa.4c6b728 * 28,636,363 / 0x10 = 48000 * 384 */ - cx18_av_write4(cx, 0x110, 0x0098d6e5); + /* 0xa.4c6b6ea * 28,636,363.63 / 0x10 = 48000 * 384 */ + cx18_av_write4(cx, 0x110, 0x0098d6dd); /* src3/4/6_ctl */ /* 0x1.4faa = (4 * 15734.26) / 48000 */ cx18_av_write4(cx, 0x900, 0x08014faa); cx18_av_write4(cx, 0x904, 0x08014faa); cx18_av_write4(cx, 0x90c, 0x08014faa); + + /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */ + cx18_av_write4(cx, 0x12c, 0x11205fff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x1193f8 = 143999.000 * 8 = + * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa11193f8); break; } } else { @@ -90,8 +120,8 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1e08040f); /* AUX_PLL_FRAC */ - /* 0x8.9504348 * 28,636,363 / 0x1e = 32000 * 256 */ - cx18_av_write4(cx, 0x110, 0x012a0869); + /* 0x8.9504318 * 28,636,363.63 / 0x1e = 32000 * 256 */ + cx18_av_write4(cx, 0x110, 0x012a0863); /* src1_ctl */ /* 0x1.0000 = 32000/32000 */ @@ -105,6 +135,16 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ cx18_av_write(cx, 0x127, 0x54); + + /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */ + cx18_av_write4(cx, 0x12c, 0x11201fff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = + * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa10d2ef8); break; case 44100: @@ -112,8 +152,8 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1809040f); /* AUX_PLL_FRAC */ - /* 0x9.76346B * 28,636,363 / 0x18 = 44100 * 256 */ - cx18_av_write4(cx, 0x110, 0x00ec6bd6); + /* 0x9.7635e74 * 28,636,363.63 / 0x18 = 44100 * 256 */ + cx18_av_write4(cx, 0x110, 0x00ec6bce); /* src1_ctl */ /* 0x1.60cd = 44100/32000 */ @@ -124,6 +164,16 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x900, 0x08017385); cx18_av_write4(cx, 0x904, 0x08017385); cx18_av_write4(cx, 0x90c, 0x08017385); + + /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */ + cx18_av_write4(cx, 0x12c, 0x112061ff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = + * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa11d4bf8); break; case 48000: @@ -131,8 +181,8 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x180a040f); /* AUX_PLL_FRAC */ - /* 0xa.4c6b728 * 28,636,363 / 0x18 = 48000 * 256 */ - cx18_av_write4(cx, 0x110, 0x0098d6e5); + /* 0xa.4c6b6ea * 28,636,363.63 / 0x18 = 48000 * 256 */ + cx18_av_write4(cx, 0x110, 0x0098d6dd); /* src1_ctl */ /* 0x1.8000 = 48000/32000 */ @@ -143,6 +193,16 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x900, 0x08015555); cx18_av_write4(cx, 0x904, 0x08015555); cx18_av_write4(cx, 0x90c, 0x08015555); + + /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */ + cx18_av_write4(cx, 0x12c, 0x11203fff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x1193f8 = 143999.000 * 8 = + * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa11193f8); break; } } -- cgit v1.2.3 From e52d829b9cb6bfd2ab0a4fa878f2e49133c0f10f Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Fri, 25 Jul 2008 17:35:31 -0500 Subject: pvrusb2: Enable IR chip on HVR-1900 class devices From: Mike Isely The Zilog IR chip on HVR-1900 devices is held in reset when the device initializes. We have to bring this chip out of reset before LIRC has any chance of operating the chip. So do it. Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-devattr.c | 5 ++++- .../drivers/media/video/pvrusb2/pvrusb2-devattr.h | 26 ++++++++++++++-------- .../drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h | 2 ++ linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 9 ++++++++ .../drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 4 +++- 5 files changed, 35 insertions(+), 11 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 5d036e7e3..e3b051197 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -97,13 +97,13 @@ static const struct pvr2_device_desc pvr2_device_24xxx = { .flag_has_cx25840 = !0, .flag_has_wm8775 = !0, .flag_has_hauppauge_rom = !0, - .flag_has_hauppauge_custom_ir = !0, .flag_has_analogtuner = !0, .flag_has_fmradio = !0, .flag_has_composite = !0, .flag_has_svideo = !0, .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, + .ir_scheme = PVR2_IR_SCHEME_24XXX, }; @@ -344,6 +344,7 @@ static const struct pvr2_device_desc pvr2_device_73xxx = { .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, + .ir_scheme = PVR2_IR_SCHEME_ZILOG, #ifdef CONFIG_VIDEO_PVRUSB2_DVB .dvb_props = &pvr2_73xxx_dvb_props, #endif @@ -453,6 +454,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = { .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .default_std_mask = V4L2_STD_NTSC_M, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, + .ir_scheme = PVR2_IR_SCHEME_ZILOG, #ifdef CONFIG_VIDEO_PVRUSB2_DVB .dvb_props = &pvr2_750xx_dvb_props, #endif @@ -474,6 +476,7 @@ static const struct pvr2_device_desc pvr2_device_751xx = { .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .default_std_mask = V4L2_STD_NTSC_M, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, + .ir_scheme = PVR2_IR_SCHEME_ZILOG, #ifdef CONFIG_VIDEO_PVRUSB2_DVB .dvb_props = &pvr2_751xx_dvb_props, #endif diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h index e23ce1d2e..cb3a33eb0 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h @@ -48,6 +48,10 @@ struct pvr2_string_table { #define PVR2_LED_SCHEME_NONE 0 #define PVR2_LED_SCHEME_HAUPPAUGE 1 +#define PVR2_IR_SCHEME_NONE 0 +#define PVR2_IR_SCHEME_24XXX 1 +#define PVR2_IR_SCHEME_ZILOG 2 + /* This describes a particular hardware type (except for the USB device ID which must live in a separate structure due to environmental constraints). See the top of pvrusb2-hdw.c for where this is @@ -126,15 +130,19 @@ struct pvr2_device_desc { ensure that it is found. */ unsigned int flag_has_wm8775:1; - /* Device has IR hardware that can be faked into looking like a - normal Hauppauge i2c IR receiver. This is currently very - specific to the 24xxx device, where Hauppauge had replaced their - 'standard' I2C IR receiver with a bunch of FPGA logic controlled - directly via the FX2. Turning this on tells the pvrusb2 driver - to virtualize the presence of the non-existant IR receiver chip and - implement the virtual receiver in terms of appropriate FX2 - commands. */ - unsigned int flag_has_hauppauge_custom_ir:1; + /* Indicate any specialized IR scheme that might need to be + supported by this driver. If not set, then it is assumed that + IR can work without help from the driver (which is frequently + the case). This is otherwise set to one of + PVR2_IR_SCHEME_xxxx. For "xxxx", the value "24XXX" indicates a + Hauppauge 24xxx class device which has an FPGA-hosted IR + receiver that can only be reached via FX2 command codes. In + that case the pvrusb2 driver will emulate the behavior of the + older 29xxx device's IR receiver (a "virtual" I2C chip) in terms + of those command codes. For the value "ZILOG", we're dealing + with an IR chip that must be taken out of reset via another FX2 + command code (which is the case for HVR-1950 devices). */ + unsigned int ir_scheme:2; /* These bits define which kinds of sources the device can handle. Note: Digital tuner presence is inferred by the diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h index b58369e7f..614755ea2 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h @@ -24,6 +24,8 @@ #define FX2CMD_MEM_WRITE_DWORD 0x01u #define FX2CMD_MEM_READ_DWORD 0x02u +#define FX2CMD_HCW_ZILOG_RESET 0x10u /* 1=reset 0=release */ + #define FX2CMD_MEM_READ_64BYTES 0x28u #define FX2CMD_REG_WRITE 0x04u diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index cbf848e82..419a473cf 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -251,6 +251,7 @@ struct pvr2_fx2cmd_descdef { static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = { {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"}, {FX2CMD_MEM_READ_DWORD, "read encoder dword"}, + {FX2CMD_HCW_ZILOG_RESET, "zilog IR reset control"}, {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"}, {FX2CMD_REG_WRITE, "write encoder register"}, {FX2CMD_REG_READ, "read encoder register"}, @@ -1728,6 +1729,14 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) if (!pvr2_hdw_dev_ok(hdw)) return; } + /* Take the IR chip out of reset, if appropriate */ + if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) { + pvr2_issue_simple_cmd(hdw, + FX2CMD_HCW_ZILOG_RESET | + (1 << 8) | + ((0) << 16)); + } + // This step MUST happen after the earlier powerup step. pvr2_i2c_core_init(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index ef741d1fc..9159686c3 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -1054,7 +1054,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) printk(KERN_INFO "%s: IR disabled\n",hdw->name); hdw->i2c_func[0x18] = i2c_black_hole; } else if (ir_mode[hdw->unit_number] == 1) { - if (hdw->hdw_desc->flag_has_hauppauge_custom_ir) { + if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) { + /* This comment is present PURELY to get + checkpatch.pl to STFU. Lovely, eh? */ hdw->i2c_func[0x18] = i2c_24xxx_ir; } } -- cgit v1.2.3 From 79e9f3261be47edf6b5a54b00fba99a355e1bec7 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Fri, 25 Jul 2008 17:50:52 -0500 Subject: pvrusb2: Cosmetic macro fix (benign) From: Mike Isely Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-context.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-context.h b/linux/drivers/media/video/pvrusb2/pvrusb2-context.h index 61801291c..d657e53bb 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-context.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-context.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#ifndef __PVRUSB2_BASE_H -#define __PVRUSB2_BASE_H +#ifndef __PVRUSB2_CONTEXT_H +#define __PVRUSB2_CONTEXT_H #include #include -- cgit v1.2.3 From af41aa918f47e0bc59c5554cabbd05db0917bed4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 21 Jul 2008 07:57:38 +0200 Subject: videodev: move all ioctl callbacks to a new v4l2_ioctl_ops struct From: Hans Verkuil All ioctl callbacks are now stored in a new v4l2_ioctl_ops struct. Drivers fill in a const struct v4l2_ioctl_ops and video_device just contains a const pointer to it. This ensures a clean separation between the const ops struct and the non-const video_device struct. Signed-off-by: Hans Verkuil --- linux/drivers/media/radio/dsbr100.c | 19 +- linux/drivers/media/radio/radio-aimslab.c | 15 +- linux/drivers/media/radio/radio-aztech.c | 15 +- linux/drivers/media/radio/radio-cadet.c | 15 +- linux/drivers/media/radio/radio-gemtek-pci.c | 14 +- linux/drivers/media/radio/radio-gemtek.c | 14 +- linux/drivers/media/radio/radio-maestro.c | 12 +- linux/drivers/media/radio/radio-maxiradio.c | 16 +- linux/drivers/media/radio/radio-rtrack2.c | 15 +- linux/drivers/media/radio/radio-sf16fmi.c | 15 +- linux/drivers/media/radio/radio-sf16fmr2.c | 15 +- linux/drivers/media/radio/radio-si470x.c | 21 +- linux/drivers/media/radio/radio-terratec.c | 15 +- linux/drivers/media/radio/radio-trust.c | 15 +- linux/drivers/media/radio/radio-typhoon.c | 15 +- linux/drivers/media/radio/radio-zoltrix.c | 15 +- linux/drivers/media/video/bt8xx/bttv-driver.c | 26 +- linux/drivers/media/video/cafe_ccic.c | 25 +- linux/drivers/media/video/cx18/cx18-ioctl.c | 92 ++--- linux/drivers/media/video/cx23885/cx23885-417.c | 20 +- linux/drivers/media/video/cx23885/cx23885-video.c | 16 +- linux/drivers/media/video/cx88/cx88-blackbird.c | 16 +- linux/drivers/media/video/cx88/cx88-video.c | 33 +- linux/drivers/media/video/em28xx/em28xx-video.c | 46 ++- linux/drivers/media/video/gspca/gspca.c | 16 +- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 130 +++---- linux/drivers/media/video/meye.c | 18 +- linux/drivers/media/video/s2255drv.c | 16 +- .../drivers/media/video/saa7134/saa7134-empress.c | 22 +- linux/drivers/media/video/saa7134/saa7134-video.c | 61 +-- linux/drivers/media/video/soc_camera.c | 56 +-- linux/drivers/media/video/stk-webcam.c | 31 +- .../media/video/usbvision/usbvision-video.c | 38 +- linux/drivers/media/video/v4l2-ioctl.c | 418 +++++++++++---------- linux/drivers/media/video/vivi.c | 18 +- linux/drivers/media/video/zr364xx.c | 19 +- 36 files changed, 754 insertions(+), 609 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/radio/dsbr100.c b/linux/drivers/media/radio/dsbr100.c index 92089e705..00be53110 100644 --- a/linux/drivers/media/radio/dsbr100.c +++ b/linux/drivers/media/radio/dsbr100.c @@ -446,14 +446,7 @@ static const struct file_operations usb_dsbr100_fops = { .llseek = no_llseek, }; -/* V4L2 interface */ -static struct video_device dsbr100_videodev_template = -{ - .owner = THIS_MODULE, - .name = "D-Link DSB-R 100", - .type = VID_TYPE_TUNER, - .fops = &usb_dsbr100_fops, - .release = video_device_release, +static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -468,6 +461,16 @@ static struct video_device dsbr100_videodev_template = .vidioc_s_input = vidioc_s_input, }; +/* V4L2 interface */ +static struct video_device dsbr100_videodev_template = { + .owner = THIS_MODULE, + .name = "D-Link DSB-R 100", + .type = VID_TYPE_TUNER, + .fops = &usb_dsbr100_fops, + .ioctl_ops = &usb_dsbr100_ioctl_ops, + .release = video_device_release, +}; + /* check if the device is present and register with v4l and usb if it is */ static int usb_dsbr100_probe(struct usb_interface *intf, diff --git a/linux/drivers/media/radio/radio-aimslab.c b/linux/drivers/media/radio/radio-aimslab.c index 4b133820e..cadbf2eef 100644 --- a/linux/drivers/media/radio/radio-aimslab.c +++ b/linux/drivers/media/radio/radio-aimslab.c @@ -390,12 +390,7 @@ static const struct file_operations rtrack_fops = { .llseek = no_llseek, }; -static struct video_device rtrack_radio= -{ - .owner = THIS_MODULE, - .name = "RadioTrack radio", - .type = VID_TYPE_TUNER, - .fops = &rtrack_fops, +static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -410,6 +405,14 @@ static struct video_device rtrack_radio= .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device rtrack_radio = { + .owner = THIS_MODULE, + .name = "RadioTrack radio", + .type = VID_TYPE_TUNER, + .fops = &rtrack_fops, + .ioctl_ops = &rtrack_ioctl_ops, +}; + static int __init rtrack_init(void) { if(io==-1) diff --git a/linux/drivers/media/radio/radio-aztech.c b/linux/drivers/media/radio/radio-aztech.c index 124df79a0..5711f7e96 100644 --- a/linux/drivers/media/radio/radio-aztech.c +++ b/linux/drivers/media/radio/radio-aztech.c @@ -354,12 +354,7 @@ static const struct file_operations aztech_fops = { .llseek = no_llseek, }; -static struct video_device aztech_radio= -{ - .owner = THIS_MODULE, - .name = "Aztech radio", - .type = VID_TYPE_TUNER, - .fops = &aztech_fops, +static const struct v4l2_ioctl_ops aztech_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -374,6 +369,14 @@ static struct video_device aztech_radio= .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device aztech_radio = { + .owner = THIS_MODULE, + .name = "Aztech radio", + .type = VID_TYPE_TUNER, + .fops = &aztech_fops, + .ioctl_ops = &aztech_ioctl_ops, +}; + module_param_named(debug,aztech_radio.debug, int, 0644); MODULE_PARM_DESC(debug,"activates debug info"); diff --git a/linux/drivers/media/radio/radio-cadet.c b/linux/drivers/media/radio/radio-cadet.c index 88e6502af..1e8e0e877 100644 --- a/linux/drivers/media/radio/radio-cadet.c +++ b/linux/drivers/media/radio/radio-cadet.c @@ -600,12 +600,7 @@ static const struct file_operations cadet_fops = { .llseek = no_llseek, }; -static struct video_device cadet_radio= -{ - .owner = THIS_MODULE, - .name = "Cadet radio", - .type = VID_TYPE_TUNER, - .fops = &cadet_fops, +static const struct v4l2_ioctl_ops cadet_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -620,6 +615,14 @@ static struct video_device cadet_radio= .vidioc_s_input = vidioc_s_input, }; +static struct video_device cadet_radio = { + .owner = THIS_MODULE, + .name = "Cadet radio", + .type = VID_TYPE_TUNER, + .fops = &cadet_fops, + .ioctl_ops = &cadet_ioctl_ops, +}; + #ifdef CONFIG_PNP static struct pnp_device_id cadet_pnp_devices[] = { diff --git a/linux/drivers/media/radio/radio-gemtek-pci.c b/linux/drivers/media/radio/radio-gemtek-pci.c index bf2704841..168e3a90c 100644 --- a/linux/drivers/media/radio/radio-gemtek-pci.c +++ b/linux/drivers/media/radio/radio-gemtek-pci.c @@ -376,11 +376,7 @@ static const struct file_operations gemtek_pci_fops = { .llseek = no_llseek, }; -static struct video_device vdev_template = { - .owner = THIS_MODULE, - .name = "Gemtek PCI Radio", - .type = VID_TYPE_TUNER, - .fops = &gemtek_pci_fops, +static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -395,6 +391,14 @@ static struct video_device vdev_template = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device vdev_template = { + .owner = THIS_MODULE, + .name = "Gemtek PCI Radio", + .type = VID_TYPE_TUNER, + .fops = &gemtek_pci_fops, + .ioctl_ops = &gemtek_pci_ioctl_ops, +}; + static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) { struct gemtek_pci_card *card; diff --git a/linux/drivers/media/radio/radio-gemtek.c b/linux/drivers/media/radio/radio-gemtek.c index 3f77c0b57..98689f5f6 100644 --- a/linux/drivers/media/radio/radio-gemtek.c +++ b/linux/drivers/media/radio/radio-gemtek.c @@ -554,11 +554,7 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) return 0; } -static struct video_device gemtek_radio = { - .owner = THIS_MODULE, - .name = "GemTek Radio card", - .type = VID_TYPE_TUNER, - .fops = &gemtek_fops, +static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -573,6 +569,14 @@ static struct video_device gemtek_radio = { .vidioc_s_ctrl = vidioc_s_ctrl }; +static struct video_device gemtek_radio = { + .owner = THIS_MODULE, + .name = "GemTek Radio card", + .type = VID_TYPE_TUNER, + .fops = &gemtek_fops, + .ioctl_ops = &gemtek_ioctl_ops, +}; + /* * Initialization / cleanup related stuff. */ diff --git a/linux/drivers/media/radio/radio-maestro.c b/linux/drivers/media/radio/radio-maestro.c index 00b6cc174..f16a2ab88 100644 --- a/linux/drivers/media/radio/radio-maestro.c +++ b/linux/drivers/media/radio/radio-maestro.c @@ -356,10 +356,7 @@ static u16 __devinit radio_power_on(struct radio_device *dev) return (ofreq == radio_bits_get(dev)); } -static struct video_device maestro_radio = { - .name = "Maestro radio", - .type = VID_TYPE_TUNER, - .fops = &maestro_fops, +static const struct v4l2_ioctl_ops maestro_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -374,6 +371,13 @@ static struct video_device maestro_radio = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device maestro_radio = { + .name = "Maestro radio", + .type = VID_TYPE_TUNER, + .fops = &maestro_fops, + .ioctl_ops = &maestro_ioctl_ops, +}; + static int __devinit maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index 612c71fed..7550b9196 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -375,13 +375,7 @@ static int vidioc_s_ctrl (struct file *file, void *priv, return -EINVAL; } -static struct video_device maxiradio_radio = -{ - .owner = THIS_MODULE, - .name = "Maxi Radio FM2000 radio", - .type = VID_TYPE_TUNER, - .fops = &maxiradio_fops, - +static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -396,6 +390,14 @@ static struct video_device maxiradio_radio = .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device maxiradio_radio = { + .owner = THIS_MODULE, + .name = "Maxi Radio FM2000 radio", + .type = VID_TYPE_TUNER, + .fops = &maxiradio_fops, + .ioctl_ops = &maxiradio_ioctl_ops, +}; + static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { if(!request_region(pci_resource_start(pdev, 0), diff --git a/linux/drivers/media/radio/radio-rtrack2.c b/linux/drivers/media/radio/radio-rtrack2.c index 3936b15e8..8828fb44d 100644 --- a/linux/drivers/media/radio/radio-rtrack2.c +++ b/linux/drivers/media/radio/radio-rtrack2.c @@ -296,12 +296,7 @@ static const struct file_operations rtrack2_fops = { .llseek = no_llseek, }; -static struct video_device rtrack2_radio= -{ - .owner = THIS_MODULE, - .name = "RadioTrack II radio", - .type = VID_TYPE_TUNER, - .fops = &rtrack2_fops, +static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -316,6 +311,14 @@ static struct video_device rtrack2_radio= .vidioc_s_input = vidioc_s_input, }; +static struct video_device rtrack2_radio = { + .owner = THIS_MODULE, + .name = "RadioTrack II radio", + .type = VID_TYPE_TUNER, + .fops = &rtrack2_fops, + .ioctl_ops = &rtrack2_ioctl_ops, +}; + static int __init rtrack2_init(void) { if(io==-1) diff --git a/linux/drivers/media/radio/radio-sf16fmi.c b/linux/drivers/media/radio/radio-sf16fmi.c index 5a1c231df..87f32221d 100644 --- a/linux/drivers/media/radio/radio-sf16fmi.c +++ b/linux/drivers/media/radio/radio-sf16fmi.c @@ -296,12 +296,7 @@ static const struct file_operations fmi_fops = { .llseek = no_llseek, }; -static struct video_device fmi_radio= -{ - .owner = THIS_MODULE, - .name = "SF16FMx radio", - .type = VID_TYPE_TUNER, - .fops = &fmi_fops, +static const struct v4l2_ioctl_ops fmi_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -316,6 +311,14 @@ static struct video_device fmi_radio= .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device fmi_radio = { + .owner = THIS_MODULE, + .name = "SF16FMx radio", + .type = VID_TYPE_TUNER, + .fops = &fmi_fops, + .ioctl_ops = &fmi_ioctl_ops, +}; + /* ladis: this is my card. does any other types exist? */ static struct isapnp_device_id id_table[] __devinitdata = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, diff --git a/linux/drivers/media/radio/radio-sf16fmr2.c b/linux/drivers/media/radio/radio-sf16fmr2.c index 555b97a6c..01b2516e7 100644 --- a/linux/drivers/media/radio/radio-sf16fmr2.c +++ b/linux/drivers/media/radio/radio-sf16fmr2.c @@ -412,12 +412,7 @@ static const struct file_operations fmr2_fops = { .llseek = no_llseek, }; -static struct video_device fmr2_radio= -{ - .owner = THIS_MODULE, - .name = "SF16FMR2 radio", - . type = VID_TYPE_TUNER, - .fops = &fmr2_fops, +static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -432,6 +427,14 @@ static struct video_device fmr2_radio= .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device fmr2_radio = { + .owner = THIS_MODULE, + .name = "SF16FMR2 radio", + .type = VID_TYPE_TUNER, + .fops = &fmr2_fops, + .ioctl_ops = &fmr2_ioctl_ops, +}; + static int __init fmr2_init(void) { fmr2_unit.port = io; diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 110989cac..cbded7f86 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -1591,15 +1591,7 @@ done: return retval; } - -/* - * si470x_viddev_tamples - video device interface - */ -static struct video_device si470x_viddev_template = { - .fops = &si470x_fops, - .name = DRIVER_NAME, - .type = VID_TYPE_TUNER, - .release = video_device_release, +static const struct v4l2_ioctl_ops si470x_ioctl_ops = { .vidioc_querycap = si470x_vidioc_querycap, .vidioc_g_input = si470x_vidioc_g_input, .vidioc_s_input = si470x_vidioc_s_input, @@ -1613,6 +1605,17 @@ static struct video_device si470x_viddev_template = { .vidioc_g_frequency = si470x_vidioc_g_frequency, .vidioc_s_frequency = si470x_vidioc_s_frequency, .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, +}; + +/* + * si470x_viddev_tamples - video device interface + */ +static struct video_device si470x_viddev_template = { + .fops = &si470x_fops, + .ioctl_ops = &si470x_ioctl_ops, + .name = DRIVER_NAME, + .type = VID_TYPE_TUNER, + .release = video_device_release, .owner = THIS_MODULE, }; diff --git a/linux/drivers/media/radio/radio-terratec.c b/linux/drivers/media/radio/radio-terratec.c index f88ab2816..5e8582055 100644 --- a/linux/drivers/media/radio/radio-terratec.c +++ b/linux/drivers/media/radio/radio-terratec.c @@ -368,12 +368,7 @@ static const struct file_operations terratec_fops = { .llseek = no_llseek, }; -static struct video_device terratec_radio= -{ - .owner = THIS_MODULE, - .name = "TerraTec ActiveRadio", - .type = VID_TYPE_TUNER, - .fops = &terratec_fops, +static const struct v4l2_ioctl_ops terratec_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -388,6 +383,14 @@ static struct video_device terratec_radio= .vidioc_s_input = vidioc_s_input, }; +static struct video_device terratec_radio = { + .owner = THIS_MODULE, + .name = "TerraTec ActiveRadio", + .type = VID_TYPE_TUNER, + .fops = &terratec_fops, + .ioctl_ops = &terratec_ioctl_ops, +}; + static int __init terratec_init(void) { if(io==-1) diff --git a/linux/drivers/media/radio/radio-trust.c b/linux/drivers/media/radio/radio-trust.c index 3e72b1c6c..57b69a7c0 100644 --- a/linux/drivers/media/radio/radio-trust.c +++ b/linux/drivers/media/radio/radio-trust.c @@ -351,12 +351,7 @@ static const struct file_operations trust_fops = { .llseek = no_llseek, }; -static struct video_device trust_radio= -{ - .owner = THIS_MODULE, - .name = "Trust FM Radio", - .type = VID_TYPE_TUNER, - .fops = &trust_fops, +static const struct v4l2_ioctl_ops trust_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -371,6 +366,14 @@ static struct video_device trust_radio= .vidioc_s_input = vidioc_s_input, }; +static struct video_device trust_radio = { + .owner = THIS_MODULE, + .name = "Trust FM Radio", + .type = VID_TYPE_TUNER, + .fops = &trust_fops, + .ioctl_ops = &trust_ioctl_ops, +}; + static int __init trust_init(void) { if(io == -1) { diff --git a/linux/drivers/media/radio/radio-typhoon.c b/linux/drivers/media/radio/radio-typhoon.c index b076936dd..3c377fbd7 100644 --- a/linux/drivers/media/radio/radio-typhoon.c +++ b/linux/drivers/media/radio/radio-typhoon.c @@ -346,12 +346,7 @@ static const struct file_operations typhoon_fops = { .llseek = no_llseek, }; -static struct video_device typhoon_radio = -{ - .owner = THIS_MODULE, - .name = "Typhoon Radio", - .type = VID_TYPE_TUNER, - .fops = &typhoon_fops, +static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -366,6 +361,14 @@ static struct video_device typhoon_radio = .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device typhoon_radio = { + .owner = THIS_MODULE, + .name = "Typhoon Radio", + .type = VID_TYPE_TUNER, + .fops = &typhoon_fops, + .ioctl_ops = &typhoon_ioctl_ops, +}; + #ifdef CONFIG_RADIO_TYPHOON_PROC_FS static int typhoon_proc_show(struct seq_file *m, void *v) diff --git a/linux/drivers/media/radio/radio-zoltrix.c b/linux/drivers/media/radio/radio-zoltrix.c index 0bcc38b46..cdd7deba7 100644 --- a/linux/drivers/media/radio/radio-zoltrix.c +++ b/linux/drivers/media/radio/radio-zoltrix.c @@ -409,12 +409,7 @@ static const struct file_operations zoltrix_fops = .llseek = no_llseek, }; -static struct video_device zoltrix_radio = -{ - .owner = THIS_MODULE, - .name = "Zoltrix Radio Plus", - .type = VID_TYPE_TUNER, - .fops = &zoltrix_fops, +static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -429,6 +424,14 @@ static struct video_device zoltrix_radio = .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device zoltrix_radio = { + .owner = THIS_MODULE, + .name = "Zoltrix Radio Plus", + .type = VID_TYPE_TUNER, + .fops = &zoltrix_fops, + .ioctl_ops = &zoltrix_ioctl_ops, +}; + static int __init zoltrix_init(void) { if (io == -1) { diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 17fa68233..8a57b2560 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -3378,10 +3378,7 @@ static const struct file_operations bttv_fops = .poll = bttv_poll, }; -static struct video_device bttv_video_template = -{ - .fops = &bttv_fops, - .minor = -1, +static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_querycap = bttv_querycap, .vidioc_enum_fmt_vid_cap = bttv_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap, @@ -3432,8 +3429,14 @@ static struct video_device bttv_video_template = .vidioc_g_register = bttv_g_register, .vidioc_s_register = bttv_s_register, #endif - .tvnorms = BTTV_NORMS, - .current_norm = V4L2_STD_PAL, +}; + +static struct video_device bttv_video_template = { + .fops = &bttv_fops, + .minor = -1, + .ioctl_ops = &bttv_ioctl_ops, + .tvnorms = BTTV_NORMS, + .current_norm = V4L2_STD_PAL, }; /* ----------------------------------------------------------------------- */ @@ -3656,10 +3659,7 @@ static const struct file_operations radio_fops = .poll = radio_poll, }; -static struct video_device radio_template = -{ - .fops = &radio_fops, - .minor = -1, +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -3676,6 +3676,12 @@ static struct video_device radio_template = .vidioc_s_frequency = bttv_s_frequency, }; +static struct video_device radio_template = { + .fops = &radio_fops, + .minor = -1, + .ioctl_ops = &radio_ioctl_ops, +}; + /* ----------------------------------------------------------------------- */ /* some debug code */ diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c index 075d57031..607f21eda 100644 --- a/linux/drivers/media/video/cafe_ccic.c +++ b/linux/drivers/media/video/cafe_ccic.c @@ -1776,17 +1776,7 @@ static const struct file_operations cafe_v4l_fops = { .llseek = no_llseek, }; -static struct video_device cafe_v4l_template = { - .name = "cafe", - .type = VFL_TYPE_GRABBER, - .type2 = VID_TYPE_CAPTURE, - .minor = -1, /* Get one dynamically */ - .tvnorms = V4L2_STD_NTSC_M, - .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ - - .fops = &cafe_v4l_fops, - .release = cafe_v4l_dev_release, - +static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { .vidioc_querycap = cafe_vidioc_querycap, .vidioc_enum_fmt_vid_cap = cafe_vidioc_enum_fmt_vid_cap, .vidioc_try_fmt_vid_cap = cafe_vidioc_try_fmt_vid_cap, @@ -1809,6 +1799,19 @@ static struct video_device cafe_v4l_template = { .vidioc_s_parm = cafe_vidioc_s_parm, }; +static struct video_device cafe_v4l_template = { + .name = "cafe", + .type = VFL_TYPE_GRABBER, + .type2 = VID_TYPE_CAPTURE, + .minor = -1, /* Get one dynamically */ + .tvnorms = V4L2_STD_NTSC_M, + .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ + + .fops = &cafe_v4l_fops, + .ioctl_ops = &cafe_v4l_ioctl_ops, + .release = cafe_v4l_dev_release, +}; + diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index 0221a67aa..e6c2bfa5d 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -892,50 +892,54 @@ int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return res; } -void cx18_set_funcs(struct video_device *vdev) -{ - vdev->vidioc_querycap = cx18_querycap; - vdev->vidioc_g_priority = cx18_g_priority; - vdev->vidioc_s_priority = cx18_s_priority; - vdev->vidioc_s_audio = cx18_s_audio; - vdev->vidioc_g_audio = cx18_g_audio; - vdev->vidioc_enumaudio = cx18_enumaudio; - vdev->vidioc_enum_input = cx18_enum_input; - vdev->vidioc_cropcap = cx18_cropcap; - vdev->vidioc_s_crop = cx18_s_crop; - vdev->vidioc_g_crop = cx18_g_crop; - vdev->vidioc_g_input = cx18_g_input; - vdev->vidioc_s_input = cx18_s_input; - vdev->vidioc_g_frequency = cx18_g_frequency; - vdev->vidioc_s_frequency = cx18_s_frequency; - vdev->vidioc_s_tuner = cx18_s_tuner; - vdev->vidioc_g_tuner = cx18_g_tuner; - vdev->vidioc_g_enc_index = cx18_g_enc_index; - vdev->vidioc_g_std = cx18_g_std; - vdev->vidioc_s_std = cx18_s_std; - vdev->vidioc_log_status = cx18_log_status; - vdev->vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap; - vdev->vidioc_encoder_cmd = cx18_encoder_cmd; - vdev->vidioc_try_encoder_cmd = cx18_try_encoder_cmd; - vdev->vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap; - vdev->vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap; - vdev->vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap; - vdev->vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap; - vdev->vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap; - vdev->vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap; - vdev->vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap; - vdev->vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap; - vdev->vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap; - vdev->vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap; - vdev->vidioc_g_chip_ident = cx18_g_chip_ident; +static const struct v4l2_ioctl_ops cx18_ioctl_ops = { + .vidioc_querycap = cx18_querycap, + .vidioc_g_priority = cx18_g_priority, + .vidioc_s_priority = cx18_s_priority, + .vidioc_s_audio = cx18_s_audio, + .vidioc_g_audio = cx18_g_audio, + .vidioc_enumaudio = cx18_enumaudio, + .vidioc_enum_input = cx18_enum_input, + .vidioc_cropcap = cx18_cropcap, + .vidioc_s_crop = cx18_s_crop, + .vidioc_g_crop = cx18_g_crop, + .vidioc_g_input = cx18_g_input, + .vidioc_s_input = cx18_s_input, + .vidioc_g_frequency = cx18_g_frequency, + .vidioc_s_frequency = cx18_s_frequency, + .vidioc_s_tuner = cx18_s_tuner, + .vidioc_g_tuner = cx18_g_tuner, + .vidioc_g_enc_index = cx18_g_enc_index, + .vidioc_g_std = cx18_g_std, + .vidioc_s_std = cx18_s_std, + .vidioc_log_status = cx18_log_status, + .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap, + .vidioc_encoder_cmd = cx18_encoder_cmd, + .vidioc_try_encoder_cmd = cx18_try_encoder_cmd, + .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap, + .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap, + .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap, + .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap, + .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap, + .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap, + .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap, + .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap, + .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap, + .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap, + .vidioc_g_chip_ident = cx18_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG - vdev->vidioc_g_register = cx18_g_register; - vdev->vidioc_s_register = cx18_s_register; + .vidioc_g_register = cx18_g_register, + .vidioc_s_register = cx18_s_register, #endif - vdev->vidioc_default = cx18_default; - vdev->vidioc_queryctrl = cx18_queryctrl; - vdev->vidioc_querymenu = cx18_querymenu; - vdev->vidioc_g_ext_ctrls = cx18_g_ext_ctrls; - vdev->vidioc_s_ext_ctrls = cx18_s_ext_ctrls; - vdev->vidioc_try_ext_ctrls = cx18_try_ext_ctrls; + .vidioc_default = cx18_default, + .vidioc_queryctrl = cx18_queryctrl, + .vidioc_querymenu = cx18_querymenu, + .vidioc_g_ext_ctrls = cx18_g_ext_ctrls, + .vidioc_s_ext_ctrls = cx18_s_ext_ctrls, + .vidioc_try_ext_ctrls = cx18_try_ext_ctrls, +}; + +void cx18_set_funcs(struct video_device *vdev) +{ + vdev->ioctl_ops = &cx18_ioctl_ops; } diff --git a/linux/drivers/media/video/cx23885/cx23885-417.c b/linux/drivers/media/video/cx23885/cx23885-417.c index 3c3563f73..5aece975c 100644 --- a/linux/drivers/media/video/cx23885/cx23885-417.c +++ b/linux/drivers/media/video/cx23885/cx23885-417.c @@ -1708,14 +1708,7 @@ static struct file_operations mpeg_fops = { .llseek = no_llseek, }; -static struct video_device cx23885_mpeg_template = { - .name = "cx23885", - .type = VID_TYPE_CAPTURE | - VID_TYPE_TUNER | - VID_TYPE_SCALES | - VID_TYPE_MPEG_ENCODER, - .fops = &mpeg_fops, - .minor = -1, +static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_s_std = vidioc_s_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, @@ -1744,6 +1737,17 @@ static struct video_device cx23885_mpeg_template = { .vidioc_queryctrl = vidioc_queryctrl, }; +static struct video_device cx23885_mpeg_template = { + .name = "cx23885", + .type = VID_TYPE_CAPTURE | + VID_TYPE_TUNER | + VID_TYPE_SCALES | + VID_TYPE_MPEG_ENCODER, + .fops = &mpeg_fops, + .ioctl_ops = &mpeg_ioctl_ops, + .minor = -1, +}; + void cx23885_417_unregister(struct cx23885_dev *dev) { dprintk(1, "%s()\n", __func__); diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index 6cb578434..8a77f2633 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -1642,12 +1642,7 @@ static const struct file_operations video_fops = { .llseek = no_llseek, }; -static struct video_device cx23885_vbi_template; -static struct video_device cx23885_video_template = { - .name = "cx23885-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, - .fops = &video_fops, - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1680,6 +1675,15 @@ static struct video_device cx23885_video_template = { .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif +}; + +static struct video_device cx23885_vbi_template; +static struct video_device cx23885_video_template = { + .name = "cx23885-video", + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, + .fops = &video_fops, + .minor = -1, + .ioctl_ops = &video_ioctl_ops, .tvnorms = CX23885_NORMS, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c index 4b780c237..9cbb9c8d5 100644 --- a/linux/drivers/media/video/cx88/cx88-blackbird.c +++ b/linux/drivers/media/video/cx88/cx88-blackbird.c @@ -1194,12 +1194,7 @@ static const struct file_operations mpeg_fops = .llseek = no_llseek, }; -static struct video_device cx8802_mpeg_template = -{ - .name = "cx8802", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES|VID_TYPE_MPEG_ENCODER, - .fops = &mpeg_fops, - .minor = -1, +static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_querymenu = vidioc_querymenu, .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, @@ -1227,6 +1222,15 @@ static struct video_device cx8802_mpeg_template = .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, .vidioc_s_std = vidioc_s_std, +}; + +static struct video_device cx8802_mpeg_template = { + .name = "cx8802", + .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | + VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER, + .fops = &mpeg_fops, + .ioctl_ops = &mpeg_ioctl_ops, + .minor = -1, .tvnorms = CX88_NORMS, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 8469f9d59..f64cdd5ed 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1953,13 +1953,7 @@ static const struct file_operations video_fops = .llseek = no_llseek, }; -static struct video_device cx8800_vbi_template; -static struct video_device cx8800_video_template = -{ - .name = "cx8800-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, - .fops = &video_fops, - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1992,6 +1986,16 @@ static struct video_device cx8800_video_template = .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif +}; + +static struct video_device cx8800_vbi_template; + +static struct video_device cx8800_video_template = { + .name = "cx8800-video", + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, + .fops = &video_fops, + .minor = -1, + .ioctl_ops = &video_ioctl_ops, .tvnorms = CX88_NORMS, .current_norm = V4L2_STD_NTSC_M, }; @@ -2006,12 +2010,7 @@ static const struct file_operations radio_fops = .llseek = no_llseek, }; -static struct video_device cx8800_radio_template = -{ - .name = "cx8800-radio", - .type = VID_TYPE_TUNER, - .fops = &radio_fops, - .minor = -1, +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -2030,6 +2029,14 @@ static struct video_device cx8800_radio_template = #endif }; +static struct video_device cx8800_radio_template = { + .name = "cx8800-radio", + .type = VID_TYPE_TUNER, + .fops = &radio_fops, + .minor = -1, + .ioctl_ops = &radio_ioctl_ops, +}; + /* ----------------------------------------------------------- */ static void cx8800_unregister_video(struct cx8800_dev *dev) diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index c456f9945..d0ca6f929 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1821,20 +1821,7 @@ static const struct file_operations em28xx_v4l_fops = { .compat_ioctl = v4l_compat_ioctl32, }; -static const struct file_operations radio_fops = { - .owner = THIS_MODULE, - .open = em28xx_v4l2_open, - .release = em28xx_v4l2_close, - .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, -}; - -static const struct video_device em28xx_video_template = { - .fops = &em28xx_v4l_fops, - .release = video_device_release, - - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1877,16 +1864,29 @@ static const struct video_device em28xx_video_template = { #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidiocgmbuf, #endif +}; + +static const struct video_device em28xx_video_template = { + .fops = &em28xx_v4l_fops, + .release = video_device_release, + .ioctl_ops = &video_ioctl_ops, + + .minor = -1, .tvnorms = V4L2_STD_ALL, .current_norm = V4L2_STD_PAL, }; -static struct video_device em28xx_radio_template = { - .name = "em28xx-radio", - .type = VID_TYPE_TUNER, - .fops = &radio_fops, - .minor = -1, +static const struct file_operations radio_fops = { + .owner = THIS_MODULE, + .open = em28xx_v4l2_open, + .release = em28xx_v4l2_close, + .ioctl = video_ioctl2, + .compat_ioctl = v4l_compat_ioctl32, + .llseek = no_llseek, +}; + +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -1905,6 +1905,14 @@ static struct video_device em28xx_radio_template = { #endif }; +static struct video_device em28xx_radio_template = { + .name = "em28xx-radio", + .type = VID_TYPE_TUNER, + .fops = &radio_fops, + .ioctl_ops = &radio_ioctl_ops, + .minor = -1, +}; + /******************************** usb interface ******************************/ diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 729e0b4ed..3f2a89fed 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -1658,12 +1658,7 @@ static struct file_operations dev_fops = { .poll = dev_poll, }; -static struct video_device gspca_template = { - .name = "gspca main driver", - .type = VID_TYPE_CAPTURE, - .fops = &dev_fops, - .release = dev_release, /* mandatory */ - .minor = -1, +static const struct v4l2_ioctl_ops dev_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_dqbuf = vidioc_dqbuf, .vidioc_qbuf = vidioc_qbuf, @@ -1692,6 +1687,15 @@ static struct video_device gspca_template = { #endif }; +static struct video_device gspca_template = { + .name = "gspca main driver", + .type = VID_TYPE_CAPTURE, + .fops = &dev_fops, + .ioctl_ops = &dev_ioctl_ops, + .release = dev_release, /* mandatory */ + .minor = -1, +}; + /* * probe and create a new gspca device * diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index 52e00a7f3..61030309d 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1842,69 +1842,73 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return res; } -void ivtv_set_funcs(struct video_device *vdev) -{ - vdev->vidioc_querycap = ivtv_querycap; - vdev->vidioc_g_priority = ivtv_g_priority; - vdev->vidioc_s_priority = ivtv_s_priority; - vdev->vidioc_s_audio = ivtv_s_audio; - vdev->vidioc_g_audio = ivtv_g_audio; - vdev->vidioc_enumaudio = ivtv_enumaudio; - vdev->vidioc_s_audout = ivtv_s_audout; - vdev->vidioc_g_audout = ivtv_g_audout; - vdev->vidioc_enum_input = ivtv_enum_input; - vdev->vidioc_enum_output = ivtv_enum_output; - vdev->vidioc_enumaudout = ivtv_enumaudout; - vdev->vidioc_cropcap = ivtv_cropcap; - vdev->vidioc_s_crop = ivtv_s_crop; - vdev->vidioc_g_crop = ivtv_g_crop; - vdev->vidioc_g_input = ivtv_g_input; - vdev->vidioc_s_input = ivtv_s_input; - vdev->vidioc_g_output = ivtv_g_output; - vdev->vidioc_s_output = ivtv_s_output; - vdev->vidioc_g_frequency = ivtv_g_frequency; - vdev->vidioc_s_frequency = ivtv_s_frequency; - vdev->vidioc_s_tuner = ivtv_s_tuner; - vdev->vidioc_g_tuner = ivtv_g_tuner; - vdev->vidioc_g_enc_index = ivtv_g_enc_index; - vdev->vidioc_g_fbuf = ivtv_g_fbuf; - vdev->vidioc_s_fbuf = ivtv_s_fbuf; - vdev->vidioc_g_std = ivtv_g_std; - vdev->vidioc_s_std = ivtv_s_std; - vdev->vidioc_overlay = ivtv_overlay; - vdev->vidioc_log_status = ivtv_log_status; - vdev->vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap; - vdev->vidioc_encoder_cmd = ivtv_encoder_cmd; - vdev->vidioc_try_encoder_cmd = ivtv_try_encoder_cmd; - vdev->vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out; - vdev->vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap; - vdev->vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap; - vdev->vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap; - vdev->vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out; - vdev->vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay; - vdev->vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out; - vdev->vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap; - vdev->vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap; - vdev->vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap; - vdev->vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out; - vdev->vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay; - vdev->vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out; - vdev->vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap; - vdev->vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap; - vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap; - vdev->vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out; - vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay; - vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out; - vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap; - vdev->vidioc_g_chip_ident = ivtv_g_chip_ident; +static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { + .vidioc_querycap = ivtv_querycap, + .vidioc_g_priority = ivtv_g_priority, + .vidioc_s_priority = ivtv_s_priority, + .vidioc_s_audio = ivtv_s_audio, + .vidioc_g_audio = ivtv_g_audio, + .vidioc_enumaudio = ivtv_enumaudio, + .vidioc_s_audout = ivtv_s_audout, + .vidioc_g_audout = ivtv_g_audout, + .vidioc_enum_input = ivtv_enum_input, + .vidioc_enum_output = ivtv_enum_output, + .vidioc_enumaudout = ivtv_enumaudout, + .vidioc_cropcap = ivtv_cropcap, + .vidioc_s_crop = ivtv_s_crop, + .vidioc_g_crop = ivtv_g_crop, + .vidioc_g_input = ivtv_g_input, + .vidioc_s_input = ivtv_s_input, + .vidioc_g_output = ivtv_g_output, + .vidioc_s_output = ivtv_s_output, + .vidioc_g_frequency = ivtv_g_frequency, + .vidioc_s_frequency = ivtv_s_frequency, + .vidioc_s_tuner = ivtv_s_tuner, + .vidioc_g_tuner = ivtv_g_tuner, + .vidioc_g_enc_index = ivtv_g_enc_index, + .vidioc_g_fbuf = ivtv_g_fbuf, + .vidioc_s_fbuf = ivtv_s_fbuf, + .vidioc_g_std = ivtv_g_std, + .vidioc_s_std = ivtv_s_std, + .vidioc_overlay = ivtv_overlay, + .vidioc_log_status = ivtv_log_status, + .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap, + .vidioc_encoder_cmd = ivtv_encoder_cmd, + .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd, + .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out, + .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap, + .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap, + .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap, + .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out, + .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay, + .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out, + .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap, + .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap, + .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap, + .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out, + .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay, + .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out, + .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap, + .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap, + .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap, + .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out, + .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay, + .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out, + .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap, + .vidioc_g_chip_ident = ivtv_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG - vdev->vidioc_g_register = ivtv_g_register; - vdev->vidioc_s_register = ivtv_s_register; + .vidioc_g_register = ivtv_g_register, + .vidioc_s_register = ivtv_s_register, #endif - vdev->vidioc_default = ivtv_default; - vdev->vidioc_queryctrl = ivtv_queryctrl; - vdev->vidioc_querymenu = ivtv_querymenu; - vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls; - vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls; - vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls; + .vidioc_default = ivtv_default, + .vidioc_queryctrl = ivtv_queryctrl, + .vidioc_querymenu = ivtv_querymenu, + .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls, + .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls, + .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls, +}; + +void ivtv_set_funcs(struct video_device *vdev) +{ + vdev->ioctl_ops = &ivtv_ioctl_ops; } diff --git a/linux/drivers/media/video/meye.c b/linux/drivers/media/video/meye.c index 4ae76d0b0..534036647 100644 --- a/linux/drivers/media/video/meye.c +++ b/linux/drivers/media/video/meye.c @@ -1703,13 +1703,7 @@ static const struct file_operations meye_fops = { .llseek = no_llseek, }; -static struct video_device meye_template = { - .owner = THIS_MODULE, - .name = "meye", - .type = VID_TYPE_CAPTURE, - .fops = &meye_fops, - .release = video_device_release, - .minor = -1, +static const struct v4l2_ioctl_ops meye_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, @@ -1730,6 +1724,16 @@ static struct video_device meye_template = { .vidioc_default = vidioc_default, }; +static struct video_device meye_template = { + .owner = THIS_MODULE, + .name = "meye", + .type = VID_TYPE_CAPTURE, + .fops = &meye_fops, + .ioctl_ops = &meye_ioctl_ops, + .release = video_device_release, + .minor = -1, +}; + #ifdef CONFIG_PM static int meye_suspend(struct pci_dev *pdev, pm_message_t state) { diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c index f6516a4e4..f13235e31 100644 --- a/linux/drivers/media/video/s2255drv.c +++ b/linux/drivers/media/video/s2255drv.c @@ -1660,12 +1660,7 @@ static const struct file_operations s2255_fops_v4l = { .llseek = no_llseek, }; -static struct video_device template = { - .name = "s2255v", - .type = VID_TYPE_CAPTURE, - .fops = &s2255_fops_v4l, - .minor = -1, - .release = video_device_release, +static const struct v4l2_ioctl_ops s2255_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1687,6 +1682,15 @@ static struct video_device template = { #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidioc_cgmbuf, #endif +}; + +static struct video_device template = { + .name = "s2255v", + .type = VID_TYPE_CAPTURE, + .fops = &s2255_fops_v4l, + .ioctl_ops = &s2255_ioctl_ops, + .minor = -1, + .release = video_device_release, .tvnorms = S2255_NORMS, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index dc3c2a6cb..1d1c19680 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -400,16 +400,7 @@ static const struct file_operations ts_fops = .llseek = no_llseek, }; -/* ----------------------------------------------------------- */ - -static struct video_device saa7134_empress_template = -{ - .name = "saa7134-empress", - .type = 0 /* FIXME */, - .type2 = 0 /* FIXME */, - .fops = &ts_fops, - .minor = -1, - +static const struct v4l2_ioctl_ops ts_ioctl_ops = { .vidioc_querycap = empress_querycap, .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, @@ -430,6 +421,17 @@ static struct video_device saa7134_empress_template = .vidioc_querymenu = empress_querymenu, .vidioc_g_ctrl = saa7134_g_ctrl, .vidioc_s_ctrl = saa7134_s_ctrl, +}; + +/* ----------------------------------------------------------- */ + +static struct video_device saa7134_empress_template = { + .name = "saa7134-empress", + .type = 0 /* FIXME */, + .type2 = 0 /* FIXME */, + .fops = &ts_fops, + .minor = -1, + .ioctl_ops = &ts_ioctl_ops, .tvnorms = SAA7134_NORMS, .current_norm = V4L2_STD_PAL, diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index e02bd2659..7e04bfa19 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -2360,26 +2360,7 @@ static const struct file_operations video_fops = .llseek = no_llseek, }; -static const struct file_operations radio_fops = -{ - .owner = THIS_MODULE, - .open = video_open, - .release = video_release, - .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, -}; - -/* ----------------------------------------------------------- */ -/* exported stuff */ - -struct video_device saa7134_video_template = -{ - .name = "saa7134-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER | - VID_TYPE_CLIPPING|VID_TYPE_SCALES, - .fops = &video_fops, - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = saa7134_querycap, .vidioc_enum_fmt_vid_cap = saa7134_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = saa7134_g_fmt_vid_cap, @@ -2428,16 +2409,18 @@ struct video_device saa7134_video_template = .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif - .tvnorms = SAA7134_NORMS, - .current_norm = V4L2_STD_PAL, }; -struct video_device saa7134_radio_template = -{ - .name = "saa7134-radio", - .type = VID_TYPE_TUNER, - .fops = &radio_fops, - .minor = -1, +static const struct file_operations radio_fops = { + .owner = THIS_MODULE, + .open = video_open, + .release = video_release, + .ioctl = video_ioctl2, + .compat_ioctl = v4l_compat_ioctl32, + .llseek = no_llseek, +}; + +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -2454,6 +2437,28 @@ struct video_device saa7134_radio_template = .vidioc_s_frequency = saa7134_s_frequency, }; +/* ----------------------------------------------------------- */ +/* exported stuff */ + +struct video_device saa7134_video_template = { + .name = "saa7134-video", + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER | + VID_TYPE_CLIPPING|VID_TYPE_SCALES, + .fops = &video_fops, + .ioctl_ops = &video_ioctl_ops, + .minor = -1, + .tvnorms = SAA7134_NORMS, + .current_norm = V4L2_STD_PAL, +}; + +struct video_device saa7134_radio_template = { + .name = "saa7134-radio", + .type = VID_TYPE_TUNER, + .fops = &radio_fops, + .ioctl_ops = &radio_ioctl_ops, + .minor = -1, +}; + int saa7134_video_init1(struct saa7134_dev *dev) { /* sanitycheck insmod options */ diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c index b01749088..9ff561452 100644 --- a/linux/drivers/media/video/soc_camera.c +++ b/linux/drivers/media/video/soc_camera.c @@ -862,6 +862,35 @@ void soc_camera_device_unregister(struct soc_camera_device *icd) } EXPORT_SYMBOL(soc_camera_device_unregister); +static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { + .vidioc_querycap = soc_camera_querycap, + .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap, + .vidioc_enum_input = soc_camera_enum_input, + .vidioc_g_input = soc_camera_g_input, + .vidioc_s_input = soc_camera_s_input, + .vidioc_s_std = soc_camera_s_std, + .vidioc_reqbufs = soc_camera_reqbufs, + .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap, + .vidioc_querybuf = soc_camera_querybuf, + .vidioc_qbuf = soc_camera_qbuf, + .vidioc_dqbuf = soc_camera_dqbuf, + .vidioc_streamon = soc_camera_streamon, + .vidioc_streamoff = soc_camera_streamoff, + .vidioc_queryctrl = soc_camera_queryctrl, + .vidioc_g_ctrl = soc_camera_g_ctrl, + .vidioc_s_ctrl = soc_camera_s_ctrl, + .vidioc_cropcap = soc_camera_cropcap, + .vidioc_g_crop = soc_camera_g_crop, + .vidioc_s_crop = soc_camera_s_crop, + .vidioc_g_chip_ident = soc_camera_g_chip_ident, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = soc_camera_g_register, + .vidioc_s_register = soc_camera_s_register, +#endif +}; + int soc_camera_video_start(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); @@ -882,35 +911,10 @@ int soc_camera_video_start(struct soc_camera_device *icd) vdev->type = VID_TYPE_CAPTURE; vdev->current_norm = V4L2_STD_UNKNOWN; vdev->fops = &soc_camera_fops; + vdev->ioctl_ops = &soc_camera_ioctl_ops; vdev->release = video_device_release; vdev->minor = -1; vdev->tvnorms = V4L2_STD_UNKNOWN, - vdev->vidioc_querycap = soc_camera_querycap; - vdev->vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap; - vdev->vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap; - vdev->vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap; - vdev->vidioc_enum_input = soc_camera_enum_input; - vdev->vidioc_g_input = soc_camera_g_input; - vdev->vidioc_s_input = soc_camera_s_input; - vdev->vidioc_s_std = soc_camera_s_std; - vdev->vidioc_reqbufs = soc_camera_reqbufs; - vdev->vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap; - vdev->vidioc_querybuf = soc_camera_querybuf; - vdev->vidioc_qbuf = soc_camera_qbuf; - vdev->vidioc_dqbuf = soc_camera_dqbuf; - vdev->vidioc_streamon = soc_camera_streamon; - vdev->vidioc_streamoff = soc_camera_streamoff; - vdev->vidioc_queryctrl = soc_camera_queryctrl; - vdev->vidioc_g_ctrl = soc_camera_g_ctrl; - vdev->vidioc_s_ctrl = soc_camera_s_ctrl; - vdev->vidioc_cropcap = soc_camera_cropcap; - vdev->vidioc_g_crop = soc_camera_g_crop; - vdev->vidioc_s_crop = soc_camera_s_crop; - vdev->vidioc_g_chip_ident = soc_camera_g_chip_ident; -#ifdef CONFIG_VIDEO_ADV_DEBUG - vdev->vidioc_g_register = soc_camera_g_register; - vdev->vidioc_s_register = soc_camera_s_register; -#endif icd->current_fmt = &icd->formats[0]; diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index 0c605632b..059125c5a 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -1329,20 +1329,7 @@ static struct file_operations v4l_stk_fops = { .llseek = no_llseek }; -static void stk_v4l_dev_release(struct video_device *vd) -{ -} - -static struct video_device stk_v4l_data = { - .name = "stkwebcam", - .type = VFL_TYPE_GRABBER, - .type2 = VID_TYPE_CAPTURE, - .minor = -1, - .tvnorms = V4L2_STD_UNKNOWN, - .current_norm = V4L2_STD_UNKNOWN, - .fops = &v4l_stk_fops, - .release = stk_v4l_dev_release, - +static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { .vidioc_querycap = stk_vidioc_querycap, .vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap, .vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap, @@ -1364,6 +1351,22 @@ static struct video_device stk_v4l_data = { .vidioc_g_parm = stk_vidioc_g_parm, }; +static void stk_v4l_dev_release(struct video_device *vd) +{ +} + +static struct video_device stk_v4l_data = { + .name = "stkwebcam", + .type = VFL_TYPE_GRABBER, + .type2 = VID_TYPE_CAPTURE, + .minor = -1, + .tvnorms = V4L2_STD_UNKNOWN, + .current_norm = V4L2_STD_UNKNOWN, + .fops = &v4l_stk_fops, + .ioctl_ops = &v4l_stk_ioctl_ops, + .release = stk_v4l_dev_release, +}; + static int stk_register_video_device(struct stk_camera *dev) { diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 5984c7562..7eccdc1ea 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -1370,13 +1370,8 @@ static const struct file_operations usbvision_fops = { /* .poll = video_poll, */ .compat_ioctl = v4l_compat_ioctl32, }; -static struct video_device usbvision_video_template = { - .owner = THIS_MODULE, - .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, - .fops = &usbvision_fops, - .name = "usbvision-video", - .release = video_device_release, - .minor = -1, + +static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1408,6 +1403,16 @@ static struct video_device usbvision_video_template = { .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif +}; + +static struct video_device usbvision_video_template = { + .owner = THIS_MODULE, + .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, + .fops = &usbvision_fops, + .ioctl_ops = &usbvision_ioctl_ops, + .name = "usbvision-video", + .release = video_device_release, + .minor = -1, .tvnorms = USBVISION_NORMS, .current_norm = V4L2_STD_PAL }; @@ -1423,14 +1428,7 @@ static const struct file_operations usbvision_radio_fops = { .compat_ioctl = v4l_compat_ioctl32, }; -static struct video_device usbvision_radio_template= -{ - .owner = THIS_MODULE, - .type = VID_TYPE_TUNER, - .fops = &usbvision_radio_fops, - .name = "usbvision-radio", - .release = video_device_release, - .minor = -1, +static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, @@ -1444,6 +1442,16 @@ static struct video_device usbvision_radio_template= .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, +}; + +static struct video_device usbvision_radio_template = { + .owner = THIS_MODULE, + .type = VID_TYPE_TUNER, + .fops = &usbvision_radio_fops, + .name = "usbvision-radio", + .release = video_device_release, + .minor = -1, + .ioctl_ops = &usbvision_radio_ioctl_ops, .tvnorms = USBVISION_NORMS, .current_norm = V4L2_STD_PAL diff --git a/linux/drivers/media/video/v4l2-ioctl.c b/linux/drivers/media/video/v4l2-ioctl.c index 61c244d87..a56e3643b 100644 --- a/linux/drivers/media/video/v4l2-ioctl.c +++ b/linux/drivers/media/video/v4l2-ioctl.c @@ -580,43 +580,46 @@ static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) return 1; } -static int check_fmt(struct video_device *vfd, enum v4l2_buf_type type) +static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) { + if (ops == NULL) + return -EINVAL; + switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_vid_cap) + if (ops->vidioc_try_fmt_vid_cap) return 0; break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_vid_overlay) + if (ops->vidioc_try_fmt_vid_overlay) return 0; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_vid_out) + if (ops->vidioc_try_fmt_vid_out) return 0; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_try_fmt_vid_out_overlay) + if (ops->vidioc_try_fmt_vid_out_overlay) return 0; break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_cap) + if (ops->vidioc_try_fmt_vbi_cap) return 0; break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_out) + if (ops->vidioc_try_fmt_vbi_out) return 0; break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_sliced_vbi_cap) + if (ops->vidioc_try_fmt_sliced_vbi_cap) return 0; break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_sliced_vbi_out) + if (ops->vidioc_try_fmt_sliced_vbi_out) return 0; break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_try_fmt_type_private) + if (ops->vidioc_try_fmt_type_private) return 0; break; } @@ -627,6 +630,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct video_device *vfd = video_devdata(file); + const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; void *fh = file->private_data; int ret = -EINVAL; @@ -636,6 +640,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, printk(KERN_CONT "\n"); } + if (ops == NULL) { + printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n", + vfd->name); + return -EINVAL; + } + #ifdef CONFIG_VIDEO_V4L1_COMPAT /*********************************************************** Handles calls to the obsoleted V4L1 API @@ -649,9 +659,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, memset(p, 0, sizeof(*p)); - if (!vfd->vidiocgmbuf) + if (!ops->vidiocgmbuf) return ret; - ret = vfd->vidiocgmbuf(file, fh, p); + ret = ops->vidiocgmbuf(file, fh, p); if (!ret) dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n", p->size, p->frames, @@ -677,10 +687,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_capability *cap = (struct v4l2_capability *)arg; memset(cap, 0, sizeof(*cap)); - if (!vfd->vidioc_querycap) + if (!ops->vidioc_querycap) break; - ret = vfd->vidioc_querycap(file, fh, cap); + ret = ops->vidioc_querycap(file, fh, cap); if (!ret) dbgarg(cmd, "driver=%s, card=%s, bus=%s, " "version=0x%08x, " @@ -696,9 +706,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { enum v4l2_priority *p = arg; - if (!vfd->vidioc_g_priority) + if (!ops->vidioc_g_priority) break; - ret = vfd->vidioc_g_priority(file, fh, p); + ret = ops->vidioc_g_priority(file, fh, p); if (!ret) dbgarg(cmd, "priority is %d\n", *p); break; @@ -707,10 +717,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { enum v4l2_priority *p = arg; - if (!vfd->vidioc_s_priority) + if (!ops->vidioc_s_priority) break; dbgarg(cmd, "setting priority to %d\n", *p); - ret = vfd->vidioc_s_priority(file, fh, *p); + ret = ops->vidioc_s_priority(file, fh, *p); break; } @@ -729,12 +739,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_enum_fmt_vid_cap) - ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f); + if (ops->vidioc_enum_fmt_vid_cap) + ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_enum_fmt_vid_overlay) - ret = vfd->vidioc_enum_fmt_vid_overlay(file, + if (ops->vidioc_enum_fmt_vid_overlay) + ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, f); break; #if 1 /* keep */ @@ -743,19 +753,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, * it though, so just warn that this is deprecated and will be * removed in the near future. */ case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_enum_fmt_vbi_cap) { + if (ops->vidioc_enum_fmt_vbi_cap) { printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n"); - ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f); + ret = ops->vidioc_enum_fmt_vbi_cap(file, fh, f); } break; #endif case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_enum_fmt_vid_out) - ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f); + if (ops->vidioc_enum_fmt_vid_out) + ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_enum_fmt_type_private) - ret = vfd->vidioc_enum_fmt_type_private(file, + if (ops->vidioc_enum_fmt_type_private) + ret = ops->vidioc_enum_fmt_type_private(file, fh, f); break; default: @@ -783,48 +793,48 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_g_fmt_vid_cap) - ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f); + if (ops->vidioc_g_fmt_vid_cap) + ret = ops->vidioc_g_fmt_vid_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_g_fmt_vid_overlay) - ret = vfd->vidioc_g_fmt_vid_overlay(file, + if (ops->vidioc_g_fmt_vid_overlay) + ret = ops->vidioc_g_fmt_vid_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_g_fmt_vid_out) - ret = vfd->vidioc_g_fmt_vid_out(file, fh, f); + if (ops->vidioc_g_fmt_vid_out) + ret = ops->vidioc_g_fmt_vid_out(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_g_fmt_vid_out_overlay) - ret = vfd->vidioc_g_fmt_vid_out_overlay(file, + if (ops->vidioc_g_fmt_vid_out_overlay) + ret = ops->vidioc_g_fmt_vid_out_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_vbi_cap) - ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f); + if (ops->vidioc_g_fmt_vbi_cap) + ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_vbi_out) - ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f); + if (ops->vidioc_g_fmt_vbi_out) + ret = ops->vidioc_g_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_sliced_vbi_cap) - ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file, + if (ops->vidioc_g_fmt_sliced_vbi_cap) + ret = ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_sliced_vbi_out) - ret = vfd->vidioc_g_fmt_sliced_vbi_out(file, + if (ops->vidioc_g_fmt_sliced_vbi_out) + ret = ops->vidioc_g_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_g_fmt_type_private) - ret = vfd->vidioc_g_fmt_type_private(file, + if (ops->vidioc_g_fmt_type_private) + ret = ops->vidioc_g_fmt_type_private(file, fh, f); break; } @@ -841,45 +851,45 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: v4l_print_pix_fmt(vfd, &f->fmt.pix); - if (vfd->vidioc_s_fmt_vid_cap) - ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f); + if (ops->vidioc_s_fmt_vid_cap) + ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_s_fmt_vid_overlay) - ret = vfd->vidioc_s_fmt_vid_overlay(file, + if (ops->vidioc_s_fmt_vid_overlay) + ret = ops->vidioc_s_fmt_vid_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: v4l_print_pix_fmt(vfd, &f->fmt.pix); - if (vfd->vidioc_s_fmt_vid_out) - ret = vfd->vidioc_s_fmt_vid_out(file, fh, f); + if (ops->vidioc_s_fmt_vid_out) + ret = ops->vidioc_s_fmt_vid_out(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_s_fmt_vid_out_overlay) - ret = vfd->vidioc_s_fmt_vid_out_overlay(file, + if (ops->vidioc_s_fmt_vid_out_overlay) + ret = ops->vidioc_s_fmt_vid_out_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_vbi_cap) - ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f); + if (ops->vidioc_s_fmt_vbi_cap) + ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_vbi_out) - ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f); + if (ops->vidioc_s_fmt_vbi_out) + ret = ops->vidioc_s_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_sliced_vbi_cap) - ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file, + if (ops->vidioc_s_fmt_sliced_vbi_cap) + ret = ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_sliced_vbi_out) - ret = vfd->vidioc_s_fmt_sliced_vbi_out(file, + if (ops->vidioc_s_fmt_sliced_vbi_out) + ret = ops->vidioc_s_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_s_fmt_type_private) - ret = vfd->vidioc_s_fmt_type_private(file, + if (ops->vidioc_s_fmt_type_private) + ret = ops->vidioc_s_fmt_type_private(file, fh, f); break; } @@ -894,48 +904,48 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_vid_cap) - ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f); + if (ops->vidioc_try_fmt_vid_cap) + ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_vid_overlay) - ret = vfd->vidioc_try_fmt_vid_overlay(file, + if (ops->vidioc_try_fmt_vid_overlay) + ret = ops->vidioc_try_fmt_vid_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_vid_out) - ret = vfd->vidioc_try_fmt_vid_out(file, fh, f); + if (ops->vidioc_try_fmt_vid_out) + ret = ops->vidioc_try_fmt_vid_out(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_try_fmt_vid_out_overlay) - ret = vfd->vidioc_try_fmt_vid_out_overlay(file, + if (ops->vidioc_try_fmt_vid_out_overlay) + ret = ops->vidioc_try_fmt_vid_out_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_cap) - ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f); + if (ops->vidioc_try_fmt_vbi_cap) + ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_out) - ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f); + if (ops->vidioc_try_fmt_vbi_out) + ret = ops->vidioc_try_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_sliced_vbi_cap) - ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file, + if (ops->vidioc_try_fmt_sliced_vbi_cap) + ret = ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_sliced_vbi_out) - ret = vfd->vidioc_try_fmt_sliced_vbi_out(file, + if (ops->vidioc_try_fmt_sliced_vbi_out) + ret = ops->vidioc_try_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_try_fmt_type_private) - ret = vfd->vidioc_try_fmt_type_private(file, + if (ops->vidioc_try_fmt_type_private) + ret = ops->vidioc_try_fmt_type_private(file, fh, f); break; } @@ -950,13 +960,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_requestbuffers *p = arg; - if (!vfd->vidioc_reqbufs) + if (!ops->vidioc_reqbufs) break; - ret = check_fmt(vfd, p->type); + ret = check_fmt(ops, p->type); if (ret) break; - ret = vfd->vidioc_reqbufs(file, fh, p); + ret = ops->vidioc_reqbufs(file, fh, p); dbgarg(cmd, "count=%d, type=%s, memory=%s\n", p->count, prt_names(p->type, v4l2_type_names), @@ -967,13 +977,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_buffer *p = arg; - if (!vfd->vidioc_querybuf) + if (!ops->vidioc_querybuf) break; - ret = check_fmt(vfd, p->type); + ret = check_fmt(ops, p->type); if (ret) break; - ret = vfd->vidioc_querybuf(file, fh, p); + ret = ops->vidioc_querybuf(file, fh, p); if (!ret) dbgbuf(cmd, vfd, p); break; @@ -982,13 +992,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_buffer *p = arg; - if (!vfd->vidioc_qbuf) + if (!ops->vidioc_qbuf) break; - ret = check_fmt(vfd, p->type); + ret = check_fmt(ops, p->type); if (ret) break; - ret = vfd->vidioc_qbuf(file, fh, p); + ret = ops->vidioc_qbuf(file, fh, p); if (!ret) dbgbuf(cmd, vfd, p); break; @@ -997,13 +1007,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_buffer *p = arg; - if (!vfd->vidioc_dqbuf) + if (!ops->vidioc_dqbuf) break; - ret = check_fmt(vfd, p->type); + ret = check_fmt(ops, p->type); if (ret) break; - ret = vfd->vidioc_dqbuf(file, fh, p); + ret = ops->vidioc_dqbuf(file, fh, p); if (!ret) dbgbuf(cmd, vfd, p); break; @@ -1012,19 +1022,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { int *i = arg; - if (!vfd->vidioc_overlay) + if (!ops->vidioc_overlay) break; dbgarg(cmd, "value=%d\n", *i); - ret = vfd->vidioc_overlay(file, fh, *i); + ret = ops->vidioc_overlay(file, fh, *i); break; } case VIDIOC_G_FBUF: { struct v4l2_framebuffer *p = arg; - if (!vfd->vidioc_g_fbuf) + if (!ops->vidioc_g_fbuf) break; - ret = vfd->vidioc_g_fbuf(file, fh, arg); + ret = ops->vidioc_g_fbuf(file, fh, arg); if (!ret) { dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", p->capability, p->flags, @@ -1037,32 +1047,32 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_framebuffer *p = arg; - if (!vfd->vidioc_s_fbuf) + if (!ops->vidioc_s_fbuf) break; dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", p->capability, p->flags, (unsigned long)p->base); v4l_print_pix_fmt(vfd, &p->fmt); - ret = vfd->vidioc_s_fbuf(file, fh, arg); + ret = ops->vidioc_s_fbuf(file, fh, arg); break; } case VIDIOC_STREAMON: { enum v4l2_buf_type i = *(int *)arg; - if (!vfd->vidioc_streamon) + if (!ops->vidioc_streamon) break; dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); - ret = vfd->vidioc_streamon(file, fh, i); + ret = ops->vidioc_streamon(file, fh, i); break; } case VIDIOC_STREAMOFF: { enum v4l2_buf_type i = *(int *)arg; - if (!vfd->vidioc_streamoff) + if (!ops->vidioc_streamoff) break; dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); - ret = vfd->vidioc_streamoff(file, fh, i); + ret = ops->vidioc_streamoff(file, fh, i); break; } /* ---------- tv norms ---------- */ @@ -1111,8 +1121,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret = 0; /* Calls the specific handler */ - if (vfd->vidioc_g_std) - ret = vfd->vidioc_g_std(file, fh, id); + if (ops->vidioc_g_std) + ret = ops->vidioc_g_std(file, fh, id); else *id = vfd->current_norm; @@ -1131,8 +1141,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, break; /* Calls the specific handler */ - if (vfd->vidioc_s_std) - ret = vfd->vidioc_s_std(file, fh, &norm); + if (ops->vidioc_s_std) + ret = ops->vidioc_s_std(file, fh, &norm); else ret = -EINVAL; @@ -1145,9 +1155,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { v4l2_std_id *p = arg; - if (!vfd->vidioc_querystd) + if (!ops->vidioc_querystd) break; - ret = vfd->vidioc_querystd(file, fh, arg); + ret = ops->vidioc_querystd(file, fh, arg); if (!ret) dbgarg(cmd, "detected std=%08Lx\n", (unsigned long long)*p); @@ -1160,12 +1170,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_input *p = arg; int i = p->index; - if (!vfd->vidioc_enum_input) + if (!ops->vidioc_enum_input) break; memset(p, 0, sizeof(*p)); p->index = i; - ret = vfd->vidioc_enum_input(file, fh, p); + ret = ops->vidioc_enum_input(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " "audioset=%d, " @@ -1180,9 +1190,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { unsigned int *i = arg; - if (!vfd->vidioc_g_input) + if (!ops->vidioc_g_input) break; - ret = vfd->vidioc_g_input(file, fh, i); + ret = ops->vidioc_g_input(file, fh, i); if (!ret) dbgarg(cmd, "value=%d\n", *i); break; @@ -1191,10 +1201,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { unsigned int *i = arg; - if (!vfd->vidioc_s_input) + if (!ops->vidioc_s_input) break; dbgarg(cmd, "value=%d\n", *i); - ret = vfd->vidioc_s_input(file, fh, *i); + ret = ops->vidioc_s_input(file, fh, *i); break; } @@ -1204,12 +1214,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_output *p = arg; int i = p->index; - if (!vfd->vidioc_enum_output) + if (!ops->vidioc_enum_output) break; memset(p, 0, sizeof(*p)); p->index = i; - ret = vfd->vidioc_enum_output(file, fh, p); + ret = ops->vidioc_enum_output(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " "audioset=0x%x, " @@ -1222,9 +1232,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { unsigned int *i = arg; - if (!vfd->vidioc_g_output) + if (!ops->vidioc_g_output) break; - ret = vfd->vidioc_g_output(file, fh, i); + ret = ops->vidioc_g_output(file, fh, i); if (!ret) dbgarg(cmd, "value=%d\n", *i); break; @@ -1233,10 +1243,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { unsigned int *i = arg; - if (!vfd->vidioc_s_output) + if (!ops->vidioc_s_output) break; dbgarg(cmd, "value=%d\n", *i); - ret = vfd->vidioc_s_output(file, fh, *i); + ret = ops->vidioc_s_output(file, fh, *i); break; } @@ -1245,9 +1255,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_queryctrl *p = arg; - if (!vfd->vidioc_queryctrl) + if (!ops->vidioc_queryctrl) break; - ret = vfd->vidioc_queryctrl(file, fh, p); + ret = ops->vidioc_queryctrl(file, fh, p); if (!ret) dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, " "step=%d, default=%d, flags=0x%08x\n", @@ -1262,9 +1272,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_control *p = arg; - if (vfd->vidioc_g_ctrl) - ret = vfd->vidioc_g_ctrl(file, fh, p); - else if (vfd->vidioc_g_ext_ctrls) { + if (ops->vidioc_g_ctrl) + ret = ops->vidioc_g_ctrl(file, fh, p); + else if (ops->vidioc_g_ext_ctrls) { struct v4l2_ext_controls ctrls; struct v4l2_ext_control ctrl; @@ -1274,7 +1284,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ctrl.id = p->id; ctrl.value = p->value; if (check_ext_ctrls(&ctrls, 1)) { - ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls); + ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); if (ret == 0) p->value = ctrl.value; } @@ -1292,16 +1302,16 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls ctrls; struct v4l2_ext_control ctrl; - if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls) + if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls) break; dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); - if (vfd->vidioc_s_ctrl) { - ret = vfd->vidioc_s_ctrl(file, fh, p); + if (ops->vidioc_s_ctrl) { + ret = ops->vidioc_s_ctrl(file, fh, p); break; } - if (!vfd->vidioc_s_ext_ctrls) + if (!ops->vidioc_s_ext_ctrls) break; ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); @@ -1310,7 +1320,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ctrl.id = p->id; ctrl.value = p->value; if (check_ext_ctrls(&ctrls, 1)) - ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls); + ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); break; } case VIDIOC_G_EXT_CTRLS: @@ -1318,10 +1328,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls *p = arg; p->error_idx = p->count; - if (!vfd->vidioc_g_ext_ctrls) + if (!ops->vidioc_g_ext_ctrls) break; if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_g_ext_ctrls(file, fh, p); + ret = ops->vidioc_g_ext_ctrls(file, fh, p); v4l_print_ext_ctrls(cmd, vfd, p, !ret); break; } @@ -1330,11 +1340,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls *p = arg; p->error_idx = p->count; - if (!vfd->vidioc_s_ext_ctrls) + if (!ops->vidioc_s_ext_ctrls) break; v4l_print_ext_ctrls(cmd, vfd, p, 1); if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_s_ext_ctrls(file, fh, p); + ret = ops->vidioc_s_ext_ctrls(file, fh, p); break; } case VIDIOC_TRY_EXT_CTRLS: @@ -1342,20 +1352,20 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls *p = arg; p->error_idx = p->count; - if (!vfd->vidioc_try_ext_ctrls) + if (!ops->vidioc_try_ext_ctrls) break; v4l_print_ext_ctrls(cmd, vfd, p, 1); if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_try_ext_ctrls(file, fh, p); + ret = ops->vidioc_try_ext_ctrls(file, fh, p); break; } case VIDIOC_QUERYMENU: { struct v4l2_querymenu *p = arg; - if (!vfd->vidioc_querymenu) + if (!ops->vidioc_querymenu) break; - ret = vfd->vidioc_querymenu(file, fh, p); + ret = ops->vidioc_querymenu(file, fh, p); if (!ret) dbgarg(cmd, "id=0x%x, index=%d, name=%s\n", p->id, p->index, p->name); @@ -1369,9 +1379,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_audio *p = arg; - if (!vfd->vidioc_enumaudio) + if (!ops->vidioc_enumaudio) break; - ret = vfd->vidioc_enumaudio(file, fh, p); + ret = ops->vidioc_enumaudio(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " "mode=0x%x\n", p->index, p->name, @@ -1385,12 +1395,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_audio *p = arg; __u32 index = p->index; - if (!vfd->vidioc_g_audio) + if (!ops->vidioc_g_audio) break; memset(p, 0, sizeof(*p)); p->index = index; - ret = vfd->vidioc_g_audio(file, fh, p); + ret = ops->vidioc_g_audio(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " "mode=0x%x\n", p->index, @@ -1403,22 +1413,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_audio *p = arg; - if (!vfd->vidioc_s_audio) + if (!ops->vidioc_s_audio) break; dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " "mode=0x%x\n", p->index, p->name, p->capability, p->mode); - ret = vfd->vidioc_s_audio(file, fh, p); + ret = ops->vidioc_s_audio(file, fh, p); break; } case VIDIOC_ENUMAUDOUT: { struct v4l2_audioout *p = arg; - if (!vfd->vidioc_enumaudout) + if (!ops->vidioc_enumaudout) break; dbgarg(cmd, "Enum for index=%d\n", p->index); - ret = vfd->vidioc_enumaudout(file, fh, p); + ret = ops->vidioc_enumaudout(file, fh, p); if (!ret) dbgarg2("index=%d, name=%s, capability=%d, " "mode=%d\n", p->index, p->name, @@ -1429,10 +1439,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_audioout *p = arg; - if (!vfd->vidioc_g_audout) + if (!ops->vidioc_g_audout) break; dbgarg(cmd, "Enum for index=%d\n", p->index); - ret = vfd->vidioc_g_audout(file, fh, p); + ret = ops->vidioc_g_audout(file, fh, p); if (!ret) dbgarg2("index=%d, name=%s, capability=%d, " "mode=%d\n", p->index, p->name, @@ -1443,22 +1453,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_audioout *p = arg; - if (!vfd->vidioc_s_audout) + if (!ops->vidioc_s_audout) break; dbgarg(cmd, "index=%d, name=%s, capability=%d, " "mode=%d\n", p->index, p->name, p->capability, p->mode); - ret = vfd->vidioc_s_audout(file, fh, p); + ret = ops->vidioc_s_audout(file, fh, p); break; } case VIDIOC_G_MODULATOR: { struct v4l2_modulator *p = arg; - if (!vfd->vidioc_g_modulator) + if (!ops->vidioc_g_modulator) break; - ret = vfd->vidioc_g_modulator(file, fh, p); + ret = ops->vidioc_g_modulator(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, " "capability=%d, rangelow=%d," @@ -1472,23 +1482,23 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_modulator *p = arg; - if (!vfd->vidioc_s_modulator) + if (!ops->vidioc_s_modulator) break; dbgarg(cmd, "index=%d, name=%s, capability=%d, " "rangelow=%d, rangehigh=%d, txsubchans=%d\n", p->index, p->name, p->capability, p->rangelow, p->rangehigh, p->txsubchans); - ret = vfd->vidioc_s_modulator(file, fh, p); + ret = ops->vidioc_s_modulator(file, fh, p); break; } case VIDIOC_G_CROP: { struct v4l2_crop *p = arg; - if (!vfd->vidioc_g_crop) + if (!ops->vidioc_g_crop) break; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret = vfd->vidioc_g_crop(file, fh, p); + ret = ops->vidioc_g_crop(file, fh, p); if (!ret) dbgrect(vfd, "", &p->c); break; @@ -1497,11 +1507,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_crop *p = arg; - if (!vfd->vidioc_s_crop) + if (!ops->vidioc_s_crop) break; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); dbgrect(vfd, "", &p->c); - ret = vfd->vidioc_s_crop(file, fh, p); + ret = ops->vidioc_s_crop(file, fh, p); break; } case VIDIOC_CROPCAP: @@ -1509,10 +1519,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_cropcap *p = arg; /*FIXME: Should also show v4l2_fract pixelaspect */ - if (!vfd->vidioc_cropcap) + if (!ops->vidioc_cropcap) break; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret = vfd->vidioc_cropcap(file, fh, p); + ret = ops->vidioc_cropcap(file, fh, p); if (!ret) { dbgrect(vfd, "bounds ", &p->bounds); dbgrect(vfd, "defrect ", &p->defrect); @@ -1523,9 +1533,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_jpegcompression *p = arg; - if (!vfd->vidioc_g_jpegcomp) + if (!ops->vidioc_g_jpegcomp) break; - ret = vfd->vidioc_g_jpegcomp(file, fh, p); + ret = ops->vidioc_g_jpegcomp(file, fh, p); if (!ret) dbgarg(cmd, "quality=%d, APPn=%d, " "APP_len=%d, COM_len=%d, " @@ -1538,22 +1548,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_jpegcompression *p = arg; - if (!vfd->vidioc_g_jpegcomp) + if (!ops->vidioc_g_jpegcomp) break; dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, " "COM_len=%d, jpeg_markers=%d\n", p->quality, p->APPn, p->APP_len, p->COM_len, p->jpeg_markers); - ret = vfd->vidioc_s_jpegcomp(file, fh, p); + ret = ops->vidioc_s_jpegcomp(file, fh, p); break; } case VIDIOC_G_ENC_INDEX: { struct v4l2_enc_idx *p = arg; - if (!vfd->vidioc_g_enc_index) + if (!ops->vidioc_g_enc_index) break; - ret = vfd->vidioc_g_enc_index(file, fh, p); + ret = ops->vidioc_g_enc_index(file, fh, p); if (!ret) dbgarg(cmd, "entries=%d, entries_cap=%d\n", p->entries, p->entries_cap); @@ -1563,10 +1573,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_encoder_cmd *p = arg; - if (!vfd->vidioc_encoder_cmd) + if (!ops->vidioc_encoder_cmd) break; memset(&p->raw, 0, sizeof(p->raw)); - ret = vfd->vidioc_encoder_cmd(file, fh, p); + ret = ops->vidioc_encoder_cmd(file, fh, p); if (!ret) dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); break; @@ -1575,10 +1585,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_encoder_cmd *p = arg; - if (!vfd->vidioc_try_encoder_cmd) + if (!ops->vidioc_try_encoder_cmd) break; memset(&p->raw, 0, sizeof(p->raw)); - ret = vfd->vidioc_try_encoder_cmd(file, fh, p); + ret = ops->vidioc_try_encoder_cmd(file, fh, p); if (!ret) dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); break; @@ -1591,8 +1601,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, memset(p, 0, sizeof(*p)); p->type = type; - if (vfd->vidioc_g_parm) { - ret = vfd->vidioc_g_parm(file, fh, p); + if (ops->vidioc_g_parm) { + ret = ops->vidioc_g_parm(file, fh, p); } else { struct v4l2_standard s; @@ -1613,10 +1623,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_streamparm *p = arg; - if (!vfd->vidioc_s_parm) + if (!ops->vidioc_s_parm) break; dbgarg(cmd, "type=%d\n", p->type); - ret = vfd->vidioc_s_parm(file, fh, p); + ret = ops->vidioc_s_parm(file, fh, p); break; } case VIDIOC_G_TUNER: @@ -1624,13 +1634,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_tuner *p = arg; __u32 index = p->index; - if (!vfd->vidioc_g_tuner) + if (!ops->vidioc_g_tuner) break; memset(p, 0, sizeof(*p)); p->index = index; - ret = vfd->vidioc_g_tuner(file, fh, p); + ret = ops->vidioc_g_tuner(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " "capability=0x%x, rangelow=%d, " @@ -1646,7 +1656,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_tuner *p = arg; - if (!vfd->vidioc_s_tuner) + if (!ops->vidioc_s_tuner) break; dbgarg(cmd, "index=%d, name=%s, type=%d, " "capability=0x%x, rangelow=%d, " @@ -1656,19 +1666,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, p->capability, p->rangelow, p->rangehigh, p->signal, p->afc, p->rxsubchans, p->audmode); - ret = vfd->vidioc_s_tuner(file, fh, p); + ret = ops->vidioc_s_tuner(file, fh, p); break; } case VIDIOC_G_FREQUENCY: { struct v4l2_frequency *p = arg; - if (!vfd->vidioc_g_frequency) + if (!ops->vidioc_g_frequency) break; memset(p->reserved, 0, sizeof(p->reserved)); - ret = vfd->vidioc_g_frequency(file, fh, p); + ret = ops->vidioc_g_frequency(file, fh, p); if (!ret) dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", p->tuner, p->type, p->frequency); @@ -1678,11 +1688,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_frequency *p = arg; - if (!vfd->vidioc_s_frequency) + if (!ops->vidioc_s_frequency) break; dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", p->tuner, p->type, p->frequency); - ret = vfd->vidioc_s_frequency(file, fh, p); + ret = ops->vidioc_s_frequency(file, fh, p); break; } case VIDIOC_G_SLICED_VBI_CAP: @@ -1690,21 +1700,21 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_sliced_vbi_cap *p = arg; __u32 type = p->type; - if (!vfd->vidioc_g_sliced_vbi_cap) + if (!ops->vidioc_g_sliced_vbi_cap) break; memset(p, 0, sizeof(*p)); p->type = type; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p); + ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p); if (!ret) dbgarg2("service_set=%d\n", p->service_set); break; } case VIDIOC_LOG_STATUS: { - if (!vfd->vidioc_log_status) + if (!ops->vidioc_log_status) break; - ret = vfd->vidioc_log_status(file, fh); + ret = ops->vidioc_log_status(file, fh); break; } #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -1714,8 +1724,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) ret = -EPERM; - else if (vfd->vidioc_g_register) - ret = vfd->vidioc_g_register(file, fh, p); + else if (ops->vidioc_g_register) + ret = ops->vidioc_g_register(file, fh, p); break; } case VIDIOC_DBG_S_REGISTER: @@ -1724,8 +1734,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) ret = -EPERM; - else if (vfd->vidioc_s_register) - ret = vfd->vidioc_s_register(file, fh, p); + else if (ops->vidioc_s_register) + ret = ops->vidioc_s_register(file, fh, p); break; } #endif @@ -1733,30 +1743,30 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_chip_ident *p = arg; - if (!vfd->vidioc_g_chip_ident) + if (!ops->vidioc_g_chip_ident) break; - ret = vfd->vidioc_g_chip_ident(file, fh, p); + ret = ops->vidioc_g_chip_ident(file, fh, p); if (!ret) dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); break; } - default: - { - if (!vfd->vidioc_default) - break; - ret = vfd->vidioc_default(file, fh, cmd, arg); - break; - } case VIDIOC_S_HW_FREQ_SEEK: { struct v4l2_hw_freq_seek *p = arg; - if (!vfd->vidioc_s_hw_freq_seek) + if (!ops->vidioc_s_hw_freq_seek) break; dbgarg(cmd, "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", p->tuner, p->type, p->seek_upward, p->wrap_around); - ret = vfd->vidioc_s_hw_freq_seek(file, fh, p); + ret = ops->vidioc_s_hw_freq_seek(file, fh, p); + break; + } + default: + { + if (!ops->vidioc_default) + break; + ret = ops->vidioc_default(file, fh, cmd, arg); break; } } /* switch */ diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 7f4a53077..fcb69f8f0 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -1069,13 +1069,7 @@ static const struct file_operations vivi_fops = { .llseek = no_llseek, }; -static struct video_device vivi_template = { - .name = "vivi", - .type = VID_TYPE_CAPTURE, - .fops = &vivi_fops, - .minor = -1, - .release = video_device_release, - +static const struct v4l2_ioctl_ops vivi_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1097,6 +1091,16 @@ static struct video_device vivi_template = { #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidiocgmbuf, #endif +}; + +static struct video_device vivi_template = { + .name = "vivi", + .type = VID_TYPE_CAPTURE, + .fops = &vivi_fops, + .ioctl_ops = &vivi_ioctl_ops, + .minor = -1, + .release = video_device_release, + .tvnorms = V4L2_STD_525_60, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index 0967cdb3f..766873fc7 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -763,14 +763,7 @@ static const struct file_operations zr364xx_fops = { .llseek = no_llseek, }; -static struct video_device zr364xx_template = { - .owner = THIS_MODULE, - .name = DRIVER_DESC, - .type = VID_TYPE_CAPTURE, - .fops = &zr364xx_fops, - .release = video_device_release, - .minor = -1, - +static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { .vidioc_querycap = zr364xx_vidioc_querycap, .vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap, .vidioc_try_fmt_vid_cap = zr364xx_vidioc_try_fmt_vid_cap, @@ -786,6 +779,16 @@ static struct video_device zr364xx_template = { .vidioc_s_ctrl = zr364xx_vidioc_s_ctrl, }; +static struct video_device zr364xx_template = { + .owner = THIS_MODULE, + .name = DRIVER_DESC, + .type = VID_TYPE_CAPTURE, + .fops = &zr364xx_fops, + .ioctl_ops = &zr364xx_ioctl_ops, + .release = video_device_release, + .minor = -1, +}; + /*******************/ -- cgit v1.2.3 From b0a3353c78a940cd8bea78e789a5e7b2c69788c7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 21 Jul 2008 12:51:45 +0200 Subject: Remove obsolete owner field from video_device struct. From: Hans Verkuil According to an old comment this should have been removed in 2.6.15. Better late than never... Signed-off-by: Hans Verkuil --- linux/drivers/media/radio/dsbr100.c | 1 - linux/drivers/media/radio/miropcm20-radio.c | 1 - linux/drivers/media/radio/radio-aimslab.c | 1 - linux/drivers/media/radio/radio-aztech.c | 1 - linux/drivers/media/radio/radio-cadet.c | 1 - linux/drivers/media/radio/radio-gemtek-pci.c | 1 - linux/drivers/media/radio/radio-gemtek.c | 1 - linux/drivers/media/radio/radio-maxiradio.c | 1 - linux/drivers/media/radio/radio-rtrack2.c | 1 - linux/drivers/media/radio/radio-sf16fmi.c | 1 - linux/drivers/media/radio/radio-sf16fmr2.c | 1 - linux/drivers/media/radio/radio-si470x.c | 1 - linux/drivers/media/radio/radio-terratec.c | 1 - linux/drivers/media/radio/radio-trust.c | 1 - linux/drivers/media/radio/radio-typhoon.c | 1 - linux/drivers/media/radio/radio-zoltrix.c | 1 - linux/drivers/media/video/bw-qcam.c | 1 - linux/drivers/media/video/c-qcam.c | 1 - linux/drivers/media/video/cpia.c | 1 - linux/drivers/media/video/cpia2/cpia2_v4l.c | 1 - linux/drivers/media/video/et61x251/et61x251_core.c | 1 - linux/drivers/media/video/meye.c | 1 - linux/drivers/media/video/ov511.c | 1 - linux/drivers/media/video/pms.c | 1 - linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 1 - linux/drivers/media/video/pwc/pwc-if.c | 2 -- linux/drivers/media/video/saa5246a.c | 1 - linux/drivers/media/video/saa5249.c | 1 - linux/drivers/media/video/se401.c | 1 - linux/drivers/media/video/sn9c102/sn9c102_core.c | 1 - linux/drivers/media/video/stv680.c | 1 - linux/drivers/media/video/usbvideo/usbvideo.c | 1 - linux/drivers/media/video/usbvideo/vicam.c | 1 - linux/drivers/media/video/usbvision/usbvision-video.c | 3 --- linux/drivers/media/video/w9966.c | 1 - linux/drivers/media/video/w9968cf.c | 1 - linux/drivers/media/video/zc0301/zc0301_core.c | 1 - linux/drivers/media/video/zr364xx.c | 1 - 38 files changed, 41 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/radio/dsbr100.c b/linux/drivers/media/radio/dsbr100.c index 00be53110..58a4b2396 100644 --- a/linux/drivers/media/radio/dsbr100.c +++ b/linux/drivers/media/radio/dsbr100.c @@ -463,7 +463,6 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { /* V4L2 interface */ static struct video_device dsbr100_videodev_template = { - .owner = THIS_MODULE, .name = "D-Link DSB-R 100", .type = VID_TYPE_TUNER, .fops = &usb_dsbr100_fops, diff --git a/linux/drivers/media/radio/miropcm20-radio.c b/linux/drivers/media/radio/miropcm20-radio.c index 8dacd5522..5be7c5c25 100644 --- a/linux/drivers/media/radio/miropcm20-radio.c +++ b/linux/drivers/media/radio/miropcm20-radio.c @@ -230,7 +230,6 @@ static const struct file_operations pcm20_fops = { }; static struct video_device pcm20_radio = { - .owner = THIS_MODULE, .name = "Miro PCM 20 radio", .type = VID_TYPE_TUNER, .fops = &pcm20_fops, diff --git a/linux/drivers/media/radio/radio-aimslab.c b/linux/drivers/media/radio/radio-aimslab.c index cadbf2eef..67e4a5e14 100644 --- a/linux/drivers/media/radio/radio-aimslab.c +++ b/linux/drivers/media/radio/radio-aimslab.c @@ -406,7 +406,6 @@ static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { }; static struct video_device rtrack_radio = { - .owner = THIS_MODULE, .name = "RadioTrack radio", .type = VID_TYPE_TUNER, .fops = &rtrack_fops, diff --git a/linux/drivers/media/radio/radio-aztech.c b/linux/drivers/media/radio/radio-aztech.c index 5711f7e96..77bc931ea 100644 --- a/linux/drivers/media/radio/radio-aztech.c +++ b/linux/drivers/media/radio/radio-aztech.c @@ -370,7 +370,6 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = { }; static struct video_device aztech_radio = { - .owner = THIS_MODULE, .name = "Aztech radio", .type = VID_TYPE_TUNER, .fops = &aztech_fops, diff --git a/linux/drivers/media/radio/radio-cadet.c b/linux/drivers/media/radio/radio-cadet.c index 1e8e0e877..54b10c713 100644 --- a/linux/drivers/media/radio/radio-cadet.c +++ b/linux/drivers/media/radio/radio-cadet.c @@ -616,7 +616,6 @@ static const struct v4l2_ioctl_ops cadet_ioctl_ops = { }; static struct video_device cadet_radio = { - .owner = THIS_MODULE, .name = "Cadet radio", .type = VID_TYPE_TUNER, .fops = &cadet_fops, diff --git a/linux/drivers/media/radio/radio-gemtek-pci.c b/linux/drivers/media/radio/radio-gemtek-pci.c index 168e3a90c..4b9c5a228 100644 --- a/linux/drivers/media/radio/radio-gemtek-pci.c +++ b/linux/drivers/media/radio/radio-gemtek-pci.c @@ -392,7 +392,6 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { }; static struct video_device vdev_template = { - .owner = THIS_MODULE, .name = "Gemtek PCI Radio", .type = VID_TYPE_TUNER, .fops = &gemtek_pci_fops, diff --git a/linux/drivers/media/radio/radio-gemtek.c b/linux/drivers/media/radio/radio-gemtek.c index 98689f5f6..0b63c500d 100644 --- a/linux/drivers/media/radio/radio-gemtek.c +++ b/linux/drivers/media/radio/radio-gemtek.c @@ -570,7 +570,6 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { }; static struct video_device gemtek_radio = { - .owner = THIS_MODULE, .name = "GemTek Radio card", .type = VID_TYPE_TUNER, .fops = &gemtek_fops, diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index 7550b9196..2cacafa5c 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -391,7 +391,6 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { }; static struct video_device maxiradio_radio = { - .owner = THIS_MODULE, .name = "Maxi Radio FM2000 radio", .type = VID_TYPE_TUNER, .fops = &maxiradio_fops, diff --git a/linux/drivers/media/radio/radio-rtrack2.c b/linux/drivers/media/radio/radio-rtrack2.c index 8828fb44d..135d104ba 100644 --- a/linux/drivers/media/radio/radio-rtrack2.c +++ b/linux/drivers/media/radio/radio-rtrack2.c @@ -312,7 +312,6 @@ static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { }; static struct video_device rtrack2_radio = { - .owner = THIS_MODULE, .name = "RadioTrack II radio", .type = VID_TYPE_TUNER, .fops = &rtrack2_fops, diff --git a/linux/drivers/media/radio/radio-sf16fmi.c b/linux/drivers/media/radio/radio-sf16fmi.c index 87f32221d..375a9cbf4 100644 --- a/linux/drivers/media/radio/radio-sf16fmi.c +++ b/linux/drivers/media/radio/radio-sf16fmi.c @@ -312,7 +312,6 @@ static const struct v4l2_ioctl_ops fmi_ioctl_ops = { }; static struct video_device fmi_radio = { - .owner = THIS_MODULE, .name = "SF16FMx radio", .type = VID_TYPE_TUNER, .fops = &fmi_fops, diff --git a/linux/drivers/media/radio/radio-sf16fmr2.c b/linux/drivers/media/radio/radio-sf16fmr2.c index 01b2516e7..7e8516a2b 100644 --- a/linux/drivers/media/radio/radio-sf16fmr2.c +++ b/linux/drivers/media/radio/radio-sf16fmr2.c @@ -428,7 +428,6 @@ static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { }; static struct video_device fmr2_radio = { - .owner = THIS_MODULE, .name = "SF16FMR2 radio", .type = VID_TYPE_TUNER, .fops = &fmr2_fops, diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index cbded7f86..15b9da575 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -1616,7 +1616,6 @@ static struct video_device si470x_viddev_template = { .name = DRIVER_NAME, .type = VID_TYPE_TUNER, .release = video_device_release, - .owner = THIS_MODULE, }; diff --git a/linux/drivers/media/radio/radio-terratec.c b/linux/drivers/media/radio/radio-terratec.c index 5e8582055..0eff7b780 100644 --- a/linux/drivers/media/radio/radio-terratec.c +++ b/linux/drivers/media/radio/radio-terratec.c @@ -384,7 +384,6 @@ static const struct v4l2_ioctl_ops terratec_ioctl_ops = { }; static struct video_device terratec_radio = { - .owner = THIS_MODULE, .name = "TerraTec ActiveRadio", .type = VID_TYPE_TUNER, .fops = &terratec_fops, diff --git a/linux/drivers/media/radio/radio-trust.c b/linux/drivers/media/radio/radio-trust.c index 57b69a7c0..28ebeb938 100644 --- a/linux/drivers/media/radio/radio-trust.c +++ b/linux/drivers/media/radio/radio-trust.c @@ -367,7 +367,6 @@ static const struct v4l2_ioctl_ops trust_ioctl_ops = { }; static struct video_device trust_radio = { - .owner = THIS_MODULE, .name = "Trust FM Radio", .type = VID_TYPE_TUNER, .fops = &trust_fops, diff --git a/linux/drivers/media/radio/radio-typhoon.c b/linux/drivers/media/radio/radio-typhoon.c index 3c377fbd7..dd7903e26 100644 --- a/linux/drivers/media/radio/radio-typhoon.c +++ b/linux/drivers/media/radio/radio-typhoon.c @@ -362,7 +362,6 @@ static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { }; static struct video_device typhoon_radio = { - .owner = THIS_MODULE, .name = "Typhoon Radio", .type = VID_TYPE_TUNER, .fops = &typhoon_fops, diff --git a/linux/drivers/media/radio/radio-zoltrix.c b/linux/drivers/media/radio/radio-zoltrix.c index cdd7deba7..9f7c84530 100644 --- a/linux/drivers/media/radio/radio-zoltrix.c +++ b/linux/drivers/media/radio/radio-zoltrix.c @@ -425,7 +425,6 @@ static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { }; static struct video_device zoltrix_radio = { - .owner = THIS_MODULE, .name = "Zoltrix Radio Plus", .type = VID_TYPE_TUNER, .fops = &zoltrix_fops, diff --git a/linux/drivers/media/video/bw-qcam.c b/linux/drivers/media/video/bw-qcam.c index cc247d6bb..3e103dede 100644 --- a/linux/drivers/media/video/bw-qcam.c +++ b/linux/drivers/media/video/bw-qcam.c @@ -908,7 +908,6 @@ static const struct file_operations qcam_fops = { }; static struct video_device qcam_template= { - .owner = THIS_MODULE, .name = "Connectix Quickcam", .type = VID_TYPE_CAPTURE, .fops = &qcam_fops, diff --git a/linux/drivers/media/video/c-qcam.c b/linux/drivers/media/video/c-qcam.c index 3824c8601..70b96484e 100644 --- a/linux/drivers/media/video/c-qcam.c +++ b/linux/drivers/media/video/c-qcam.c @@ -703,7 +703,6 @@ static const struct file_operations qcam_fops = { static struct video_device qcam_template= { - .owner = THIS_MODULE, .name = "Colour QuickCam", .type = VID_TYPE_CAPTURE, .fops = &qcam_fops, diff --git a/linux/drivers/media/video/cpia.c b/linux/drivers/media/video/cpia.c index d5941cc15..aeaddc047 100644 --- a/linux/drivers/media/video/cpia.c +++ b/linux/drivers/media/video/cpia.c @@ -3799,7 +3799,6 @@ static const struct file_operations cpia_fops = { }; static struct video_device cpia_template = { - .owner = THIS_MODULE, .name = "CPiA Camera", .type = VID_TYPE_CAPTURE, .fops = &cpia_fops, diff --git a/linux/drivers/media/video/cpia2/cpia2_v4l.c b/linux/drivers/media/video/cpia2/cpia2_v4l.c index 8817c3841..4e45de78d 100644 --- a/linux/drivers/media/video/cpia2/cpia2_v4l.c +++ b/linux/drivers/media/video/cpia2/cpia2_v4l.c @@ -1936,7 +1936,6 @@ static const struct file_operations fops_template = { static struct video_device cpia2_template = { /* I could not find any place for the old .initialize initializer?? */ - .owner= THIS_MODULE, .name= "CPiA2 Camera", .type= VID_TYPE_CAPTURE, .type2 = V4L2_CAP_VIDEO_CAPTURE | diff --git a/linux/drivers/media/video/et61x251/et61x251_core.c b/linux/drivers/media/video/et61x251/et61x251_core.c index 0711a34fb..f3a2ed067 100644 --- a/linux/drivers/media/video/et61x251/et61x251_core.c +++ b/linux/drivers/media/video/et61x251/et61x251_core.c @@ -2589,7 +2589,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); - cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &et61x251_fops; cam->v4ldev->minor = video_nr[dev_nr]; diff --git a/linux/drivers/media/video/meye.c b/linux/drivers/media/video/meye.c index 534036647..f5cc0c636 100644 --- a/linux/drivers/media/video/meye.c +++ b/linux/drivers/media/video/meye.c @@ -1725,7 +1725,6 @@ static const struct v4l2_ioctl_ops meye_ioctl_ops = { }; static struct video_device meye_template = { - .owner = THIS_MODULE, .name = "meye", .type = VID_TYPE_CAPTURE, .fops = &meye_fops, diff --git a/linux/drivers/media/video/ov511.c b/linux/drivers/media/video/ov511.c index ebfe94076..a4125b44d 100644 --- a/linux/drivers/media/video/ov511.c +++ b/linux/drivers/media/video/ov511.c @@ -4670,7 +4670,6 @@ static const struct file_operations ov511_fops = { }; static struct video_device vdev_template = { - .owner = THIS_MODULE, .name = "OV511 USB Camera", .type = VID_TYPE_CAPTURE, .fops = &ov511_fops, diff --git a/linux/drivers/media/video/pms.c b/linux/drivers/media/video/pms.c index 31d8a929f..98dc31354 100644 --- a/linux/drivers/media/video/pms.c +++ b/linux/drivers/media/video/pms.c @@ -896,7 +896,6 @@ static const struct file_operations pms_fops = { static struct video_device pms_template= { - .owner = THIS_MODULE, .name = "Mediavision PMS", .type = VID_TYPE_CAPTURE, .fops = &pms_fops, diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index f097d6aaf..4d7cd7cd7 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -1162,7 +1162,6 @@ static const struct file_operations vdev_fops = { static struct video_device vdev_template = { - .owner = THIS_MODULE, .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER, .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index e51ee878b..e8e8fd280 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -165,7 +165,6 @@ static const struct file_operations pwc_fops = { .llseek = no_llseek, }; static struct video_device pwc_template = { - .owner = THIS_MODULE, .name = "Philips Webcam", /* Filled in later */ .type = VID_TYPE_CAPTURE, .release = video_device_release, @@ -1773,7 +1772,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); pdev->vdev->parent = &(udev->dev); strcpy(pdev->vdev->name, name); - pdev->vdev->owner = THIS_MODULE; video_set_drvdata(pdev->vdev, pdev); pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); diff --git a/linux/drivers/media/video/saa5246a.c b/linux/drivers/media/video/saa5246a.c index 49b4a046c..2b85850ca 100644 --- a/linux/drivers/media/video/saa5246a.c +++ b/linux/drivers/media/video/saa5246a.c @@ -831,7 +831,6 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { - .owner = THIS_MODULE, .name = IF_NAME, .type = VID_TYPE_TELETEXT, .fops = &saa_fops, diff --git a/linux/drivers/media/video/saa5249.c b/linux/drivers/media/video/saa5249.c index 6423a6762..8627d68dd 100644 --- a/linux/drivers/media/video/saa5249.c +++ b/linux/drivers/media/video/saa5249.c @@ -712,7 +712,6 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { - .owner = THIS_MODULE, .name = IF_NAME, .type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */ .fops = &saa_fops, diff --git a/linux/drivers/media/video/se401.c b/linux/drivers/media/video/se401.c index c82bfddde..5da0625b7 100644 --- a/linux/drivers/media/video/se401.c +++ b/linux/drivers/media/video/se401.c @@ -1238,7 +1238,6 @@ static const struct file_operations se401_fops = { .llseek = no_llseek, }; static struct video_device se401_template = { - .owner = THIS_MODULE, .name = "se401 USB camera", .type = VID_TYPE_CAPTURE, .fops = &se401_fops, diff --git a/linux/drivers/media/video/sn9c102/sn9c102_core.c b/linux/drivers/media/video/sn9c102/sn9c102_core.c index ea062da55..e41d3afcd 100644 --- a/linux/drivers/media/video/sn9c102/sn9c102_core.c +++ b/linux/drivers/media/video/sn9c102/sn9c102_core.c @@ -3313,7 +3313,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "SN9C1xx PC Camera"); - cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &sn9c102_fops; cam->v4ldev->minor = video_nr[dev_nr]; diff --git a/linux/drivers/media/video/stv680.c b/linux/drivers/media/video/stv680.c index 29c62e534..2e8348cc7 100644 --- a/linux/drivers/media/video/stv680.c +++ b/linux/drivers/media/video/stv680.c @@ -1406,7 +1406,6 @@ static const struct file_operations stv680_fops = { .llseek = no_llseek, }; static struct video_device stv680_template = { - .owner = THIS_MODULE, .name = "STV0680 USB camera", .type = VID_TYPE_CAPTURE, .fops = &stv680_fops, diff --git a/linux/drivers/media/video/usbvideo/usbvideo.c b/linux/drivers/media/video/usbvideo/usbvideo.c index f399db543..737ff846b 100644 --- a/linux/drivers/media/video/usbvideo/usbvideo.c +++ b/linux/drivers/media/video/usbvideo/usbvideo.c @@ -952,7 +952,6 @@ static const struct file_operations usbvideo_fops = { .llseek = no_llseek, }; static const struct video_device usbvideo_template = { - .owner = THIS_MODULE, .type = VID_TYPE_CAPTURE, .fops = &usbvideo_fops, }; diff --git a/linux/drivers/media/video/usbvideo/vicam.c b/linux/drivers/media/video/usbvideo/vicam.c index 2aa05f7ca..e24a089ec 100644 --- a/linux/drivers/media/video/usbvideo/vicam.c +++ b/linux/drivers/media/video/usbvideo/vicam.c @@ -1101,7 +1101,6 @@ static const struct file_operations vicam_fops = { }; static struct video_device vicam_template = { - .owner = THIS_MODULE, .name = "ViCam-based USB Camera", .type = VID_TYPE_CAPTURE, .fops = &vicam_fops, diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 7eccdc1ea..e97f955aa 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -1406,7 +1406,6 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { }; static struct video_device usbvision_video_template = { - .owner = THIS_MODULE, .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, .fops = &usbvision_fops, .ioctl_ops = &usbvision_ioctl_ops, @@ -1445,7 +1444,6 @@ static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { }; static struct video_device usbvision_radio_template = { - .owner = THIS_MODULE, .type = VID_TYPE_TUNER, .fops = &usbvision_radio_fops, .name = "usbvision-radio", @@ -1469,7 +1467,6 @@ static const struct file_operations usbvision_vbi_fops = { static struct video_device usbvision_vbi_template= { - .owner = THIS_MODULE, .type = VID_TYPE_TUNER, .fops = &usbvision_vbi_fops, .release = video_device_release, diff --git a/linux/drivers/media/video/w9966.c b/linux/drivers/media/video/w9966.c index 66c730b8b..543c54ecb 100644 --- a/linux/drivers/media/video/w9966.c +++ b/linux/drivers/media/video/w9966.c @@ -197,7 +197,6 @@ static const struct file_operations w9966_fops = { .llseek = no_llseek, }; static struct video_device w9966_template = { - .owner = THIS_MODULE, .name = W9966_DRIVERNAME, .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES, .fops = &w9966_fops, diff --git a/linux/drivers/media/video/w9968cf.c b/linux/drivers/media/video/w9968cf.c index 8e0f6bcfd..47b2ca9fe 100644 --- a/linux/drivers/media/video/w9968cf.c +++ b/linux/drivers/media/video/w9968cf.c @@ -3558,7 +3558,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, symbolic(camlist, mod_id)); - cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &w9968cf_fops; cam->v4ldev->minor = video_nr[dev_nr]; diff --git a/linux/drivers/media/video/zc0301/zc0301_core.c b/linux/drivers/media/video/zc0301/zc0301_core.c index e167fa560..57d2f62e7 100644 --- a/linux/drivers/media/video/zc0301/zc0301_core.c +++ b/linux/drivers/media/video/zc0301/zc0301_core.c @@ -1989,7 +1989,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); - cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &zc0301_fops; cam->v4ldev->minor = video_nr[dev_nr]; diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index 766873fc7..a697d7d6f 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -780,7 +780,6 @@ static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { }; static struct video_device zr364xx_template = { - .owner = THIS_MODULE, .name = DRIVER_DESC, .type = VID_TYPE_CAPTURE, .fops = &zr364xx_fops, -- cgit v1.2.3 From d833592062af2f091939de4dbdf66283f27c81ec Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 Jul 2008 19:20:32 +0000 Subject: replace __FUNCTION__ with __func__ From: Alexander Beregalov v4l: replace __FUNCTION__ with __func__ Signed-off-by: Alexander Beregalov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx23885/cx23885-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 14e14f884..0c34db9f7 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -1449,7 +1449,7 @@ void cx23885_cancel_buffers(struct cx23885_tsport *port) struct cx23885_dev *dev = port->dev; struct cx23885_dmaqueue *q = &port->mpegq; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); del_timer_sync(&q->timeout); cx23885_stop_dma(port); do_cancel_buffers(port, "cancel", 0); -- cgit v1.2.3 From 89fe48e70c85b3ff9795e6a5fc3b190ecb030297 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 21 Jul 2008 19:21:58 +0000 Subject: replace __FUNCTION__ with __func__ From: Alexander Beregalov v4l/drx397xD: replace __FUNCTION__ with __func__ Signed-off-by: Alexander Beregalov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/drx397xD.c | 34 ++++++++++++++-------------- linux/drivers/media/dvb/frontends/drx397xD.h | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/frontends/drx397xD.c b/linux/drivers/media/dvb/frontends/drx397xD.c index 52a9a6553..f1ea891d7 100644 --- a/linux/drivers/media/dvb/frontends/drx397xD.c +++ b/linux/drivers/media/dvb/frontends/drx397xD.c @@ -97,7 +97,7 @@ static void drx_release_fw(struct drx397xD_state *s) { fw_ix_t ix = s->chip_rev; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); write_lock(&fw[ix].lock); if (fw[ix].refcnt) { @@ -114,7 +114,7 @@ static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) size_t size, len; int i = 0, j, rc = -EINVAL; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); if (ix < 0 || ix >= ARRAY_SIZE(fw)) return -EINVAL; @@ -198,10 +198,10 @@ static int write_fw(struct drx397xD_state *s, blob_ix_t ix) int len, rc = 0, i = 0; if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { - pr_debug("%s drx_fw_ix_t out of range\n", __FUNCTION__); + pr_debug("%s drx_fw_ix_t out of range\n", __func__); return -EINVAL; } - pr_debug("%s %s\n", __FUNCTION__, blob_name[ix]); + pr_debug("%s %s\n", __func__, blob_name[ix]); read_lock(&fw[s->chip_rev].lock); data = fw[s->chip_rev].data[ix]; @@ -306,7 +306,7 @@ static int PLL_Set(struct drx397xD_state *s, u32 f_tuner, f = fep->frequency; int rc; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); if ((f > s->frontend.ops.tuner_ops.info.frequency_max) || (f < s->frontend.ops.tuner_ops.info.frequency_min)) @@ -326,7 +326,7 @@ static int PLL_Set(struct drx397xD_state *s, return rc; *df_tuner = f_tuner - f; - pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __FUNCTION__, f, + pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __func__, f, f_tuner); return 0; @@ -341,7 +341,7 @@ static int SC_WaitForReady(struct drx397xD_state *s) int cnt = 1000; int rc; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); while (cnt--) { rc = RD16(s, 0x820043); @@ -355,7 +355,7 @@ static int SC_SendCommand(struct drx397xD_state *s, int cmd) { int rc; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); WR16(s, 0x820043, cmd); SC_WaitForReady(s); @@ -369,7 +369,7 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd) { int rc, cnt = 1000; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); rc = WR16(s, 0x420032, cmd); if (rc < 0) @@ -390,7 +390,7 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd) static int HI_CfgCommand(struct drx397xD_state *s) { - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); WR16(s, 0x420033, 0x3973); WR16(s, 0x420034, s->config.w50); // code 4, log 4 @@ -420,7 +420,7 @@ static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc) u16 w0C = agc->w0C; int quot, rem, i, rc = -EINVAL; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); if (agc->w04 > 0x3ff) goto exit_rc; @@ -479,7 +479,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) u16 w06 = agc->w06; int rc = -1; - pr_debug("%s %d 0x%x 0x%x\n", __FUNCTION__, agc->d00, w04, w06); + pr_debug("%s %d 0x%x 0x%x\n", __func__, agc->d00, w04, w06); if (w04 > 0x3ff) goto exit_rc; @@ -555,7 +555,7 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s) int lockstat; u32 clk, clk_limit; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); if (s->config.d5C == 0) { EXIT_RC(WR16(s, 0x08200e8, 0x010)); @@ -599,7 +599,7 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s) if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) { s->f_osc = clk; - pr_debug("%s: osc %d %d [Hz]\n", __FUNCTION__, + pr_debug("%s: osc %d %d [Hz]\n", __func__, s->config.f_osc * 1000, clk - s->config.f_osc * 1000); } rc = WR16(s, 0x08200e8, 0); @@ -611,7 +611,7 @@ static int ConfigureMPEGOutput(struct drx397xD_state *s, int type) { int rc, si, bp; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); si = s->config.wA0; if (s->config.w98 == 0) { @@ -647,7 +647,7 @@ static int drx_tune(struct drx397xD_state *s, int rc, df_tuner; int a, b, c, d; - pr_debug("%s %d\n", __FUNCTION__, s->config.d60); + pr_debug("%s %d\n", __func__, s->config.d60); if (s->config.d60 != 2) goto set_tuner; @@ -1124,7 +1124,7 @@ static int drx397x_init(struct dvb_frontend *fe) struct drx397xD_state *s = fe->demodulator_priv; int rc; - pr_debug("%s\n", __FUNCTION__); + pr_debug("%s\n", __func__); s->config.rfagc.d00 = 2; /* 0x7c */ s->config.rfagc.w04 = 0; diff --git a/linux/drivers/media/dvb/frontends/drx397xD.h b/linux/drivers/media/dvb/frontends/drx397xD.h index ddc7a0797..2ad1ea0cc 100644 --- a/linux/drivers/media/dvb/frontends/drx397xD.h +++ b/linux/drivers/media/dvb/frontends/drx397xD.h @@ -122,7 +122,7 @@ extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif /* CONFIG_DVB_DRX397XD */ -- cgit v1.2.3 From 6adacf5c9a13c4404bd17bf0e054658b59d8f130 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 22 Jul 2008 17:20:12 +0000 Subject: make ivtv_claim_stream() static From: Adrian Bunk ivtv_claim_stream() can now become static. Signed-off-by: Adrian Bunk Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/ivtv/ivtv-fileops.c | 2 +- linux/drivers/media/video/ivtv/ivtv-fileops.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c index 7ec5c99f9..304261efc 100644 --- a/linux/drivers/media/video/ivtv/ivtv-fileops.c +++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c @@ -39,7 +39,7 @@ associated VBI streams are also automatically claimed. Possible error returns: -EBUSY if someone else has claimed the stream or 0 on success. */ -int ivtv_claim_stream(struct ivtv_open_id *id, int type) +static int ivtv_claim_stream(struct ivtv_open_id *id, int type) { struct ivtv *itv = id->itv; struct ivtv_stream *s = &itv->streams[type]; diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.h b/linux/drivers/media/video/ivtv/ivtv-fileops.h index 2c8d5186c..df81e7901 100644 --- a/linux/drivers/media/video/ivtv/ivtv-fileops.h +++ b/linux/drivers/media/video/ivtv/ivtv-fileops.h @@ -38,11 +38,6 @@ void ivtv_unmute(struct ivtv *itv); /* Utilities */ -/* Try to claim a stream for the filehandle. Return 0 on success, - -EBUSY if stream already claimed. Once a stream is claimed, it - remains claimed until the associated filehandle is closed. */ -int ivtv_claim_stream(struct ivtv_open_id *id, int type); - /* Release a previously claimed stream. */ void ivtv_release_stream(struct ivtv_stream *s); -- cgit v1.2.3 From e05ee23c4aa187dee867807cb814cc0dcb052858 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 22 Jul 2008 21:25:35 +0200 Subject: videodev: missed two more usages of the removed 'owner' field. From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/drivers/media/video/arv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/arv.c b/linux/drivers/media/video/arv.c index 8d8d339b5..2832070ed 100644 --- a/linux/drivers/media/video/arv.c +++ b/linux/drivers/media/video/arv.c @@ -759,7 +759,6 @@ static const struct file_operations ar_fops = { }; static struct video_device ar_template = { - .owner = THIS_MODULE, .name = "Colour AR VGA", .type = VID_TYPE_CAPTURE, .fops = &ar_fops, -- cgit v1.2.3 From 3704c8e93fbb67c577b68ade395b963a83fa194d Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 23 Jul 2008 08:24:06 +0200 Subject: gspca: Get the card name of QUERYCAP from the usb product name. From: Jean-Francois Moine This is a preliminary for using the driver_info of the struct usb_device_id to handle the specific per webcam information. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 729e0b4ed..99faae3df 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -841,7 +841,16 @@ static int vidioc_querycap(struct file *file, void *priv, memset(cap, 0, sizeof *cap); strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); - strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); +/* strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); */ + if (gspca_dev->dev->product != NULL) { + strncpy(cap->card, gspca_dev->dev->product, + sizeof cap->card); + } else { + snprintf(cap->card, sizeof cap->card, + "USB Camera (%04x:%04x)", + le16_to_cpu(gspca_dev->dev->descriptor.idVendor), + le16_to_cpu(gspca_dev->dev->descriptor.idProduct)); + } strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name, sizeof cap->bus_info); cap->version = DRIVER_VERSION_NUMBER; -- cgit v1.2.3 From b85c5b4a6559eafcf3ad4253b97ae6cb1428ab97 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 23 Jul 2008 08:39:42 +0200 Subject: gspca: Do not use the driver_info field of usb_device_id. From: Jean-Francois Moine The field driver_info will be used to handle the specific per webcam information. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/conex.c | 1 - linux/drivers/media/video/gspca/etoms.c | 1 - linux/drivers/media/video/gspca/mars.c | 1 - linux/drivers/media/video/gspca/ov519.c | 1 - linux/drivers/media/video/gspca/pac7311.c | 1 - linux/drivers/media/video/gspca/sonixj.c | 1 - linux/drivers/media/video/gspca/spca500.c | 1 - linux/drivers/media/video/gspca/spca501.c | 1 - linux/drivers/media/video/gspca/spca505.c | 1 - linux/drivers/media/video/gspca/spca506.c | 1 - linux/drivers/media/video/gspca/spca508.c | 1 - linux/drivers/media/video/gspca/stk014.c | 1 - linux/drivers/media/video/gspca/sunplus.c | 1 - linux/drivers/media/video/gspca/t613.c | 1 - linux/drivers/media/video/gspca/tv8532.c | 1 - linux/drivers/media/video/gspca/vc032x.c | 1 - linux/drivers/media/video/gspca/zc3xx.c | 1 - 17 files changed, 17 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/conex.c b/linux/drivers/media/video/gspca/conex.c index 18c1dec2f..f5ef7599d 100644 --- a/linux/drivers/media/video/gspca/conex.c +++ b/linux/drivers/media/video/gspca/conex.c @@ -815,7 +815,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index 3d420ea65..3f64b04a8 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -617,7 +617,6 @@ static int sd_config(struct gspca_dev *gspca_dev, /* break; */ } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 1; if (sd->sensor == SENSOR_PAS106) { cam->cam_mode = sif_mode; diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index a4706162f..2d47876bf 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -137,7 +137,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/linux/drivers/media/video/gspca/ov519.c b/linux/drivers/media/video/gspca/ov519.c index 1fb3a3eee..c93bd927a 100644 --- a/linux/drivers/media/video/gspca/ov519.c +++ b/linux/drivers/media/video/gspca/ov519.c @@ -1372,7 +1372,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; } - cam->dev_name = (char *) id->driver_info; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index c2d4984cf..ce8403dcf 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -263,7 +263,6 @@ static int sd_config(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x3e, 0x20); cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x05; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 5d16f16f0..e38175f31 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -987,7 +987,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index 81c5e091d..64461896d 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -745,7 +745,6 @@ static int sd_config(struct gspca_dev *gspca_dev, break; } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; if (sd->subtype != LogitechClickSmart310) { cam->cam_mode = vga_mode; diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c index 10e90646d..cd496140c 100644 --- a/linux/drivers/media/video/gspca/spca501.c +++ b/linux/drivers/media/video/gspca/spca501.c @@ -1984,7 +1984,6 @@ static int sd_config(struct gspca_dev *gspca_dev, break; } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index fc392b6d1..7dd5432a7 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -731,7 +731,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; if (sd->subtype != IntelPCCameraPro) diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index 40e8541b2..36dc13c11 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -307,7 +307,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index a8d611eba..b449022aa 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1579,7 +1579,6 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); diff --git a/linux/drivers/media/video/gspca/stk014.c b/linux/drivers/media/video/gspca/stk014.c index 90efde17b..f6390b49f 100644 --- a/linux/drivers/media/video/gspca/stk014.c +++ b/linux/drivers/media/video/gspca/stk014.c @@ -296,7 +296,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x02; gspca_dev->cam.cam_mode = vga_mode; gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); diff --git a/linux/drivers/media/video/gspca/sunplus.c b/linux/drivers/media/video/gspca/sunplus.c index 2ebf859fb..533435a54 100644 --- a/linux/drivers/media/video/gspca/sunplus.c +++ b/linux/drivers/media/video/gspca/sunplus.c @@ -1052,7 +1052,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; switch (sd->bridge) { diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 5188ec486..9a0f55e13 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -435,7 +435,6 @@ static int sd_config(struct gspca_dev *gspca_dev, #endif cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode_t16; diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c index 7de866036..c4f039c33 100644 --- a/linux/drivers/media/video/gspca/tv8532.c +++ b/linux/drivers/media/video/gspca/tv8532.c @@ -246,7 +246,6 @@ static int sd_config(struct gspca_dev *gspca_dev, tv_8532WriteEEprom(gspca_dev); cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 1; cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index c811379c7..9510e1bb7 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -1618,7 +1618,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x02; if (sd->bridge == BRIDGE_VC0321) { cam->cam_mode = vc0321_mode; diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index f7f8c61b3..3633c30bc 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7158,7 +7158,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; /*fixme:test*/ gspca_dev->nbalt--; -- cgit v1.2.3 From 5d277ea89dae091b14e55f45e0762eafaa58d0f8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 Jul 2008 09:26:31 +0200 Subject: v4l-dvb: remove broken PlanB driver From: Adrian Bunk The PlanB driver has been broken since around May 2004. No one stepped in to maintain it, so it is now being removed. Signed-off-by: Adrian Bunk Acked-by: Hans Verkuil Acked-by: Michel Lanners Acked-by: Benjamin Herrenschmidt Signed-off-by: Hans Verkuil --- linux/drivers/media/video/Kconfig | 11 - linux/drivers/media/video/Makefile | 1 - linux/drivers/media/video/planb.c | 2314 ----------------------------------- linux/drivers/media/video/planb.h | 232 ---- linux/drivers/media/video/saa7196.h | 117 -- 5 files changed, 2675 deletions(-) delete mode 100644 linux/drivers/media/video/planb.c delete mode 100644 linux/drivers/media/video/planb.h delete mode 100644 linux/drivers/media/video/saa7196.h (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 2a747db6d..d4a6e56a7 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -487,17 +487,6 @@ config VIDEO_PMS To compile this driver as a module, choose M here: the module will be called pms. -config VIDEO_PLANB - tristate "PlanB Video-In on PowerMac" - depends on PPC_PMAC && VIDEO_V4L1 && BROKEN - help - PlanB is the V4L driver for the PowerMac 7x00/8x00 series video - input hardware. If you want to experiment with this, say Y. - Otherwise, or if you don't understand a word, say N. See - for more info. - - Saying M will compile this driver as a module (planb). - config VIDEO_BWQCAM tristate "Quickcam BW Video For Linux" depends on PARPORT && VIDEO_V4L1 diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index a0240a105..bf429b023 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -58,7 +58,6 @@ obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o obj-$(CONFIG_VIDEO_PMS) += pms.o -obj-$(CONFIG_VIDEO_PLANB) += planb.o obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o obj-$(CONFIG_VIDEO_STRADIS) += stradis.o obj-$(CONFIG_VIDEO_CPIA) += cpia.o diff --git a/linux/drivers/media/video/planb.c b/linux/drivers/media/video/planb.c deleted file mode 100644 index 358dc2996..000000000 --- a/linux/drivers/media/video/planb.c +++ /dev/null @@ -1,2314 +0,0 @@ -/* - planb - PlanB frame grabber driver - - PlanB is used in the 7x00/8x00 series of PowerMacintosh - Computers as video input DMA controller. - - Copyright (C) 1998 Michel Lanners (mlan@cpu.lu) - - Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de) - - Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* $Id: planb.c,v 1.18 1999/05/02 17:36:34 mlan Exp $ */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "compat.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "planb.h" -#include "saa7196.h" - -/* Would you mind for some ugly debugging? */ -#if 0 /* keep */; -#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */ -#else -#define DEBUG(x...) /* Don't debug driver */ -#endif - -#if 0 /* keep */; -#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */ -#else -#define IDEBUG(x...) /* Don't debug interrupt part */ -#endif - -/* Ever seen a Mac with more than 1 of these? */ -#define PLANB_MAX 1 - -static int planb_num; -static struct planb planbs[PLANB_MAX]; -static volatile struct planb_registers *planb_regs; - -static int def_norm = PLANB_DEF_NORM; /* default norm */ -static int video_nr = -1; - -module_param(def_norm, int, 0); -MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)"); -module_param(video_nr, int, 0); -MODULE_LICENSE("GPL"); - - -/* ------------------ PlanB Exported Functions ------------------ */ -static long planb_write(struct video_device *, const char *, unsigned long, int); -static long planb_read(struct video_device *, char *, unsigned long, int); -static int planb_open(struct video_device *, int); -static void planb_close(struct video_device *); -static int planb_ioctl(struct video_device *, unsigned int, void *); -static int planb_init_done(struct video_device *); -static int planb_mmap(struct video_device *, const char *, unsigned long); -static void release_planb(void); -int init_planbs(struct video_init *); - -/* ------------------ PlanB Internal Functions ------------------ */ -static int planb_prepare_open(struct planb *); -static void planb_prepare_close(struct planb *); -static void saa_write_reg(unsigned char, unsigned char); -static unsigned char saa_status(int, struct planb *); -static void saa_set(unsigned char, unsigned char, struct planb *); -static void saa_init_regs(struct planb *); -static int grabbuf_alloc(struct planb *); -static int vgrab(struct planb *, struct video_mmap *); -static void add_clip(struct planb *, struct video_clip *); -static void fill_cmd_buff(struct planb *); -static void cmd_buff(struct planb *); -static volatile struct dbdma_cmd *setup_grab_cmd(int, struct planb *); -static void overlay_start(struct planb *); -static void overlay_stop(struct planb *); -static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *, unsigned short, - unsigned int); -static inline void tab_cmd_store(volatile struct dbdma_cmd *, unsigned int, - unsigned int); -static inline void tab_cmd_gen(volatile struct dbdma_cmd *, unsigned short, - unsigned short, unsigned int, unsigned int); -static int init_planb(struct planb *); -static int find_planb(void); -static void planb_pre_capture(int, int, struct planb *); -static volatile struct dbdma_cmd *cmd_geo_setup(volatile struct dbdma_cmd *, - int, int, int, int, int, struct planb *); -static inline void planb_dbdma_stop(volatile struct dbdma_regs *); -static unsigned int saa_geo_setup(int, int, int, int, struct planb *); -static inline int overlay_is_active(struct planb *); - -/*******************************/ -/* Memory management functions */ -/*******************************/ - -static int grabbuf_alloc(struct planb *pb) -{ - int i, npage; - - npage = MAX_GBUFFERS * ((PLANB_MAX_FBUF / PAGE_SIZE + 1) -#ifndef PLANB_GSCANLINE - + MAX_LNUM -#endif /* PLANB_GSCANLINE */ - ); - if ((pb->rawbuf = kmalloc(npage - * sizeof(unsigned long), GFP_KERNEL)) == 0) - return -ENOMEM; - for (i = 0; i < npage; i++) { - pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL - |GFP_DMA, 0); - if (!pb->rawbuf[i]) - break; - SetPageReserved(virt_to_page(pb->rawbuf[i])); - } - if (i-- < npage) { - printk(KERN_DEBUG "PlanB: init_grab: grab buffer not allocated\n"); - for (; i > 0; i--) { - ClearPageReserved(virt_to_page(pb->rawbuf[i])); - free_pages((unsigned long)pb->rawbuf[i], 0); - } - kfree(pb->rawbuf); - return -ENOBUFS; - } - pb->rawbuf_size = npage; - return 0; -} - -/*****************************/ -/* Hardware access functions */ -/*****************************/ - -static void saa_write_reg(unsigned char addr, unsigned char val) -{ - planb_regs->saa_addr = addr; eieio(); - planb_regs->saa_regval = val; eieio(); - return; -} - -/* return status byte 0 or 1: */ -static unsigned char saa_status(int byte, struct planb *pb) -{ - saa_regs[pb->win.norm][SAA7196_STDC] = - (saa_regs[pb->win.norm][SAA7196_STDC] & ~2) | ((byte & 1) << 1); - saa_write_reg (SAA7196_STDC, saa_regs[pb->win.norm][SAA7196_STDC]); - - /* Let's wait 30msec for this one */ - msleep_interruptible(30); - - return (unsigned char)in_8 (&planb_regs->saa_status); -} - -static void saa_set(unsigned char addr, unsigned char val, struct planb *pb) -{ - if(saa_regs[pb->win.norm][addr] != val) { - saa_regs[pb->win.norm][addr] = val; - saa_write_reg (addr, val); - } - return; -} - -static void saa_init_regs(struct planb *pb) -{ - int i; - - for (i = 0; i < SAA7196_NUMREGS; i++) - saa_write_reg (i, saa_regs[pb->win.norm][i]); -} - -static unsigned int saa_geo_setup(int width, int height, int interlace, int bpp, - struct planb *pb) -{ - int ht, norm = pb->win.norm; - - switch(bpp) { - case 2: - /* RGB555+a 1x16-bit + 16-bit transparent */ - saa_regs[norm][SAA7196_FMTS] &= ~0x3; - break; - case 1: - case 4: - /* RGB888 1x24-bit + 8-bit transparent */ - saa_regs[norm][SAA7196_FMTS] &= ~0x1; - saa_regs[norm][SAA7196_FMTS] |= 0x2; - break; - default: - return -EINVAL; - } - ht = (interlace ? height / 2 : height); - saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff); - saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3) - | (width >> 8 & 0x3); - saa_regs[norm][SAA7196_OUTLINE] = (unsigned char) (ht & 0xff); - saa_regs[norm][SAA7196_VYP] = (saa_regs[norm][SAA7196_VYP] & ~0x3) - | (ht >> 8 & 0x3); - /* feed both fields if interlaced, or else feed only even fields */ - saa_regs[norm][SAA7196_FMTS] = (interlace) ? - (saa_regs[norm][SAA7196_FMTS] & ~0x60) - : (saa_regs[norm][SAA7196_FMTS] | 0x60); - /* transparent mode; extended format enabled */ - saa_regs[norm][SAA7196_DPATH] |= 0x3; - - return 0; -} - -/***************************/ -/* DBDMA support functions */ -/***************************/ - -static inline void planb_dbdma_restart(volatile struct dbdma_regs *ch) -{ - out_le32(&ch->control, PLANB_CLR(RUN)); - out_le32(&ch->control, PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE)); -} - -static inline void planb_dbdma_stop(volatile struct dbdma_regs *ch) -{ - int i = 0; - - out_le32(&ch->control, PLANB_CLR(RUN) | PLANB_SET(FLUSH)); - while((in_le32(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) { - IDEBUG("PlanB: waiting for DMA to stop\n"); - i++; - } -} - -static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *ch, - unsigned short command, unsigned int cmd_dep) -{ - st_le16(&ch->command, command); - st_le32(&ch->cmd_dep, cmd_dep); -} - -static inline void tab_cmd_store(volatile struct dbdma_cmd *ch, - unsigned int phy_addr, unsigned int cmd_dep) -{ - st_le16(&ch->command, STORE_WORD | KEY_SYSTEM); - st_le16(&ch->req_count, 4); - st_le32(&ch->phy_addr, phy_addr); - st_le32(&ch->cmd_dep, cmd_dep); -} - -static inline void tab_cmd_gen(volatile struct dbdma_cmd *ch, - unsigned short command, unsigned short req_count, - unsigned int phy_addr, unsigned int cmd_dep) -{ - st_le16(&ch->command, command); - st_le16(&ch->req_count, req_count); - st_le32(&ch->phy_addr, phy_addr); - st_le32(&ch->cmd_dep, cmd_dep); -} - -static volatile struct dbdma_cmd *cmd_geo_setup( - volatile struct dbdma_cmd *c1, int width, int height, int interlace, - int bpp, int clip, struct planb *pb) -{ - int norm = pb->win.norm; - - if((saa_geo_setup(width, height, interlace, bpp, pb)) != 0) - return (volatile struct dbdma_cmd *)NULL; - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_FMTS); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_FMTS]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_DPATH); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_DPATH]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->even), - bpp | ((clip)? PLANB_CLIPMASK: 0)); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->odd), - bpp | ((clip)? PLANB_CLIPMASK: 0)); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_OUTPIX); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_OUTPIX]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_HFILT); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_HFILT]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_OUTLINE); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_OUTLINE]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_VYP); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_VYP]); - return c1; -} - -/******************************/ -/* misc. supporting functions */ -/******************************/ - -static inline void planb_lock(struct planb *pb) -{ - mutex_lock(&pb->lock); -} - -static inline void planb_unlock(struct planb *pb) -{ - mutex_unlock(&pb->lock); -} - -/***************/ -/* Driver Core */ -/***************/ - -static int planb_prepare_open(struct planb *pb) -{ - int i, size; - - /* allocate memory for two plus alpha command buffers (size: max lines, - plus 40 commands handling, plus 1 alignment), plus dummy command buf, - plus clipmask buffer, plus frame grabbing status */ - size = (pb->tab_size*(2+MAX_GBUFFERS*TAB_FACTOR)+1+MAX_GBUFFERS - * PLANB_DUMMY)*sizeof(struct dbdma_cmd) - +(PLANB_MAXLINES*((PLANB_MAXPIXELS+7)& ~7))/8 - +MAX_GBUFFERS*sizeof(unsigned int); - if ((pb->priv_space = kzalloc (size, GFP_KERNEL)) == 0) - return -ENOMEM; - pb->overlay_last1 = pb->ch1_cmd = (volatile struct dbdma_cmd *) - DBDMA_ALIGN (pb->priv_space); - pb->overlay_last2 = pb->ch2_cmd = pb->ch1_cmd + pb->tab_size; - pb->ch1_cmd_phys = virt_to_bus(pb->ch1_cmd); - pb->cap_cmd[0] = pb->ch2_cmd + pb->tab_size; - pb->pre_cmd[0] = pb->cap_cmd[0] + pb->tab_size * TAB_FACTOR; - for (i = 1; i < MAX_GBUFFERS; i++) { - pb->cap_cmd[i] = pb->pre_cmd[i-1] + PLANB_DUMMY; - pb->pre_cmd[i] = pb->cap_cmd[i] + pb->tab_size * TAB_FACTOR; - } - pb->frame_stat=(volatile unsigned int *)(pb->pre_cmd[MAX_GBUFFERS-1] - + PLANB_DUMMY); - pb->mask = (unsigned char *)(pb->frame_stat+MAX_GBUFFERS); - - pb->rawbuf = NULL; - pb->rawbuf_size = 0; - pb->grabbing = 0; - for (i = 0; i < MAX_GBUFFERS; i++) { - pb->frame_stat[i] = GBUFFER_UNUSED; - pb->gwidth[i] = 0; - pb->gheight[i] = 0; - pb->gfmt[i] = 0; - pb->gnorm_switch[i] = 0; -#ifndef PLANB_GSCANLINE - pb->lsize[i] = 0; - pb->lnum[i] = 0; -#endif /* PLANB_GSCANLINE */ - } - pb->gcount = 0; - pb->suspend = 0; - pb->last_fr = -999; - pb->prev_last_fr = -999; - - /* Reset DMA controllers */ - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - - return 0; -} - -static void planb_prepare_close(struct planb *pb) -{ - int i; - - /* make sure the dma's are idle */ - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - /* free kernel memory of command buffers */ - if(pb->priv_space != 0) { - kfree (pb->priv_space); - pb->priv_space = 0; - pb->cmd_buff_inited = 0; - } - if(pb->rawbuf) { - for (i = 0; i < pb->rawbuf_size; i++) { - ClearPageReserved(virt_to_page(pb->rawbuf[i])); - free_pages((unsigned long)pb->rawbuf[i], 0); - } - kfree(pb->rawbuf); - } - pb->rawbuf = NULL; -} - -/*****************************/ -/* overlay support functions */ -/*****************************/ - -static inline int overlay_is_active(struct planb *pb) -{ - unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd); - unsigned int caddr = (unsigned)in_le32(&pb->planb_base->ch1.cmdptr); - - return (in_le32(&pb->overlay_last1->cmd_dep) == pb->ch1_cmd_phys) - && (caddr < (pb->ch1_cmd_phys + size)) - && (caddr >= (unsigned)pb->ch1_cmd_phys); -} - -static void overlay_start(struct planb *pb) -{ - - DEBUG("PlanB: overlay_start()\n"); - - if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) { - - DEBUG("PlanB: presumably, grabbing is in progress...\n"); - - planb_dbdma_stop(&pb->planb_base->ch2); - out_le32 (&pb->planb_base->ch2.cmdptr, - virt_to_bus(pb->ch2_cmd)); - planb_dbdma_restart(&pb->planb_base->ch2); - st_le16 (&pb->ch1_cmd->command, DBDMA_NOP); - tab_cmd_dbdma(pb->last_cmd[pb->last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->ch1_cmd)); - eieio(); - pb->prev_last_fr = pb->last_fr; - pb->last_fr = -2; - if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) { - IDEBUG("PlanB: became inactive " - "in the mean time... reactivating\n"); - planb_dbdma_stop(&pb->planb_base->ch1); - out_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->ch1_cmd)); - planb_dbdma_restart(&pb->planb_base->ch1); - } - } else { - - DEBUG("PlanB: currently idle, so can do whatever\n"); - - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - st_le32 (&pb->planb_base->ch2.cmdptr, - virt_to_bus(pb->ch2_cmd)); - st_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->ch1_cmd)); - out_le16 (&pb->ch1_cmd->command, DBDMA_NOP); - planb_dbdma_restart(&pb->planb_base->ch2); - planb_dbdma_restart(&pb->planb_base->ch1); - pb->last_fr = -1; - } - return; -} - -static void overlay_stop(struct planb *pb) -{ - DEBUG("PlanB: overlay_stop()\n"); - - if(pb->last_fr == -1) { - - DEBUG("PlanB: no grabbing, it seems...\n"); - - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - pb->last_fr = -999; - } else if(pb->last_fr == -2) { - unsigned int cmd_dep; - tab_cmd_dbdma(pb->cap_cmd[pb->prev_last_fr], DBDMA_STOP, 0); - eieio(); - cmd_dep = (unsigned int)in_le32(&pb->overlay_last1->cmd_dep); - if(overlay_is_active(pb)) { - - DEBUG("PlanB: overlay is currently active\n"); - - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - if(cmd_dep != pb->ch1_cmd_phys) { - out_le32(&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->overlay_last1)); - planb_dbdma_restart(&pb->planb_base->ch1); - } - } - pb->last_fr = pb->prev_last_fr; - pb->prev_last_fr = -999; - } - return; -} - -static void suspend_overlay(struct planb *pb) -{ - int fr = -1; - struct dbdma_cmd last; - - DEBUG("PlanB: suspend_overlay: %d\n", pb->suspend); - - if(pb->suspend++) - return; - if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) { - if(pb->last_fr == -2) { - fr = pb->prev_last_fr; - memcpy(&last, (void*)pb->last_cmd[fr], sizeof(last)); - tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0); - } - if(overlay_is_active(pb)) { - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - pb->suspended.overlay = 1; - pb->suspended.frame = fr; - memcpy(&pb->suspended.cmd, &last, sizeof(last)); - return; - } - } - pb->suspended.overlay = 0; - pb->suspended.frame = fr; - memcpy(&pb->suspended.cmd, &last, sizeof(last)); - return; -} - -static void resume_overlay(struct planb *pb) -{ - - DEBUG("PlanB: resume_overlay: %d\n", pb->suspend); - - if(pb->suspend > 1) - return; - if(pb->suspended.frame != -1) { - memcpy((void*)pb->last_cmd[pb->suspended.frame], - &pb->suspended.cmd, sizeof(pb->suspended.cmd)); - } - if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) { - goto finish; - } - if(pb->suspended.overlay) { - - DEBUG("PlanB: overlay being resumed\n"); - - st_le16 (&pb->ch1_cmd->command, DBDMA_NOP); - st_le16 (&pb->ch2_cmd->command, DBDMA_NOP); - /* Set command buffer addresses */ - st_le32(&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->overlay_last1)); - out_le32(&pb->planb_base->ch2.cmdptr, - virt_to_bus(pb->overlay_last2)); - /* Start the DMA controller */ - out_le32 (&pb->planb_base->ch2.control, - PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE)); - out_le32 (&pb->planb_base->ch1.control, - PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE)); - } else if(pb->suspended.frame != -1) { - out_le32(&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->last_cmd[pb->suspended.frame])); - out_le32 (&pb->planb_base->ch1.control, - PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE)); - } - -finish: - pb->suspend--; - wake_up_interruptible(&pb->suspendq); -} - -static void add_clip(struct planb *pb, struct video_clip *clip) -{ - volatile unsigned char *base; - int xc = clip->x, yc = clip->y; - int wc = clip->width, hc = clip->height; - int ww = pb->win.width, hw = pb->win.height; - int x, y, xtmp1, xtmp2; - - DEBUG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc); - - if(xc < 0) { - wc += xc; - xc = 0; - } - if(yc < 0) { - hc += yc; - yc = 0; - } - if(xc + wc > ww) - wc = ww - xc; - if(wc <= 0) /* Nothing to do */ - return; - if(yc + hc > hw) - hc = hw - yc; - - for (y = yc; y < yc+hc; y++) { - xtmp1=xc>>3; - xtmp2=(xc+wc)>>3; - base = pb->mask + y*96; - if(xc != 0 || wc >= 8) - *(base + xtmp1) &= (unsigned char)(0x00ff & - (0xff00 >> (xc&7))); - for (x = xtmp1 + 1; x < xtmp2; x++) { - *(base + x) = 0; - } - if(xc < (ww & ~0x7)) - *(base + xtmp2) &= (unsigned char)(0x00ff >> - ((xc+wc) & 7)); - } - - return; -} - -static void fill_cmd_buff(struct planb *pb) -{ - int restore = 0; - volatile struct dbdma_cmd last; - - DEBUG("PlanB: fill_cmd_buff()\n"); - - if(pb->overlay_last1 != pb->ch1_cmd) { - restore = 1; - last = *(pb->overlay_last1); - } - memset ((void *) pb->ch1_cmd, 0, 2 * pb->tab_size - * sizeof(struct dbdma_cmd)); - cmd_buff (pb); - if(restore) - *(pb->overlay_last1) = last; - if(pb->suspended.overlay) { - unsigned long jump_addr = in_le32(&pb->overlay_last1->cmd_dep); - if(jump_addr != pb->ch1_cmd_phys) { - int i; - - DEBUG("PlanB: adjusting ch1's jump address\n"); - - for(i = 0; i < MAX_GBUFFERS; i++) { - if(pb->need_pre_capture[i]) { - if(jump_addr == virt_to_bus(pb->pre_cmd[i])) - goto found; - } else { - if(jump_addr == virt_to_bus(pb->cap_cmd[i])) - goto found; - } - } - - DEBUG("PlanB: not found...\n"); - - goto out; -found: - if(pb->need_pre_capture[i]) - out_le32(&pb->pre_cmd[i]->phy_addr, - virt_to_bus(pb->overlay_last1)); - else - out_le32(&pb->cap_cmd[i]->phy_addr, - virt_to_bus(pb->overlay_last1)); - } - } -out: - pb->cmd_buff_inited = 1; - - return; -} - -static void cmd_buff(struct planb *pb) -{ - int i, bpp, count, nlines, stepsize, interlace; - unsigned long base, jump, addr_com, addr_dep; - volatile struct dbdma_cmd *c1 = pb->ch1_cmd; - volatile struct dbdma_cmd *c2 = pb->ch2_cmd; - - interlace = pb->win.interlace; - bpp = pb->win.bpp; - count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ? - (pb->win.swidth - pb->win.x) : pb->win.width)); - nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ? - (pb->win.sheight - pb->win.y) : pb->win.height); - - /* Do video in: */ - - /* Preamble commands: */ - addr_com = virt_to_bus(c1); - addr_dep = virt_to_bus(&c1->cmd_dep); - tab_cmd_dbdma(c1++, DBDMA_NOP, 0); - jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */ - if((c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace, - bpp, 1, pb)) == NULL) { - printk(KERN_WARNING "PlanB: encountered serious problems\n"); - tab_cmd_dbdma(pb->ch1_cmd + 1, DBDMA_STOP, 0); - tab_cmd_dbdma(pb->ch2_cmd + 1, DBDMA_STOP, 0); - return; - } - tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16); - tab_cmd_store(c1++, addr_dep, jump); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel), - PLANB_SET(FIELD_SYNC)); - /* (1) wait for field sync to be set */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - /* wait for field sync to be cleared */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - /* if not odd field, wait until field sync is set again */ - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++; - /* assert ch_sync to ch2 */ - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control), - PLANB_SET(CH_SYNC)); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - - base = (pb->frame_buffer_phys + pb->offset + pb->win.y * (pb->win.bpl - + pb->win.pad) + pb->win.x * bpp); - - if (interlace) { - stepsize = 2; - jump = virt_to_bus(c1 + (nlines + 1) / 2); - } else { - stepsize = 1; - jump = virt_to_bus(c1 + nlines); - } - - /* even field data: */ - for (i=0; i < nlines; i += stepsize, c1++) - tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, - count, base + i * (pb->win.bpl + pb->win.pad), jump); - - /* For non-interlaced, we use even fields only */ - if (!interlace) - goto cmd_tab_data_end; - - /* Resync to odd field */ - /* (2) wait for field sync to be set */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - /* wait for field sync to be cleared */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - /* if not odd field, wait until field sync is set again */ - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++; - /* assert ch_sync to ch2 */ - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control), - PLANB_SET(CH_SYNC)); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - - /* odd field data: */ - jump = virt_to_bus(c1 + nlines / 2); - for (i=1; i < nlines; i += stepsize, c1++) - tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count, - base + i * (pb->win.bpl + pb->win.pad), jump); - - /* And jump back to the start */ -cmd_tab_data_end: - pb->overlay_last1 = c1; /* keep a pointer to the last command */ - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch1_cmd)); - - /* Clipmask command buffer */ - - /* Preamble commands: */ - tab_cmd_dbdma(c2++, DBDMA_NOP, 0); - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel), - PLANB_SET(CH_SYNC)); - /* wait until ch1 asserts ch_sync */ - tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0); - /* clear ch_sync asserted by ch1 */ - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.control), - PLANB_CLR(CH_SYNC)); - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel), - PLANB_SET(FIELD_SYNC)); - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel), - PLANB_SET(ODD_FIELD)); - - /* jump to end of even field if appropriate */ - /* this points to (interlace)? pos. C: pos. B */ - jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2): - virt_to_bus(c2 + nlines + 2); - /* if odd field, skip over to odd field clipmasking */ - tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump); - - /* even field mask: */ - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel), - PLANB_SET(DMA_ABORT)); - /* this points to pos. B */ - jump = (interlace) ? virt_to_bus(c2 + nlines + 1): - virt_to_bus(c2 + nlines); - base = virt_to_bus(pb->mask); - for (i=0; i < nlines; i += stepsize, c2++) - tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96, - base + i * 96, jump); - - /* For non-interlaced, we use only even fields */ - if(!interlace) - goto cmd_tab_mask_end; - - /* odd field mask: */ -/* C */ tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel), - PLANB_SET(DMA_ABORT)); - /* this points to pos. B */ - jump = virt_to_bus(c2 + nlines / 2); - base = virt_to_bus(pb->mask); - for (i=1; i < nlines; i += 2, c2++) /* abort if set */ - tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96, - base + i * 96, jump); - - /* Inform channel 1 and jump back to start */ -cmd_tab_mask_end: - /* ok, I just realized this is kind of flawed. */ - /* this part is reached only after odd field clipmasking. */ - /* wanna clean up? */ - /* wait for field sync to be set */ - /* corresponds to fsync (1) of ch1 */ -/* B */ tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0); - /* restart ch1, meant to clear any dead bit or something */ - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control), - PLANB_CLR(RUN)); - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control), - PLANB_SET(RUN)); - pb->overlay_last2 = c2; /* keep a pointer to the last command */ - /* start over even field clipmasking */ - tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch2_cmd)); - - eieio(); - return; -} - -/*********************************/ -/* grabdisplay support functions */ -/*********************************/ - -static int palette2fmt[] = { - 0, - PLANB_GRAY, - 0, - 0, - 0, - PLANB_COLOUR32, - PLANB_COLOUR15, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -}; - -#define PLANB_PALETTE_MAX 15 - -static int vgrab(struct planb *pb, struct video_mmap *mp) -{ - unsigned int fr = mp->frame; - unsigned int format; - - if(pb->rawbuf==NULL) { - int err; - if((err=grabbuf_alloc(pb))) - return err; - } - - IDEBUG("PlanB: grab %d: %dx%d(%u)\n", pb->grabbing, - mp->width, mp->height, fr); - - if(pb->grabbing >= MAX_GBUFFERS) - return -ENOBUFS; - if(fr > (MAX_GBUFFERS - 1) || fr < 0) - return -EINVAL; - if(mp->height <= 0 || mp->width <= 0) - return -EINVAL; - if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX) - return -EINVAL; - if((format = palette2fmt[mp->format]) == 0) - return -EINVAL; - if (mp->height * mp->width * format > PLANB_MAX_FBUF) /* format = bpp */ - return -EINVAL; - - planb_lock(pb); - if(mp->width != pb->gwidth[fr] || mp->height != pb->gheight[fr] || - format != pb->gfmt[fr] || (pb->gnorm_switch[fr])) { - int i; -#ifndef PLANB_GSCANLINE - unsigned int osize = pb->gwidth[fr] * pb->gheight[fr] - * pb->gfmt[fr]; - unsigned int nsize = mp->width * mp->height * format; -#endif - - IDEBUG("PlanB: gwidth = %d, gheight = %d, mp->format = %u\n", - mp->width, mp->height, mp->format); - -#ifndef PLANB_GSCANLINE - if(pb->gnorm_switch[fr]) - nsize = 0; - if (nsize < osize) { - for(i = pb->gbuf_idx[fr]; osize > 0; i++) { - memset((void *)pb->rawbuf[i], 0, PAGE_SIZE); - osize -= PAGE_SIZE; - } - } - for(i = pb->l_fr_addr_idx[fr]; i < pb->l_fr_addr_idx[fr] - + pb->lnum[fr]; i++) - memset((void *)pb->rawbuf[i], 0, PAGE_SIZE); -#else -/* XXX TODO */ -/* - if(pb->gnorm_switch[fr]) - memset((void *)pb->gbuffer[fr], 0, - pb->gbytes_per_line * pb->gheight[fr]); - else { - if(mp-> - for(i = 0; i < pb->gheight[fr]; i++) { - memset((void *)(pb->gbuffer[fr] - + pb->gbytes_per_line * i - } - } -*/ -#endif - pb->gwidth[fr] = mp->width; - pb->gheight[fr] = mp->height; - pb->gfmt[fr] = format; - pb->last_cmd[fr] = setup_grab_cmd(fr, pb); - planb_pre_capture(fr, pb->gfmt[fr], pb); /* gfmt = bpp */ - pb->need_pre_capture[fr] = 1; - pb->gnorm_switch[fr] = 0; - } else - pb->need_pre_capture[fr] = 0; - pb->frame_stat[fr] = GBUFFER_GRABBING; - if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) { - - IDEBUG("PlanB: ch1 inactive, initiating grabbing\n"); - - planb_dbdma_stop(&pb->planb_base->ch1); - if(pb->need_pre_capture[fr]) { - - IDEBUG("PlanB: padding pre-capture sequence\n"); - - out_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->pre_cmd[fr])); - } else { - tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0); - tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0); - /* let's be on the safe side. here is not timing critical. */ - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), DBDMA_NOP, 0); - out_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->cap_cmd[fr])); - } - planb_dbdma_restart(&pb->planb_base->ch1); - pb->last_fr = fr; - } else { - int i; - - IDEBUG("PlanB: ch1 active, grabbing being queued\n"); - - if((pb->last_fr == -1) || ((pb->last_fr == -2) && - overlay_is_active(pb))) { - - IDEBUG("PlanB: overlay is active, grabbing defered\n"); - - tab_cmd_dbdma(pb->last_cmd[fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->ch1_cmd)); - if(pb->need_pre_capture[fr]) { - - IDEBUG("PlanB: padding pre-capture sequence\n"); - - tab_cmd_store(pb->pre_cmd[fr], - virt_to_bus(&pb->overlay_last1->cmd_dep), - virt_to_bus(pb->ch1_cmd)); - eieio(); - out_le32 (&pb->overlay_last1->cmd_dep, - virt_to_bus(pb->pre_cmd[fr])); - } else { - tab_cmd_store(pb->cap_cmd[fr], - virt_to_bus(&pb->overlay_last1->cmd_dep), - virt_to_bus(pb->ch1_cmd)); - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP, 0); - eieio(); - out_le32 (&pb->overlay_last1->cmd_dep, - virt_to_bus(pb->cap_cmd[fr])); - } - for(i = 0; overlay_is_active(pb) && i < 999; i++) - IDEBUG("PlanB: waiting for overlay done\n"); - tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0); - pb->prev_last_fr = fr; - pb->last_fr = -2; - } else if(pb->last_fr == -2) { - - IDEBUG("PlanB: mixed mode detected, grabbing" - " will be done before activating overlay\n"); - - tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0); - if(pb->need_pre_capture[fr]) { - - IDEBUG("PlanB: padding pre-capture sequence\n"); - - tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->pre_cmd[fr])); - eieio(); - } else { - tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0); - if(pb->gwidth[pb->prev_last_fr] != - pb->gwidth[fr] - || pb->gheight[pb->prev_last_fr] != - pb->gheight[fr] - || pb->gfmt[pb->prev_last_fr] != - pb->gfmt[fr]) - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP, 0); - else - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->cap_cmd[fr] + 16)); - tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->cap_cmd[fr])); - eieio(); - } - tab_cmd_dbdma(pb->last_cmd[fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->ch1_cmd)); - eieio(); - pb->prev_last_fr = fr; - pb->last_fr = -2; - } else { - - IDEBUG("PlanB: active grabbing session detected\n"); - - if(pb->need_pre_capture[fr]) { - - IDEBUG("PlanB: padding pre-capture sequence\n"); - - tab_cmd_dbdma(pb->last_cmd[pb->last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->pre_cmd[fr])); - eieio(); - } else { - tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0); - tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0); - if(pb->gwidth[pb->last_fr] != pb->gwidth[fr] - || pb->gheight[pb->last_fr] != - pb->gheight[fr] - || pb->gfmt[pb->last_fr] != - pb->gfmt[fr]) - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP, 0); - else - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->cap_cmd[fr] + 16)); - tab_cmd_dbdma(pb->last_cmd[pb->last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->cap_cmd[fr])); - eieio(); - } - pb->last_fr = fr; - } - if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) { - - IDEBUG("PlanB: became inactive in the mean time..." - "reactivating\n"); - - planb_dbdma_stop(&pb->planb_base->ch1); - out_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->cap_cmd[fr])); - planb_dbdma_restart(&pb->planb_base->ch1); - } - } - pb->grabbing++; - planb_unlock(pb); - - return 0; -} - -static void planb_pre_capture(int fr, int bpp, struct planb *pb) -{ - volatile struct dbdma_cmd *c1 = pb->pre_cmd[fr]; - int interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0; - - tab_cmd_dbdma(c1++, DBDMA_NOP, 0); - if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace, - bpp, 0, pb)) == NULL) { - printk(KERN_WARNING "PlanB: encountered some problems\n"); - tab_cmd_dbdma(pb->pre_cmd[fr] + 1, DBDMA_STOP, 0); - return; - } - /* Sync to even field */ - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel), - PLANB_SET(FIELD_SYNC)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++; - tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - /* For non-interlaced, we use even fields only */ - if (pb->gheight[fr] <= pb->maxlines/2) - goto cmd_tab_data_end; - /* Sync to odd field */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++; - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); -cmd_tab_data_end: - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->cap_cmd[fr])); - - eieio(); -} - -static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb) -{ - int i, bpp, count, nlines, stepsize, interlace; -#ifdef PLANB_GSCANLINE - int scanline; -#else - int nlpp, leftover1; - unsigned long base; -#endif - unsigned long jump; - int pagei; - volatile struct dbdma_cmd *c1; - volatile struct dbdma_cmd *jump_addr; - - c1 = pb->cap_cmd[fr]; - interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0; - bpp = pb->gfmt[fr]; /* gfmt = bpp */ - count = bpp * pb->gwidth[fr]; - nlines = pb->gheight[fr]; -#ifdef PLANB_GSCANLINE - scanline = pb->gbytes_per_line; -#else - pb->lsize[fr] = count; - pb->lnum[fr] = 0; -#endif - - /* Do video in: */ - - /* Preamble commands: */ - tab_cmd_dbdma(c1++, DBDMA_NOP, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++; - if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace, - bpp, 0, pb)) == NULL) { - printk(KERN_WARNING "PlanB: encountered serious problems\n"); - tab_cmd_dbdma(pb->cap_cmd[fr] + 1, DBDMA_STOP, 0); - return (pb->cap_cmd[fr] + 2); - } - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel), - PLANB_SET(FIELD_SYNC)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++; - tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - - if (interlace) { - stepsize = 2; - jump_addr = c1 + TAB_FACTOR * (nlines + 1) / 2; - } else { - stepsize = 1; - jump_addr = c1 + TAB_FACTOR * nlines; - } - jump = virt_to_bus(jump_addr); - - /* even field data: */ - - pagei = pb->gbuf_idx[fr]; -#ifdef PLANB_GSCANLINE - for (i = 0; i < nlines; i += stepsize) { - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, - virt_to_bus(pb->rawbuf[pagei - + i * scanline / PAGE_SIZE]), jump); - } -#else - i = 0; - leftover1 = 0; - do { - int j; - - base = virt_to_bus(pb->rawbuf[pagei]); - nlpp = (PAGE_SIZE - leftover1) / count / stepsize; - for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++) - tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, - count, base + count * j * stepsize + leftover1, jump); - if(i < nlines) { - int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1; - - if(lov0 == 0) - leftover1 = 0; - else { - if(lov0 >= count) { - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base - + count * nlpp * stepsize + leftover1, jump); - } else { - pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei] - + count * nlpp * stepsize + leftover1; - pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1; - pb->l_to_next_size[fr][pb->lnum[fr]] = count - lov0; - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, - virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr] - + pb->lnum[fr]]), jump); - if(++pb->lnum[fr] > MAX_LNUM) - pb->lnum[fr]--; - } - leftover1 = count * stepsize - lov0; - i += stepsize; - } - } - pagei++; - } while(i < nlines); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump); - c1 = jump_addr; -#endif /* PLANB_GSCANLINE */ - - /* For non-interlaced, we use even fields only */ - if (!interlace) - goto cmd_tab_data_end; - - /* Sync to odd field */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++; - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - - /* odd field data: */ - jump_addr = c1 + TAB_FACTOR * nlines / 2; - jump = virt_to_bus(jump_addr); -#ifdef PLANB_GSCANLINE - for (i = 1; i < nlines; i += stepsize) { - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, - virt_to_bus(pb->rawbuf[pagei - + i * scanline / PAGE_SIZE]), jump); - } -#else - i = 1; - leftover1 = 0; - pagei = pb->gbuf_idx[fr]; - if(nlines <= 1) - goto skip; - do { - int j; - - base = virt_to_bus(pb->rawbuf[pagei]); - nlpp = (PAGE_SIZE - leftover1) / count / stepsize; - if(leftover1 >= count) { - tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count, - base + leftover1 - count, jump); - i += stepsize; - } - for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++) - tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count, - base + count * (j * stepsize + 1) + leftover1, jump); - if(i < nlines) { - int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1; - - if(lov0 == 0) - leftover1 = 0; - else { - if(lov0 > count) { - pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei] - + count * (nlpp * stepsize + 1) + leftover1; - pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1; - pb->l_to_next_size[fr][pb->lnum[fr]] = count * stepsize - - lov0; - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, - virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr] - + pb->lnum[fr]]), jump); - if(++pb->lnum[fr] > MAX_LNUM) - pb->lnum[fr]--; - i += stepsize; - } - leftover1 = count * stepsize - lov0; - } - } - pagei++; - } while(i < nlines); -skip: - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump); - c1 = jump_addr; -#endif /* PLANB_GSCANLINE */ - -cmd_tab_data_end: - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->intr_stat), - (fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ); - /* stop it */ - tab_cmd_dbdma(c1, DBDMA_STOP, 0); - - eieio(); - return c1; -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -static irqreturn_t planb_irq(int irq, void *dev_id, struct pt_regs * regs) -#else -static irqreturn_t planb_irq(int irq, void *dev_id) -#endif -{ - unsigned int stat, astat; - struct planb *pb = (struct planb *)dev_id; - - IDEBUG("PlanB: planb_irq()\n"); - - /* get/clear interrupt status bits */ - eieio(); - stat = in_le32(&pb->planb_base->intr_stat); - astat = stat & pb->intr_mask; - out_le32(&pb->planb_base->intr_stat, PLANB_FRM_IRQ - & ~astat & stat & ~PLANB_GEN_IRQ); - IDEBUG("PlanB: stat = %X, astat = %X\n", stat, astat); - - if(astat & PLANB_FRM_IRQ) { - unsigned int fr = stat >> 9; -#ifndef PLANB_GSCANLINE - int i; -#endif - IDEBUG("PlanB: PLANB_FRM_IRQ\n"); - - pb->gcount++; - - IDEBUG("PlanB: grab %d: fr = %d, gcount = %d\n", - pb->grabbing, fr, pb->gcount); -#ifndef PLANB_GSCANLINE - IDEBUG("PlanB: %d * %d bytes are being copied over\n", - pb->lnum[fr], pb->lsize[fr]); - for(i = 0; i < pb->lnum[fr]; i++) { - int first = pb->lsize[fr] - pb->l_to_next_size[fr][i]; - - memcpy(pb->l_to_addr[fr][i], - pb->rawbuf[pb->l_fr_addr_idx[fr] + i], - first); - memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]], - pb->rawbuf[pb->l_fr_addr_idx[fr] + i] + first, - pb->l_to_next_size[fr][i]); - } -#endif - pb->frame_stat[fr] = GBUFFER_DONE; - pb->grabbing--; - wake_up_interruptible(&pb->capq); - return IRQ_HANDLED; - } - /* incorrect interrupts? */ - pb->intr_mask = PLANB_CLR_IRQ; - out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ); - printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts" - " unconditionally\n"); - return IRQ_HANDLED; -} - -/******************************* - * Device Operations functions * - *******************************/ - -static int planb_open(struct video_device *dev, int mode) -{ - struct planb *pb = (struct planb *)dev; - - if (pb->user == 0) { - int err; - if((err = planb_prepare_open(pb)) != 0) - return err; - } - pb->user++; - - DEBUG("PlanB: device opened\n"); - return 0; -} - -static void planb_close(struct video_device *dev) -{ - struct planb *pb = (struct planb *)dev; - - if(pb->user < 1) /* ??? */ - return; - planb_lock(pb); - if (pb->user == 1) { - if (pb->overlay) { - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - pb->overlay = 0; - } - planb_prepare_close(pb); - } - pb->user--; - planb_unlock(pb); - - DEBUG("PlanB: device closed\n"); -} - -static long planb_read(struct video_device *v, char *buf, unsigned long count, - int nonblock) -{ - DEBUG("planb: read request\n"); - return -EINVAL; -} - -static long planb_write(struct video_device *v, const char *buf, - unsigned long count, int nonblock) -{ - DEBUG("planb: write request\n"); - return -EINVAL; -} - -static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) -{ - struct planb *pb=(struct planb *)dev; - - switch (cmd) - { - case VIDIOCGCAP: - { - struct video_capability b; - - DEBUG("PlanB: IOCTL VIDIOCGCAP\n"); - - strcpy (b.name, pb->video_dev.name); - b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | - VID_TYPE_FRAMERAM | VID_TYPE_SCALES | - VID_TYPE_CAPTURE; - b.channels = 2; /* composite & svhs */ - b.audios = 0; - b.maxwidth = PLANB_MAXPIXELS; - b.maxheight = PLANB_MAXLINES; - b.minwidth = 32; /* wild guess */ - b.minheight = 32; - if (copy_to_user(arg,&b,sizeof(b))) - return -EFAULT; - return 0; - } - case VIDIOCSFBUF: - { - struct video_buffer v; - unsigned short bpp; - unsigned int fmt; - - DEBUG("PlanB: IOCTL VIDIOCSFBUF\n"); - - if (!capable(CAP_SYS_ADMIN) - || !capable(CAP_SYS_RAWIO)) - return -EPERM; - if (copy_from_user(&v, arg,sizeof(v))) - return -EFAULT; - planb_lock(pb); - switch(v.depth) { - case 8: - bpp = 1; - fmt = PLANB_GRAY; - break; - case 15: - case 16: - bpp = 2; - fmt = PLANB_COLOUR15; - break; - case 24: - case 32: - bpp = 4; - fmt = PLANB_COLOUR32; - break; - default: - planb_unlock(pb); - return -EINVAL; - } - if (bpp * v.width > v.bytesperline) { - planb_unlock(pb); - return -EINVAL; - } - pb->win.bpp = bpp; - pb->win.color_fmt = fmt; - pb->frame_buffer_phys = (unsigned long) v.base; - pb->win.sheight = v.height; - pb->win.swidth = v.width; - pb->picture.depth = pb->win.depth = v.depth; - pb->win.bpl = pb->win.bpp * pb->win.swidth; - pb->win.pad = v.bytesperline - pb->win.bpl; - - DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d," - " bpl %d (+ %d)\n", v.base, v.width,v.height, - pb->win.bpp, pb->win.bpl, pb->win.pad); - - pb->cmd_buff_inited = 0; - if(pb->overlay) { - suspend_overlay(pb); - fill_cmd_buff(pb); - resume_overlay(pb); - } - planb_unlock(pb); - return 0; - } - case VIDIOCGFBUF: - { - struct video_buffer v; - - DEBUG("PlanB: IOCTL VIDIOCGFBUF\n"); - - v.base = (void *)pb->frame_buffer_phys; - v.height = pb->win.sheight; - v.width = pb->win.swidth; - v.depth = pb->win.depth; - v.bytesperline = pb->win.bpl + pb->win.pad; - if (copy_to_user(arg, &v, sizeof(v))) - return -EFAULT; - return 0; - } - case VIDIOCCAPTURE: - { - int i; - - if(copy_from_user(&i, arg, sizeof(i))) - return -EFAULT; - if(i==0) { - DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n"); - - if (!(pb->overlay)) - return 0; - planb_lock(pb); - pb->overlay = 0; - overlay_stop(pb); - planb_unlock(pb); - } else { - DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n"); - - if (pb->frame_buffer_phys == 0 || - pb->win.width == 0 || - pb->win.height == 0) - return -EINVAL; - if (pb->overlay) - return 0; - planb_lock(pb); - pb->overlay = 1; - if(!(pb->cmd_buff_inited)) - fill_cmd_buff(pb); - overlay_start(pb); - planb_unlock(pb); - } - return 0; - } - case VIDIOCGCHAN: - { - struct video_channel v; - - DEBUG("PlanB: IOCTL VIDIOCGCHAN\n"); - - if(copy_from_user(&v, arg,sizeof(v))) - return -EFAULT; - v.flags = 0; - v.tuners = 0; - v.type = VIDEO_TYPE_CAMERA; - v.norm = pb->win.norm; - switch(v.channel) - { - case 0: - strcpy(v.name,"Composite"); - break; - case 1: - strcpy(v.name,"SVHS"); - break; - default: - return -EINVAL; - break; - } - if(copy_to_user(arg,&v,sizeof(v))) - return -EFAULT; - - return 0; - } - case VIDIOCSCHAN: - { - struct video_channel v; - - DEBUG("PlanB: IOCTL VIDIOCSCHAN\n"); - - if(copy_from_user(&v, arg, sizeof(v))) - return -EFAULT; - - if (v.norm != pb->win.norm) { - int i, maxlines; - - switch (v.norm) - { - case VIDEO_MODE_PAL: - case VIDEO_MODE_SECAM: - maxlines = PLANB_MAXLINES; - break; - case VIDEO_MODE_NTSC: - maxlines = PLANB_NTSC_MAXLINES; - break; - default: - return -EINVAL; - break; - } - planb_lock(pb); - /* empty the grabbing queue */ - wait_event(pb->capq, !pb->grabbing); - pb->maxlines = maxlines; - pb->win.norm = v.norm; - /* Stop overlay if running */ - suspend_overlay(pb); - for(i = 0; i < MAX_GBUFFERS; i++) - pb->gnorm_switch[i] = 1; - /* I know it's an overkill, but.... */ - fill_cmd_buff(pb); - /* ok, now init it accordingly */ - saa_init_regs (pb); - /* restart overlay if it was running */ - resume_overlay(pb); - planb_unlock(pb); - } - - switch(v.channel) - { - case 0: /* Composite */ - saa_set (SAA7196_IOCC, - ((saa_regs[pb->win.norm][SAA7196_IOCC] & - ~7) | 3), pb); - break; - case 1: /* SVHS */ - saa_set (SAA7196_IOCC, - ((saa_regs[pb->win.norm][SAA7196_IOCC] & - ~7) | 4), pb); - break; - default: - return -EINVAL; - break; - } - - return 0; - } - case VIDIOCGPICT: - { - struct video_picture vp = pb->picture; - - DEBUG("PlanB: IOCTL VIDIOCGPICT\n"); - - switch(pb->win.color_fmt) { - case PLANB_GRAY: - vp.palette = VIDEO_PALETTE_GREY; - case PLANB_COLOUR15: - vp.palette = VIDEO_PALETTE_RGB555; - break; - case PLANB_COLOUR32: - vp.palette = VIDEO_PALETTE_RGB32; - break; - default: - vp.palette = 0; - break; - } - - if(copy_to_user(arg,&vp,sizeof(vp))) - return -EFAULT; - return 0; - } - case VIDIOCSPICT: - { - struct video_picture vp; - - DEBUG("PlanB: IOCTL VIDIOCSPICT\n"); - - if(copy_from_user(&vp,arg,sizeof(vp))) - return -EFAULT; - pb->picture = vp; - /* Should we do sanity checks here? */ - saa_set (SAA7196_BRIG, (unsigned char) - ((pb->picture.brightness) >> 8), pb); - saa_set (SAA7196_HUEC, (unsigned char) - ((pb->picture.hue) >> 8) ^ 0x80, pb); - saa_set (SAA7196_CSAT, (unsigned char) - ((pb->picture.colour) >> 9), pb); - saa_set (SAA7196_CONT, (unsigned char) - ((pb->picture.contrast) >> 9), pb); - - return 0; - } - case VIDIOCSWIN: - { - struct video_window vw; - struct video_clip clip; - int i; - - DEBUG("PlanB: IOCTL VIDIOCSWIN\n"); - - if(copy_from_user(&vw,arg,sizeof(vw))) - return -EFAULT; - - planb_lock(pb); - /* Stop overlay if running */ - suspend_overlay(pb); - pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0; - if (pb->win.x != vw.x || - pb->win.y != vw.y || - pb->win.width != vw.width || - pb->win.height != vw.height || - !pb->cmd_buff_inited) { - pb->win.x = vw.x; - pb->win.y = vw.y; - pb->win.width = vw.width; - pb->win.height = vw.height; - fill_cmd_buff(pb); - } - /* Reset clip mask */ - memset ((void *) pb->mask, 0xff, (pb->maxlines - * ((PLANB_MAXPIXELS + 7) & ~7)) / 8); - /* Add any clip rects */ - for (i = 0; i < vw.clipcount; i++) { - if (copy_from_user(&clip, vw.clips + i, - sizeof(struct video_clip))) - return -EFAULT; - add_clip(pb, &clip); - } - /* restart overlay if it was running */ - resume_overlay(pb); - planb_unlock(pb); - return 0; - } - case VIDIOCGWIN: - { - struct video_window vw; - - DEBUG("PlanB: IOCTL VIDIOCGWIN\n"); - - vw.x=pb->win.x; - vw.y=pb->win.y; - vw.width=pb->win.width; - vw.height=pb->win.height; - vw.chromakey=0; - vw.flags=0; - if(pb->win.interlace) - vw.flags|=VIDEO_WINDOW_INTERLACE; - if(copy_to_user(arg,&vw,sizeof(vw))) - return -EFAULT; - return 0; - } - case VIDIOCSYNC: { - int i; - - IDEBUG("PlanB: IOCTL VIDIOCSYNC\n"); - - if(copy_from_user((void *)&i,arg,sizeof(int))) - return -EFAULT; - - IDEBUG("PlanB: sync to frame %d\n", i); - - if(i > (MAX_GBUFFERS - 1) || i < 0) - return -EINVAL; -chk_grab: - switch (pb->frame_stat[i]) { - case GBUFFER_UNUSED: - return -EINVAL; - case GBUFFER_GRABBING: - IDEBUG("PlanB: waiting for grab" - " done (%d)\n", i); - interruptible_sleep_on(&pb->capq); - if(signal_pending(current)) - return -EINTR; - goto chk_grab; - case GBUFFER_DONE: - pb->frame_stat[i] = GBUFFER_UNUSED; - break; - } - return 0; - } - - case VIDIOCMCAPTURE: - { - struct video_mmap vm; - volatile unsigned int status; - - IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n"); - - if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm))) - return -EFAULT; - status = pb->frame_stat[vm.frame]; - if (status != GBUFFER_UNUSED) - return -EBUSY; - - return vgrab(pb, &vm); - } - - case VIDIOCGMBUF: - { - int i; - struct video_mbuf vm; - - DEBUG("PlanB: IOCTL VIDIOCGMBUF\n"); - - memset(&vm, 0 , sizeof(vm)); - vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS; - vm.frames = MAX_GBUFFERS; - for(i = 0; i= SAA7196_NUMREGS) - return -EINVAL; - preg.val = saa_regs[pb->win.norm][preg.addr]; - if(copy_to_user((void *)arg, (void *)&preg, - sizeof(preg))) - return -EFAULT; - return 0; - } - - case PLANBIOCSSAAREGS: - { - struct planb_saa_regs preg; - - DEBUG("PlanB: IOCTL PLANBIOCSSAAREGS\n"); - - if(copy_from_user(&preg, arg, sizeof(preg))) - return -EFAULT; - if(preg.addr >= SAA7196_NUMREGS) - return -EINVAL; - saa_set (preg.addr, preg.val, pb); - return 0; - } - - case PLANBIOCGSTAT: - { - struct planb_stat_regs pstat; - - DEBUG("PlanB: IOCTL PLANBIOCGSTAT\n"); - - pstat.ch1_stat = in_le32(&pb->planb_base->ch1.status); - pstat.ch2_stat = in_le32(&pb->planb_base->ch2.status); - pstat.saa_stat0 = saa_status(0, pb); - pstat.saa_stat1 = saa_status(1, pb); - - if(copy_to_user((void *)arg, (void *)&pstat, - sizeof(pstat))) - return -EFAULT; - return 0; - } - - case PLANBIOCSMODE: { - int v; - - DEBUG("PlanB: IOCTL PLANBIOCSMODE\n"); - - if(copy_from_user(&v, arg, sizeof(v))) - return -EFAULT; - - switch(v) - { - case PLANB_TV_MODE: - saa_set (SAA7196_STDC, - (saa_regs[pb->win.norm][SAA7196_STDC] & - 0x7f), pb); - break; - case PLANB_VTR_MODE: - saa_set (SAA7196_STDC, - (saa_regs[pb->win.norm][SAA7196_STDC] | - 0x80), pb); - break; - default: - return -EINVAL; - break; - } - pb->win.mode = v; - return 0; - } - case PLANBIOCGMODE: { - int v=pb->win.mode; - - DEBUG("PlanB: IOCTL PLANBIOCGMODE\n"); - - if(copy_to_user(arg,&v,sizeof(v))) - return -EFAULT; - return 0; - } -#ifdef PLANB_GSCANLINE - case PLANBG_GRAB_BPL: { - int v=pb->gbytes_per_line; - - DEBUG("PlanB: IOCTL PLANBG_GRAB_BPL\n"); - - if(copy_to_user(arg,&v,sizeof(v))) - return -EFAULT; - return 0; - } -#endif /* PLANB_GSCANLINE */ - case PLANB_INTR_DEBUG: { - int i; - - DEBUG("PlanB: IOCTL PLANB_INTR_DEBUG\n"); - - if(copy_from_user(&i, arg, sizeof(i))) - return -EFAULT; - - /* avoid hang ups all together */ - for (i = 0; i < MAX_GBUFFERS; i++) { - if(pb->frame_stat[i] == GBUFFER_GRABBING) { - pb->frame_stat[i] = GBUFFER_DONE; - } - } - if(pb->grabbing) - pb->grabbing--; - wake_up_interruptible(&pb->capq); - return 0; - } - case PLANB_INV_REGS: { - int i; - struct planb_any_regs any; - - DEBUG("PlanB: IOCTL PLANB_INV_REGS\n"); - - if(copy_from_user(&any, arg, sizeof(any))) - return -EFAULT; - if(any.offset < 0 || any.offset + any.bytes > 0x400) - return -EINVAL; - if(any.bytes > 128) - return -EINVAL; - for (i = 0; i < any.bytes; i++) { - any.data[i] = - in_8((unsigned char *)pb->planb_base - + any.offset + i); - } - if(copy_to_user(arg,&any,sizeof(any))) - return -EFAULT; - return 0; - } - default: - { - DEBUG("PlanB: Unimplemented IOCTL\n"); - return -ENOIOCTLCMD; - } - /* Some IOCTLs are currently unsupported on PlanB */ - case VIDIOCGTUNER: { - DEBUG("PlanB: IOCTL VIDIOCGTUNER\n"); - goto unimplemented; } - case VIDIOCSTUNER: { - DEBUG("PlanB: IOCTL VIDIOCSTUNER\n"); - goto unimplemented; } - case VIDIOCSFREQ: { - DEBUG("PlanB: IOCTL VIDIOCSFREQ\n"); - goto unimplemented; } - case VIDIOCGFREQ: { - DEBUG("PlanB: IOCTL VIDIOCGFREQ\n"); - goto unimplemented; } - case VIDIOCKEY: { - DEBUG("PlanB: IOCTL VIDIOCKEY\n"); - goto unimplemented; } - case VIDIOCSAUDIO: { - DEBUG("PlanB: IOCTL VIDIOCSAUDIO\n"); - goto unimplemented; } - case VIDIOCGAUDIO: { - DEBUG("PlanB: IOCTL VIDIOCGAUDIO\n"); - goto unimplemented; } -unimplemented: - DEBUG(" Unimplemented\n"); - return -ENOIOCTLCMD; - } - return 0; -} - -static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, unsigned long size) -{ - int i; - struct planb *pb = (struct planb *)dev; - unsigned long start = (unsigned long)adr; - - if (size > MAX_GBUFFERS * PLANB_MAX_FBUF) - return -EINVAL; - if (!pb->rawbuf) { - int err; - if((err=grabbuf_alloc(pb))) - return err; - } - for (i = 0; i < pb->rawbuf_size; i++) { - unsigned long pfn; - - pfn = virt_to_phys((void *)pb->rawbuf[i]) >> PAGE_SHIFT; - if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; - start += PAGE_SIZE; - if (size <= PAGE_SIZE) - break; - size -= PAGE_SIZE; - } - return 0; -} - -static struct video_device planb_template= -{ - .owner = THIS_MODULE, - .name = PLANB_DEVICE_NAME, - .type = VID_TYPE_OVERLAY, - .open = planb_open, - .close = planb_close, - .read = planb_read, - .write = planb_write, - .ioctl = planb_ioctl, - .mmap = planb_mmap, /* mmap? */ -}; - -static int init_planb(struct planb *pb) -{ - unsigned char saa_rev; - int i, result; - - memset ((void *) &pb->win, 0, sizeof (struct planb_window)); - /* Simple sanity check */ - if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) { - printk(KERN_ERR "PlanB: Option(s) invalid\n"); - return -2; - } - pb->win.norm = def_norm; - pb->win.mode = PLANB_TV_MODE; /* TV mode */ - pb->win.interlace=1; - pb->win.x=0; - pb->win.y=0; - pb->win.width=768; /* 640 */ - pb->win.height=576; /* 480 */ - pb->maxlines=576; -#if 0 /* keep */; - btv->win.cropwidth=768; /* 640 */ - btv->win.cropheight=576; /* 480 */ - btv->win.cropx=0; - btv->win.cropy=0; -#endif - pb->win.pad=0; - pb->win.bpp=4; - pb->win.depth=32; - pb->win.color_fmt=PLANB_COLOUR32; - pb->win.bpl=1024*pb->win.bpp; - pb->win.swidth=1024; - pb->win.sheight=768; -#ifdef PLANB_GSCANLINE - if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE - || (pb->gbytes_per_line <= 0)) - return -3; - else { - /* page align pb->gbytes_per_line for DMA purpose */ - for(i = PAGE_SIZE; pb->gbytes_per_line < (i>>1);) - i>>=1; - pb->gbytes_per_line = i; - } -#endif - pb->tab_size = PLANB_MAXLINES + 40; - pb->suspend = 0; - mutex_init(&pb->lock); - pb->ch1_cmd = 0; - pb->ch2_cmd = 0; - pb->mask = 0; - pb->priv_space = 0; - pb->offset = 0; - pb->user = 0; - pb->overlay = 0; - init_waitqueue_head(&pb->suspendq); - pb->cmd_buff_inited = 0; - pb->frame_buffer_phys = 0; - - /* Reset DMA controllers */ - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - - saa_rev = (saa_status(0, pb) & 0xf0) >> 4; - printk(KERN_INFO "PlanB: SAA7196 video processor rev. %d\n", saa_rev); - /* Initialize the SAA registers in memory and on chip */ - saa_init_regs (pb); - - /* clear interrupt mask */ - pb->intr_mask = PLANB_CLR_IRQ; - - result = request_irq(pb->irq, planb_irq, 0, "PlanB", pb); - if (result < 0) { - if (result==-EINVAL) - printk(KERN_ERR "PlanB: Bad irq number (%d) " - "or handler\n", (int)pb->irq); - else if (result==-EBUSY) - printk(KERN_ERR "PlanB: I don't know why, " - "but IRQ %d is busy\n", (int)pb->irq); - return result; - } - disable_irq(pb->irq); - - /* Now add the template and register the device unit. */ - memcpy(&pb->video_dev,&planb_template,sizeof(planb_template)); - - pb->picture.brightness=0x90<<8; - pb->picture.contrast = 0x70 << 8; - pb->picture.colour = 0x70<<8; - pb->picture.hue = 0x8000; - pb->picture.whiteness = 0; - pb->picture.depth = pb->win.depth; - - pb->frame_stat=NULL; - init_waitqueue_head(&pb->capq); - for(i=0; igbuf_idx[i] = PLANB_MAX_FBUF * i / PAGE_SIZE; - pb->gwidth[i]=0; - pb->gheight[i]=0; - pb->gfmt[i]=0; - pb->cap_cmd[i]=NULL; -#ifndef PLANB_GSCANLINE - pb->l_fr_addr_idx[i] = MAX_GBUFFERS * (PLANB_MAX_FBUF - / PAGE_SIZE + 1) + MAX_LNUM * i; - pb->lsize[i] = 0; - pb->lnum[i] = 0; -#endif - } - pb->rawbuf=NULL; - pb->grabbing=0; - - /* enable interrupts */ - out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ); - pb->intr_mask = PLANB_FRM_IRQ; - enable_irq(pb->irq); - - if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0) - return -1; - - return 0; -} - -/* - * Scan for a PlanB controller, request the irq and map the io memory - */ - -static int find_planb(void) -{ - struct planb *pb; - struct device_node *planb_devices; - unsigned char dev_fn, confreg, bus; - unsigned int old_base, new_base; - unsigned int irq; - struct pci_dev *pdev; - int rc; - - if (!machine_is(powermac)) - return 0; - - planb_devices = of_find_node_by_name(NULL, "planb"); - if (planb_devices == 0) { - planb_num=0; - printk(KERN_WARNING "PlanB: no device found!\n"); - return planb_num; - } - - if (planb_devices->next != NULL) - printk(KERN_ERR "Warning: only using first PlanB device!\n"); - pb = &planbs[0]; - planb_num = 1; - - if (planb_devices->n_addrs != 1) { - printk (KERN_WARNING "PlanB: expecting 1 address for planb " - "(got %d)", planb_devices->n_addrs); - of_node_put(planb_devices); - return 0; - } - - if (planb_devices->n_intrs == 0) { - printk(KERN_WARNING "PlanB: no intrs for device %s\n", - planb_devices->full_name); - of_node_put(planb_devices); - return 0; - } else { - irq = planb_devices->intrs[0].line; - } - - /* Initialize PlanB's PCI registers */ - - /* There is a bug with the way OF assigns addresses - to the devices behind the chaos bridge. - control needs only 0x1000 of space, but decodes only - the upper 16 bits. It therefore occupies a full 64K. - OF assigns the planb controller memory within this space; - so we need to change that here in order to access planb. */ - - /* We remap to 0xf1000000 in hope that nobody uses it ! */ - - bus = (planb_devices->addrs[0].space >> 16) & 0xff; - dev_fn = (planb_devices->addrs[0].space >> 8) & 0xff; - confreg = planb_devices->addrs[0].space & 0xff; - old_base = planb_devices->addrs[0].address; - new_base = 0xf1000000; - of_node_put(planb_devices); - - DEBUG("PlanB: Found on bus %d, dev %d, func %d, " - "membase 0x%x (base reg. 0x%x)\n", - bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg); - - pdev = pci_get_bus_and_slot(bus, dev_fn); - if (!pdev) { - printk(KERN_ERR "planb: cannot find slot\n"); - goto err_out; - } - - /* Enable response in memory space, bus mastering, - use memory write and invalidate */ - rc = pci_enable_device(pdev); - if (rc) { - printk(KERN_ERR "planb: cannot enable PCI device %s\n", - pci_name(pdev)); - goto err_out; - } - rc = pci_set_mwi(pdev); - if (rc) { - printk(KERN_ERR "planb: cannot enable MWI on PCI device %s\n", - pci_name(pdev)); - goto err_out_disable; - } - pci_set_master(pdev); - - /* Set the new base address */ - pci_write_config_dword (pdev, confreg, new_base); - - planb_regs = (volatile struct planb_registers *) - ioremap (new_base, 0x400); - pb->planb_base = planb_regs; - pb->planb_base_phys = (struct planb_registers *)new_base; - pb->irq = irq; - pb->dev = pdev; - - return planb_num; - -err_out_disable: - pci_disable_device(pdev); -err_out: - /* FIXME handle error */ /* comment moved from pci_find_slot, above */ - pci_dev_put(pdev); - return 0; -} - -static void release_planb(void) -{ - int i; - struct planb *pb; - - for (i=0;iplanb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - - /* clear and free interrupts */ - pb->intr_mask = PLANB_CLR_IRQ; - out_le32 (&pb->planb_base->intr_stat, PLANB_CLR_IRQ); - free_irq(pb->irq, pb); - - /* make sure all allocated memory are freed */ - planb_prepare_close(pb); - - printk(KERN_INFO "PlanB: unregistering with v4l\n"); - video_unregister_device(&pb->video_dev); - - pci_dev_put(pb->dev); - - /* note that iounmap() does nothing on the PPC right now */ - iounmap ((void *)pb->planb_base); - } -} - -static int __init init_planbs(void) -{ - int i; - - if (find_planb()<=0) - return -EIO; - - for (i=0; i -#include "saa7196.h" -#endif /* __KERNEL__ */ - -#define PLANB_DEVICE_NAME "Apple PlanB Video-In" -#define PLANB_REV "1.0" - -#ifdef __KERNEL__ -//#define PLANB_GSCANLINE /* use this if apps have the notion of */ - /* grab buffer scanline */ -/* This should be safe for both PAL and NTSC */ -#define PLANB_MAXPIXELS 768 -#define PLANB_MAXLINES 576 -#define PLANB_NTSC_MAXLINES 480 - -/* Uncomment your preferred norm ;-) */ -#define PLANB_DEF_NORM VIDEO_MODE_PAL -//#define PLANB_DEF_NORM VIDEO_MODE_NTSC -//#define PLANB_DEF_NORM VIDEO_MODE_SECAM - -/* fields settings */ -#define PLANB_GRAY 0x1 /* 8-bit mono? */ -#define PLANB_COLOUR15 0x2 /* 16-bit mode */ -#define PLANB_COLOUR32 0x4 /* 32-bit mode */ -#define PLANB_CLIPMASK 0x8 /* hardware clipmasking */ - -/* misc. flags for PlanB DMA operation */ -#define CH_SYNC 0x1 /* synchronize channels (set by ch1; - cleared by ch2) */ -#define FIELD_SYNC 0x2 /* used for the start of each field - (0 -> 1 -> 0 for ch1; 0 -> 1 for ch2) */ -#define EVEN_FIELD 0x0 /* even field is detected if unset */ -#define DMA_ABORT 0x2 /* error or just out of sync if set */ -#define ODD_FIELD 0x4 /* odd field is detected if set */ - -/* for capture operations */ -#define MAX_GBUFFERS 2 -/* note PLANB_MAX_FBUF must be divisible by PAGE_SIZE */ -#ifdef PLANB_GSCANLINE -#define PLANB_MAX_FBUF 0x240000 /* 576 * 1024 * 4 */ -#define TAB_FACTOR (1) -#else -#define PLANB_MAX_FBUF 0x1b0000 /* 576 * 768 * 4 */ -#define TAB_FACTOR (2) -#endif -#endif /* __KERNEL__ */ - -struct planb_saa_regs { - unsigned char addr; - unsigned char val; -}; - -struct planb_stat_regs { - unsigned int ch1_stat; - unsigned int ch2_stat; - unsigned char saa_stat0; - unsigned char saa_stat1; -}; - -struct planb_any_regs { - unsigned int offset; - unsigned int bytes; - unsigned char data[128]; -}; - -/* planb private ioctls */ -#define PLANBIOCGSAAREGS _IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs) /* Read a saa7196 reg value */ -#define PLANBIOCSSAAREGS _IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs) /* Set a saa7196 reg value */ -#define PLANBIOCGSTAT _IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs) /* Read planb status */ -#define PLANB_TV_MODE 1 -#define PLANB_VTR_MODE 2 -#define PLANBIOCGMODE _IOR('v', BASE_VIDIOCPRIVATE + 3, int) /* Get TV/VTR mode */ -#define PLANBIOCSMODE _IOW('v', BASE_VIDIOCPRIVATE + 4, int) /* Set TV/VTR mode */ - -#ifdef PLANB_GSCANLINE -#define PLANBG_GRAB_BPL _IOR('v', BASE_VIDIOCPRIVATE + 5, int) /* # of bytes per scanline in grab buffer */ -#endif - -/* call wake_up_interruptible() with appropriate actions */ -#define PLANB_INTR_DEBUG _IOW('v', BASE_VIDIOCPRIVATE + 20, int) -/* investigate which reg does what */ -#define PLANB_INV_REGS _IOWR('v', BASE_VIDIOCPRIVATE + 21, struct planb_any_regs) - -#ifdef __KERNEL__ - -/* Potentially useful macros */ -#define PLANB_SET(x) ((x) << 16 | (x)) -#define PLANB_CLR(x) ((x) << 16) - -/* This represents the physical register layout */ -struct planb_registers { - volatile struct dbdma_regs ch1; /* 0x00: video in */ - volatile unsigned int even; /* 0x40: even field setting */ - volatile unsigned int odd; /* 0x44; odd field setting */ - unsigned int pad1[14]; /* empty? */ - volatile struct dbdma_regs ch2; /* 0x80: clipmask out */ - unsigned int pad2[16]; /* 0xc0: empty? */ - volatile unsigned int reg3; /* 0x100: ???? */ - volatile unsigned int intr_stat; /* 0x104: irq status */ -#define PLANB_CLR_IRQ 0x00 /* clear Plan B interrupt */ -#define PLANB_GEN_IRQ 0x01 /* assert Plan B interrupt */ -#define PLANB_FRM_IRQ 0x0100 /* end of frame */ - unsigned int pad3[1]; /* empty? */ - volatile unsigned int reg5; /* 0x10c: ??? */ - unsigned int pad4[60]; /* empty? */ - volatile unsigned char saa_addr; /* 0x200: SAA subadr */ - char pad5[3]; - volatile unsigned char saa_regval; /* SAA7196 write reg. val */ - char pad6[3]; - volatile unsigned char saa_status; /* SAA7196 status byte */ - /* There is more unused stuff here */ -}; - -struct planb_window { - int x, y; - ushort width, height; - ushort bpp, bpl, depth, pad; - ushort swidth, sheight; - int norm; - int interlace; - u32 color_fmt; - int chromakey; - int mode; /* used to switch between TV/VTR modes */ -}; - -struct planb_suspend { - int overlay; - int frame; - struct dbdma_cmd cmd; -}; - -struct planb { - struct video_device video_dev; - struct video_picture picture; /* Current picture params */ - struct video_audio audio_dev; /* Current audio params */ - - volatile struct planb_registers *planb_base; /* virt base of planb */ - struct planb_registers *planb_base_phys; /* phys base of planb */ - void *priv_space; /* Org. alloc. mem for kfree */ - int user; - unsigned int tab_size; - int maxlines; - struct mutex lock; - unsigned int irq; /* interrupt number */ - volatile unsigned int intr_mask; - struct pci_dev *dev; /* Our PCI device */ - - int overlay; /* overlay running? */ - struct planb_window win; - unsigned long frame_buffer_phys; /* We need phys for DMA */ - int offset; /* offset of pixel 1 */ - volatile struct dbdma_cmd *ch1_cmd; /* Video In DMA cmd buffer */ - volatile struct dbdma_cmd *ch2_cmd; /* Clip Out DMA cmd buffer */ - volatile struct dbdma_cmd *overlay_last1; - volatile struct dbdma_cmd *overlay_last2; - unsigned long ch1_cmd_phys; - volatile unsigned char *mask; /* Clipmask buffer */ - int suspend; - wait_queue_head_t suspendq; - struct planb_suspend suspended; - int cmd_buff_inited; /* cmd buffer inited? */ - - int grabbing; - unsigned int gcount; - wait_queue_head_t capq; - int last_fr; - int prev_last_fr; - unsigned char **rawbuf; - int rawbuf_size; - int gbuf_idx[MAX_GBUFFERS]; - volatile struct dbdma_cmd *cap_cmd[MAX_GBUFFERS]; - volatile struct dbdma_cmd *last_cmd[MAX_GBUFFERS]; - volatile struct dbdma_cmd *pre_cmd[MAX_GBUFFERS]; - int need_pre_capture[MAX_GBUFFERS]; -#define PLANB_DUMMY 40 /* # of command buf's allocated for pre-capture seq. */ - int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS]; - unsigned int gfmt[MAX_GBUFFERS]; - int gnorm_switch[MAX_GBUFFERS]; - volatile unsigned int *frame_stat; -#define GBUFFER_UNUSED 0x00U -#define GBUFFER_GRABBING 0x01U -#define GBUFFER_DONE 0x02U -#ifdef PLANB_GSCANLINE - int gbytes_per_line; -#else -#define MAX_LNUM 431 /* change this if PLANB_MAXLINES or */ - /* PLANB_MAXPIXELS changes */ - int l_fr_addr_idx[MAX_GBUFFERS]; - unsigned char *l_to_addr[MAX_GBUFFERS][MAX_LNUM]; - int l_to_next_idx[MAX_GBUFFERS][MAX_LNUM]; - int l_to_next_size[MAX_GBUFFERS][MAX_LNUM]; - int lsize[MAX_GBUFFERS], lnum[MAX_GBUFFERS]; -#endif -}; - -#endif /* __KERNEL__ */ - -#endif /* _PLANB_H_ */ diff --git a/linux/drivers/media/video/saa7196.h b/linux/drivers/media/video/saa7196.h deleted file mode 100644 index cd4b6354a..000000000 --- a/linux/drivers/media/video/saa7196.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - Definitions for the Philips SAA7196 digital video decoder, - scaler, and clock generator circuit (DESCpro), as used in - the PlanB video input of the Powermac 7x00/8x00 series. - - Copyright (C) 1998 Michel Lanners (mlan@cpu.lu) - - The register defines are shamelessly copied from the meteor - driver out of NetBSD (with permission), - and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe - (Thanks !) - - Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu) - - The default values used for PlanB are my mistakes. -*/ - -/* $Id: saa7196.h,v 1.5 1999/03/26 23:28:47 mlan Exp $ */ - -#ifndef _SAA7196_H_ -#define _SAA7196_H_ - -#define SAA7196_NUMREGS 0x31 /* Number of registers (used)*/ -#define NUM_SUPPORTED_NORM 3 /* Number of supported norms by PlanB */ - -/* Decoder part: */ -#define SAA7196_IDEL 0x00 /* Increment delay */ -#define SAA7196_HSB5 0x01 /* H-sync begin; 50 hz */ -#define SAA7196_HSS5 0x02 /* H-sync stop; 50 hz */ -#define SAA7196_HCB5 0x03 /* H-clamp begin; 50 hz */ -#define SAA7196_HCS5 0x04 /* H-clamp stop; 50 hz */ -#define SAA7196_HSP5 0x05 /* H-sync after PHI1; 50 hz */ -#define SAA7196_LUMC 0x06 /* Luminance control */ -#define SAA7196_HUEC 0x07 /* Hue control */ -#define SAA7196_CKTQ 0x08 /* Colour Killer Threshold QAM (PAL, NTSC) */ -#define SAA7196_CKTS 0x09 /* Colour Killer Threshold SECAM */ -#define SAA7196_PALS 0x0a /* PAL switch sensitivity */ -#define SAA7196_SECAMS 0x0b /* SECAM switch sensitivity */ -#define SAA7196_CGAINC 0x0c /* Chroma gain control */ -#define SAA7196_STDC 0x0d /* Standard/Mode control */ -#define SAA7196_IOCC 0x0e /* I/O and Clock Control */ -#define SAA7196_CTRL1 0x0f /* Control #1 */ -#define SAA7196_CTRL2 0x10 /* Control #2 */ -#define SAA7196_CGAINR 0x11 /* Chroma Gain Reference */ -#define SAA7196_CSAT 0x12 /* Chroma Saturation */ -#define SAA7196_CONT 0x13 /* Luminance Contrast */ -#define SAA7196_HSB6 0x14 /* H-sync begin; 60 hz */ -#define SAA7196_HSS6 0x15 /* H-sync stop; 60 hz */ -#define SAA7196_HCB6 0x16 /* H-clamp begin; 60 hz */ -#define SAA7196_HCS6 0x17 /* H-clamp stop; 60 hz */ -#define SAA7196_HSP6 0x18 /* H-sync after PHI1; 60 hz */ -#define SAA7196_BRIG 0x19 /* Luminance Brightness */ - -/* Scaler part: */ -#define SAA7196_FMTS 0x20 /* Formats and sequence */ -#define SAA7196_OUTPIX 0x21 /* Output data pixel/line */ -#define SAA7196_INPIX 0x22 /* Input data pixel/line */ -#define SAA7196_HWS 0x23 /* Horiz. window start */ -#define SAA7196_HFILT 0x24 /* Horiz. filter */ -#define SAA7196_OUTLINE 0x25 /* Output data lines/field */ -#define SAA7196_INLINE 0x26 /* Input data lines/field */ -#define SAA7196_VWS 0x27 /* Vertical window start */ -#define SAA7196_VYP 0x28 /* AFS/vertical Y processing */ -#define SAA7196_VBS 0x29 /* Vertical Bypass start */ -#define SAA7196_VBCNT 0x2a /* Vertical Bypass count */ -#define SAA7196_VBP 0x2b /* veritcal Bypass Polarity */ -#define SAA7196_VLOW 0x2c /* Colour-keying lower V limit */ -#define SAA7196_VHIGH 0x2d /* Colour-keying upper V limit */ -#define SAA7196_ULOW 0x2e /* Colour-keying lower U limit */ -#define SAA7196_UHIGH 0x2f /* Colour-keying upper U limit */ -#define SAA7196_DPATH 0x30 /* Data path setting */ - -/* Initialization default values: */ - -unsigned char saa_regs[NUM_SUPPORTED_NORM][SAA7196_NUMREGS] = { - -/* PAL, 768x576 (no scaling), composite video-in */ -/* Decoder: */ - { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff, - 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x06, 0x3b, 0x98, - 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2, - 0xe9, 0xa2, -/* Padding */ - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* Scaler: */ - 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12, - 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x87 }, - -/* NTSC, 640x480? (no scaling), composite video-in */ -/* Decoder: */ - { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x50, 0x00, - 0xf8, 0xf0, 0xfe, 0xe0, 0x00, 0x06, 0x3b, 0x98, - 0x00, 0x2c, 0x3d, 0x40, 0x34, 0x0a, 0xf4, 0xd2, - 0xe9, 0x98, -/* Padding */ - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* Scaler: */ - 0x72, 0x80, 0x80, 0x03, 0x89, 0xf0, 0xf0, 0x0d, - 0xa0, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x87 }, - -/* SECAM, 768x576 (no scaling), composite video-in */ -/* Decoder: */ - { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff, - 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x07, 0x3b, 0x98, - 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2, - 0xe9, 0xa2, -/* Padding */ - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* Scaler: */ - 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12, - 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x87 } - }; - -#endif /* _SAA7196_H_ */ -- cgit v1.2.3 From c201b83b7aab962a7369b64863ba52ec2b973659 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 Jul 2008 10:32:50 +0200 Subject: videodev: replace videodev.h includes by videodev2.h where possible From: Hans Verkuil Several V4L2 drivers still included videodev.h. Fix this. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cs53l32a.c | 2 +- linux/drivers/media/video/m52790.c | 2 +- linux/drivers/media/video/msp3400-driver.c | 1 - linux/drivers/media/video/msp3400-kthreads.c | 1 - linux/drivers/media/video/saa717x.c | 1 - linux/drivers/media/video/tda7432.c | 2 +- linux/drivers/media/video/tda9875.c | 2 +- linux/drivers/media/video/tlv320aic23b.c | 2 +- linux/drivers/media/video/tveeprom.c | 2 +- linux/drivers/media/video/tvp5150.c | 2 +- linux/drivers/media/video/v4l2-common.c | 2 +- linux/drivers/media/video/vino.c | 2 +- linux/drivers/media/video/vp27smpx.c | 2 +- linux/drivers/media/video/vpx3220.c | 2 +- linux/drivers/media/video/w9966.c | 2 +- linux/drivers/media/video/w9968cf.h | 2 +- linux/drivers/media/video/wm8739.c | 2 +- linux/drivers/media/video/wm8775.c | 2 +- 18 files changed, 15 insertions(+), 18 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cs53l32a.c b/linux/drivers/media/video/cs53l32a.c index bef0950e5..f5ea3f4a9 100644 --- a/linux/drivers/media/video/cs53l32a.c +++ b/linux/drivers/media/video/cs53l32a.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/linux/drivers/media/video/m52790.c b/linux/drivers/media/video/m52790.c index 87e948caf..f39da4a36 100644 --- a/linux/drivers/media/video/m52790.c +++ b/linux/drivers/media/video/m52790.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c index d67af9753..c6c0a584c 100644 --- a/linux/drivers/media/video/msp3400-driver.c +++ b/linux/drivers/media/video/msp3400-driver.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c index ba19edac0..29c0d5cf6 100644 --- a/linux/drivers/media/video/msp3400-kthreads.c +++ b/linux/drivers/media/video/msp3400-kthreads.c @@ -27,7 +27,6 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) #include #endif -#include #include #include #include diff --git a/linux/drivers/media/video/saa717x.c b/linux/drivers/media/video/saa717x.c index a478bf25e..b0751c195 100644 --- a/linux/drivers/media/video/saa717x.c +++ b/linux/drivers/media/video/saa717x.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include diff --git a/linux/drivers/media/video/tda7432.c b/linux/drivers/media/video/tda7432.c index 1e70a7710..375b8d6d2 100644 --- a/linux/drivers/media/video/tda7432.c +++ b/linux/drivers/media/video/tda7432.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include diff --git a/linux/drivers/media/video/tda9875.c b/linux/drivers/media/video/tda9875.c index 5c3d43082..20e738264 100644 --- a/linux/drivers/media/video/tda9875.c +++ b/linux/drivers/media/video/tda9875.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/linux/drivers/media/video/tlv320aic23b.c b/linux/drivers/media/video/tlv320aic23b.c index b601c232a..a531a46d1 100644 --- a/linux/drivers/media/video/tlv320aic23b.c +++ b/linux/drivers/media/video/tlv320aic23b.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include "compat.h" diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c index 5dc1d3c27..5f088e669 100644 --- a/linux/drivers/media/video/tveeprom.c +++ b/linux/drivers/media/video/tveeprom.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 6ac63245d..28c5c6761 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -7,7 +7,7 @@ #include #include "compat.h" -#include +#include #include #include #include diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 1e795e928..a027d9baa 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -64,7 +64,7 @@ #include #endif -#include +#include #include "compat.h" MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr"); diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index 60527b164..b379abf28 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include #include diff --git a/linux/drivers/media/video/vp27smpx.c b/linux/drivers/media/video/vp27smpx.c index 6c47c5e5a..80de9e796 100644 --- a/linux/drivers/media/video/vp27smpx.c +++ b/linux/drivers/media/video/vp27smpx.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c index 989166eec..e4252f3c5 100644 --- a/linux/drivers/media/video/vpx3220.c +++ b/linux/drivers/media/video/vpx3220.c @@ -34,7 +34,7 @@ #define I2C_NAME(x) (x)->name #include "compat.h" -#include +#include #include #include diff --git a/linux/drivers/media/video/w9966.c b/linux/drivers/media/video/w9966.c index 543c54ecb..964c28c8a 100644 --- a/linux/drivers/media/video/w9966.c +++ b/linux/drivers/media/video/w9966.c @@ -58,7 +58,7 @@ #include #include #include "compat.h" -#include +#include #include #include #include diff --git a/linux/drivers/media/video/w9968cf.h b/linux/drivers/media/video/w9968cf.h index 15ea445e5..62c26b1ed 100644 --- a/linux/drivers/media/video/w9968cf.h +++ b/linux/drivers/media/video/w9968cf.h @@ -21,7 +21,7 @@ #ifndef _W9968CF_H_ #define _W9968CF_H_ -#include +#include #include #include #include diff --git a/linux/drivers/media/video/wm8739.c b/linux/drivers/media/video/wm8739.c index b361d0d42..3ad19cf13 100644 --- a/linux/drivers/media/video/wm8739.c +++ b/linux/drivers/media/video/wm8739.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/linux/drivers/media/video/wm8775.c b/linux/drivers/media/video/wm8775.c index e7a2e0449..ff7fa162b 100644 --- a/linux/drivers/media/video/wm8775.c +++ b/linux/drivers/media/video/wm8775.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3 From ddb6d77848776ec7f6b3135f2dfa5fbc1544b003 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 Jul 2008 12:39:54 +0200 Subject: videodev: remove some CONFIG_VIDEO_V4L1_COMPAT code from v4l2-dev.h From: Hans Verkuil The video_device_create_file and video_device_remove_file functions can be removed from v4l2-dev.h, removing the dependency on videodev.h in v4l2-dev.h. Also removed a few more videodev.h includes that should have been videodev2.h. Signed-off-by: Hans Verkuil --- linux/drivers/media/common/tuners/tda9887.c | 4 +- linux/drivers/media/common/tuners/tuner-simple.c | 2 +- linux/drivers/media/video/cpia2/cpia2_core.c | 1 + linux/drivers/media/video/ov511.c | 34 ++++++++-------- linux/drivers/media/video/pwc/pwc-if.c | 11 ++--- linux/drivers/media/video/stk-webcam.c | 14 ++++--- linux/drivers/media/video/stv680.c | 47 +++++++++++----------- linux/drivers/media/video/usbvideo/vicam.c | 1 + .../drivers/media/video/usbvision/usbvision-core.c | 1 - .../media/video/usbvision/usbvision-video.c | 1 - linux/drivers/media/video/vpx3220.c | 2 +- 11 files changed, 61 insertions(+), 57 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/tda9887.c b/linux/drivers/media/common/tuners/tda9887.c index 61a56026d..d588c5d88 100644 --- a/linux/drivers/media/common/tuners/tda9887.c +++ b/linux/drivers/media/common/tuners/tda9887.c @@ -6,12 +6,12 @@ #include #include #include -#include "compat.h" -#include +#include #include #include #include "tuner-i2c.h" #include "tda9887.h" +#include "compat.h" /* Chips: diff --git a/linux/drivers/media/common/tuners/tuner-simple.c b/linux/drivers/media/common/tuners/tuner-simple.c index a029cf8f5..f352af87b 100644 --- a/linux/drivers/media/common/tuners/tuner-simple.c +++ b/linux/drivers/media/common/tuners/tuner-simple.c @@ -7,7 +7,7 @@ #include #include #include "compat.h" -#include +#include #include #include #include diff --git a/linux/drivers/media/video/cpia2/cpia2_core.c b/linux/drivers/media/video/cpia2/cpia2_core.c index eab48dfd0..ce43a054a 100644 --- a/linux/drivers/media/video/cpia2/cpia2_core.c +++ b/linux/drivers/media/video/cpia2/cpia2_core.c @@ -32,6 +32,7 @@ #include "cpia2.h" #include +#include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) #include diff --git a/linux/drivers/media/video/ov511.c b/linux/drivers/media/video/ov511.c index a4125b44d..982bc3d10 100644 --- a/linux/drivers/media/video/ov511.c +++ b/linux/drivers/media/video/ov511.c @@ -5664,43 +5664,43 @@ static int ov_create_sysfs(struct video_device *vdev) { int rc; - rc = video_device_create_file(vdev, &dev_attr_custom_id); + rc = device_create_file(&vdev->dev, &dev_attr_custom_id); if (rc) goto err; - rc = video_device_create_file(vdev, &dev_attr_model); + rc = device_create_file(&vdev->dev, &dev_attr_model); if (rc) goto err_id; - rc = video_device_create_file(vdev, &dev_attr_bridge); + rc = device_create_file(&vdev->dev, &dev_attr_bridge); if (rc) goto err_model; - rc = video_device_create_file(vdev, &dev_attr_sensor); + rc = device_create_file(&vdev->dev, &dev_attr_sensor); if (rc) goto err_bridge; - rc = video_device_create_file(vdev, &dev_attr_brightness); + rc = device_create_file(&vdev->dev, &dev_attr_brightness); if (rc) goto err_sensor; - rc = video_device_create_file(vdev, &dev_attr_saturation); + rc = device_create_file(&vdev->dev, &dev_attr_saturation); if (rc) goto err_bright; - rc = video_device_create_file(vdev, &dev_attr_contrast); + rc = device_create_file(&vdev->dev, &dev_attr_contrast); if (rc) goto err_sat; - rc = video_device_create_file(vdev, &dev_attr_hue); + rc = device_create_file(&vdev->dev, &dev_attr_hue); if (rc) goto err_contrast; - rc = video_device_create_file(vdev, &dev_attr_exposure); + rc = device_create_file(&vdev->dev, &dev_attr_exposure); if (rc) goto err_hue; return 0; err_hue: - video_device_remove_file(vdev, &dev_attr_hue); + device_remove_file(&vdev->dev, &dev_attr_hue); err_contrast: - video_device_remove_file(vdev, &dev_attr_contrast); + device_remove_file(&vdev->dev, &dev_attr_contrast); err_sat: - video_device_remove_file(vdev, &dev_attr_saturation); + device_remove_file(&vdev->dev, &dev_attr_saturation); err_bright: - video_device_remove_file(vdev, &dev_attr_brightness); + device_remove_file(&vdev->dev, &dev_attr_brightness); err_sensor: - video_device_remove_file(vdev, &dev_attr_sensor); + device_remove_file(&vdev->dev, &dev_attr_sensor); err_bridge: - video_device_remove_file(vdev, &dev_attr_bridge); + device_remove_file(&vdev->dev, &dev_attr_bridge); err_model: - video_device_remove_file(vdev, &dev_attr_model); + device_remove_file(&vdev->dev, &dev_attr_model); err_id: - video_device_remove_file(vdev, &dev_attr_custom_id); + device_remove_file(&vdev->dev, &dev_attr_custom_id); err: return rc; } diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index e8e8fd280..dc1e9c6b4 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -1051,19 +1051,20 @@ static int pwc_create_sysfs_files(struct video_device *vdev) struct pwc_device *pdev = video_get_drvdata(vdev); int rc; - rc = video_device_create_file(vdev, &dev_attr_button); + rc = device_create_file(&vdev->dev, &dev_attr_button); if (rc) goto err; if (pdev->features & FEATURE_MOTOR_PANTILT) { - rc = video_device_create_file(vdev, &dev_attr_pan_tilt); + rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt); if (rc) goto err_button; } return 0; err_button: - video_device_remove_file(vdev, &dev_attr_button); + device_remove_file(&vdev->dev, &dev_attr_button); err: + PWC_ERROR("Could not create sysfs files.\n"); return rc; } @@ -1071,8 +1072,8 @@ static void pwc_remove_sysfs_files(struct video_device *vdev) { struct pwc_device *pdev = video_get_drvdata(vdev); if (pdev->features & FEATURE_MOTOR_PANTILT) - video_device_remove_file(vdev, &dev_attr_pan_tilt); - video_device_remove_file(vdev, &dev_attr_button); + device_remove_file(&vdev->dev, &dev_attr_pan_tilt); + device_remove_file(&vdev->dev, &dev_attr_button); } #ifdef CONFIG_USB_PWC_DEBUG diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index 059125c5a..5daa2294d 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -342,17 +342,19 @@ static int stk_create_sysfs_files(struct video_device *vdev) { int ret; - ret = video_device_create_file(vdev, &dev_attr_brightness); - ret += video_device_create_file(vdev, &dev_attr_hflip); - ret += video_device_create_file(vdev, &dev_attr_vflip); + ret = device_create_file(&vdev->dev, &dev_attr_brightness); + ret += device_create_file(&vdev->dev, &dev_attr_hflip); + ret += device_create_file(&vdev->dev, &dev_attr_vflip); + if (ret) + STK_WARNING("Could not create sysfs files\n"); return ret; } static void stk_remove_sysfs_files(struct video_device *vdev) { - video_device_remove_file(vdev, &dev_attr_brightness); - video_device_remove_file(vdev, &dev_attr_hflip); - video_device_remove_file(vdev, &dev_attr_vflip); + device_remove_file(&vdev->dev, &dev_attr_brightness); + device_remove_file(&vdev->dev, &dev_attr_hflip); + device_remove_file(&vdev->dev, &dev_attr_vflip); } #else diff --git a/linux/drivers/media/video/stv680.c b/linux/drivers/media/video/stv680.c index 2e8348cc7..57baad8eb 100644 --- a/linux/drivers/media/video/stv680.c +++ b/linux/drivers/media/video/stv680.c @@ -526,53 +526,54 @@ static int stv680_create_sysfs_files(struct video_device *vdev) { int rc; - rc = video_device_create_file(vdev, &dev_attr_model); + rc = device_create_file(&vdev->dev, &dev_attr_model); if (rc) goto err; - rc = video_device_create_file(vdev, &dev_attr_in_use); + rc = device_create_file(&vdev->dev, &dev_attr_in_use); if (rc) goto err_model; - rc = video_device_create_file(vdev, &dev_attr_streaming); + rc = device_create_file(&vdev->dev, &dev_attr_streaming); if (rc) goto err_inuse; - rc = video_device_create_file(vdev, &dev_attr_palette); + rc = device_create_file(&vdev->dev, &dev_attr_palette); if (rc) goto err_stream; - rc = video_device_create_file(vdev, &dev_attr_frames_total); + rc = device_create_file(&vdev->dev, &dev_attr_frames_total); if (rc) goto err_pal; - rc = video_device_create_file(vdev, &dev_attr_frames_read); + rc = device_create_file(&vdev->dev, &dev_attr_frames_read); if (rc) goto err_framtot; - rc = video_device_create_file(vdev, &dev_attr_packets_dropped); + rc = device_create_file(&vdev->dev, &dev_attr_packets_dropped); if (rc) goto err_framread; - rc = video_device_create_file(vdev, &dev_attr_decoding_errors); + rc = device_create_file(&vdev->dev, &dev_attr_decoding_errors); if (rc) goto err_dropped; return 0; err_dropped: - video_device_remove_file(vdev, &dev_attr_packets_dropped); + device_remove_file(&vdev->dev, &dev_attr_packets_dropped); err_framread: - video_device_remove_file(vdev, &dev_attr_frames_read); + device_remove_file(&vdev->dev, &dev_attr_frames_read); err_framtot: - video_device_remove_file(vdev, &dev_attr_frames_total); + device_remove_file(&vdev->dev, &dev_attr_frames_total); err_pal: - video_device_remove_file(vdev, &dev_attr_palette); + device_remove_file(&vdev->dev, &dev_attr_palette); err_stream: - video_device_remove_file(vdev, &dev_attr_streaming); + device_remove_file(&vdev->dev, &dev_attr_streaming); err_inuse: - video_device_remove_file(vdev, &dev_attr_in_use); + device_remove_file(&vdev->dev, &dev_attr_in_use); err_model: - video_device_remove_file(vdev, &dev_attr_model); + device_remove_file(&vdev->dev, &dev_attr_model); err: + PDEBUG(0, "STV(e): Could not create sysfs files"); return rc; } static void stv680_remove_sysfs_files(struct video_device *vdev) { - video_device_remove_file(vdev, &dev_attr_model); - video_device_remove_file(vdev, &dev_attr_in_use); - video_device_remove_file(vdev, &dev_attr_streaming); - video_device_remove_file(vdev, &dev_attr_palette); - video_device_remove_file(vdev, &dev_attr_frames_total); - video_device_remove_file(vdev, &dev_attr_frames_read); - video_device_remove_file(vdev, &dev_attr_packets_dropped); - video_device_remove_file(vdev, &dev_attr_decoding_errors); + device_remove_file(&vdev->dev, &dev_attr_model); + device_remove_file(&vdev->dev, &dev_attr_in_use); + device_remove_file(&vdev->dev, &dev_attr_streaming); + device_remove_file(&vdev->dev, &dev_attr_palette); + device_remove_file(&vdev->dev, &dev_attr_frames_total); + device_remove_file(&vdev->dev, &dev_attr_frames_read); + device_remove_file(&vdev->dev, &dev_attr_packets_dropped); + device_remove_file(&vdev->dev, &dev_attr_decoding_errors); } /******************************************************************** diff --git a/linux/drivers/media/video/usbvideo/vicam.c b/linux/drivers/media/video/usbvideo/vicam.c index e24a089ec..165d35cfa 100644 --- a/linux/drivers/media/video/usbvideo/vicam.c +++ b/linux/drivers/media/video/usbvideo/vicam.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c index 4c391727e..8c2b53513 100644 --- a/linux/drivers/media/video/usbvision/usbvision-core.c +++ b/linux/drivers/media/video/usbvision/usbvision-core.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index e97f955aa..a65e5db0a 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c index e4252f3c5..989166eec 100644 --- a/linux/drivers/media/video/vpx3220.c +++ b/linux/drivers/media/video/vpx3220.c @@ -34,7 +34,7 @@ #define I2C_NAME(x) (x)->name #include "compat.h" -#include +#include #include #include -- cgit v1.2.3 From 838a44104a792f93926bbf9f69e90b6f84c1ddb3 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 25 Jul 2008 13:53:03 +0200 Subject: gspca: Set the specific per webcam information in driver_info. From: Jean-Francois Moine This patch removes a big part of the code run at probe time. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/conex.c | 3 +- linux/drivers/media/video/gspca/etoms.c | 24 +- linux/drivers/media/video/gspca/mars.c | 3 +- linux/drivers/media/video/gspca/ov519.c | 27 ++- linux/drivers/media/video/gspca/pac207.c | 19 +- linux/drivers/media/video/gspca/pac7311.c | 16 +- linux/drivers/media/video/gspca/sonixj.c | 243 ++++----------------- linux/drivers/media/video/gspca/spca500.c | 133 ++---------- linux/drivers/media/video/gspca/spca501.c | 69 +----- linux/drivers/media/video/gspca/spca505.c | 29 +-- linux/drivers/media/video/gspca/spca506.c | 10 +- linux/drivers/media/video/gspca/spca508.c | 67 +----- linux/drivers/media/video/gspca/spca561.c | 57 ++--- linux/drivers/media/video/gspca/stk014.c | 3 +- linux/drivers/media/video/gspca/sunplus.c | 349 +++++++----------------------- linux/drivers/media/video/gspca/t613.c | 16 +- linux/drivers/media/video/gspca/tv8532.c | 11 +- linux/drivers/media/video/gspca/vc032x.c | 38 +--- linux/drivers/media/video/gspca/zc3xx.c | 125 +++++------ 19 files changed, 284 insertions(+), 958 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/conex.c b/linux/drivers/media/video/gspca/conex.c index f5ef7599d..44b0bffeb 100644 --- a/linux/drivers/media/video/gspca/conex.c +++ b/linux/drivers/media/video/gspca/conex.c @@ -1007,9 +1007,8 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")}, + {USB_DEVICE(0x0572, 0x0041)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index 3f64b04a8..4e15e7dff 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -599,25 +599,10 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; -/* switch (vendor) { */ -/* case 0x102c: * Etoms */ - switch (product) { - case 0x6151: - sd->sensor = SENSOR_PAS106; /* Etoms61x151 */ - break; - case 0x6251: - sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */ - break; -/* } */ -/* break; */ - } + cam = &gspca_dev->cam; cam->epaddr = 1; + sd->sensor = id->driver_info; if (sd->sensor == SENSOR_PAS106) { cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; @@ -913,12 +898,11 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { #ifndef CONFIG_USB_ET61X251 - {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")}, + {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, #endif - {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")}, + {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, {} }; diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index 2d47876bf..21c4ee56a 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -420,9 +420,8 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")}, + {USB_DEVICE(0x093a, 0x050f)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/ov519.c b/linux/drivers/media/video/gspca/ov519.c index c93bd927a..5864656e3 100644 --- a/linux/drivers/media/video/gspca/ov519.c +++ b/linux/drivers/media/video/gspca/ov519.c @@ -2178,21 +2178,20 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")}, - {USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")}, - {USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")}, - {USB_DEVICE(0x041e, 0x4061), DVNM("Creative Live! VISTA VF0400")}, - {USB_DEVICE(0x041e, 0x4064), DVNM("Creative Live! VISTA VF0420")}, - {USB_DEVICE(0x041e, 0x4068), DVNM("Creative Live! VISTA VF0470")}, - {USB_DEVICE(0x045e, 0x028c), DVNM("Microsoft xbox cam")}, - {USB_DEVICE(0x054c, 0x0154), DVNM("Sonny toy4")}, - {USB_DEVICE(0x054c, 0x0155), DVNM("Sonny toy5")}, - {USB_DEVICE(0x05a9, 0x0519), DVNM("OmniVision")}, - {USB_DEVICE(0x05a9, 0x0530), DVNM("OmniVision")}, - {USB_DEVICE(0x05a9, 0x4519), DVNM("OmniVision")}, - {USB_DEVICE(0x05a9, 0x8519), DVNM("OmniVision")}, + {USB_DEVICE(0x041e, 0x4052)}, + {USB_DEVICE(0x041e, 0x405f)}, + {USB_DEVICE(0x041e, 0x4060)}, + {USB_DEVICE(0x041e, 0x4061)}, + {USB_DEVICE(0x041e, 0x4064)}, + {USB_DEVICE(0x041e, 0x4068)}, + {USB_DEVICE(0x045e, 0x028c)}, + {USB_DEVICE(0x054c, 0x0154)}, + {USB_DEVICE(0x054c, 0x0155)}, + {USB_DEVICE(0x05a9, 0x0519)}, + {USB_DEVICE(0x05a9, 0x0530)}, + {USB_DEVICE(0x05a9, 0x4519)}, + {USB_DEVICE(0x05a9, 0x8519)}, {} }; #undef DVNAME diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c index f79074637..7ef18d578 100644 --- a/linux/drivers/media/video/gspca/pac207.c +++ b/linux/drivers/media/video/gspca/pac207.c @@ -570,17 +570,16 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")}, - {USB_DEVICE(0x093a, 0x2460), DVNM("Q-Tec Webcam 100")}, - {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")}, - {USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")}, - {USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")}, - {USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")}, - {USB_DEVICE(0x093a, 0x2471), DVNM("Genius VideoCam GE111")}, - {USB_DEVICE(0x093a, 0x2472), DVNM("Genius VideoCam GE110")}, - {USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")}, + {USB_DEVICE(0x041e, 0x4028)}, + {USB_DEVICE(0x093a, 0x2460)}, + {USB_DEVICE(0x093a, 0x2463)}, + {USB_DEVICE(0x093a, 0x2464)}, + {USB_DEVICE(0x093a, 0x2468)}, + {USB_DEVICE(0x093a, 0x2470)}, + {USB_DEVICE(0x093a, 0x2471)}, + {USB_DEVICE(0x093a, 0x2472)}, + {USB_DEVICE(0x2001, 0xf115)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index ce8403dcf..9beea8205 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -722,16 +722,14 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x093a, 0x2600), DVNM("Typhoon")}, - {USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")}, - {USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")}, - {USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")}, - {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera")}, - /* and also ', Trust WB-3350p, SIGMA cam 2350' */ - {USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")}, - {USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")}, + {USB_DEVICE(0x093a, 0x2600)}, + {USB_DEVICE(0x093a, 0x2601)}, + {USB_DEVICE(0x093a, 0x2603)}, + {USB_DEVICE(0x093a, 0x2608)}, + {USB_DEVICE(0x093a, 0x260e)}, + {USB_DEVICE(0x093a, 0x260f)}, + {USB_DEVICE(0x093a, 0x2621)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index e38175f31..5264b06dc 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -806,191 +806,16 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 product; - - product = id->idProduct; - sd->sensor = -1; - switch (id->idVendor) { - case 0x0458: /* Genius */ -/* switch (product) { - case 0x7025: */ - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_MI0360; - sd->i2c_base = 0x5d; -/* break; - } */ - break; - case 0x045e: -/* switch (product) { - case 0x00f5: - case 0x00f7: */ - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OV7660; - sd->i2c_base = 0x21; -/* break; - } */ - break; - case 0x0471: /* Philips */ -/* switch (product) { - case 0x0327: - case 0x0328: - case 0x0330: */ - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_MI0360; - sd->i2c_base = 0x5d; -/* break; - } */ - break; - case 0x0c45: /* Sonix */ - switch (product) { - case 0x6040: - sd->bridge = BRIDGE_SN9C102P; -/* sd->sensor = SENSOR_MI0360; * from BW600.inf */ -/*fixme: MI0360 base=5d ? */ - sd->sensor = SENSOR_HV7131R; /* gspcav1 value */ - sd->i2c_base = 0x11; - break; -/* case 0x607a: * from BW600.inf - sd->bridge = BRIDGE_SN9C102P; - sd->sensor = SENSOR_OV7648; - sd->i2c_base = 0x??; - break; */ - case 0x607c: - sd->bridge = BRIDGE_SN9C102P; - sd->sensor = SENSOR_HV7131R; - sd->i2c_base = 0x11; - break; -/* case 0x607e: * from BW600.inf - sd->bridge = BRIDGE_SN9C102P; - sd->sensor = SENSOR_OV7630; - sd->i2c_base = 0x??; - break; */ - case 0x60c0: - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_MI0360; - sd->i2c_base = 0x5d; - break; -/* case 0x60c8: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OM6801; - sd->i2c_base = 0x??; - break; */ -/* case 0x60cc: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_HV7131GP; - sd->i2c_base = 0x??; - break; */ - case 0x60ec: - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_MO4000; - sd->i2c_base = 0x21; - break; -/* case 0x60ef: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_ICM105C; - sd->i2c_base = 0x??; - break; */ -/* case 0x60fa: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OV7648; - sd->i2c_base = 0x??; - break; */ - case 0x60fb: - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OV7660; - sd->i2c_base = 0x21; - break; - case 0x60fc: - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_HV7131R; - sd->i2c_base = 0x11; - break; -/* case 0x60fe: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OV7630; - sd->i2c_base = 0x??; - break; */ -/* case 0x6108: * from BW600.inf - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_OM6801; - sd->i2c_base = 0x??; - break; */ -/* case 0x6122: * from BW600.inf - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_ICM105C; - sd->i2c_base = 0x??; - break; */ - case 0x612a: -/* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */ - sd->bridge = BRIDGE_SN9C325; - sd->sensor = SENSOR_OV7648; - sd->i2c_base = 0x21; -/*fixme: sensor_init has base = 00 et 6e!*/ - break; -/* case 0x6123: * from BW600.inf - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_SanyoCCD; - sd->i2c_base = 0x??; - break; */ - case 0x612c: - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_MO4000; - sd->i2c_base = 0x21; - break; -/* case 0x612e: * from BW600.inf - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_OV7630; - sd->i2c_base = 0x??; - break; */ -/* case 0x612f: * from BW600.inf - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_ICM105C; - sd->i2c_base = 0x??; - break; */ - case 0x6130: - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_MI0360; - sd->i2c_base = 0x5d; - break; - case 0x6138: - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_MO4000; - sd->i2c_base = 0x21; - break; -/* case 0x613a: * from BW600.inf - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_OV7648; - sd->i2c_base = 0x??; - break; */ - case 0x613b: - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_OV7660; - sd->i2c_base = 0x21; - break; - case 0x613c: - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_HV7131R; - sd->i2c_base = 0x11; - break; -/* case 0x613e: * from BW600.inf - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_OV7630; - sd->i2c_base = 0x??; - break; */ - } - break; - } - if (sd->sensor < 0) { - PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x", - id->idVendor, product); - return -EINVAL; - } cam = &gspca_dev->cam; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); + sd->bridge = id->driver_info >> 16; + sd->sensor = id->driver_info >> 8; + sd->i2c_base = id->driver_info; + sd->qindex = 4; /* set the quantization table */ sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; @@ -1617,29 +1442,51 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name +#define BSI(bridge, sensor, i2c_addr) \ + .driver_info = (BRIDGE_ ## bridge << 16) \ + | (SENSOR_ ## sensor << 8) \ + | (i2c_addr) static const __devinitdata struct usb_device_id device_table[] = { #ifndef CONFIG_USB_SN9C102 - {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")}, - {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")}, - {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")}, - {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")}, - {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")}, + {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, + {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, + {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, + {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, + {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, #endif - {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")}, - {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")}, - {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")}, - {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")}, - {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")}, - {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")}, - {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")}, - {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")}, - {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")}, + {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, + {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, +/* bw600.inf: + {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ +/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, +/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, +/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, + {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)}, +/* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)}, +/* bw600.inf: + {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */ + {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ #ifndef CONFIG_USB_SN9C102 - {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")}, - {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")}, - {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")}, - {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")}, + {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, + {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, + {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, +/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ #endif {} }; diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index 64461896d..09c89c1ac 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -644,108 +644,10 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x040a: /* Kodak cameras */ -/* switch (product) { */ -/* case 0x0300: */ - sd->subtype = KodakEZ200; -/* break; */ -/* } */ - break; - case 0x041e: /* Creative cameras */ -/* switch (product) { */ -/* case 0x400a: */ - sd->subtype = CreativePCCam300; -/* break; */ -/* } */ - break; - case 0x046d: /* Logitech Labtec */ - switch (product) { - case 0x0890: - sd->subtype = LogitechTraveler; - break; - case 0x0900: - sd->subtype = LogitechClickSmart310; - break; - case 0x0901: - sd->subtype = LogitechClickSmart510; - break; - } - break; - case 0x04a5: /* Benq */ -/* switch (product) { */ -/* case 0x300c: */ - sd->subtype = BenqDC1016; -/* break; */ -/* } */ - break; - case 0x04fc: /* SunPlus */ -/* switch (product) { */ -/* case 0x7333: */ - sd->subtype = PalmPixDC85; -/* break; */ -/* } */ - break; - case 0x055f: /* Mustek cameras */ - switch (product) { - case 0xc200: - sd->subtype = MustekGsmart300; - break; - case 0xc220: - sd->subtype = Gsmartmini; - break; - } - break; - case 0x06bd: /* Agfa Cl20 */ -/* switch (product) { */ -/* case 0x0404: */ - sd->subtype = AgfaCl20; -/* break; */ -/* } */ - break; - case 0x06be: /* Optimedia */ -/* switch (product) { */ -/* case 0x0800: */ - sd->subtype = Optimedia; -/* break; */ -/* } */ - break; - case 0x084d: /* D-Link / Minton */ -/* switch (product) { */ -/* case 0x0003: * DSC-350 / S-Cam F5 */ - sd->subtype = DLinkDSC350; -/* break; */ -/* } */ - break; - case 0x08ca: /* Aiptek */ -/* switch (product) { */ -/* case 0x0103: */ - sd->subtype = AiptekPocketDV; -/* break; */ -/* } */ - break; - case 0x2899: /* ToptroIndustrial */ -/* switch (product) { */ -/* case 0x012c: */ - sd->subtype = ToptroIndus; -/* break; */ -/* } */ - break; - case 0x8086: /* Intel */ -/* switch (product) { */ -/* case 0x0630: * Pocket PC Camera */ - sd->subtype = IntelPocketPCCamera; -/* break; */ -/* } */ - break; - } + cam = &gspca_dev->cam; cam->epaddr = 0x01; + sd->subtype = id->driver_info; if (sd->subtype != LogitechClickSmart310) { cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; @@ -1175,23 +1077,22 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")}, - {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")}, - {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")}, - {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")}, - {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")}, - {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")}, - {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")}, - {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")}, - {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")}, - {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")}, - {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")}, - {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")}, - {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")}, - {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")}, - {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")}, + {USB_DEVICE(0x040a, 0x0300), KodakEZ200}, + {USB_DEVICE(0x041e, 0x400a), CreativePCCam300}, + {USB_DEVICE(0x046d, 0x0890), LogitechTraveler}, + {USB_DEVICE(0x046d, 0x0900), LogitechClickSmart310}, + {USB_DEVICE(0x046d, 0x0901), LogitechClickSmart510}, + {USB_DEVICE(0x04a5, 0x300c), BenqDC1016}, + {USB_DEVICE(0x04fc, 0x7333), PalmPixDC85}, + {USB_DEVICE(0x055f, 0xc200), MustekGsmart300}, + {USB_DEVICE(0x055f, 0xc220), Gsmartmini}, + {USB_DEVICE(0x06bd, 0x0404), AgfaCl20}, + {USB_DEVICE(0x06be, 0x0800), Optimedia}, + {USB_DEVICE(0x084d, 0x0003), DLinkDSC350}, + {USB_DEVICE(0x08ca, 0x0103), AiptekPocketDV}, + {USB_DEVICE(0x2899, 0x012c), ToptroIndus}, + {USB_DEVICE(0x8086, 0x0630), IntelPocketPCCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c index cd496140c..8444c7c58 100644 --- a/linux/drivers/media/video/gspca/spca501.c +++ b/linux/drivers/media/video/gspca/spca501.c @@ -1931,62 +1931,12 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x0000: /* Unknow Camera */ -/* switch (product) { */ -/* case 0x0000: */ - sd->subtype = MystFromOriUnknownCamera; -/* break; */ -/* } */ - break; - case 0x040a: /* Kodak cameras */ -/* switch (product) { */ -/* case 0x0002: */ - sd->subtype = KodakDVC325; -/* break; */ -/* } */ - break; - case 0x0497: /* Smile International */ -/* switch (product) { */ -/* case 0xc001: */ - sd->subtype = SmileIntlCamera; -/* break; */ -/* } */ - break; - case 0x0506: /* 3COM cameras */ -/* switch (product) { */ -/* case 0x00df: */ - sd->subtype = ThreeComHomeConnectLite; -/* break; */ -/* } */ - break; - case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ - switch (product) { - case 0x0401: - sd->subtype = IntelCreateAndShare; - break; - case 0x0402: - sd->subtype = ViewQuestM318B; - break; - } - break; - case 0x1776: /* Arowana */ -/* switch (product) { */ -/* case 0x501c: */ - sd->subtype = Arowana300KCMOSCamera; -/* break; */ -/* } */ - break; - } + cam = &gspca_dev->cam; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + sd->subtype = id->driver_info; sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; @@ -2190,15 +2140,14 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")}, - {USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")}, - {USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")}, - {USB_DEVICE(0x0733, 0x0401), DVNM("Intel Create and Share")}, - {USB_DEVICE(0x0733, 0x0402), DVNM("ViewQuest M318B")}, - {USB_DEVICE(0x1776, 0x501c), DVNM("Arowana 300K CMOS Camera")}, - {USB_DEVICE(0x0000, 0x0000), DVNM("MystFromOri Unknow Camera")}, + {USB_DEVICE(0x040a, 0x0002), KodakDVC325}, + {USB_DEVICE(0x0497, 0xc001), SmileIntlCamera}, + {USB_DEVICE(0x0506, 0x00df), ThreeComHomeConnectLite}, + {USB_DEVICE(0x0733, 0x0401), IntelCreateAndShare}, + {USB_DEVICE(0x0733, 0x0402), ViewQuestM318B}, + {USB_DEVICE(0x1776, 0x501c), Arowana300KCMOSCamera}, + {USB_DEVICE(0x0000, 0x0000), MystFromOriUnknownCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index 7dd5432a7..4d84883fa 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -707,32 +707,11 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x041e: /* Creative cameras */ -/* switch (product) { */ -/* case 0x401d: * here505b */ - sd->subtype = Nxultra; -/* break; */ -/* } */ - break; - case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ -/* switch (product) { */ -/* case 0x0430: */ -/* fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ - sd->subtype = IntelPCCameraPro; -/* break; */ -/* } */ - break; - } cam = &gspca_dev->cam; cam->epaddr = 0x01; cam->cam_mode = vga_mode; + sd->subtype = id->driver_info; if (sd->subtype != IntelPCCameraPro) cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; else /* no 640x480 for IntelPCCameraPro */ @@ -975,10 +954,10 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")}, - {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")}, + {USB_DEVICE(0x041e, 0x401d), Nxultra}, + {USB_DEVICE(0x0733, 0x0430), IntelPCCameraPro}, +/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index 36dc13c11..2c281a056 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -800,12 +800,12 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x06e1, 0xa190), DVNM("ADS Instant VCD")}, -/* {USB_DEVICE(0x0733, 0x0430), DVNM("UsbGrabber PV321c")}, */ - {USB_DEVICE(0x0734, 0x043b), DVNM("3DeMon USB Capture aka")}, - {USB_DEVICE(0x99fa, 0x8988), DVNM("Grandtec V.cap")}, + {USB_DEVICE(0x06e1, 0xa190)}, +/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 + {USB_DEVICE(0x0733, 0x0430)}, */ + {USB_DEVICE(0x0734, 0x043b)}, + {USB_DEVICE(0x99fa, 0x8988)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index b449022aa..cac6471e9 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1511,58 +1511,8 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 product; int data1, data2; - product = id->idProduct; - switch (id->idVendor) { - case 0x0130: /* Clone webcam */ -/* switch (product) { */ -/* case 0x0130: */ - sd->subtype = HamaUSBSightcam; /* same as Hama 0010 */ -/* break; */ -/* } */ - break; - case 0x041e: /* Creative cameras */ -/* switch (product) { */ -/* case 0x4018: */ - sd->subtype = CreativeVista; -/* break; */ -/* } */ - break; - case 0x0461: /* MicroInnovation */ -/* switch (product) { */ -/* case 0x0815: */ - sd->subtype = MicroInnovationIC200; -/* break; */ -/* } */ - break; - case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ -/* switch (product) { */ -/* case 0x110: */ - sd->subtype = ViewQuestVQ110; -/* break; */ -/* } */ - break; - case 0x0af9: /* Hama cameras */ - switch (product) { - case 0x0010: - sd->subtype = HamaUSBSightcam; - break; - case 0x0011: - sd->subtype = HamaUSBSightcam2; - break; - } - break; - case 0x8086: /* Intel */ -/* switch (product) { */ -/* case 0x0110: */ - sd->subtype = IntelEasyPCCamera; -/* break; */ -/* } */ - break; - } - /* Read from global register the USB product and vendor IDs, just to * prove that we can communicate with the device. This works, which * confirms at we are communicating properly and that the device @@ -1582,6 +1532,8 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->epaddr = 0x01; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); + + sd->subtype = id->driver_info; sd->brightness = BRIGHTNESS_DEF; switch (sd->subtype) { @@ -1779,15 +1731,14 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x0130, 0x0130), DVNM("Clone Digital Webcam 11043")}, - {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")}, - {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")}, - {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")}, - {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")}, - {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")}, - {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")}, + {USB_DEVICE(0x0130, 0x0130), HamaUSBSightcam}, + {USB_DEVICE(0x041e, 0x4018), CreativeVista}, + {USB_DEVICE(0x0461, 0x0815), MicroInnovationIC200}, + {USB_DEVICE(0x0733, 0x0110), ViewQuestVQ110}, + {USB_DEVICE(0x0af9, 0x0010), HamaUSBSightcam}, + {USB_DEVICE(0x0af9, 0x0011), HamaUSBSightcam2}, + {USB_DEVICE(0x8086, 0x0110), IntelEasyPCCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 85c37f396..3b46f7dda 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -579,35 +579,15 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Bad vendor / product from device"); return -EINVAL; } - switch (product) { - case 0x0928: - case 0x0929: - case 0x092a: - case 0x092b: - case 0x092c: - case 0x092d: - case 0x092e: - case 0x092f: - case 0x403b: - sd->chip_revision = Rev012A; - break; - default: -/* case 0x0561: - case 0x0815: * ?? in spca508.c - case 0x401a: - case 0x7004: - case 0x7e50: - case 0xa001: - case 0xcdee: */ - sd->chip_revision = Rev072A; - break; - } + cam = &gspca_dev->cam; cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + + sd->chip_revision = id->driver_info; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; @@ -994,23 +974,22 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")}, - {USB_DEVICE(0x041e, 0x403b), DVNM("Creative Webcam Vista (VF0010)")}, - {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")}, - {USB_DEVICE(0x046d, 0x0928), DVNM("Logitech QC Express Etch2")}, - {USB_DEVICE(0x046d, 0x0929), DVNM("Labtec Webcam Elch2")}, - {USB_DEVICE(0x046d, 0x092a), DVNM("Logitech QC for Notebook")}, - {USB_DEVICE(0x046d, 0x092b), DVNM("Labtec Webcam Plus")}, - {USB_DEVICE(0x046d, 0x092c), DVNM("Logitech QC chat Elch2")}, - {USB_DEVICE(0x046d, 0x092d), DVNM("Logitech QC Elch2")}, - {USB_DEVICE(0x046d, 0x092e), DVNM("Logitech QC Elch2")}, - {USB_DEVICE(0x046d, 0x092f), DVNM("Logitech QC Elch2")}, - {USB_DEVICE(0x04fc, 0x0561), DVNM("Flexcam 100")}, - {USB_DEVICE(0x060b, 0xa001), DVNM("Maxell Compact Pc PM3")}, - {USB_DEVICE(0x10fd, 0x7e50), DVNM("FlyCam Usb 100")}, - {USB_DEVICE(0xabcd, 0xcdee), DVNM("Petcam")}, + {USB_DEVICE(0x041e, 0x401a), Rev072A}, + {USB_DEVICE(0x041e, 0x403b), Rev012A}, + {USB_DEVICE(0x0458, 0x7004), Rev072A}, + {USB_DEVICE(0x046d, 0x0928), Rev012A}, + {USB_DEVICE(0x046d, 0x0929), Rev012A}, + {USB_DEVICE(0x046d, 0x092a), Rev012A}, + {USB_DEVICE(0x046d, 0x092b), Rev012A}, + {USB_DEVICE(0x046d, 0x092c), Rev012A}, + {USB_DEVICE(0x046d, 0x092d), Rev012A}, + {USB_DEVICE(0x046d, 0x092e), Rev012A}, + {USB_DEVICE(0x046d, 0x092f), Rev012A}, + {USB_DEVICE(0x04fc, 0x0561), Rev072A}, + {USB_DEVICE(0x060b, 0xa001), Rev072A}, + {USB_DEVICE(0x10fd, 0x7e50), Rev072A}, + {USB_DEVICE(0xabcd, 0xcdee), Rev072A}, {} }; diff --git a/linux/drivers/media/video/gspca/stk014.c b/linux/drivers/media/video/gspca/stk014.c index f6390b49f..16219cf6a 100644 --- a/linux/drivers/media/video/gspca/stk014.c +++ b/linux/drivers/media/video/gspca/stk014.c @@ -545,9 +545,8 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")}, + {USB_DEVICE(0x05e1, 0x0893)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/sunplus.c b/linux/drivers/media/video/gspca/sunplus.c index 533435a54..8701b07c8 100644 --- a/linux/drivers/media/video/gspca/sunplus.c +++ b/linux/drivers/media/video/gspca/sunplus.c @@ -832,228 +832,29 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; struct cam *cam; - __u16 vendor; - __u16 product; - __u8 fw; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x041e: /* Creative cameras */ -/* switch (product) { */ -/* case 0x400b: */ -/* case 0x4012: */ -/* case 0x4013: */ -/* sd->bridge = BRIDGE_SPCA504C; */ -/* break; */ -/* } */ - break; - case 0x0458: /* Genius KYE cameras */ -/* switch (product) { */ -/* case 0x7006: */ - sd->bridge = BRIDGE_SPCA504B; -/* break; */ -/* } */ - break; - case 0x0461: /* MicroInnovation */ -/* switch (product) { */ -/* case 0x0821: */ - sd->bridge = BRIDGE_SPCA533; -/* break; */ -/* } */ - break; - case 0x046d: /* Logitech Labtec */ - switch (product) { - case 0x0905: - sd->subtype = LogitechClickSmart820; - sd->bridge = BRIDGE_SPCA533; - break; - case 0x0960: - sd->subtype = LogitechClickSmart420; - sd->bridge = BRIDGE_SPCA504C; - break; - } - break; - case 0x0471: /* Philips */ -/* switch (product) { */ -/* case 0x0322: */ - sd->bridge = BRIDGE_SPCA504B; -/* break; */ -/* } */ - break; - case 0x04a5: /* Benq */ - switch (product) { - case 0x3003: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x3008: - case 0x300a: - sd->bridge = BRIDGE_SPCA533; - break; - } - break; - case 0x04f1: /* JVC */ -/* switch (product) { */ -/* case 0x1001: */ - sd->bridge = BRIDGE_SPCA504B; -/* break; */ -/* } */ - break; - case 0x04fc: /* SunPlus */ - switch (product) { - case 0x500c: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x504a: + + cam = &gspca_dev->cam; + cam->epaddr = 0x01; + + sd->bridge = id->driver_info >> 8; + sd->subtype = id->driver_info; + + if (sd->subtype == AiptekMiniPenCam13) { /* try to get the firmware as some cam answer 2.0.1.2.2 * and should be a spca504b then overwrite that setting */ - reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1); - fw = gspca_dev->usb_buf[0]; - if (fw == 1) { - sd->subtype = AiptekMiniPenCam13; - sd->bridge = BRIDGE_SPCA504; - } else if (fw == 2) { - sd->bridge = BRIDGE_SPCA504B; - } else - return -ENODEV; - break; - case 0x504b: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x5330: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x5360: - sd->bridge = BRIDGE_SPCA536; - break; - case 0xffff: - sd->bridge = BRIDGE_SPCA504B; - break; - } - break; - case 0x052b: /* ?? Megapix */ -/* switch (product) { */ -/* case 0x1513: */ - sd->subtype = MegapixV4; - sd->bridge = BRIDGE_SPCA533; -/* break; */ -/* } */ - break; - case 0x0546: /* Polaroid */ - switch (product) { - case 0x3155: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x3191: - case 0x3273: + reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1); + switch (gspca_dev->usb_buf[0]) { + case 1: + break; /* (right bridge/subtype) */ + case 2: sd->bridge = BRIDGE_SPCA504B; + sd->subtype = 0; break; + default: + return -ENODEV; } - break; - case 0x055f: /* Mustek cameras */ - switch (product) { - case 0xc211: - sd->bridge = BRIDGE_SPCA536; - break; - case 0xc230: - case 0xc232: - sd->bridge = BRIDGE_SPCA533; - break; - case 0xc360: - sd->bridge = BRIDGE_SPCA536; - break; - case 0xc420: - sd->bridge = BRIDGE_SPCA504; - break; - case 0xc430: - case 0xc440: - sd->bridge = BRIDGE_SPCA533; - break; - case 0xc520: - sd->bridge = BRIDGE_SPCA504; - break; - case 0xc530: - case 0xc540: - case 0xc630: - case 0xc650: - sd->bridge = BRIDGE_SPCA533; - break; - } - break; - case 0x05da: /* Digital Dream cameras */ -/* switch (product) { */ -/* case 0x1018: */ - sd->bridge = BRIDGE_SPCA504B; -/* break; */ -/* } */ - break; - case 0x06d6: /* Trust */ -/* switch (product) { */ -/* case 0x0031: */ - sd->bridge = BRIDGE_SPCA533; /* SPCA533A */ -/* break; */ -/* } */ - break; - case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ - switch (product) { - case 0x1311: - case 0x1314: - case 0x2211: - case 0x2221: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x3261: - case 0x3281: - sd->bridge = BRIDGE_SPCA536; - break; - } - break; - case 0x08ca: /* Aiptek */ - switch (product) { - case 0x0104: - case 0x0106: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x2008: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x2010: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x2016: - case 0x2018: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x2020: - case 0x2022: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x2024: - sd->bridge = BRIDGE_SPCA536; - break; - case 0x2028: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x2040: - case 0x2042: - case 0x2050: - case 0x2060: - sd->bridge = BRIDGE_SPCA536; - break; - } - break; - case 0x0d64: /* SunPlus */ -/* switch (product) { */ -/* case 0x0303: */ - sd->bridge = BRIDGE_SPCA536; -/* break; */ -/* } */ - break; } - cam = &gspca_dev->cam; - cam->epaddr = 0x01; - switch (sd->bridge) { default: /* case BRIDGE_SPCA504B: */ @@ -1608,65 +1409,67 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name +#define BS(bridge, subtype) \ + .driver_info = (BRIDGE_ ## bridge << 8) \ + | (subtype) static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")}, - {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")}, - {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")}, - {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")}, - {USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")}, - {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")}, - {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")}, - {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")}, - {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")}, - {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")}, - {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")}, - {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")}, - {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")}, - {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")}, - {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")}, - {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")}, - {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")}, - {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")}, - {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")}, - {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")}, - {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")}, - {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")}, - {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")}, - {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")}, - {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")}, - {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")}, - {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")}, - {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")}, - {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")}, - {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")}, - {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")}, - {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")}, - {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")}, - {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")}, - {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")}, - {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")}, - {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")}, - {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")}, - {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")}, - {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")}, - {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")}, - {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")}, - {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")}, - {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")}, - {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")}, - {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")}, - {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")}, - {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")}, - {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")}, - {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")}, - {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")}, - {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")}, - {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")}, - {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")}, - {USB_DEVICE(0x08ca, 0x2050), DVNM("Medion MD 41437")}, - {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")}, - {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")}, + {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)}, + {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)}, + {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)}, + {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)}, + {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)}, + {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)}, + {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)}, + {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)}, + {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)}, + {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)}, + {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)}, + {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)}, + {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)}, + {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)}, + {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)}, + {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)}, + {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)}, + {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)}, + {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)}, + {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)}, + {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)}, + {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)}, + {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)}, + {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)}, + {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)}, + {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)}, + {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)}, + {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)}, + {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 9a0f55e13..56b1dfa72 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -420,19 +420,6 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; -#if 0 - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x17a1: - /* t613 + tas5130A */ - /* Currently one sensor supported... */ - break; - } -#endif cam = &gspca_dev->cam; cam->epaddr = 0x01; @@ -1031,9 +1018,8 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")}, + {USB_DEVICE(0x17a1, 0x0128)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c index c4f039c33..fcac077bb 100644 --- a/linux/drivers/media/video/gspca/tv8532.c +++ b/linux/drivers/media/video/gspca/tv8532.c @@ -629,13 +629,12 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")}, - {USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")}, - {USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")}, - {USB_DEVICE(0x0545, 0x8333), DVNM("Veo Stingray")}, - {USB_DEVICE(0x0923, 0x010f), DVNM("ICM532 cams")}, + {USB_DEVICE(0x046d, 0x0920)}, + {USB_DEVICE(0x046d, 0x0921)}, + {USB_DEVICE(0x0545, 0x808b)}, + {USB_DEVICE(0x0545, 0x8333)}, + {USB_DEVICE(0x0923, 0x010f)}, {} }; diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 9510e1bb7..a83944228 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -1596,29 +1596,10 @@ static int sd_config(struct gspca_dev *gspca_dev, struct usb_device *dev = gspca_dev->dev; struct cam *cam; int sensor; - __u16 product; - - product = id->idProduct; - sd->bridge = BRIDGE_VC0321; - switch (id->idVendor) { - case 0x0ac8: /* Vimicro z-star */ - switch (product) { - case 0x0323: - sd->bridge = BRIDGE_VC0323; - break; - } - break; - case 0x17ef: /* Lenovo */ -/* switch (product) { */ -/* case 0x4802: * Lenovo MI1310_SOC */ - sd->bridge = BRIDGE_VC0323; -/* break; */ -/* } */ - break; - } cam = &gspca_dev->cam; cam->epaddr = 0x02; + sd->bridge = id->driver_info; if (sd->bridge == BRIDGE_VC0321) { cam->cam_mode = vc0321_mode; cam->nmodes = ARRAY_SIZE(vc0321_mode); @@ -1964,16 +1945,15 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")}, - {USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")}, - {USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")}, - {USB_DEVICE(0x0ac8, 0x0323), DVNM("Vimicro Vc0323")}, - {USB_DEVICE(0x0ac8, 0x0328), DVNM("A4Tech PK-130MG")}, - {USB_DEVICE(0x0ac8, 0xc001), DVNM("Sony embedded vimicro")}, - {USB_DEVICE(0x0ac8, 0xc002), DVNM("Sony embedded vimicro")}, - {USB_DEVICE(0x17ef, 0x4802), DVNM("Lenovo Vc0323+MI1310_SOC")}, + {USB_DEVICE(0x046d, 0x0892), BRIDGE_VC0321}, + {USB_DEVICE(0x046d, 0x0896), BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0x0321), BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0x0323), BRIDGE_VC0323}, + {USB_DEVICE(0x0ac8, 0x0328), BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0xc001), BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0xc002), BRIDGE_VC0321}, + {USB_DEVICE(0x17ef, 0x4802), BRIDGE_VC0323}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 3633c30bc..ff68e16aa 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7017,31 +7017,7 @@ static int sd_config(struct gspca_dev *gspca_dev, /* define some sensors from the vendor/product */ sd->sharpness = 2; - sd->sensor = -1; - switch (id->idVendor) { - case 0x041e: /* Creative */ - switch (id->idProduct) { - case 0x4051: /* zc301 chips */ - case 0x4053: - sd->sensor = SENSOR_TAS5130C_VF0250; - break; - } - break; - case 0x046d: /* Logitech Labtec */ - switch (id->idProduct) { - case 0x08dd: - sd->sensor = SENSOR_MC501CB; - break; - } - break; - case 0x0ac8: /* Vimicro z-star */ - switch (id->idProduct) { - case 0x305b: - sd->sensor = SENSOR_TAS5130C_VF0250; - break; - } - break; - } + sd->sensor = id->driver_info; sensor = zcxx_probeSensor(gspca_dev); if (sensor >= 0) PDEBUG(D_PROBE, "probe sensor -> %02x", sensor); @@ -7534,70 +7510,69 @@ static const struct sd_desc sd_desc = { .querymenu = sd_querymenu, }; -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")}, + {USB_DEVICE(0x041e, 0x041e)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")}, - {USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")}, - {USB_DEVICE(0x041e, 0x401e), DVNM("Creative Nx Pro")}, - {USB_DEVICE(0x041e, 0x401f), DVNM("Creative Webcam Notebook PD1171")}, + {USB_DEVICE(0x041e, 0x4017)}, + {USB_DEVICE(0x041e, 0x401c)}, + {USB_DEVICE(0x041e, 0x401e)}, + {USB_DEVICE(0x041e, 0x401f)}, #endif - {USB_DEVICE(0x041e, 0x4029), DVNM("Creative WebCam Vista Pro")}, + {USB_DEVICE(0x041e, 0x4029)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x041e, 0x4034), DVNM("Creative Instant P0620")}, - {USB_DEVICE(0x041e, 0x4035), DVNM("Creative Instant P0620D")}, - {USB_DEVICE(0x041e, 0x4036), DVNM("Creative Live !")}, - {USB_DEVICE(0x041e, 0x403a), DVNM("Creative Nx Pro 2")}, + {USB_DEVICE(0x041e, 0x4034)}, + {USB_DEVICE(0x041e, 0x4035)}, + {USB_DEVICE(0x041e, 0x4036)}, + {USB_DEVICE(0x041e, 0x403a)}, #endif - {USB_DEVICE(0x041e, 0x4051), DVNM("Creative Notebook Pro (VF0250)")}, - {USB_DEVICE(0x041e, 0x4053), DVNM("Creative Live!Cam Video IM")}, + {USB_DEVICE(0x041e, 0x4051), SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x041e, 0x4053), SENSOR_TAS5130C_VF0250}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x0458, 0x7007), DVNM("Genius VideoCam V2")}, - {USB_DEVICE(0x0458, 0x700c), DVNM("Genius VideoCam V3")}, - {USB_DEVICE(0x0458, 0x700f), DVNM("Genius VideoCam Web V2")}, + {USB_DEVICE(0x0458, 0x7007)}, + {USB_DEVICE(0x0458, 0x700c)}, + {USB_DEVICE(0x0458, 0x700f)}, #endif - {USB_DEVICE(0x0461, 0x0a00), DVNM("MicroInnovation WebCam320")}, - {USB_DEVICE(0x046d, 0x08a0), DVNM("Logitech QC IM")}, - {USB_DEVICE(0x046d, 0x08a1), DVNM("Logitech QC IM 0x08A1 +sound")}, - {USB_DEVICE(0x046d, 0x08a2), DVNM("Labtec Webcam Pro")}, - {USB_DEVICE(0x046d, 0x08a3), DVNM("Logitech QC Chat")}, - {USB_DEVICE(0x046d, 0x08a6), DVNM("Logitech QCim")}, - {USB_DEVICE(0x046d, 0x08a7), DVNM("Logitech QuickCam Image")}, - {USB_DEVICE(0x046d, 0x08a9), DVNM("Logitech Notebook Deluxe")}, - {USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")}, - {USB_DEVICE(0x046d, 0x08ac), DVNM("Logitech QuickCam Cool")}, - {USB_DEVICE(0x046d, 0x08ad), DVNM("Logitech QCCommunicate STX")}, + {USB_DEVICE(0x0461, 0x0a00)}, + {USB_DEVICE(0x046d, 0x08a0)}, + {USB_DEVICE(0x046d, 0x08a1)}, + {USB_DEVICE(0x046d, 0x08a2)}, + {USB_DEVICE(0x046d, 0x08a3)}, + {USB_DEVICE(0x046d, 0x08a6)}, + {USB_DEVICE(0x046d, 0x08a7)}, + {USB_DEVICE(0x046d, 0x08a9)}, + {USB_DEVICE(0x046d, 0x08aa)}, + {USB_DEVICE(0x046d, 0x08ac)}, + {USB_DEVICE(0x046d, 0x08ad)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x046d, 0x08ae), DVNM("Logitech QuickCam for Notebooks")}, + {USB_DEVICE(0x046d, 0x08ae)}, #endif - {USB_DEVICE(0x046d, 0x08af), DVNM("Logitech QuickCam Cool")}, - {USB_DEVICE(0x046d, 0x08b9), DVNM("Logitech QC IM ???")}, - {USB_DEVICE(0x046d, 0x08d7), DVNM("Logitech QCam STX")}, - {USB_DEVICE(0x046d, 0x08d9), DVNM("Logitech QuickCam IM/Connect")}, - {USB_DEVICE(0x046d, 0x08d8), DVNM("Logitech Notebook Deluxe")}, - {USB_DEVICE(0x046d, 0x08da), DVNM("Logitech QuickCam Messenger")}, - {USB_DEVICE(0x046d, 0x08dd), DVNM("Logitech QuickCam for Notebooks")}, - {USB_DEVICE(0x0471, 0x0325), DVNM("Philips SPC 200 NC")}, - {USB_DEVICE(0x0471, 0x0326), DVNM("Philips SPC 300 NC")}, - {USB_DEVICE(0x0471, 0x032d), DVNM("Philips spc210nc")}, - {USB_DEVICE(0x0471, 0x032e), DVNM("Philips spc315nc")}, - {USB_DEVICE(0x055f, 0xc005), DVNM("Mustek Wcam300A")}, + {USB_DEVICE(0x046d, 0x08af)}, + {USB_DEVICE(0x046d, 0x08b9)}, + {USB_DEVICE(0x046d, 0x08d7)}, + {USB_DEVICE(0x046d, 0x08d9)}, + {USB_DEVICE(0x046d, 0x08d8)}, + {USB_DEVICE(0x046d, 0x08da)}, + {USB_DEVICE(0x046d, 0x08dd), SENSOR_MC501CB}, + {USB_DEVICE(0x0471, 0x0325)}, + {USB_DEVICE(0x0471, 0x0326)}, + {USB_DEVICE(0x0471, 0x032d)}, + {USB_DEVICE(0x0471, 0x032e)}, + {USB_DEVICE(0x055f, 0xc005)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x055f, 0xd003), DVNM("Mustek WCam300A")}, - {USB_DEVICE(0x055f, 0xd004), DVNM("Mustek WCam300 AN")}, + {USB_DEVICE(0x055f, 0xd003)}, + {USB_DEVICE(0x055f, 0xd004)}, #endif - {USB_DEVICE(0x0698, 0x2003), DVNM("CTX M730V built in")}, - {USB_DEVICE(0x0ac8, 0x0302), DVNM("Z-star Vimicro zc0302")}, + {USB_DEVICE(0x0698, 0x2003)}, + {USB_DEVICE(0x0ac8, 0x0302)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x0ac8, 0x301b), DVNM("Z-Star zc301b")}, - {USB_DEVICE(0x0ac8, 0x303b), DVNM("Vimicro 0x303b")}, + {USB_DEVICE(0x0ac8, 0x301b)}, + {USB_DEVICE(0x0ac8, 0x303b)}, #endif - {USB_DEVICE(0x0ac8, 0x305b), DVNM("Z-star Vimicro zc0305b")}, + {USB_DEVICE(0x0ac8, 0x305b), SENSOR_TAS5130C_VF0250}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x0ac8, 0x307b), DVNM("Z-Star 307b")}, - {USB_DEVICE(0x10fd, 0x0128), DVNM("Typhoon Webshot II 300k 0x0128")}, - {USB_DEVICE(0x10fd, 0x8050), DVNM("Typhoon Webshot II USB 300k")}, + {USB_DEVICE(0x0ac8, 0x307b)}, + {USB_DEVICE(0x10fd, 0x0128)}, + {USB_DEVICE(0x10fd, 0x8050)}, #endif {} /* end of entry */ }; -- cgit v1.2.3 From 4e47a6a81e12b9e49561c88bd1c2dce9c7d565d5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 27 Jul 2008 21:37:23 +0200 Subject: v4l2-ioctl: do not try to handle private V4L1 ioctls From: Hans Verkuil Some drivers (e.g. zoran) have private V4L1 ioctls. Do not try to pass them to v4l1_compat_translate because then the driver will never see them. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-ioctl.c b/linux/drivers/media/video/v4l2-ioctl.c index a56e3643b..1c8fa257d 100644 --- a/linux/drivers/media/video/v4l2-ioctl.c +++ b/linux/drivers/media/video/v4l2-ioctl.c @@ -675,7 +675,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, __video_do_ioctl will be called again, with one or more V4L2 ioctls. ********************************************************/ - if (_IOC_TYPE(cmd) == 'v') + if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE) return v4l_compat_translate_ioctl(inode, file, cmd, arg, __video_do_ioctl); #endif -- cgit v1.2.3 From 8dcba258bfae4be17ed5beb7a53d746075789e4f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 Jul 2008 15:31:23 +0200 Subject: First mxb cleanup phase From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/drivers/media/video/mxb.c | 13 ++- linux/drivers/media/video/tda9840.c | 170 +++++++++++++---------------------- linux/drivers/media/video/tea6415c.c | 135 +++++++++------------------- linux/drivers/media/video/tea6420.c | 151 ++++++++++++------------------- 4 files changed, 167 insertions(+), 302 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c index bf2462a58..974505a9e 100644 --- a/linux/drivers/media/video/mxb.c +++ b/linux/drivers/media/video/mxb.c @@ -467,15 +467,15 @@ static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data /* checking for i2c-devices can be omitted here, because we already did this in "mxb_vl42_probe" */ - saa7146_vv_init(dev,&vv_data); - if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { + saa7146_vv_init(dev, &vv_data); + if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { ERR(("cannot register capture v4l2 device. skipping.\n")); return -1; } /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ - if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) { - if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { + if (MXB_BOARD_CAN_DO_VBI(dev)) { + if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { ERR(("cannot register vbi v4l2 device. skipping.\n")); } } @@ -487,7 +487,7 @@ static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data i2c_use_client(mxb->saa7111a); i2c_use_client(mxb->tuner); - printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num); + printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num); mxb_num++; mxb_init_done(dev); @@ -738,8 +738,8 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); memset(t,0,sizeof(*t)); - strcpy(t->name, "Television"); + strlcpy(t->name, "Television", sizeof(t->name)); t->type = V4L2_TUNER_ANALOG_TV; t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ @@ -747,7 +747,6 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) /* FIXME: add the real signal strength here */ t->signal = 0xffff; t->afc = 0; - mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte); t->audmode = mxb->cur_mode; diff --git a/linux/drivers/media/video/tda9840.c b/linux/drivers/media/video/tda9840.c index f4ebfd84b..2d3d430c5 100644 --- a/linux/drivers/media/video/tda9840.c +++ b/linux/drivers/media/video/tda9840.c @@ -2,6 +2,7 @@ tda9840 - i2c-driver for the tda9840 by SGS Thomson Copyright (C) 1998-2003 Michael Hunold + Copyright (C) 2008 Hans Verkuil The tda9840 is a stereo/dual sound processor with digital identification. It can be found at address 0x84 on the i2c-bus. @@ -28,16 +29,19 @@ #include #include #include +#include +#include +#include "tda9840.h" #include "compat.h" -#include "tda9840.h" +MODULE_AUTHOR("Michael Hunold "); +MODULE_DESCRIPTION("tda9840 driver"); +MODULE_LICENSE("GPL"); -static int debug; /* insmod parameter */ +static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); -#define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) +MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define SWITCH 0x00 #define LEVEL_ADJUST 0x02 @@ -50,18 +54,21 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; -static struct i2c_driver driver; -static struct i2c_client client_template; +static void tda9840_write(struct i2c_client *client, u8 reg, u8 val) +{ + if (i2c_smbus_write_byte_data(client, reg, val)) + v4l_dbg(1, debug, client, "error writing %02x to %02x\n", + val, reg); +} -static int command(struct i2c_client *client, unsigned int cmd, void *arg) +static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) { int result; int byte = *(int *)arg; switch (cmd) { case TDA9840_SWITCH: - - dprintk("TDA9840_SWITCH: 0x%02x\n", byte); + v4l_dbg(1, debug, client, "TDA9840_SWITCH: 0x%02x\n", byte); if (byte != TDA9840_SET_MONO && byte != TDA9840_SET_MUTE @@ -74,14 +81,11 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) return -EINVAL; } - result = i2c_smbus_write_byte_data(client, SWITCH, byte); - if (result) - dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + tda9840_write(client, SWITCH, byte); break; case TDA9840_LEVEL_ADJUST: - - dprintk("TDA9840_LEVEL_ADJUST: %d\n", byte); + v4l_dbg(1, debug, client, "TDA9840_LEVEL_ADJUST: %d\n", byte); /* check for correct range */ if (byte > 25 || byte < -20) @@ -93,15 +97,11 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) byte += 0x8; else byte = -byte; - - result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte); - if (result) - dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + tda9840_write(client, LEVEL_ADJUST, byte); break; case TDA9840_STEREO_ADJUST: - - dprintk("TDA9840_STEREO_ADJUST: %d\n", byte); + v4l_dbg(1, debug, client, "TDA9840_STEREO_ADJUST: %d\n", byte); /* check for correct range */ if (byte > 25 || byte < -24) @@ -114,9 +114,7 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) else byte = -byte; - result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte); - if (result) - dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + tda9840_write(client, STEREO_ADJUST, byte); break; case TDA9840_DETECT: { @@ -124,29 +122,29 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST); if (byte == -1) { - dprintk("i2c_smbus_read_byte_data() failed\n"); + v4l_dbg(1, debug, client, + "i2c_smbus_read_byte_data() failed\n"); return -EIO; } - if (0 != (byte & 0x80)) { - dprintk("TDA9840_DETECT: register contents invalid\n"); + if (byte & 0x80) { + v4l_dbg(1, debug, client, + "TDA9840_DETECT: register contents invalid\n"); return -EINVAL; } - dprintk("TDA9840_DETECT: byte: 0x%02x\n", byte); - *ret = ((byte & 0x60) >> 5); + v4l_dbg(1, debug, client, "TDA9840_DETECT: byte: 0x%02x\n", byte); + *ret = (byte & 0x60) >> 5; result = 0; break; } case TDA9840_TEST: - dprintk("TDA9840_TEST: 0x%02x\n", byte); + v4l_dbg(1, debug, client, "TDA9840_TEST: 0x%02x\n", byte); /* mask out irrelevant bits */ byte &= 0x3; - result = i2c_smbus_write_byte_data(client, TEST, byte); - if (result) - dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + tda9840_write(client, TEST, byte); break; default: return -ENOIOCTLCMD; @@ -158,99 +156,55 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int detect(struct i2c_adapter *adapter, int address, int kind) +static int tda9840_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - struct i2c_client *client; - int result = 0; - - int byte = 0x0; + int result; + int byte; /* let's see whether this adapter can support what we need */ - if (0 == i2c_check_functionality(adapter, - I2C_FUNC_SMBUS_READ_BYTE_DATA | - I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA | + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return 0; - } - /* allocate memory for client structure */ - client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) { - printk("not enough kernel memory\n"); - return -ENOMEM; - } - - /* fill client structure */ - memcpy(client, &client_template, sizeof(struct i2c_client)); - client->addr = address; - client->adapter = adapter; - - /* tell the i2c layer a new client has arrived */ - if (0 != (result = i2c_attach_client(client))) { - kfree(client); - return result; - } + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); /* set initial values for level & stereo - adjustment, mode */ byte = 0; - result = command(client, TDA9840_LEVEL_ADJUST, &byte); - result += command(client, TDA9840_STEREO_ADJUST, &byte); + result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte); + result += tda9840_command(client, TDA9840_STEREO_ADJUST, &byte); byte = TDA9840_SET_MONO; - result = command(client, TDA9840_SWITCH, &byte); + result = tda9840_command(client, TDA9840_SWITCH, &byte); if (result) { - dprintk("could not initialize tda9840\n"); + v4l_dbg(1, debug, client, "could not initialize tda9840\n"); return -ENODEV; } - - printk("tda9840: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); return 0; } -static int attach(struct i2c_adapter *adapter) +static int tda9840_legacy_probe(struct i2c_adapter *adapter) { - /* let's see whether this is a know adapter we can attach to */ - if (adapter->id != I2C_HW_SAA7146) { - dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); - return -ENODEV; - } - - return i2c_probe(adapter, &addr_data, &detect); + /* Let's see whether this is a known adapter we can attach to. + Prevents conflicts with tvaudio.c. */ + return adapter->id == I2C_HW_SAA7146; } - -static int detach(struct i2c_client *client) -{ - int ret = i2c_detach_client(client); - kfree(client); - return ret; -} - -static struct i2c_driver driver = { - .driver = { - .name = "tda9840", - }, - .id = I2C_DRIVERID_TDA9840, - .attach_adapter = attach, - .detach_client = detach, - .command = command, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id tda9840_id[] = { + { "tda9840", 0 }, + { } }; +MODULE_DEVICE_TABLE(i2c, tda9840_id); +#endif -static struct i2c_client client_template = { +static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tda9840", - .driver = &driver, + .driverid = I2C_DRIVERID_TDA9840, + .command = tda9840_command, + .probe = tda9840_probe, + .legacy_probe = tda9840_legacy_probe, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = tda9840_id, +#endif }; - -static int __init this_module_init(void) -{ - return i2c_add_driver(&driver); -} - -static void __exit this_module_exit(void) -{ - i2c_del_driver(&driver); -} - -module_init(this_module_init); -module_exit(this_module_exit); - -MODULE_AUTHOR("Michael Hunold "); -MODULE_DESCRIPTION("tda9840 driver"); -MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/video/tea6415c.c b/linux/drivers/media/video/tea6415c.c index da654bd15..073f020fa 100644 --- a/linux/drivers/media/video/tea6415c.c +++ b/linux/drivers/media/video/tea6415c.c @@ -2,6 +2,7 @@ tea6415c - i2c-driver for the tea6415c by SGS Thomson Copyright (C) 1998-2003 Michael Hunold + Copyright (C) 2008 Hans Verkuil The tea6415c is a bus controlled video-matrix-switch with 8 inputs and 6 outputs. @@ -30,19 +31,19 @@ #include #include #include +#include +#include +#include "tea6415c.h" #include "compat.h" -#include "tea6415c.h" +MODULE_AUTHOR("Michael Hunold "); +MODULE_DESCRIPTION("tea6415c driver"); +MODULE_LICENSE("GPL"); -static int debug; /* insmod parameter */ +static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); - -#define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) -#define TEA6415C_NUM_INPUTS 8 -#define TEA6415C_NUM_OUTPUTS 6 +MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; @@ -50,60 +51,6 @@ static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIEN /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; -static struct i2c_driver driver; -static struct i2c_client client_template; - -/* this function is called by i2c_probe */ -static int detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client = NULL; - int err = 0; - - /* let's see whether this adapter can support what we need */ - if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { - return 0; - } - - /* allocate memory for client structure */ - client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) { - return -ENOMEM; - } - - /* fill client structure */ - memcpy(client, &client_template, sizeof(struct i2c_client)); - client->addr = address; - client->adapter = adapter; - - /* tell the i2c layer a new client has arrived */ - if (0 != (err = i2c_attach_client(client))) { - kfree(client); - return err; - } - - printk("tea6415c: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); - - return 0; -} - -static int attach(struct i2c_adapter *adapter) -{ - /* let's see whether this is a know adapter we can attach to */ - if (adapter->id != I2C_HW_SAA7146) { - dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); - return -ENODEV; - } - - return i2c_probe(adapter, &addr_data, &detect); -} - -static int detach(struct i2c_client *client) -{ - int ret = i2c_detach_client(client); - kfree(client); - return ret; -} - /* makes a connection between the input-pin 'i' and the output-pin 'o' for the tea6415c-client 'client' */ static int switch_matrix(struct i2c_client *client, int i, int o) @@ -111,7 +58,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o) u8 byte = 0; int ret; - dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); + v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o); /* check if the pins are valid */ if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) @@ -169,14 +116,14 @@ static int switch_matrix(struct i2c_client *client, int i, int o) ret = i2c_smbus_write_byte(client, byte); if (ret) { - dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); + v4l_dbg(1, debug, client, + "i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } - return ret; } -static int command(struct i2c_client *client, unsigned int cmd, void *arg) +static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg) { struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; int result = 0; @@ -188,38 +135,44 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) default: return -ENOIOCTLCMD; } - return result; } -static struct i2c_driver driver = { - .driver = { - .name = "tea6415c", - }, - .id = I2C_DRIVERID_TEA6415C, - .attach_adapter = attach, - .detach_client = detach, - .command = command, -}; - -static struct i2c_client client_template = { - .name = "tea6415c", - .driver = &driver, -}; - -static int __init this_module_init(void) +/* this function is called by i2c_probe */ +static int tea6415c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - return i2c_add_driver(&driver); + /* let's see whether this adapter can support what we need */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) + return 0; + + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + return 0; } -static void __exit this_module_exit(void) +static int tea6415c_legacy_probe(struct i2c_adapter *adapter) { - i2c_del_driver(&driver); + /* Let's see whether this is a known adapter we can attach to. + Prevents conflicts with tvaudio.c. */ + return adapter->id == I2C_HW_SAA7146; } -module_init(this_module_init); -module_exit(this_module_exit); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id tea6415c_id[] = { + { "tea6415c", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tea6415c_id); +#endif -MODULE_AUTHOR("Michael Hunold "); -MODULE_DESCRIPTION("tea6415c driver"); -MODULE_LICENSE("GPL"); +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "tea6415c", + .driverid = I2C_DRIVERID_TEA6415C, + .command = tea6415c_command, + .probe = tea6415c_probe, + .legacy_probe = tea6415c_legacy_probe, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = tea6415c_id, +#endif +}; diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c index d0c63703c..8ded72ade 100644 --- a/linux/drivers/media/video/tea6420.c +++ b/linux/drivers/media/video/tea6420.c @@ -2,6 +2,7 @@ tea6420 - i2c-driver for the tea6420 by SGS Thomson Copyright (C) 1998-2003 Michael Hunold + Copyright (C) 2008 Hans Verkuil The tea6420 is a bus controlled audio-matrix with 5 stereo inputs, 4 stereo outputs and gain control for each output. @@ -30,16 +31,19 @@ #include #include #include +#include +#include +#include "tea6420.h" #include "compat.h" -#include "tea6420.h" +MODULE_AUTHOR("Michael Hunold "); +MODULE_DESCRIPTION("tea6420 driver"); +MODULE_LICENSE("GPL"); -static int debug; /* insmod parameter */ +static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); -#define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) +MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; @@ -47,23 +51,20 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; -static struct i2c_driver driver; -static struct i2c_client client_template; - /* make a connection between the input 'i' and the output 'o' with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) { - u8 byte = 0; + u8 byte; int ret; - dprintk("adr:0x%02x, i:%d, o:%d, g:%d\n", client->addr, i, o, g); + v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g); /* check if the parameters are valid */ if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0) return -1; - byte = ((o - 1) << 5); + byte = ((o - 1) << 5); byte |= (i - 1); /* to understand this, have a look at the tea6420-specs (p.5) */ @@ -83,40 +84,41 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) ret = i2c_smbus_write_byte(client, byte); if (ret) { - dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); + v4l_dbg(1, debug, client, + "i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } - return 0; } -/* this function is called by i2c_probe */ -static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) +static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg) { - struct i2c_client *client; - int err = 0, i = 0; + struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; + int result = 0; - /* let's see whether this adapter can support what we need */ - if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { - return 0; + switch (cmd) { + case TEA6420_SWITCH: + result = tea6420_switch(client, a->in, a->out, a->gain); + break; + default: + return -ENOIOCTLCMD; } - /* allocate memory for client structure */ - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) { - return -ENOMEM; - } + return result; +} - /* fill client structure */ - memcpy(client, &client_template, sizeof(struct i2c_client)); - client->addr = address; - client->adapter = adapter; +/* this function is called by i2c_probe */ +static int tea6420_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err, i; - /* tell the i2c layer a new client has arrived */ - if (0 != (err = i2c_attach_client(client))) { - kfree(client); - return err; - } + /* let's see whether this adapter can support what we need */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) + return -EIO; + + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); /* set initial values: set "mute"-input to all outputs at gain 0 */ err = 0; @@ -124,78 +126,35 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) err += tea6420_switch(client, 6, i, 0); } if (err) { - dprintk("could not initialize tea6420\n"); + v4l_dbg(1, debug, client, "could not initialize tea6420\n"); kfree(client); return -ENODEV; } - - printk("tea6420: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); - return 0; } -static int attach(struct i2c_adapter *adapter) +static int tea6420_legacy_probe(struct i2c_adapter *adapter) { - /* let's see whether this is a know adapter we can attach to */ - if (adapter->id != I2C_HW_SAA7146) { - dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); - return -ENODEV; - } - - return i2c_probe(adapter, &addr_data, &tea6420_detect); -} - -static int detach(struct i2c_client *client) -{ - int ret = i2c_detach_client(client); - kfree(client); - return ret; -} - -static int command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; - int result = 0; - - switch (cmd) { - case TEA6420_SWITCH: - result = tea6420_switch(client, a->in, a->out, a->gain); - break; - default: - return -ENOIOCTLCMD; - } - - return result; + /* Let's see whether this is a known adapter we can attach to. + Prevents conflicts with tvaudio.c. */ + return adapter->id == I2C_HW_SAA7146; } -static struct i2c_driver driver = { - .driver = { - .name = "tea6420", - }, - .id = I2C_DRIVERID_TEA6420, - .attach_adapter = attach, - .detach_client = detach, - .command = command, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id tea6420_id[] = { + { "tea6420", 0 }, + { } }; +MODULE_DEVICE_TABLE(i2c, tea6420_id); +#endif -static struct i2c_client client_template = { +static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tea6420", - .driver = &driver, + .driverid = I2C_DRIVERID_TEA6420, + .command = tea6420_command, + .probe = tea6420_probe, + .legacy_probe = tea6420_legacy_probe, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = tea6420_id, +#endif }; - -static int __init this_module_init(void) -{ - return i2c_add_driver(&driver); -} - -static void __exit this_module_exit(void) -{ - i2c_del_driver(&driver); -} - -module_init(this_module_init); -module_exit(this_module_exit); - -MODULE_AUTHOR("Michael Hunold "); -MODULE_DESCRIPTION("tea6420 driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 350bbc5926746c35a38095da02fa7e82d67cca22 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 08:43:59 +0200 Subject: gspca: Webcam 0c45:6143 added in sonixj. From: Jean-Francois Moine It is an other Pccam168. The .inf says SN9C120B + SP80708, but it should work as SN9C120 + MI0360. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 5264b06dc..6abab94fb 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1488,6 +1488,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ #endif + {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From c87e72d1b35c10453f721894751ee489d193851b Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 12:49:55 +0200 Subject: gspca: Bad sensor for some webcams in zc3xx since 28b8203a830e. From: Jean-Francois Moine '.driver_info = ' forgotten in usb device id table. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index ff68e16aa..0c7b20598 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7525,8 +7525,8 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4036)}, {USB_DEVICE(0x041e, 0x403a)}, #endif - {USB_DEVICE(0x041e, 0x4051), SENSOR_TAS5130C_VF0250}, - {USB_DEVICE(0x041e, 0x4053), SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0458, 0x7007)}, {USB_DEVICE(0x0458, 0x700c)}, @@ -7552,7 +7552,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x08d9)}, {USB_DEVICE(0x046d, 0x08d8)}, {USB_DEVICE(0x046d, 0x08da)}, - {USB_DEVICE(0x046d, 0x08dd), SENSOR_MC501CB}, + {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, {USB_DEVICE(0x0471, 0x0325)}, {USB_DEVICE(0x0471, 0x0326)}, {USB_DEVICE(0x0471, 0x032d)}, @@ -7568,7 +7568,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0ac8, 0x301b)}, {USB_DEVICE(0x0ac8, 0x303b)}, #endif - {USB_DEVICE(0x0ac8, 0x305b), SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0ac8, 0x307b)}, {USB_DEVICE(0x10fd, 0x0128)}, -- cgit v1.2.3 From 08868bb28026054e1144aa03c4c59c7062ee21c2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 13:02:47 +0200 Subject: gspca: Remove the remaining frame decoding functions from the subdrivers. From: Jean-Francois Moine SPCA505 and SPCA508 added in the pixel formats. Decode functions and associated resources removed in spca505, 506 and 508. The decode routines are now found in the V4L library. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca505.c | 105 ++++++++---------------------- linux/drivers/media/video/gspca/spca506.c | 105 ++++++++---------------------- linux/drivers/media/video/gspca/spca508.c | 91 ++++++-------------------- 3 files changed, 74 insertions(+), 227 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index 4d84883fa..83dd8abf9 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -31,10 +31,6 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - int buflen; - unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */ - unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ - unsigned char brightness; char subtype; @@ -64,29 +60,29 @@ static struct ctrl sd_ctrls[] = { }; static struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 160 * 2, - .sizeimage = 160 * 120 * 2, + {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 160 * 3, + .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 5}, - {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 176 * 2, - .sizeimage = 176 * 144 * 2, + {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 176 * 3, + .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 4}, - {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, - .sizeimage = 320 * 240 * 2, + {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 320 * 3, + .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, - {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 352 * 2, - .sizeimage = 352 * 288 * 2, + {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 352 * 3, + .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, - {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 640 * 2, - .sizeimage = 640 * 480 * 2, + {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 640 * 3, + .sizeimage = 640 * 480 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; @@ -829,77 +825,30 @@ static void sd_close(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); } -/* convert YYUV per line to YUYV (YUV 4:2:2) */ -static void yyuv_decode(unsigned char *out, - unsigned char *in, - int width, - int height) -{ - unsigned char *Ui, *Vi, *yi, *yi1; - unsigned char *out1; - int i, j; - - yi = in; - for (i = height / 2; --i >= 0; ) { - out1 = out + width * 2; /* next line */ - yi1 = yi + width; - Ui = yi1 + width; - Vi = Ui + width / 2; - for (j = width / 2; --j >= 0; ) { - *out++ = 128 + *yi++; - *out++ = 128 + *Ui; - *out++ = 128 + *yi++; - *out++ = 128 + *Vi; - - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Ui++; - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Vi++; - } - yi += width * 2; - out = out1; - } -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { case 0: /* start of frame */ - if (gspca_dev->last_packet_type == FIRST_PACKET) { - yyuv_decode(sd->tmpbuf2, sd->tmpbuf, - gspca_dev->width, - gspca_dev->height); - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - sd->tmpbuf2, - gspca_dev->width - * gspca_dev->height - * 2); - } - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, 0); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); data += SPCA50X_OFFSET_DATA; len -= SPCA50X_OFFSET_DATA; - if (len > 0) - memcpy(sd->tmpbuf, data, len); - else - len = 0; - sd->buflen = len; - return; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; case 0xff: /* drop */ /* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; + break; + default: + data += 1; + len -= 1; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; } - data += 1; - len -= 1; - memcpy(&sd->tmpbuf[sd->buflen], data, len); - sd->buflen += len; } static void setbrightness(struct gspca_dev *gspca_dev) diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index 2c281a056..6fe715c80 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -33,10 +33,6 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - int buflen; - __u8 tmpbuf[640 * 480 * 3]; /* YYUV per line */ - __u8 tmpbuf2[640 * 480 * 2]; /* YUYV */ - unsigned char brightness; unsigned char contrast; unsigned char colors; @@ -115,29 +111,29 @@ static struct ctrl sd_ctrls[] = { }; static struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 160 * 2, - .sizeimage = 160 * 120 * 2, + {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 160 * 3, + .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 5}, - {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 176 * 2, - .sizeimage = 176 * 144 * 2, + {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 176 * 3, + .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 4}, - {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, - .sizeimage = 320 * 240 * 2, + {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 320 * 3, + .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, - {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 352 * 2, - .sizeimage = 352 * 288 * 2, + {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 352 * 3, + .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, - {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 640 * 2, - .sizeimage = 640 * 480 * 2, + {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 640 * 3, + .sizeimage = 640 * 480 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; @@ -572,77 +568,30 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -/* convert YYUV per line to YUYV (YUV 4:2:2) */ -static void yyuv_decode(unsigned char *out, - unsigned char *in, - int width, - int height) -{ - unsigned char *Ui, *Vi, *yi, *yi1; - unsigned char *out1; - int i, j; - - yi = in; - for (i = height / 2; --i >= 0; ) { - out1 = out + width * 2; /* next line */ - yi1 = yi + width; - Ui = yi1 + width; - Vi = Ui + width / 2; - for (j = width / 2; --j >= 0; ) { - *out++ = 128 + *yi++; - *out++ = 128 + *Ui; - *out++ = 128 + *yi++; - *out++ = 128 + *Vi; - - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Ui++; - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Vi++; - } - yi += width * 2; - out = out1; - } -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { case 0: /* start of frame */ - if (gspca_dev->last_packet_type == FIRST_PACKET) { - yyuv_decode(sd->tmpbuf2, sd->tmpbuf, - gspca_dev->width, - gspca_dev->height); - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - sd->tmpbuf2, - gspca_dev->width - * gspca_dev->height - * 2); - } - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, 0); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); data += SPCA50X_OFFSET_DATA; len -= SPCA50X_OFFSET_DATA; - if (len > 0) - memcpy(sd->tmpbuf, data, len); - else - len = 0; - sd->buflen = len; - return; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; case 0xff: /* drop */ /* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; + break; + default: + data += 1; + len -= 1; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; } - data += 1; - len -= 1; - memcpy(&sd->tmpbuf[sd->buflen], data, len); - sd->buflen += len; } static void setbrightness(struct gspca_dev *gspca_dev) diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index cac6471e9..d4237525b 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -30,10 +30,6 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - int buflen; - unsigned char tmpbuf[352 * 288 * 3 / 2]; /* YUVY per line */ - unsigned char tmpbuf2[352 * 288 * 2]; /* YUYV */ - unsigned char brightness; char subtype; @@ -68,23 +64,23 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format sif_mode[] = { {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 160 * 2, - .sizeimage = 160 * 120 * 2, + .bytesperline = 160 * 3, + .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 3}, {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 176 * 2, - .sizeimage = 176 * 144 * 2, + .bytesperline = 176 * 3, + .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, - .sizeimage = 320 * 240 * 2, + .bytesperline = 320 * 3, + .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 352 * 2, - .sizeimage = 352 * 288 * 2, + .bytesperline = 352 * 3, + .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; @@ -1605,77 +1601,30 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -/* convert YUVY per line to YUYV (YUV 4:2:2) */ -static void yuvy_decode(unsigned char *out, - unsigned char *in, - int width, - int height) -{ - unsigned char *Ui, *Vi, *yi, *yi1; - unsigned char *out1; - int i, j; - - yi = in; - for (i = height / 2; --i >= 0; ) { - out1 = out + width * 2; /* next line */ - Ui = yi + width; - Vi = Ui + width / 2; - yi1 = Vi + width / 2; - for (j = width / 2; --j >= 0; ) { - *out++ = 128 + *yi++; - *out++ = 128 + *Ui; - *out++ = 128 + *yi++; - *out++ = 128 + *Vi; - - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Ui++; - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Vi++; - } - yi += width * 2; - out = out1; - } -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { case 0: /* start of frame */ - if (gspca_dev->last_packet_type == FIRST_PACKET) { - yuvy_decode(sd->tmpbuf2, sd->tmpbuf, - gspca_dev->width, - gspca_dev->height); - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - sd->tmpbuf2, - gspca_dev->width - * gspca_dev->height - * 2); - } - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, 0); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); data += SPCA508_OFFSET_DATA; len -= SPCA508_OFFSET_DATA; - if (len > 0) - memcpy(sd->tmpbuf, data, len); - else - len = 0; - sd->buflen = len; - return; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; case 0xff: /* drop */ /* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; + break; + default: + data += 1; + len -= 1; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; } - data += 1; - len -= 1; - memcpy(&sd->tmpbuf[sd->buflen], data, len); - sd->buflen += len; } static void setbrightness(struct gspca_dev *gspca_dev) -- cgit v1.2.3 From 9782f69f6d88cc756f9c0e0d01846779df901da8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 13:26:43 +0200 Subject: v4l2-dev: remove unused type and type2 field from video_device From: Hans Verkuil The type and type2 fields were unused and so could be removed. Instead add a vfl_type field that contains the type of the video device. Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_fops.c | 2 +- linux/drivers/media/radio/dsbr100.c | 1 - linux/drivers/media/radio/miropcm20-radio.c | 1 - linux/drivers/media/radio/radio-aimslab.c | 1 - linux/drivers/media/radio/radio-aztech.c | 1 - linux/drivers/media/radio/radio-cadet.c | 1 - linux/drivers/media/radio/radio-gemtek-pci.c | 1 - linux/drivers/media/radio/radio-gemtek.c | 1 - linux/drivers/media/radio/radio-maestro.c | 1 - linux/drivers/media/radio/radio-maxiradio.c | 1 - linux/drivers/media/radio/radio-rtrack2.c | 1 - linux/drivers/media/radio/radio-sf16fmi.c | 1 - linux/drivers/media/radio/radio-sf16fmr2.c | 1 - linux/drivers/media/radio/radio-si470x.c | 1 - linux/drivers/media/radio/radio-terratec.c | 1 - linux/drivers/media/radio/radio-trust.c | 1 - linux/drivers/media/radio/radio-typhoon.c | 1 - linux/drivers/media/radio/radio-zoltrix.c | 1 - linux/drivers/media/video/bt8xx/bttv-driver.c | 23 +++++----------------- linux/drivers/media/video/bw-qcam.c | 1 - linux/drivers/media/video/c-qcam.c | 1 - linux/drivers/media/video/cafe_ccic.c | 2 -- linux/drivers/media/video/cpia.c | 1 - linux/drivers/media/video/cpia2/cpia2_v4l.c | 3 --- linux/drivers/media/video/cx18/cx18-streams.c | 3 --- linux/drivers/media/video/cx23885/cx23885-417.c | 4 ---- linux/drivers/media/video/cx23885/cx23885-video.c | 15 +++++++------- linux/drivers/media/video/cx88/cx88-blackbird.c | 2 -- linux/drivers/media/video/cx88/cx88-video.c | 3 --- linux/drivers/media/video/em28xx/em28xx-video.c | 14 +++---------- linux/drivers/media/video/et61x251/et61x251_core.c | 1 - linux/drivers/media/video/gspca/gspca.c | 1 - linux/drivers/media/video/ivtv/ivtv-streams.c | 5 ----- linux/drivers/media/video/meye.c | 1 - linux/drivers/media/video/ov511.c | 1 - linux/drivers/media/video/pms.c | 1 - linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 4 ---- linux/drivers/media/video/pwc/pwc-if.c | 1 - linux/drivers/media/video/s2255drv.c | 1 - linux/drivers/media/video/saa5246a.c | 1 - linux/drivers/media/video/saa5249.c | 1 - linux/drivers/media/video/saa7134/saa7134-core.c | 9 +++------ .../drivers/media/video/saa7134/saa7134-empress.c | 2 -- linux/drivers/media/video/saa7134/saa7134-video.c | 3 --- linux/drivers/media/video/se401.c | 1 - linux/drivers/media/video/sn9c102/sn9c102_core.c | 1 - linux/drivers/media/video/soc_camera.c | 1 - linux/drivers/media/video/stk-webcam.c | 2 -- linux/drivers/media/video/stradis.c | 1 - linux/drivers/media/video/stv680.c | 1 - linux/drivers/media/video/usbvideo/usbvideo.c | 1 - linux/drivers/media/video/usbvideo/vicam.c | 1 - .../media/video/usbvision/usbvision-video.c | 3 --- linux/drivers/media/video/uvc/uvc_driver.c | 2 -- linux/drivers/media/video/v4l2-dev.c | 1 + linux/drivers/media/video/vino.c | 2 -- linux/drivers/media/video/vivi.c | 1 - linux/drivers/media/video/w9966.c | 1 - linux/drivers/media/video/w9968cf.c | 1 - linux/drivers/media/video/zc0301/zc0301_core.c | 1 - linux/drivers/media/video/zoran_driver.c | 2 -- linux/drivers/media/video/zr364xx.c | 1 - 62 files changed, 21 insertions(+), 126 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c index ac035cbcf..a3dafa4fe 100644 --- a/linux/drivers/media/common/saa7146_fops.c +++ b/linux/drivers/media/common/saa7146_fops.c @@ -564,7 +564,7 @@ int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev DEB_EE(("dev:%p\n",dev)); - if( VFL_TYPE_GRABBER == (*vid)->type ) { + if ((*vid)->vfl_type == VFL_TYPE_GRABBER) { vv->video_minor = -1; } else { vv->vbi_minor = -1; diff --git a/linux/drivers/media/radio/dsbr100.c b/linux/drivers/media/radio/dsbr100.c index 58a4b2396..d223846d5 100644 --- a/linux/drivers/media/radio/dsbr100.c +++ b/linux/drivers/media/radio/dsbr100.c @@ -464,7 +464,6 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { /* V4L2 interface */ static struct video_device dsbr100_videodev_template = { .name = "D-Link DSB-R 100", - .type = VID_TYPE_TUNER, .fops = &usb_dsbr100_fops, .ioctl_ops = &usb_dsbr100_ioctl_ops, .release = video_device_release, diff --git a/linux/drivers/media/radio/miropcm20-radio.c b/linux/drivers/media/radio/miropcm20-radio.c index 5be7c5c25..efbb9cce8 100644 --- a/linux/drivers/media/radio/miropcm20-radio.c +++ b/linux/drivers/media/radio/miropcm20-radio.c @@ -231,7 +231,6 @@ static const struct file_operations pcm20_fops = { static struct video_device pcm20_radio = { .name = "Miro PCM 20 radio", - .type = VID_TYPE_TUNER, .fops = &pcm20_fops, .priv = &pcm20_unit }; diff --git a/linux/drivers/media/radio/radio-aimslab.c b/linux/drivers/media/radio/radio-aimslab.c index 67e4a5e14..516677a98 100644 --- a/linux/drivers/media/radio/radio-aimslab.c +++ b/linux/drivers/media/radio/radio-aimslab.c @@ -407,7 +407,6 @@ static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { static struct video_device rtrack_radio = { .name = "RadioTrack radio", - .type = VID_TYPE_TUNER, .fops = &rtrack_fops, .ioctl_ops = &rtrack_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-aztech.c b/linux/drivers/media/radio/radio-aztech.c index 77bc931ea..8adb1b003 100644 --- a/linux/drivers/media/radio/radio-aztech.c +++ b/linux/drivers/media/radio/radio-aztech.c @@ -371,7 +371,6 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = { static struct video_device aztech_radio = { .name = "Aztech radio", - .type = VID_TYPE_TUNER, .fops = &aztech_fops, .ioctl_ops = &aztech_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-cadet.c b/linux/drivers/media/radio/radio-cadet.c index 54b10c713..6588f0cd3 100644 --- a/linux/drivers/media/radio/radio-cadet.c +++ b/linux/drivers/media/radio/radio-cadet.c @@ -617,7 +617,6 @@ static const struct v4l2_ioctl_ops cadet_ioctl_ops = { static struct video_device cadet_radio = { .name = "Cadet radio", - .type = VID_TYPE_TUNER, .fops = &cadet_fops, .ioctl_ops = &cadet_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-gemtek-pci.c b/linux/drivers/media/radio/radio-gemtek-pci.c index 4b9c5a228..efee362c7 100644 --- a/linux/drivers/media/radio/radio-gemtek-pci.c +++ b/linux/drivers/media/radio/radio-gemtek-pci.c @@ -393,7 +393,6 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { static struct video_device vdev_template = { .name = "Gemtek PCI Radio", - .type = VID_TYPE_TUNER, .fops = &gemtek_pci_fops, .ioctl_ops = &gemtek_pci_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-gemtek.c b/linux/drivers/media/radio/radio-gemtek.c index 0b63c500d..bf1837ab2 100644 --- a/linux/drivers/media/radio/radio-gemtek.c +++ b/linux/drivers/media/radio/radio-gemtek.c @@ -571,7 +571,6 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { static struct video_device gemtek_radio = { .name = "GemTek Radio card", - .type = VID_TYPE_TUNER, .fops = &gemtek_fops, .ioctl_ops = &gemtek_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-maestro.c b/linux/drivers/media/radio/radio-maestro.c index f16a2ab88..3b382e2b3 100644 --- a/linux/drivers/media/radio/radio-maestro.c +++ b/linux/drivers/media/radio/radio-maestro.c @@ -373,7 +373,6 @@ static const struct v4l2_ioctl_ops maestro_ioctl_ops = { static struct video_device maestro_radio = { .name = "Maestro radio", - .type = VID_TYPE_TUNER, .fops = &maestro_fops, .ioctl_ops = &maestro_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index 2cacafa5c..0f6bbd81b 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -392,7 +392,6 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { static struct video_device maxiradio_radio = { .name = "Maxi Radio FM2000 radio", - .type = VID_TYPE_TUNER, .fops = &maxiradio_fops, .ioctl_ops = &maxiradio_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-rtrack2.c b/linux/drivers/media/radio/radio-rtrack2.c index 135d104ba..31d6eabbb 100644 --- a/linux/drivers/media/radio/radio-rtrack2.c +++ b/linux/drivers/media/radio/radio-rtrack2.c @@ -313,7 +313,6 @@ static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { static struct video_device rtrack2_radio = { .name = "RadioTrack II radio", - .type = VID_TYPE_TUNER, .fops = &rtrack2_fops, .ioctl_ops = &rtrack2_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-sf16fmi.c b/linux/drivers/media/radio/radio-sf16fmi.c index 375a9cbf4..d4433b6a3 100644 --- a/linux/drivers/media/radio/radio-sf16fmi.c +++ b/linux/drivers/media/radio/radio-sf16fmi.c @@ -313,7 +313,6 @@ static const struct v4l2_ioctl_ops fmi_ioctl_ops = { static struct video_device fmi_radio = { .name = "SF16FMx radio", - .type = VID_TYPE_TUNER, .fops = &fmi_fops, .ioctl_ops = &fmi_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-sf16fmr2.c b/linux/drivers/media/radio/radio-sf16fmr2.c index 7e8516a2b..7b7748561 100644 --- a/linux/drivers/media/radio/radio-sf16fmr2.c +++ b/linux/drivers/media/radio/radio-sf16fmr2.c @@ -429,7 +429,6 @@ static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { static struct video_device fmr2_radio = { .name = "SF16FMR2 radio", - .type = VID_TYPE_TUNER, .fops = &fmr2_fops, .ioctl_ops = &fmr2_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 15b9da575..afff1345b 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -1614,7 +1614,6 @@ static struct video_device si470x_viddev_template = { .fops = &si470x_fops, .ioctl_ops = &si470x_ioctl_ops, .name = DRIVER_NAME, - .type = VID_TYPE_TUNER, .release = video_device_release, }; diff --git a/linux/drivers/media/radio/radio-terratec.c b/linux/drivers/media/radio/radio-terratec.c index 0eff7b780..768582f53 100644 --- a/linux/drivers/media/radio/radio-terratec.c +++ b/linux/drivers/media/radio/radio-terratec.c @@ -385,7 +385,6 @@ static const struct v4l2_ioctl_ops terratec_ioctl_ops = { static struct video_device terratec_radio = { .name = "TerraTec ActiveRadio", - .type = VID_TYPE_TUNER, .fops = &terratec_fops, .ioctl_ops = &terratec_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-trust.c b/linux/drivers/media/radio/radio-trust.c index 28ebeb938..648007027 100644 --- a/linux/drivers/media/radio/radio-trust.c +++ b/linux/drivers/media/radio/radio-trust.c @@ -368,7 +368,6 @@ static const struct v4l2_ioctl_ops trust_ioctl_ops = { static struct video_device trust_radio = { .name = "Trust FM Radio", - .type = VID_TYPE_TUNER, .fops = &trust_fops, .ioctl_ops = &trust_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-typhoon.c b/linux/drivers/media/radio/radio-typhoon.c index dd7903e26..fa66168d7 100644 --- a/linux/drivers/media/radio/radio-typhoon.c +++ b/linux/drivers/media/radio/radio-typhoon.c @@ -363,7 +363,6 @@ static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { static struct video_device typhoon_radio = { .name = "Typhoon Radio", - .type = VID_TYPE_TUNER, .fops = &typhoon_fops, .ioctl_ops = &typhoon_ioctl_ops, }; diff --git a/linux/drivers/media/radio/radio-zoltrix.c b/linux/drivers/media/radio/radio-zoltrix.c index 9f7c84530..ef6d6a66f 100644 --- a/linux/drivers/media/radio/radio-zoltrix.c +++ b/linux/drivers/media/radio/radio-zoltrix.c @@ -426,7 +426,6 @@ static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { static struct video_device zoltrix_radio = { .name = "Zoltrix Radio Plus", - .type = VID_TYPE_TUNER, .fops = &zoltrix_fops, .ioctl_ops = &zoltrix_ioctl_ops, }; diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 8a57b2560..40f8a0332 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -4206,8 +4206,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) static struct video_device *vdev_init(struct bttv *btv, const struct video_device *template, - const char *type_name, - const int type) + const char *type_name) { struct video_device *vfd; @@ -4218,7 +4217,6 @@ static struct video_device *vdev_init(struct bttv *btv, vfd->minor = -1; vfd->parent = &btv->c.pci->dev; vfd->release = video_device_release; - vfd->type = type; vfd->debug = bttv_debug; snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", @@ -4254,20 +4252,11 @@ static void bttv_unregister_video(struct bttv *btv) /* register video4linux devices */ static int __devinit bttv_register_video(struct bttv *btv) { - int video_type = VID_TYPE_CAPTURE | - VID_TYPE_TUNER | - VID_TYPE_CLIPPING| - VID_TYPE_SCALES; - - if (no_overlay <= 0) { - bttv_video_template.type |= VID_TYPE_OVERLAY; - } else { + if (no_overlay > 0) printk("bttv: Overlay support disabled.\n"); - } /* video */ - btv->video_dev = vdev_init(btv, &bttv_video_template, - "video", video_type); + btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); if (NULL == btv->video_dev) goto err; @@ -4283,8 +4272,7 @@ static int __devinit bttv_register_video(struct bttv *btv) } /* vbi */ - btv->vbi_dev = vdev_init(btv, &bttv_video_template, - "vbi", VID_TYPE_TUNER | VID_TYPE_TELETEXT); + btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi"); if (NULL == btv->vbi_dev) goto err; @@ -4296,8 +4284,7 @@ static int __devinit bttv_register_video(struct bttv *btv) if (!btv->has_radio) return 0; /* radio */ - btv->radio_dev = vdev_init(btv, &radio_template, - "radio", VID_TYPE_TUNER); + btv->radio_dev = vdev_init(btv, &radio_template, "radio"); if (NULL == btv->radio_dev) goto err; if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) diff --git a/linux/drivers/media/video/bw-qcam.c b/linux/drivers/media/video/bw-qcam.c index 3e103dede..df2b25b69 100644 --- a/linux/drivers/media/video/bw-qcam.c +++ b/linux/drivers/media/video/bw-qcam.c @@ -909,7 +909,6 @@ static const struct file_operations qcam_fops = { static struct video_device qcam_template= { .name = "Connectix Quickcam", - .type = VID_TYPE_CAPTURE, .fops = &qcam_fops, }; diff --git a/linux/drivers/media/video/c-qcam.c b/linux/drivers/media/video/c-qcam.c index 70b96484e..fe8937ed1 100644 --- a/linux/drivers/media/video/c-qcam.c +++ b/linux/drivers/media/video/c-qcam.c @@ -704,7 +704,6 @@ static const struct file_operations qcam_fops = { static struct video_device qcam_template= { .name = "Colour QuickCam", - .type = VID_TYPE_CAPTURE, .fops = &qcam_fops, }; diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c index 607f21eda..35ecaa0c1 100644 --- a/linux/drivers/media/video/cafe_ccic.c +++ b/linux/drivers/media/video/cafe_ccic.c @@ -1801,8 +1801,6 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { static struct video_device cafe_v4l_template = { .name = "cafe", - .type = VFL_TYPE_GRABBER, - .type2 = VID_TYPE_CAPTURE, .minor = -1, /* Get one dynamically */ .tvnorms = V4L2_STD_NTSC_M, .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ diff --git a/linux/drivers/media/video/cpia.c b/linux/drivers/media/video/cpia.c index aeaddc047..21c1f4dbb 100644 --- a/linux/drivers/media/video/cpia.c +++ b/linux/drivers/media/video/cpia.c @@ -3800,7 +3800,6 @@ static const struct file_operations cpia_fops = { static struct video_device cpia_template = { .name = "CPiA Camera", - .type = VID_TYPE_CAPTURE, .fops = &cpia_fops, }; diff --git a/linux/drivers/media/video/cpia2/cpia2_v4l.c b/linux/drivers/media/video/cpia2/cpia2_v4l.c index 4e45de78d..515c8b57a 100644 --- a/linux/drivers/media/video/cpia2/cpia2_v4l.c +++ b/linux/drivers/media/video/cpia2/cpia2_v4l.c @@ -1937,9 +1937,6 @@ static const struct file_operations fops_template = { static struct video_device cpia2_template = { /* I could not find any place for the old .initialize initializer?? */ .name= "CPiA2 Camera", - .type= VID_TYPE_CAPTURE, - .type2 = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING, .minor= -1, .fops= &fops_template, .release= video_device_release, diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index 3eedae726..911a97ce3 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -187,9 +187,6 @@ static int cx18_prep_dev(struct cx18 *cx, int type) return -ENOMEM; } - s->v4l2dev->type = - VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT | - VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER; snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", cx->num); diff --git a/linux/drivers/media/video/cx23885/cx23885-417.c b/linux/drivers/media/video/cx23885/cx23885-417.c index 5aece975c..a8ca3bd9f 100644 --- a/linux/drivers/media/video/cx23885/cx23885-417.c +++ b/linux/drivers/media/video/cx23885/cx23885-417.c @@ -1739,10 +1739,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { static struct video_device cx23885_mpeg_template = { .name = "cx23885", - .type = VID_TYPE_CAPTURE | - VID_TYPE_TUNER | - VID_TYPE_SCALES | - VID_TYPE_MPEG_ENCODER, .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, .minor = -1, diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index 8a77f2633..3f1765de0 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -1680,7 +1680,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static struct video_device cx23885_vbi_template; static struct video_device cx23885_video_template = { .name = "cx23885-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, .fops = &video_fops, .minor = -1, .ioctl_ops = &video_ioctl_ops, @@ -1698,11 +1697,7 @@ static const struct file_operations radio_fops = { }; #if 0 -static struct video_device cx23885_radio_template = { - .name = "cx23885-radio", - .type = VID_TYPE_TUNER, - .fops = &radio_fops, - .minor = -1, +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -1716,6 +1711,13 @@ static struct video_device cx23885_radio_template = { .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, }; + +static struct video_device cx23885_radio_template = { + .name = "cx23885-radio", + .fops = &radio_fops, + .ioctl_ops = &radio_ioctl_ops, + .minor = -1, +}; #endif void cx23885_video_unregister(struct cx23885_dev *dev) @@ -1762,7 +1764,6 @@ int cx23885_video_register(struct cx23885_dev *dev) memcpy(&cx23885_vbi_template, &cx23885_video_template, sizeof(cx23885_vbi_template)); strcpy(cx23885_vbi_template.name, "cx23885-vbi"); - cx23885_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER; dev->tvnorm = cx23885_video_template.current_norm; diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c index 9cbb9c8d5..696a8752a 100644 --- a/linux/drivers/media/video/cx88/cx88-blackbird.c +++ b/linux/drivers/media/video/cx88/cx88-blackbird.c @@ -1226,8 +1226,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { static struct video_device cx8802_mpeg_template = { .name = "cx8802", - .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | - VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER, .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, .minor = -1, diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index f64cdd5ed..5dafb7d73 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1992,7 +1992,6 @@ static struct video_device cx8800_vbi_template; static struct video_device cx8800_video_template = { .name = "cx8800-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, .fops = &video_fops, .minor = -1, .ioctl_ops = &video_ioctl_ops, @@ -2031,7 +2030,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static struct video_device cx8800_radio_template = { .name = "cx8800-radio", - .type = VID_TYPE_TUNER, .fops = &radio_fops, .minor = -1, .ioctl_ops = &radio_ioctl_ops, @@ -2108,7 +2106,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, memcpy( &cx8800_vbi_template, &cx8800_video_template, sizeof(cx8800_vbi_template) ); strcpy(cx8800_vbi_template.name,"cx8800-vbi"); - cx8800_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER; /* initialize driver struct */ #if 0 diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index d0ca6f929..81d942e39 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1907,7 +1907,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static struct video_device em28xx_radio_template = { .name = "em28xx-radio", - .type = VID_TYPE_TUNER, .fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops, .minor = -1, @@ -1953,7 +1952,6 @@ EXPORT_SYMBOL(em28xx_unregister_extension); static struct video_device *em28xx_vdev_init(struct em28xx *dev, const struct video_device *template, - const int type, const char *type_name) { struct video_device *vfd; @@ -1965,7 +1963,6 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, vfd->minor = -1; vfd->parent = &dev->udev->dev; vfd->release = video_device_release; - vfd->type = type; vfd->debug = video_debug; snprintf(vfd->name, sizeof(vfd->name), "%s %s", @@ -2043,14 +2040,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, list_add_tail(&dev->devlist, &em28xx_devlist); /* allocate and fill video video_device struct */ - dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, - VID_TYPE_CAPTURE, "video"); + dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); if (NULL == dev->vdev) { em28xx_errdev("cannot allocate video_device.\n"); goto fail_unreg; } - if (dev->tuner_type != TUNER_ABSENT) - dev->vdev->type |= VID_TYPE_TUNER; /* register v4l2 video video_device */ retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, @@ -2062,8 +2056,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, } /* Allocate and fill vbi video_device struct */ - dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, - VFL_TYPE_VBI, "vbi"); + dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi"); /* register v4l2 vbi video_device */ if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]) < 0) { @@ -2073,8 +2066,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, } if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { - dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, - VFL_TYPE_RADIO, "radio"); + dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio"); if (NULL == dev->radio_dev) { em28xx_errdev("cannot allocate video_device.\n"); goto fail_unreg; diff --git a/linux/drivers/media/video/et61x251/et61x251_core.c b/linux/drivers/media/video/et61x251/et61x251_core.c index f3a2ed067..7d0f31db5 100644 --- a/linux/drivers/media/video/et61x251/et61x251_core.c +++ b/linux/drivers/media/video/et61x251/et61x251_core.c @@ -2589,7 +2589,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &et61x251_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 3f2a89fed..7f19e4a5a 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -1689,7 +1689,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { static struct video_device gspca_template = { .name = "gspca main driver", - .type = VID_TYPE_CAPTURE, .fops = &dev_fops, .ioctl_ops = &dev_ioctl_ops, .release = dev_release, /* mandatory */ diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c index b883c4e08..54d2023b2 100644 --- a/linux/drivers/media/video/ivtv/ivtv-streams.c +++ b/linux/drivers/media/video/ivtv/ivtv-streams.c @@ -208,11 +208,6 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) return -ENOMEM; } - s->v4l2dev->type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT | - VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER; - if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { - s->v4l2dev->type |= VID_TYPE_MPEG_DECODER; - } snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", itv->num, s->name); diff --git a/linux/drivers/media/video/meye.c b/linux/drivers/media/video/meye.c index f5cc0c636..d128a611e 100644 --- a/linux/drivers/media/video/meye.c +++ b/linux/drivers/media/video/meye.c @@ -1726,7 +1726,6 @@ static const struct v4l2_ioctl_ops meye_ioctl_ops = { static struct video_device meye_template = { .name = "meye", - .type = VID_TYPE_CAPTURE, .fops = &meye_fops, .ioctl_ops = &meye_ioctl_ops, .release = video_device_release, diff --git a/linux/drivers/media/video/ov511.c b/linux/drivers/media/video/ov511.c index 982bc3d10..c693b6fb0 100644 --- a/linux/drivers/media/video/ov511.c +++ b/linux/drivers/media/video/ov511.c @@ -4671,7 +4671,6 @@ static const struct file_operations ov511_fops = { static struct video_device vdev_template = { .name = "OV511 USB Camera", - .type = VID_TYPE_CAPTURE, .fops = &ov511_fops, .release = video_device_release, .minor = -1, diff --git a/linux/drivers/media/video/pms.c b/linux/drivers/media/video/pms.c index 98dc31354..e36b39b44 100644 --- a/linux/drivers/media/video/pms.c +++ b/linux/drivers/media/video/pms.c @@ -897,7 +897,6 @@ static const struct file_operations pms_fops = { static struct video_device pms_template= { .name = "Mediavision PMS", - .type = VID_TYPE_CAPTURE, .fops = &pms_fops, }; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 4d7cd7cd7..1619c2756 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -1162,10 +1162,6 @@ static const struct file_operations vdev_fops = { static struct video_device vdev_template = { - .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER, - .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE - | V4L2_CAP_TUNER | V4L2_CAP_AUDIO - | V4L2_CAP_READWRITE), .fops = &vdev_fops, }; diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index dc1e9c6b4..f005e2338 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -166,7 +166,6 @@ static const struct file_operations pwc_fops = { }; static struct video_device pwc_template = { .name = "Philips Webcam", /* Filled in later */ - .type = VID_TYPE_CAPTURE, .release = video_device_release, .fops = &pwc_fops, .minor = -1, diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c index f13235e31..3a8cd28cb 100644 --- a/linux/drivers/media/video/s2255drv.c +++ b/linux/drivers/media/video/s2255drv.c @@ -1686,7 +1686,6 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { static struct video_device template = { .name = "s2255v", - .type = VID_TYPE_CAPTURE, .fops = &s2255_fops_v4l, .ioctl_ops = &s2255_ioctl_ops, .minor = -1, diff --git a/linux/drivers/media/video/saa5246a.c b/linux/drivers/media/video/saa5246a.c index 2b85850ca..3765dcee9 100644 --- a/linux/drivers/media/video/saa5246a.c +++ b/linux/drivers/media/video/saa5246a.c @@ -832,7 +832,6 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { .name = IF_NAME, - .type = VID_TYPE_TELETEXT, .fops = &saa_fops, .release = video_device_release, .minor = -1, diff --git a/linux/drivers/media/video/saa5249.c b/linux/drivers/media/video/saa5249.c index 8627d68dd..662690c8b 100644 --- a/linux/drivers/media/video/saa5249.c +++ b/linux/drivers/media/video/saa5249.c @@ -713,7 +713,6 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { .name = IF_NAME, - .type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */ .fops = &saa_fops, }; diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 254a04717..cb878cd26 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -1068,11 +1068,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, v4l2_prio_init(&dev->prio); /* register v4l devices */ - if (saa7134_no_overlay <= 0) { - saa7134_video_template.type |= VID_TYPE_OVERLAY; - } else { - printk("%s: Overlay support disabled.\n",dev->name); - } + if (saa7134_no_overlay > 0) + printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name); + dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, video_nr[dev->nr]); @@ -1085,7 +1083,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, dev->name,dev->video_dev->minor & 0x1f); dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); - dev->vbi_dev->type = VID_TYPE_TUNER | VID_TYPE_TELETEXT; err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, vbi_nr[dev->nr]); diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 1d1c19680..74361c588 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -427,8 +427,6 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { static struct video_device saa7134_empress_template = { .name = "saa7134-empress", - .type = 0 /* FIXME */, - .type2 = 0 /* FIXME */, .fops = &ts_fops, .minor = -1, .ioctl_ops = &ts_ioctl_ops, diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 7e04bfa19..68290f01e 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -2442,8 +2442,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { struct video_device saa7134_video_template = { .name = "saa7134-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER | - VID_TYPE_CLIPPING|VID_TYPE_SCALES, .fops = &video_fops, .ioctl_ops = &video_ioctl_ops, .minor = -1, @@ -2453,7 +2451,6 @@ struct video_device saa7134_video_template = { struct video_device saa7134_radio_template = { .name = "saa7134-radio", - .type = VID_TYPE_TUNER, .fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops, .minor = -1, diff --git a/linux/drivers/media/video/se401.c b/linux/drivers/media/video/se401.c index 5da0625b7..f59d63618 100644 --- a/linux/drivers/media/video/se401.c +++ b/linux/drivers/media/video/se401.c @@ -1239,7 +1239,6 @@ static const struct file_operations se401_fops = { }; static struct video_device se401_template = { .name = "se401 USB camera", - .type = VID_TYPE_CAPTURE, .fops = &se401_fops, }; diff --git a/linux/drivers/media/video/sn9c102/sn9c102_core.c b/linux/drivers/media/video/sn9c102/sn9c102_core.c index e41d3afcd..e92e79da3 100644 --- a/linux/drivers/media/video/sn9c102/sn9c102_core.c +++ b/linux/drivers/media/video/sn9c102/sn9c102_core.c @@ -3313,7 +3313,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "SN9C1xx PC Camera"); - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &sn9c102_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c index 9ff561452..b6be5ee67 100644 --- a/linux/drivers/media/video/soc_camera.c +++ b/linux/drivers/media/video/soc_camera.c @@ -908,7 +908,6 @@ int soc_camera_video_start(struct soc_camera_device *icd) strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); /* Maybe better &ici->dev */ vdev->parent = &icd->dev; - vdev->type = VID_TYPE_CAPTURE; vdev->current_norm = V4L2_STD_UNKNOWN; vdev->fops = &soc_camera_fops; vdev->ioctl_ops = &soc_camera_ioctl_ops; diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index 5daa2294d..bb2fcea64 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -1359,8 +1359,6 @@ static void stk_v4l_dev_release(struct video_device *vd) static struct video_device stk_v4l_data = { .name = "stkwebcam", - .type = VFL_TYPE_GRABBER, - .type2 = VID_TYPE_CAPTURE, .minor = -1, .tvnorms = V4L2_STD_UNKNOWN, .current_norm = V4L2_STD_UNKNOWN, diff --git a/linux/drivers/media/video/stradis.c b/linux/drivers/media/video/stradis.c index 7f46a1d64..19243ac19 100644 --- a/linux/drivers/media/video/stradis.c +++ b/linux/drivers/media/video/stradis.c @@ -1924,7 +1924,6 @@ static const struct file_operations saa_fops = { /* template for video_device-structure */ static struct video_device saa_template = { .name = "SAA7146A", - .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, .fops = &saa_fops, .minor = -1, }; diff --git a/linux/drivers/media/video/stv680.c b/linux/drivers/media/video/stv680.c index 57baad8eb..34844ffec 100644 --- a/linux/drivers/media/video/stv680.c +++ b/linux/drivers/media/video/stv680.c @@ -1408,7 +1408,6 @@ static const struct file_operations stv680_fops = { }; static struct video_device stv680_template = { .name = "STV0680 USB camera", - .type = VID_TYPE_CAPTURE, .fops = &stv680_fops, .release = video_device_release, .minor = -1, diff --git a/linux/drivers/media/video/usbvideo/usbvideo.c b/linux/drivers/media/video/usbvideo/usbvideo.c index 737ff846b..5bda83f7d 100644 --- a/linux/drivers/media/video/usbvideo/usbvideo.c +++ b/linux/drivers/media/video/usbvideo/usbvideo.c @@ -952,7 +952,6 @@ static const struct file_operations usbvideo_fops = { .llseek = no_llseek, }; static const struct video_device usbvideo_template = { - .type = VID_TYPE_CAPTURE, .fops = &usbvideo_fops, }; diff --git a/linux/drivers/media/video/usbvideo/vicam.c b/linux/drivers/media/video/usbvideo/vicam.c index 165d35cfa..e31b64f17 100644 --- a/linux/drivers/media/video/usbvideo/vicam.c +++ b/linux/drivers/media/video/usbvideo/vicam.c @@ -1103,7 +1103,6 @@ static const struct file_operations vicam_fops = { static struct video_device vicam_template = { .name = "ViCam-based USB Camera", - .type = VID_TYPE_CAPTURE, .fops = &vicam_fops, .minor = -1, }; diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index a65e5db0a..b977116a0 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -1405,7 +1405,6 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { }; static struct video_device usbvision_video_template = { - .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, .fops = &usbvision_fops, .ioctl_ops = &usbvision_ioctl_ops, .name = "usbvision-video", @@ -1443,7 +1442,6 @@ static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { }; static struct video_device usbvision_radio_template = { - .type = VID_TYPE_TUNER, .fops = &usbvision_radio_fops, .name = "usbvision-radio", .release = video_device_release, @@ -1466,7 +1464,6 @@ static const struct file_operations usbvision_vbi_fops = { static struct video_device usbvision_vbi_template= { - .type = VID_TYPE_TUNER, .fops = &usbvision_vbi_fops, .release = video_device_release, .name = "usbvision-vbi", diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c index 79d6821c4..b3c4d75e8 100644 --- a/linux/drivers/media/video/uvc/uvc_driver.c +++ b/linux/drivers/media/video/uvc/uvc_driver.c @@ -1459,8 +1459,6 @@ static int uvc_register_video(struct uvc_device *dev) * get another one. */ vdev->parent = &dev->intf->dev; - vdev->type = 0; - vdev->type2 = 0; vdev->minor = -1; vdev->fops = &uvc_fops; vdev->release = video_device_release; diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index 279f436fe..d7aa8f6a4 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -340,6 +340,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, } } video_device[i] = vfd; + vfd->vfl_type = type; vfd->minor = i; ret = get_index(vfd, index); diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index b379abf28..cde8bf65a 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -4389,8 +4389,6 @@ static const struct file_operations vino_fops = { static struct video_device v4l_device_template = { .name = "NOT SET", - /*.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | */ - /* VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY */ .fops = &vino_fops, .minor = -1, }; diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index fcb69f8f0..573149cc0 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -1095,7 +1095,6 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = { static struct video_device vivi_template = { .name = "vivi", - .type = VID_TYPE_CAPTURE, .fops = &vivi_fops, .ioctl_ops = &vivi_ioctl_ops, .minor = -1, diff --git a/linux/drivers/media/video/w9966.c b/linux/drivers/media/video/w9966.c index 964c28c8a..6aefc6566 100644 --- a/linux/drivers/media/video/w9966.c +++ b/linux/drivers/media/video/w9966.c @@ -198,7 +198,6 @@ static const struct file_operations w9966_fops = { }; static struct video_device w9966_template = { .name = W9966_DRIVERNAME, - .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES, .fops = &w9966_fops, }; diff --git a/linux/drivers/media/video/w9968cf.c b/linux/drivers/media/video/w9968cf.c index 47b2ca9fe..666438e8d 100644 --- a/linux/drivers/media/video/w9968cf.c +++ b/linux/drivers/media/video/w9968cf.c @@ -3558,7 +3558,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, symbolic(camlist, mod_id)); - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &w9968cf_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; diff --git a/linux/drivers/media/video/zc0301/zc0301_core.c b/linux/drivers/media/video/zc0301/zc0301_core.c index 57d2f62e7..e59145f65 100644 --- a/linux/drivers/media/video/zc0301/zc0301_core.c +++ b/linux/drivers/media/video/zc0301/zc0301_core.c @@ -1989,7 +1989,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &zc0301_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; diff --git a/linux/drivers/media/video/zoran_driver.c b/linux/drivers/media/video/zoran_driver.c index 989a6f7e0..9f09f04cd 100644 --- a/linux/drivers/media/video/zoran_driver.c +++ b/linux/drivers/media/video/zoran_driver.c @@ -4709,8 +4709,6 @@ static const struct file_operations zoran_fops = { struct video_device zoran_template __devinitdata = { .name = ZORAN_NAME, - .type = ZORAN_VID_TYPE, - .type2 = ZORAN_V4L2_VID_FLAGS, .fops = &zoran_fops, .release = &zoran_vdev_release, .minor = -1 diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index a697d7d6f..53a934daa 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -781,7 +781,6 @@ static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { static struct video_device zr364xx_template = { .name = DRIVER_DESC, - .type = VID_TYPE_CAPTURE, .fops = &zr364xx_fops, .ioctl_ops = &zr364xx_ioctl_ops, .release = video_device_release, -- cgit v1.2.3 From 9d2bbe7ac1500f09286d51f912bdec9bb7d6b493 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 13:37:58 +0200 Subject: fix a few assorted spelling mistakes. From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/drivers/media/video/videobuf-vmalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/videobuf-vmalloc.c b/linux/drivers/media/video/videobuf-vmalloc.c index eb25cc257..e9cf83572 100644 --- a/linux/drivers/media/video/videobuf-vmalloc.c +++ b/linux/drivers/media/video/videobuf-vmalloc.c @@ -204,7 +204,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, return 0; /* FIXME: to properly support USERPTR, remap should occur. - The code bellow won't work, since mem->vma = NULL + The code below won't work, since mem->vma = NULL */ /* Try to remap memory */ rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0); -- cgit v1.2.3 From e791213b73718f65586a29d8cf7945fefd188429 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 14:01:24 +0200 Subject: saa7134-empress.c: fix deadlock From: Hans Verkuil ts_release() locked a mutex that videobuf_stop() also tried to obtain. But ts_release() shouldn't hold that mutex at all. Make empress_users atomic as well to prevent possible race condition. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7134/saa7134-empress.c | 12 ++++-------- linux/drivers/media/video/saa7134/saa7134.h | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 1d1c19680..d8f26ac84 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -89,14 +89,14 @@ static int ts_open(struct inode *inode, struct file *file) err = -EBUSY; if (!mutex_trylock(&dev->empress_tsq.vb_lock)) goto done; - if (dev->empress_users) + if (atomic_read(&dev->empress_users)) goto done_up; /* Unmute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); - dev->empress_users++; + atomic_inc(&dev->empress_users); file->private_data = dev; err = 0; @@ -110,8 +110,6 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->empress_tsq.vb_lock); - videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); @@ -122,9 +120,7 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - dev->empress_users--; - - mutex_unlock(&dev->empress_tsq.vb_lock); + atomic_dec(&dev->empress_users); return 0; } @@ -455,7 +451,7 @@ static void empress_signal_update(struct work_struct *work) ts_reset_encoder(dev); } else { dprintk("video signal acquired\n"); - if (dev->empress_users) + if (atomic_read(&dev->empress_users)) ts_init_encoder(dev); } } diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 053c358ff..9acb601c2 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -566,7 +566,7 @@ struct saa7134_dev { /* SAA7134_MPEG_EMPRESS only */ struct video_device *empress_dev; struct videobuf_queue empress_tsq; - unsigned int empress_users; + atomic_t empress_users; struct work_struct empress_workqueue; int empress_started; -- cgit v1.2.3 From ec67295f0c67ff8c37ae249851deb75140d15d83 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 14:04:06 +0200 Subject: empress: fix control handling oops From: Hans Verkuil Signed-off-by: Hans Verkuil --- .../drivers/media/video/saa7134/saa7134-empress.c | 20 +++++++++-- linux/drivers/media/video/saa7134/saa7134-video.c | 40 +++++++++++++++------- linux/drivers/media/video/saa7134/saa7134.h | 4 +-- 3 files changed, 48 insertions(+), 16 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index d8f26ac84..4ce2ea65f 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -329,6 +329,22 @@ static int empress_g_ext_ctrls(struct file *file, void *priv, return saa7134_i2c_call_saa6752(dev, VIDIOC_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) { @@ -415,8 +431,8 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { .vidioc_queryctrl = empress_queryctrl, .vidioc_querymenu = empress_querymenu, - .vidioc_g_ctrl = saa7134_g_ctrl, - .vidioc_s_ctrl = saa7134_s_ctrl, + .vidioc_g_ctrl = empress_g_ctrl, + .vidioc_s_ctrl = empress_s_ctrl, }; /* ----------------------------------------------------------- */ diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 7e04bfa19..350c5ff5a 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -1112,10 +1112,8 @@ static struct videobuf_queue_ops video_qops = { /* ------------------------------------------------------------------ */ -int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) +int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; const struct v4l2_queryctrl* ctrl; ctrl = ctrl_by_id(c->id); @@ -1160,20 +1158,31 @@ int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) } return 0; } -EXPORT_SYMBOL_GPL(saa7134_g_ctrl); +EXPORT_SYMBOL_GPL(saa7134_g_ctrl_internal); + +static int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) +{ + struct saa7134_fh *fh = priv; + + return saa7134_g_ctrl_internal(fh->dev, fh, c); +} -int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c) +int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c) { const struct v4l2_queryctrl* ctrl; - struct saa7134_fh *fh = f; - struct saa7134_dev *dev = fh->dev; unsigned long flags; int restart_overlay = 0; - int err = -EINVAL; + int err; - err = v4l2_prio_check(&dev->prio, &fh->prio); - if (0 != err) - return err; + /* When called from the empress code fh == NULL. + That needs to be fixed somehow, but for now this is + good enough. */ + if (fh) { + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; + } + err = -EINVAL; mutex_lock(&dev->lock); @@ -1274,7 +1283,14 @@ error: mutex_unlock(&dev->lock); return err; } -EXPORT_SYMBOL_GPL(saa7134_s_ctrl); +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); +} /* ------------------------------------------------------------------ */ diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 9acb601c2..e3ad9d9e7 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -668,8 +668,8 @@ extern unsigned int video_debug; extern struct video_device saa7134_video_template; extern struct video_device saa7134_radio_template; -int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c); -int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c); +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_videoport_init(struct saa7134_dev *dev); -- cgit v1.2.3 From de70eb5e79c86c8efc2c0568c70f44bf0752c336 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 14:16:29 +0200 Subject: saa7146: fix VIDIOC_ENUM_FMT From: Hans Verkuil VIDIOC_ENUM_FMT should keep the index and type fields. Instead, type was zeroed. Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_video.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index d3185e610..a2333bff8 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -959,21 +959,18 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int case VIDIOC_ENUM_FMT: { struct v4l2_fmtdesc *f = arg; - int index; switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OVERLAY: { - index = f->index; - if (index < 0 || index >= NUM_FORMATS) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (f->index >= NUM_FORMATS) return -EINVAL; - } - memset(f,0,sizeof(*f)); - f->index = index; - strlcpy((char *)f->description,formats[index].name,sizeof(f->description)); - f->pixelformat = formats[index].pixelformat; + strlcpy((char *)f->description, formats[f->index].name, + sizeof(f->description)); + f->pixelformat = formats[f->index].pixelformat; + f->flags = 0; + memset(f->reserved, 0, sizeof(f->reserved)); break; - } default: return -EINVAL; } -- cgit v1.2.3 From e3a2c9f318da42e472341ef31a8d11864d772a0a Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 26 Jul 2008 11:06:57 -0400 Subject: mxl5007t: move i2c gate handling outside of mutex protected code blocks From: Michael Krufky There is no reason to protect the i2c gate handling within the mxl5007t state mutex. Thanks to Steven Toth for pointing this out. Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/mxl5007t.c | 45 +++++++++++++++------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index fc6aec1bd..9fa8d82b2 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -665,11 +665,11 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) s32 rf_input_level; int ret; - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked); if (mxl_fail(ret)) goto fail; @@ -681,10 +681,11 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) goto fail; mxl_debug("rf input power: %d", rf_input_level); fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); return ret; } @@ -735,11 +736,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, return -EINVAL; } - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_tuner_init(state, mode); if (mxl_fail(ret)) goto fail; @@ -752,10 +753,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, state->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); return ret; } @@ -814,11 +816,11 @@ static int mxl5007t_set_analog_params(struct dvb_frontend *fe, } mxl_debug("setting mxl5007 to system %s", mode_name); - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode); if (mxl_fail(ret)) goto fail; @@ -830,10 +832,11 @@ static int mxl5007t_set_analog_params(struct dvb_frontend *fe, state->frequency = freq; state->bandwidth = 0; fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); return ret; } @@ -845,11 +848,11 @@ static int mxl5007t_init(struct dvb_frontend *fe) int ret; u8 d; - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_read_reg(state, 0x05, &d); if (mxl_fail(ret)) goto fail; @@ -857,11 +860,11 @@ static int mxl5007t_init(struct dvb_frontend *fe) ret = mxl5007t_write_reg(state, 0x05, d | 0x01); mxl_fail(ret); fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); - return ret; } @@ -871,11 +874,11 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) int ret; u8 d; - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_read_reg(state, 0x05, &d); if (mxl_fail(ret)) goto fail; @@ -883,11 +886,11 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); mxl_fail(ret); fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); - return ret; } @@ -1017,18 +1020,18 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, mutex_init(&state->lock); - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_get_chip_id(state); + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); - /* check return value of mxl5007t_get_chip_id */ if (mxl_fail(ret)) goto fail; -- cgit v1.2.3 From 0f759758075a8804b29f80b70dd0a54b3f0ff374 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 19:17:23 +0200 Subject: gspca: Set the specific per webcam information in driver_info for sonixb. From: Jean-Francois Moine Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixb.c | 134 +++++++++++++------------------ 1 file changed, 57 insertions(+), 77 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index b3dfa0447..fed9e30cf 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -58,6 +58,12 @@ struct sd { __u8 reg11; }; +/* flags used in the device id table */ +#define F_GAIN 0x01 /* has gain */ +#define F_AUTO 0x02 /* has autogain */ +#define F_SIF 0x04 /* sif or vga */ +#define F_H18 0x08 /* long (18 b) or short (12 b) frame header */ + #define COMP2 0x8f #define COMP 0xc7 /* 0x87 //0x07 */ #define COMP1 0xc9 /* 0x89 //0x09 */ @@ -784,74 +790,28 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 product; int sif = 0; /* nctrls depends upon the sensor, so we use a per cam copy */ memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc)); gspca_dev->sd_desc = &sd->sd_desc; - sd->fr_h_sz = 12; /* default size of the frame header */ - sd->sd_desc.nctrls = 2; /* default nb of ctrls */ - product = id->idProduct; -/* switch (id->idVendor) { */ -/* case 0x0c45: * Sonix */ - switch (product) { - case 0x6001: /* SN9C102 */ - case 0x6005: /* SN9C101 */ - case 0x6007: /* SN9C101 */ - sd->sensor = SENSOR_TAS5110; - sd->sensor_has_gain = 1; - sd->sd_desc.nctrls = 4; - sd->sd_desc.dq_callback = do_autogain; - sif = 1; - break; - case 0x6009: /* SN9C101 */ - case 0x600d: /* SN9C101 */ - case 0x6029: /* SN9C101 */ - sd->sensor = SENSOR_PAS106; - sif = 1; - break; - case 0x6011: /* SN9C101 - SN9C101G */ - sd->sensor = SENSOR_OV6650; - sd->sensor_has_gain = 1; - sd->sensor_addr = 0x60; - sd->sd_desc.nctrls = 5; - sd->sd_desc.dq_callback = do_autogain; - sif = 1; - break; - case 0x6019: /* SN9C101 */ - case 0x602c: /* SN9C102 */ - case 0x602e: /* SN9C102 */ - case 0x60b0: /* SN9C103 */ - sd->sensor = SENSOR_OV7630; - sd->sensor_addr = 0x21; - sd->sensor_has_gain = 1; - sd->sd_desc.nctrls = 5; - sd->sd_desc.dq_callback = do_autogain; - if (product == 0x60b0) - sd->fr_h_sz = 18; /* size of frame header */ - break; - case 0x6024: /* SN9C102 */ - case 0x6025: /* SN9C102 */ - sd->sensor = SENSOR_TAS5130CXX; - break; - case 0x6028: /* SN9C102 */ - sd->sensor = SENSOR_PAS202; - break; - case 0x602d: /* SN9C102 */ - sd->sensor = SENSOR_HV7131R; - break; - case 0x60af: /* SN9C103 */ - sd->sensor = SENSOR_PAS202; - sd->fr_h_sz = 18; /* size of frame header (?) */ - break; - } -/* break; */ -/* } */ + /* copy the webcam info from the device id */ + sd->sensor = (id->driver_info >> 24) & 0xff; + if (id->driver_info & (F_GAIN << 16)) + sd->sensor_has_gain = 1; + if (id->driver_info & (F_AUTO << 16)) + sd->sd_desc.dq_callback = do_autogain; + if (id->driver_info & (F_SIF << 16)) + sif = 1; + if (id->driver_info & (F_H18 << 16)) + sd->fr_h_sz = 18; /* size of frame header */ + else + sd->fr_h_sz = 12; + sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff; + sd->sensor_addr = id->driver_info & 0xff; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; if (!sif) { cam->cam_mode = vga_mode; @@ -1245,27 +1205,47 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name +#define SFCI(sensor, flags, nctrls, i2c_addr) \ + .driver_info = (SENSOR_ ## sensor << 24) \ + | ((flags) << 16) \ + | ((nctrls) << 8) \ + | (i2c_addr) static __devinitdata struct usb_device_id device_table[] = { #ifndef CONFIG_USB_SN9C102 - {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")}, - {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")}, - {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, - {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")}, - {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")}, + {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */ + SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */ + SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */ + SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */ + SFCI(PAS106, F_SIF, 2, 0)}, + {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */ + SFCI(PAS106, F_SIF, 2, 0)}, #endif - {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")}, + {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */ + SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)}, #ifndef CONFIG_USB_SN9C102 - {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")}, - {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")}, - {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")}, - {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")}, - {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")}, - {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")}, - {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")}, - {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")}, - {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")}, - {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")}, + {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ + SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ + SFCI(TAS5130CXX, 0, 2, 0)}, + {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ + SFCI(TAS5130CXX, 0, 2, 0)}, + {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */ + SFCI(PAS202, 0, 2, 0)}, + {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */ + SFCI(PAS106, F_SIF, 2, 0)}, + {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */ + SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */ + SFCI(HV7131R, 0, 2, 0)}, + {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */ + SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */ + SFCI(PAS202, F_H18, 2, 0)}, + {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */ + SFCI(OV7630, F_GAIN|F_AUTO|F_SIF|F_H18, 5, 0x21)}, #endif {} }; -- cgit v1.2.3 From 178fcff7ffd533c71c1849f411700ad8547b11e6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 19:30:01 +0200 Subject: gspca: Bad webcam information in some modules since 28b8203a830e. From: Jean-Francois Moine Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca500.c | 30 +++++++++++++++--------------- linux/drivers/media/video/gspca/spca501.c | 14 +++++++------- linux/drivers/media/video/gspca/spca505.c | 4 ++-- linux/drivers/media/video/gspca/spca508.c | 14 +++++++------- linux/drivers/media/video/gspca/spca561.c | 30 +++++++++++++++--------------- linux/drivers/media/video/gspca/vc032x.c | 16 ++++++++-------- 6 files changed, 54 insertions(+), 54 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index 09c89c1ac..be88d30a3 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -1078,21 +1078,21 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0300), KodakEZ200}, - {USB_DEVICE(0x041e, 0x400a), CreativePCCam300}, - {USB_DEVICE(0x046d, 0x0890), LogitechTraveler}, - {USB_DEVICE(0x046d, 0x0900), LogitechClickSmart310}, - {USB_DEVICE(0x046d, 0x0901), LogitechClickSmart510}, - {USB_DEVICE(0x04a5, 0x300c), BenqDC1016}, - {USB_DEVICE(0x04fc, 0x7333), PalmPixDC85}, - {USB_DEVICE(0x055f, 0xc200), MustekGsmart300}, - {USB_DEVICE(0x055f, 0xc220), Gsmartmini}, - {USB_DEVICE(0x06bd, 0x0404), AgfaCl20}, - {USB_DEVICE(0x06be, 0x0800), Optimedia}, - {USB_DEVICE(0x084d, 0x0003), DLinkDSC350}, - {USB_DEVICE(0x08ca, 0x0103), AiptekPocketDV}, - {USB_DEVICE(0x2899, 0x012c), ToptroIndus}, - {USB_DEVICE(0x8086, 0x0630), IntelPocketPCCamera}, + {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200}, + {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300}, + {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler}, + {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310}, + {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510}, + {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016}, + {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85}, + {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300}, + {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini}, + {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20}, + {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia}, + {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350}, + {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV}, + {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus}, + {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c index 8444c7c58..f8df18e85 100644 --- a/linux/drivers/media/video/gspca/spca501.c +++ b/linux/drivers/media/video/gspca/spca501.c @@ -2141,13 +2141,13 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0002), KodakDVC325}, - {USB_DEVICE(0x0497, 0xc001), SmileIntlCamera}, - {USB_DEVICE(0x0506, 0x00df), ThreeComHomeConnectLite}, - {USB_DEVICE(0x0733, 0x0401), IntelCreateAndShare}, - {USB_DEVICE(0x0733, 0x0402), ViewQuestM318B}, - {USB_DEVICE(0x1776, 0x501c), Arowana300KCMOSCamera}, - {USB_DEVICE(0x0000, 0x0000), MystFromOriUnknownCamera}, + {USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325}, + {USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera}, + {USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite}, + {USB_DEVICE(0x0733, 0x0401), .driver_info = IntelCreateAndShare}, + {USB_DEVICE(0x0733, 0x0402), .driver_info = ViewQuestM318B}, + {USB_DEVICE(0x1776, 0x501c), .driver_info = Arowana300KCMOSCamera}, + {USB_DEVICE(0x0000, 0x0000), .driver_info = MystFromOriUnknownCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index 83dd8abf9..c19cfebc1 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -904,8 +904,8 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401d), Nxultra}, - {USB_DEVICE(0x0733, 0x0430), IntelPCCameraPro}, + {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra}, + {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro}, /*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ {} }; diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index d4237525b..9fca74ad1 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1681,13 +1681,13 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x0130, 0x0130), HamaUSBSightcam}, - {USB_DEVICE(0x041e, 0x4018), CreativeVista}, - {USB_DEVICE(0x0461, 0x0815), MicroInnovationIC200}, - {USB_DEVICE(0x0733, 0x0110), ViewQuestVQ110}, - {USB_DEVICE(0x0af9, 0x0010), HamaUSBSightcam}, - {USB_DEVICE(0x0af9, 0x0011), HamaUSBSightcam2}, - {USB_DEVICE(0x8086, 0x0110), IntelEasyPCCamera}, + {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam}, + {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista}, + {USB_DEVICE(0x0461, 0x0815), .driver_info = MicroInnovationIC200}, + {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110}, + {USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam}, + {USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2}, + {USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 3b46f7dda..a26174508 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -975,21 +975,21 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401a), Rev072A}, - {USB_DEVICE(0x041e, 0x403b), Rev012A}, - {USB_DEVICE(0x0458, 0x7004), Rev072A}, - {USB_DEVICE(0x046d, 0x0928), Rev012A}, - {USB_DEVICE(0x046d, 0x0929), Rev012A}, - {USB_DEVICE(0x046d, 0x092a), Rev012A}, - {USB_DEVICE(0x046d, 0x092b), Rev012A}, - {USB_DEVICE(0x046d, 0x092c), Rev012A}, - {USB_DEVICE(0x046d, 0x092d), Rev012A}, - {USB_DEVICE(0x046d, 0x092e), Rev012A}, - {USB_DEVICE(0x046d, 0x092f), Rev012A}, - {USB_DEVICE(0x04fc, 0x0561), Rev072A}, - {USB_DEVICE(0x060b, 0xa001), Rev072A}, - {USB_DEVICE(0x10fd, 0x7e50), Rev072A}, - {USB_DEVICE(0xabcd, 0xcdee), Rev072A}, + {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A}, + {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A}, + {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A}, + {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A}, + {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A}, + {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A}, + {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A}, + {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A}, {} }; diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index a83944228..4c4daf6ec 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -1946,14 +1946,14 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0x0892), BRIDGE_VC0321}, - {USB_DEVICE(0x046d, 0x0896), BRIDGE_VC0321}, - {USB_DEVICE(0x0ac8, 0x0321), BRIDGE_VC0321}, - {USB_DEVICE(0x0ac8, 0x0323), BRIDGE_VC0323}, - {USB_DEVICE(0x0ac8, 0x0328), BRIDGE_VC0321}, - {USB_DEVICE(0x0ac8, 0xc001), BRIDGE_VC0321}, - {USB_DEVICE(0x0ac8, 0xc002), BRIDGE_VC0321}, - {USB_DEVICE(0x17ef, 0x4802), BRIDGE_VC0323}, + {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323}, + {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From 77b963e9fbc0911412eb7b86df83d976f81abf2d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 26 Jul 2008 14:43:17 -0400 Subject: mxl5007t: remove excessive locks From: Michael Krufky The use of mutex locking is overly paranoid in this driver. The only locks we need are around the manipulation of the register arrays. The other locks are not needed - remove them. Thanks to Steven Toth for pointing this out. Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/mxl5007t.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c index 9fa8d82b2..e795650c2 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.c +++ b/linux/drivers/media/common/tuners/mxl5007t.c @@ -668,8 +668,6 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - mutex_lock(&state->lock); - ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked); if (mxl_fail(ret)) goto fail; @@ -681,8 +679,6 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) goto fail; mxl_debug("rf input power: %d", rf_input_level); fail: - mutex_unlock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -851,8 +847,6 @@ static int mxl5007t_init(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - mutex_lock(&state->lock); - ret = mxl5007t_read_reg(state, 0x05, &d); if (mxl_fail(ret)) goto fail; @@ -860,8 +854,6 @@ static int mxl5007t_init(struct dvb_frontend *fe) ret = mxl5007t_write_reg(state, 0x05, d | 0x01); mxl_fail(ret); fail: - mutex_unlock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -877,8 +869,6 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - mutex_lock(&state->lock); - ret = mxl5007t_read_reg(state, 0x05, &d); if (mxl_fail(ret)) goto fail; @@ -886,8 +876,6 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); mxl_fail(ret); fail: - mutex_unlock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -1023,12 +1011,8 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - mutex_lock(&state->lock); - ret = mxl5007t_get_chip_id(state); - mutex_unlock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); -- cgit v1.2.3 From 52ec8fb25f8dc47b38cfc49a11662da844ef0568 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 26 Jul 2008 17:28:26 -0400 Subject: pvrusb2: fix device descriptions for HVR-1900 & HVR-1950 From: Michael Krufky Signed-off-by: Michael Krufky Acked-By: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c index e3b051197..88e175168 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -330,7 +330,7 @@ static const char *pvr2_fw1_names_73xxx[] = { }; static const struct pvr2_device_desc pvr2_device_73xxx = { - .description = "WinTV PVR USB2 Model Category 73xxx", + .description = "WinTV HVR-1900 Model Category 73xxx", .shortname = "73xxx", .client_modules.lst = pvr2_client_73xxx, .client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx), @@ -439,7 +439,7 @@ static const char *pvr2_fw1_names_75xxx[] = { }; static const struct pvr2_device_desc pvr2_device_750xx = { - .description = "WinTV PVR USB2 Model Category 750xx", + .description = "WinTV HVR-1950 Model Category 750xx", .shortname = "750xx", .client_modules.lst = pvr2_client_75xxx, .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), @@ -461,7 +461,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = { }; static const struct pvr2_device_desc pvr2_device_751xx = { - .description = "WinTV PVR USB2 Model Category 751xx", + .description = "WinTV HVR-1950 Model Category 751xx", .shortname = "751xx", .client_modules.lst = pvr2_client_75xxx, .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), -- cgit v1.2.3 From 68a9ab040fc3603f2d5cf37f95bed2659afb320a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 27 Jul 2008 07:56:33 +0200 Subject: gspca: Webcams with Sonix bridge and sensor ov7630 are VGA. From: Jean-Francois Moine This fixes a bug introduced in c503a6f8332a (thanks to Hans de Goede). Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index fed9e30cf..b249015f2 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -1227,7 +1227,7 @@ static __devinitdata struct usb_device_id device_table[] = { SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)}, #ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ SFCI(TAS5130CXX, 0, 2, 0)}, {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ @@ -1237,15 +1237,15 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */ SFCI(PAS106, F_SIF, 2, 0)}, {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */ SFCI(HV7131R, 0, 2, 0)}, {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */ SFCI(PAS202, F_H18, 2, 0)}, {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_SIF|F_H18, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)}, #endif {} }; -- cgit v1.2.3 From f1fae3804533a11cddcf0187578fb003416523df Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 27 Jul 2008 11:30:21 +0200 Subject: s2255drv: add missing header From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/drivers/media/video/s2255drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c index 97820ee4a..e09b43c31 100644 --- a/linux/drivers/media/video/s2255drv.c +++ b/linux/drivers/media/video/s2255drv.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From b758fc01ef8bdaa9a7380ef01c1e27cf6a96e256 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 13:04:55 +0000 Subject: remove select's of FW_LOADER From: Adrian Bunk After commit d9b19199e4894089456aaad295023263b5225c1a (always enable FW_LOADER unless EMBEDDED=y) we can remove the FW_LOADER select's and corresponding dependencies on HOTPLUG. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/Kconfig | 9 ++------- linux/drivers/media/dvb/bt8xx/Kconfig | 2 -- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 -- linux/drivers/media/dvb/frontends/Kconfig | 24 ++++++++---------------- linux/drivers/media/dvb/ttpci/Kconfig | 4 ---- linux/drivers/media/dvb/ttusb-dec/Kconfig | 2 -- linux/drivers/media/video/bt8xx/Kconfig | 2 -- linux/drivers/media/video/cx18/Kconfig | 2 -- linux/drivers/media/video/cx23885/Kconfig | 2 -- linux/drivers/media/video/cx25840/Kconfig | 2 -- linux/drivers/media/video/cx88/Kconfig | 3 +-- linux/drivers/media/video/ivtv/Kconfig | 2 -- linux/drivers/media/video/pvrusb2/Kconfig | 2 -- linux/drivers/media/video/saa7134/Kconfig | 2 -- 14 files changed, 11 insertions(+), 49 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/Kconfig b/linux/drivers/media/common/tuners/Kconfig index 8d93ba857..6f92beaa5 100644 --- a/linux/drivers/media/common/tuners/Kconfig +++ b/linux/drivers/media/common/tuners/Kconfig @@ -21,9 +21,8 @@ config MEDIA_TUNER tristate default VIDEO_MEDIA && I2C depends on VIDEO_MEDIA && I2C - select FW_LOADER if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE @@ -138,8 +137,6 @@ config MEDIA_TUNER_QT1010 config MEDIA_TUNER_XC2028 tristate "XCeive xc2028/xc3028 tuners" depends on VIDEO_MEDIA && I2C - depends on HOTPLUG - select FW_LOADER default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the xc2028/xc3028 tuners. @@ -147,8 +144,6 @@ config MEDIA_TUNER_XC2028 config MEDIA_TUNER_XC5000 tristate "Xceive XC5000 silicon tuner" depends on VIDEO_MEDIA && I2C - depends on HOTPLUG - select FW_LOADER default m if DVB_FE_CUSTOMISE help A driver for the silicon tuner XC5000 from Xceive. diff --git a/linux/drivers/media/dvb/bt8xx/Kconfig b/linux/drivers/media/dvb/bt8xx/Kconfig index 7588db131..7e9c090fc 100644 --- a/linux/drivers/media/dvb/bt8xx/Kconfig +++ b/linux/drivers/media/dvb/bt8xx/Kconfig @@ -1,7 +1,6 @@ config DVB_BT8XX tristate "BT8xx based PCI cards" depends on DVB_CORE && PCI && I2C && VIDEO_BT848 - depends on HOTPLUG # due to FW_LOADER select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_SP887X if !DVB_FE_CUSTOMISE select DVB_NXT6000 if !DVB_FE_CUSTOMISE @@ -10,7 +9,6 @@ config DVB_BT8XX select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE - select FW_LOADER help Support for PCI cards based on the Bt8xx PCI bridge. Examples are the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 3c663c65e..e84152b75 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -1,8 +1,6 @@ config DVB_USB tristate "Support for various USB DVB devices" depends on DVB_CORE && USB && I2C && INPUT - depends on HOTPLUG # due to FW_LOADER - select FW_LOADER help By enabling this you will be able to choose the various supported USB1.1 and USB2.0 DVB devices. diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index fa7f0c563..574dffe91 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -97,9 +97,8 @@ comment "DVB-T (terrestrial) frontends" config DVB_SP8870 tristate "Spase sp8870 based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. @@ -110,9 +109,8 @@ config DVB_SP8870 config DVB_SP887X tristate "Spase sp887x based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. @@ -158,9 +156,8 @@ config DVB_L64781 config DVB_TDA1004X tristate "Philips TDA10045H/TDA10046H based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. @@ -225,9 +222,8 @@ config DVB_DIB7000P config DVB_TDA10048 tristate "Philips TDA10048HN based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. @@ -267,9 +263,8 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" config DVB_NXT200X tristate "NxtWave Communications NXT2002/NXT2004 based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. @@ -282,9 +277,8 @@ config DVB_NXT200X config DVB_OR51211 tristate "Oren OR51211 based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help An ATSC 8VSB tuner module. Say Y when you want to support this frontend. @@ -295,9 +289,8 @@ config DVB_OR51211 config DVB_OR51132 tristate "Oren OR51132 based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. @@ -311,9 +304,8 @@ config DVB_OR51132 config DVB_BCM3510 tristate "Broadcom BCM3510" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig index 87c973ac6..41b5a988b 100644 --- a/linux/drivers/media/dvb/ttpci/Kconfig +++ b/linux/drivers/media/dvb/ttpci/Kconfig @@ -5,8 +5,6 @@ config TTPCI_EEPROM config DVB_AV7110 tristate "AV7110 cards" depends on DVB_CORE && PCI && I2C - depends on HOTPLUG - select FW_LOADER if !DVB_AV7110_FIRMWARE select TTPCI_EEPROM select VIDEO_SAA7146_VV depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV @@ -127,14 +125,12 @@ config DVB_BUDGET_AV depends on DVB_BUDGET_CORE && I2C select VIDEO_SAA7146_VV depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV - depends on HOTPLUG # dependency of FW_LOADER select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_TDA10021 if !DVB_FE_CUSTOMISE select DVB_TDA10023 if !DVB_FE_CUSTOMISE select DVB_TUA6100 if !DVB_FE_CUSTOMISE - select FW_LOADER help Support for simple SAA7146 based DVB cards (so called Budget- or Nova-PCI cards) without onboard diff --git a/linux/drivers/media/dvb/ttusb-dec/Kconfig b/linux/drivers/media/dvb/ttusb-dec/Kconfig index a23cc0aa1..d5f48a310 100644 --- a/linux/drivers/media/dvb/ttusb-dec/Kconfig +++ b/linux/drivers/media/dvb/ttusb-dec/Kconfig @@ -1,8 +1,6 @@ config DVB_TTUSB_DEC tristate "Technotrend/Hauppauge USB DEC devices" depends on DVB_CORE && USB && INPUT - depends on HOTPLUG # due to FW_LOADER - select FW_LOADER select CRC32 help Support for external USB adapters designed by Technotrend and diff --git a/linux/drivers/media/video/bt8xx/Kconfig b/linux/drivers/media/video/bt8xx/Kconfig index 24a34fc1f..ce71e8e7b 100644 --- a/linux/drivers/media/video/bt8xx/Kconfig +++ b/linux/drivers/media/video/bt8xx/Kconfig @@ -1,9 +1,7 @@ config VIDEO_BT848 tristate "BT848 Video For Linux" depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_BTCX select VIDEOBUF_DMA_SG select VIDEO_IR diff --git a/linux/drivers/media/video/cx18/Kconfig b/linux/drivers/media/video/cx18/Kconfig index 9aefdc5ea..ef48565de 100644 --- a/linux/drivers/media/video/cx18/Kconfig +++ b/linux/drivers/media/video/cx18/Kconfig @@ -2,9 +2,7 @@ config VIDEO_CX18 tristate "Conexant cx23418 MPEG encoder support" depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL depends on INPUT # due to VIDEO_IR - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_IR select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/linux/drivers/media/video/cx23885/Kconfig b/linux/drivers/media/video/cx23885/Kconfig index 5cfb46bbd..e60bd31b5 100644 --- a/linux/drivers/media/video/cx23885/Kconfig +++ b/linux/drivers/media/video/cx23885/Kconfig @@ -1,9 +1,7 @@ config VIDEO_CX23885 tristate "Conexant cx23885 (2388x successor) support" depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_BTCX select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/linux/drivers/media/video/cx25840/Kconfig b/linux/drivers/media/video/cx25840/Kconfig index 448f4cd0c..de515dada 100644 --- a/linux/drivers/media/video/cx25840/Kconfig +++ b/linux/drivers/media/video/cx25840/Kconfig @@ -1,8 +1,6 @@ config VIDEO_CX25840 tristate "Conexant CX2584x audio/video decoders" depends on VIDEO_V4L2 && I2C && EXPERIMENTAL - depends on HOTPLUG # due to FW_LOADER - select FW_LOADER ---help--- Support for the Conexant CX2584x audio/video decoders. diff --git a/linux/drivers/media/video/cx88/Kconfig b/linux/drivers/media/video/cx88/Kconfig index 10e20d819..9dd7bdf65 100644 --- a/linux/drivers/media/video/cx88/Kconfig +++ b/linux/drivers/media/video/cx88/Kconfig @@ -33,9 +33,8 @@ config VIDEO_CX88_ALSA config VIDEO_CX88_BLACKBIRD tristate "Blackbird MPEG encoder support (cx2388x + cx23416)" - depends on VIDEO_CX88 && HOTPLUG + depends on VIDEO_CX88 select VIDEO_CX2341X - select FW_LOADER ---help--- This adds support for MPEG encoder cards based on the Blackbird reference design, using the Conexant 2388x diff --git a/linux/drivers/media/video/ivtv/Kconfig b/linux/drivers/media/video/ivtv/Kconfig index 5d7ee8fcd..0069898bd 100644 --- a/linux/drivers/media/video/ivtv/Kconfig +++ b/linux/drivers/media/video/ivtv/Kconfig @@ -2,9 +2,7 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL depends on INPUT # due to VIDEO_IR - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_IR select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/linux/drivers/media/video/pvrusb2/Kconfig b/linux/drivers/media/video/pvrusb2/Kconfig index 4482b2c72..19eb274c9 100644 --- a/linux/drivers/media/video/pvrusb2/Kconfig +++ b/linux/drivers/media/video/pvrusb2/Kconfig @@ -2,8 +2,6 @@ config VIDEO_PVRUSB2 tristate "Hauppauge WinTV-PVR USB2 support" depends on VIDEO_V4L2 && I2C depends on VIDEO_MEDIA # Avoids pvrusb = Y / DVB = M - depends on HOTPLUG # due to FW_LOADER - select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_CX2341X diff --git a/linux/drivers/media/video/saa7134/Kconfig b/linux/drivers/media/video/saa7134/Kconfig index 83f076abc..7021bbf58 100644 --- a/linux/drivers/media/video/saa7134/Kconfig +++ b/linux/drivers/media/video/saa7134/Kconfig @@ -27,9 +27,7 @@ config VIDEO_SAA7134_ALSA config VIDEO_SAA7134_DVB tristate "DVB/ATSC Support for saa7134 based TV cards" depends on VIDEO_SAA7134 && DVB_CORE - depends on HOTPLUG # due to FW_LOADER select VIDEOBUF_DVB - select FW_LOADER select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE -- cgit v1.2.3 From 983693ce340ad9713179eaac6359a5cac52ce858 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 12:33:36 -0300 Subject: backport commit 27ac792ca0b0a1e7e65f20342260650516c95864 From: Mauro Carvalho Chehab kernel-sync: Author: Andrea Righi Date: Wed Jul 23 21:28:13 2008 -0700 PAGE_ALIGN(): correctly handle 64-bit values on 32-bit architectures On 32-bit architectures PAGE_ALIGN() truncates 64-bit values to the 32-bit boundary. For example: u64 val = PAGE_ALIGN(size); always returns a value < 4GB even if size is greater than 4GB. The problem resides in PAGE_MASK definition (from include/asm-x86/page.h for example): #define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) ... #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) The "~" is performed on a 32-bit value, so everything in "and" with PAGE_MASK greater than 4GB will be truncated to the 32-bit boundary. Using the ALIGN() macro seems to be the right way, because it uses typeof(addr) for the mask. Also move the PAGE_ALIGN() definitions out of include/asm-*/page.h in include/linux/mm.h. See also lkml discussion: http://lkml.org/lkml/2008/6/11/237 [akpm@linux-foundation.org: fix drivers/media/video/uvc/uvc_queue.c] [akpm@linux-foundation.org: fix v850] [akpm@linux-foundation.org: fix powerpc] [akpm@linux-foundation.org: fix arm] [akpm@linux-foundation.org: fix mips] [akpm@linux-foundation.org: fix drivers/media/video/pvrusb2/pvrusb2-dvb.c] [akpm@linux-foundation.org: fix drivers/mtd/maps/uclinux.c] [akpm@linux-foundation.org: fix powerpc] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/pvrusb2/pvrusb2-dvb.c | 1 + linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c | 1 + linux/drivers/media/video/uvc/uvc_queue.c | 1 + linux/drivers/media/video/videobuf-core.c | 1 + 4 files changed, 4 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/linux/drivers/media/video/pvrusb2/pvrusb2-dvb.c index a317347ad..29d18e867 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-dvb.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-dvb.c @@ -24,6 +24,7 @@ #else #include #endif +#include #include "compat.h" #include "dvbdev.h" #include "pvrusb2-debug.h" diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c index fa599a1bf..987e71142 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c @@ -22,6 +22,7 @@ #include "pvrusb2-debug.h" #include #include +#include #include #include #include diff --git a/linux/drivers/media/video/uvc/uvc_queue.c b/linux/drivers/media/video/uvc/uvc_queue.c index 7388d0cee..5646a6a32 100644 --- a/linux/drivers/media/video/uvc/uvc_queue.c +++ b/linux/drivers/media/video/uvc/uvc_queue.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/linux/drivers/media/video/videobuf-core.c b/linux/drivers/media/video/videobuf-core.c index 16c32c68c..b104cd593 100644 --- a/linux/drivers/media/video/videobuf-core.c +++ b/linux/drivers/media/video/videobuf-core.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From ae79da457847bbc639abf3ac9053839a1dafe67f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 12:36:24 -0300 Subject: backport commit 8d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06 From: Mauro Carvalho Chehab kernel-sync: Author: FUJITA Tomonori Date: Fri Jul 25 19:44:49 2008 -0700 dma-mapping: add the device argument to dma_mapping_error() Add per-device dma_mapping_ops support for CONFIG_X86_64 as POWER architecture does: This enables us to cleanly fix the Calgary IOMMU issue that some devices are not behind the IOMMU (http://lkml.org/lkml/2008/5/8/423). I think that per-device dma_mapping_ops support would be also helpful for KVM people to support PCI passthrough but Andi thinks that this makes it difficult to support the PCI passthrough (see the above thread). So I CC'ed this to KVM camp. Comments are appreciated. A pointer to dma_mapping_ops to struct dev_archdata is added. If the pointer is non NULL, DMA operations in asm/dma-mapping.h use it. If it's NULL, the system-wide dma_ops pointer is used as before. If it's useful for KVM people, I plan to implement a mechanism to register a hook called when a new pci (or dma capable) device is created (it works with hot plugging). It enables IOMMUs to set up an appropriate dma_mapping_ops per device. The major obstacle is that dma_mapping_error doesn't take a pointer to the device unlike other DMA operations. So x86 can't have dma_mapping_ops per device. Note all the POWER IOMMUs use the same dma_mapping_error function so this is not a problem for POWER but x86 IOMMUs use different dma_mapping_error functions. The first patch adds the device argument to dma_mapping_error. The patch is trivial but large since it touches lots of drivers and dma-mapping.h in all the architecture. This patch: dma_mapping_error() doesn't take a pointer to the device unlike other DMA operations. So we can't have dma_mapping_ops per device. Note that POWER already has dma_mapping_ops per device but all the POWER IOMMUs use the same dma_mapping_error function. x86 IOMMUs use device argument. [akpm@linux-foundation.org: fix sge] [akpm@linux-foundation.org: fix svc_rdma] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix bnx2x] [akpm@linux-foundation.org: fix s2io] [akpm@linux-foundation.org: fix pasemi_mac] [akpm@linux-foundation.org: fix sdhci] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix sparc] [akpm@linux-foundation.org: fix ibmvscsi] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/pluto2/pluto2.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c index d654d872e..cb368e2e0 100644 --- a/linux/drivers/media/dvb/pluto2/pluto2.c +++ b/linux/drivers/media/dvb/pluto2/pluto2.c @@ -242,7 +242,11 @@ static int __devinit pluto_dma_map(struct pluto *pluto) pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf, TS_DMA_BYTES, PCI_DMA_FROMDEVICE); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) return pci_dma_mapping_error(pluto->dma_addr); +#else + return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr); +#endif } static void pluto_dma_unmap(struct pluto *pluto) -- cgit v1.2.3 From acc5679dd0f99d8651e8018872bcc7d0d719c7d1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 13:47:52 -0300 Subject: em28xx-cards: Add GrabBeeX+ USB2800 model From: Aron Szabo Added GrabBeeX+ USB2800 model (analog only) Signed-off-by: Aron Szabo Signed-off-by: Douglas Schilling Landgraf [mchehab@infradead.org: Need to fix some merge conflicts] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 19 +++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx.h | 1 + 2 files changed, 20 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 9510ac044..97b0cde6e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -376,6 +376,21 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2800_BOARD_GRABBEEX_USB2800] = { + .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", + .is_em2800 = 1, + .vchannels = 2, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { .name = "Leadtek Winfast USB II", .is_em2800 = 1, @@ -542,6 +557,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, { USB_DEVICE(0x0438, 0xb002), .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, + { USB_DEVICE(0xeb1a, 0x2801), + .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -864,6 +881,8 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) break; case (EM2800_BOARD_KWORLD_USB2800): break; + case (EM2800_BOARD_GRABBEEX_USB2800): + break; } } diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 8c97635c2..7d397fc12 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -60,6 +60,7 @@ #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 +#define EM2800_BOARD_GRABBEEX_USB2800 21 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From 7badc67bd1dbbce7a96802f2aba9fa94695a70d4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 27 Jul 2008 19:01:59 +0200 Subject: gspca: probe/open race. From: Oliver Neukum The device is flagged present after it is registered. During that window calls to open() that should work fail with -ENODEV. Reversing the order fixes the race. Signed-off-by: Oliver Neukum Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 3c4ce567f..ffa2d7de0 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -1765,6 +1765,7 @@ int gspca_dev_probe(struct usb_interface *intf, memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops); gspca_dev->vdev.fops = &gspca_dev->fops; gspca_dev->fops.owner = module; /* module protection */ + gspca_dev->present = 1; ret = video_register_device(&gspca_dev->vdev, VFL_TYPE_GRABBER, video_nr); @@ -1773,7 +1774,6 @@ int gspca_dev_probe(struct usb_interface *intf, goto out; } - gspca_dev->present = 1; usb_set_intfdata(intf, gspca_dev); PDEBUG(D_PROBE, "probe ok"); return 0; -- cgit v1.2.3 From da9aefb66f5cb47a840fa62630e2b6daecfba5b5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 14:03:32 -0300 Subject: em28xx-cards: New supported IDs for analog models From: Douglas Schilling Landgraf - New supported IDs for analog models (Based on Markus Rechberger version of em28xx driver) - Validation field for new em28xx boards. Signed-off-by: Douglas Schilling Landgraf [mchehab@infradead.org: Need to fix some merge conflicts] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 1223 +++++++++++++++++++---- linux/drivers/media/video/em28xx/em28xx.h | 45 +- 2 files changed, 1094 insertions(+), 174 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 97b0cde6e..b2b017afc 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -53,6 +53,15 @@ struct em28xx_hash_table { }; struct em28xx_board em28xx_boards[] = { + [EM2750_BOARD_UNKNOWN] = { + .name = "Unknown EM2750/EM2751 webcam grabber", + .vchannels = 1, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 0, + } }, + }, [EM2800_BOARD_UNKNOWN] = { .name = "Unknown EM2800 video grabber", .is_em2800 = 1, @@ -74,6 +83,39 @@ struct em28xx_board em28xx_boards[] = { .is_em2800 = 0, .tuner_type = TUNER_ABSENT, }, + [EM2750_BOARD_DLCW_130] = { + /* Beijing Huaqi Information Digital Technology Co., Ltd */ + .name = "Huaqi DLCW-130", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 1, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 0, + } }, + }, + [EM2800_BOARD_KWORLD_USB2800] = { + .name = "Kworld USB2800", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_PHILIPS_FCV1236D, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, [EM2820_BOARD_KWORLD_PVRTV2800RF] = { .name = "Kworld PVR TV 2800 RF", .is_em2800 = 0, @@ -152,13 +194,251 @@ struct em28xx_board em28xx_boards[] = { MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), } }, }, - [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { - .name = "Hauppauge WinTV HVR 900", + [EM2820_BOARD_DLINK_USB_TV] = { + .name = "D-Link DUB-T210 TV Tuner", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .is_em2800 = 0, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_HERCULES_SMART_TV_USB2] = { + .name = "Hercules Smart TV USB 2.0", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = { + .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .is_em2800 = 0, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_GADMEI_UTV310] = { + .name = "Gadmei UTV310", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_TNF_5335MF, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = { + .name = "Leadtek Winfast USB II Deluxe", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7114, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = 2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = 9, + .amux = 1, + } }, + }, + [EM2820_BOARD_PINNACLE_DVC_100] = { + .name = "Pinnacle Dazzle DVC 100", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { + .name = "Videology 20K14XUSB USB2.0", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 1, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 0, + } }, + }, + [EM2821_BOARD_PROLINK_PLAYTV_USB2] = { + .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .is_em2800 = 0, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */ + .tda9887_conf = TDA9887_PRESENT, /* unknown? */ + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2821_BOARD_SUPERCOMP_USB_2] = { + .name = "Supercomp USB 2.0 TV", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .is_em2800 = 0, + .tuner_type = TUNER_PHILIPS_FM1236_MK3, + .tda9887_conf = TDA9887_PRESENT | + TDA9887_PORT1_ACTIVE | + TDA9887_PORT2_ACTIVE, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2821_BOARD_USBGEAR_VD204] = { + .name = "Usbgear VD204v9", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 2, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2860_BOARD_NETGMBH_CAM] = { + /* Beijing Huaqi Information Digital Technology Co., Ltd */ + .name = "NetGMBH Cam", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 1, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 0, + } }, + }, + [EM2860_BOARD_TYPHOON_DVD_MAKER] = { + .name = "Typhoon DVD Maker", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 2, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2860_BOARD_GADMEI_UTV330] = { + .name = "Gadmei UTV330", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, + .tuner_type = TUNER_TNF_5335MF, .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2860_BOARD_TERRATEC_HYBRID_XS] = { + .name = "Terratec Cinergy A Hybrid XS", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_dvb = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -174,12 +454,11 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { - .name = "Hauppauge WinTV HVR 900 (R2)", + [EM2861_BOARD_KWORLD_PVRTV_300U] = { + .name = "KWorld PVRTV 300U", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, - .mts_firmware = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -195,16 +474,12 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { - .name = "Hauppauge WinTV HVR 950", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, - .input = { { + [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { + .name = "Yakumo MovieMixer", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 1, + .decoder = EM28XX_TVP5150, + .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, .amux = 0, @@ -218,19 +493,17 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { - .name = "Pinnacle PCTV HD Pro Stick", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, + [EM2861_BOARD_PLEXTOR_PX_TV100U] = { + .name = "Plextor ConvertX PX-TV100U", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_TNF_5335MF, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, - .amux = 0, + .amux = 1, }, { .type = EM28XX_VMUX_COMPOSITE1, .vmux = TVP5150_COMPOSITE1, @@ -241,15 +514,42 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { - .name = "AMD ATI TV Wonder HD 600", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, + [EM2870_BOARD_TERRATEC_XS] = { + .name = "Terratec Cinergy T XS", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_XC2028, + }, + [EM2870_BOARD_TERRATEC_XS_MT2060] = { + .name = "Terratec Cinergy T XS (MT2060)", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_ABSENT, /* MT2060 */ + }, + [EM2870_BOARD_KWORLD_350U] = { + .name = "Kworld 350 U DVB-T", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_XC2028, + }, + [EM2870_BOARD_KWORLD_355U] = { + .name = "Kworld 355 U DVB-T", + .valid = EM28XX_BOARD_NOT_VALIDATED, + }, + [EM2870_BOARD_PINNACLE_PCTV_DVB] = { + .name = "Pinnacle PCTV DVB-T", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_ABSENT, /* MT2060 */ + }, + [EM2870_BOARD_COMPRO_VIDEOMATE] = { + .name = "Compro, VideoMate U3", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_ABSENT, /* MT2060 */ + }, + [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { + .name = "Terratec Hybrid XS Secam", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .has_msp34xx = 1, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -264,15 +564,382 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { - .name = "AMD ATI TV Wonder HD 600", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { + .name = "Hauppauge WinTV HVR 900", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { + .name = "Hauppauge WinTV HVR 900 (R2)", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { + .name = "Hauppauge WinTV HVR 950", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { + .name = "Pinnacle PCTV HD Pro Stick", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { + .name = "AMD ATI TV Wonder HD 600", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { + .name = "AMD ATI TV Wonder HD 600", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_TERRATEC_HYBRID_XS] = { + .name = "Terratec Hybrid XS", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, + .has_dvb = 1, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + /* maybe there's a reason behind it why Terratec sells the Hybrid XS + as Prodigy XS with a different PID, let's keep it separated for now + maybe we'll need it lateron */ + [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { + .name = "Terratec Prodigy XS", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2820_BOARD_MSI_VOX_USB_2] = { + .name = "MSI VOX USB 2.0", + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT | + TDA9887_PORT1_ACTIVE | + TDA9887_PORT2_ACTIVE, + .max_range_640_480 = 1, + + .decoder = EM28XX_SAA7114, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE4, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_TERRATEC_CINERGY_200] = { + .name = "Terratec Cinergy 200 USB", + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_GRABBEEX_USB2800] = { + .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", + .is_em2800 = 1, + .vchannels = 2, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { + .name = "Leadtek Winfast USB II", + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_KWORLD_USB2800] = { + .name = "Kworld USB2800", + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_PHILIPS_FCV1236D, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_PINNACLE_DVC_90] = { + .name = "Pinnacle Dazzle DVC 90/DVC 100", + .vchannels = 3, + .tuner_type = TUNER_ABSENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_VGEAR_POCKETTV] = { + .name = "V-Gear PocketTV", + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { + .name = "Pixelview Prolink PlayTV USB 2.0", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_YMEC_TVF_5533MF, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, + [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { + .name = "PointNix Intra-Oral Camera", + .has_snapshot_button = 1, + .vchannels = 1, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_ABSENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 0, + } }, + }, + [EM2880_BOARD_MSI_DIGIVOX_AD] = { + .name = "MSI DigiVox A/D", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_MSI_DIGIVOX_AD_II] = { + .name = "MSI DigiVox A/D II", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -287,13 +954,12 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_TERRATEC_HYBRID_XS] = { - .name = "Terratec Hybrid XS", + [EM2880_BOARD_KWORLD_DVB_305U] = { + .name = "KWorld DVB-T 305U", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .decoder = EM28XX_TVP5150, - .has_dvb = 1, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -308,13 +974,10 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - /* maybe there's a reason behind it why Terratec sells the Hybrid XS - as Prodigy XS with a different PID, let's keep it separated for now - maybe we'll need it lateron */ - [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { - .name = "Terratec Prodigy XS", + [EM2880_BOARD_KWORLD_DVB_310U] = { + .name = "KWorld DVB-T 310U", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .decoder = EM28XX_TVP5150, .input = { { @@ -331,175 +994,145 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2820_BOARD_MSI_VOX_USB_2] = { - .name = "MSI VOX USB 2.0", - .vchannels = 3, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT | - TDA9887_PORT1_ACTIVE | - TDA9887_PORT2_ACTIVE, - .max_range_640_480 = 1, - - .decoder = EM28XX_SAA7114, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE4, - .amux = 0, - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, - .amux = 1, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, - .amux = 1, - } }, - }, - [EM2800_BOARD_TERRATEC_CINERGY_200] = { - .name = "Terratec Cinergy 200 USB", - .is_em2800 = 1, + [EM2881_BOARD_DNT_DA2_HYBRID] = { + .name = "DNT DA2 Hybrid", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = TVP5150_COMPOSITE0, .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2800_BOARD_GRABBEEX_USB2800] = { - .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", - .is_em2800 = 1, - .vchannels = 2, - .decoder = EM28XX_SAA7113, + [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { + .name = "Pinnacle Hybrid Pro", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { - .name = "Leadtek Winfast USB II", - .is_em2800 = 1, + [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { + .name = "Pinnacle Hybrid Pro (2)", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = TVP5150_COMPOSITE0, .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2800_BOARD_KWORLD_USB2800] = { - .name = "Kworld USB2800", - .is_em2800 = 1, + [EM2882_BOARD_KWORLD_VS_DVBT] = { + .name = "Kworld VS-DVB-T 323UR", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_PHILIPS_FCV1236D, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = TVP5150_COMPOSITE0, .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2820_BOARD_PINNACLE_DVC_90] = { - .name = "Pinnacle Dazzle DVC 90/DVC 100", + [EM2882_BOARD_TERRATEC_HYBRID_XS] = { + .name = "Terratec Hybrid XS (em2882)", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_ABSENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2800_BOARD_VGEAR_POCKETTV] = { - .name = "V-Gear PocketTV", - .is_em2800 = 1, + [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { + .name = "Hauppauge WinTV HVR 950", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = TVP5150_COMPOSITE0, .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { - .name = "Pixelview Prolink PlayTV USB 2.0", + [EM2883_BOARD_KWORLD_HYBRID_A316] = { + .name = "Kworld PlusTV HD Hybrid 330", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_YMEC_TVF_5533MF, - .decoder = EM28XX_SAA7113, + .is_em2800 = 0, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, - .amux = EM28XX_AMUX_LINE_IN, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, - .amux = EM28XX_AMUX_LINE_IN, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, - .amux = EM28XX_AMUX_LINE_IN, - } }, - }, - [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { - .name = "PointNix Intra-Oral Camera", - .has_snapshot_button = 1, - .vchannels = 1, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_ABSENT, - .decoder = EM28XX_SAA7113, - .input = { { - .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, - .amux = 0, + .vmux = TVP5150_SVIDEO, + .amux = 1, } }, }, }; @@ -508,7 +1141,9 @@ const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); /* table of devices that work with this driver */ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0xeb1a, 0x2750), - .driver_info = EM2820_BOARD_UNKNOWN }, + .driver_info = EM2750_BOARD_UNKNOWN }, + { USB_DEVICE(0xeb1a, 0x2751), + .driver_info = EM2750_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2820), @@ -525,20 +1160,46 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2883), .driver_info = EM2820_BOARD_UNKNOWN }, + { USB_DEVICE(0xeb1a, 0xe300), + .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, + { USB_DEVICE(0xeb1a, 0xe305), + .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, + { USB_DEVICE(0xeb1a, 0xe310), + .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, + { USB_DEVICE(0xeb1a, 0xa316), + .driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 }, + { USB_DEVICE(0xeb1a, 0xe320), + .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II }, + { USB_DEVICE(0xeb1a, 0xe323), + .driver_info = EM2882_BOARD_KWORLD_VS_DVBT }, + { USB_DEVICE(0xeb1a, 0xe350), + .driver_info = EM2870_BOARD_KWORLD_350U }, + { USB_DEVICE(0xeb1a, 0xe355), + .driver_info = EM2870_BOARD_KWORLD_355U }, + { USB_DEVICE(0xeb1a, 0x2801), + .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, + { USB_DEVICE(0xeb1a, 0xe357), + .driver_info = EM2870_BOARD_KWORLD_355U }, { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, - { USB_DEVICE(0x2304, 0x0208), - .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, + { USB_DEVICE(0x0ccd, 0x004c), + .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR }, + { USB_DEVICE(0x0ccd, 0x004f), + .driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x005e), + .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x0042), + .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x0043), + .driver_info = EM2870_BOARD_TERRATEC_XS }, + { USB_DEVICE(0x0ccd, 0x0047), + .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, + { USB_DEVICE(0x185b, 0x2870), + .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, { USB_DEVICE(0x2040, 0x4201), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, - { USB_DEVICE(0x2304, 0x0207), - .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, - { USB_DEVICE(0x2304, 0x021a), - .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, - { USB_DEVICE(0x2304, 0x0227), - .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, { USB_DEVICE(0x2040, 0x6500), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { USB_DEVICE(0x2040, 0x6502), @@ -551,14 +1212,27 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, - { USB_DEVICE(0x0ccd, 0x0042), - .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, - { USB_DEVICE(0x0ccd, 0x0047), - .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, { USB_DEVICE(0x0438, 0xb002), .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, - { USB_DEVICE(0xeb1a, 0x2801), - .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, + { USB_DEVICE(0x2001, 0xf112), + .driver_info = EM2820_BOARD_DLINK_USB_TV }, + { USB_DEVICE(0x2304, 0x0207), + .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x2304, 0x0208), + .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, + { USB_DEVICE(0x2304, 0x021a), + .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x2304, 0x0226), + .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO }, + { USB_DEVICE(0x2304, 0x0227), + .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, + { USB_DEVICE(0x0413, 0x6023), + .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII }, + { USB_DEVICE(0x093b, 0xa005), + .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U }, +#if 0 + EM2880_BOARD_KWORLD_DVB_310U }, +#endif { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -567,6 +1241,18 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table); * Reset sequences for analog/digital modes */ +/* Reset for the most [analog] boards */ +static struct em28xx_reg_seq default_analog[] = { + {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + +/* Reset for the most [digital] boards */ +static struct em28xx_reg_seq default_digital[] = { + {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + /* Board Hauppauge WinTV HVR 900 analog */ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, @@ -582,14 +1268,42 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { { -1, -1, -1, -1}, }; -/* Board Hauppauge WinTV HVR 900 tuner_callback */ -static struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = { +/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ +static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { + {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + +/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ +static struct em28xx_reg_seq em2880_msi_digivox_ad_digital[] = { + {EM28XX_R08_GPIO, 0x6a, ~EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + +/* Board - EM2870 Kworld 355u + Analog - No input analog */ +static struct em28xx_reg_seq em2870_kworld_355u_digital[] = { + {EM2880_R04_GPO, 0x01, 0xff, 10}, + { -1, -1, -1, -1}, +}; + +/* Callback for the most boards */ +static struct em28xx_reg_seq default_callback[] = { {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, { -1, -1, -1, -1}, }; +/* Callback for EM2882 TERRATEC HYBRID XS */ +static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = { + {EM28XX_R08_GPIO, 0x2e, 0xff, 6}, + {EM28XX_R08_GPIO, 0x3e, ~EM_GPIO_4, 6}, + {EM2880_R04_GPO, 0x04, 0xff, 10}, + {EM2880_R04_GPO, 0x0c, 0xff, 10}, + { -1, -1, -1, -1}, +}; + /* * EEPROM hash table for devices with generic USB IDs */ @@ -636,6 +1350,7 @@ static void em28xx_set_model(struct em28xx *dev) dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; dev->has_dvb = em28xx_boards[dev->model].has_dvb; dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button; + dev->valid = em28xx_boards[dev->model].valid; } /* Since em28xx_pre_card_setup() requires a proper dev->model, @@ -671,9 +1386,12 @@ void em28xx_pre_card_setup(struct em28xx *dev) case EM2880_BOARD_TERRATEC_PRODIGY_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: - case EM2880_BOARD_TERRATEC_HYBRID_XS: + case EM2860_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: + case EM2882_BOARD_PINNACLE_HYBRID_PRO: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_KWORLD_HYBRID_A316: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); @@ -682,9 +1400,158 @@ void em28xx_pre_card_setup(struct em28xx *dev) /* Sets GPO/GPIO sequences for this device */ dev->analog_gpio = hauppauge_wintv_hvr_900_analog; dev->digital_gpio = hauppauge_wintv_hvr_900_digital; - dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback; - dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback; + dev->tun_analog_gpio = default_callback; + dev->tun_digital_gpio = default_callback; + break; + + case EM2882_BOARD_TERRATEC_HYBRID_XS: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + msleep(50); + + /* should be added ir_codes here */ + + /* Sets GPO/GPIO sequences for this device */ + dev->analog_gpio = hauppauge_wintv_hvr_900_analog; + dev->digital_gpio = hauppauge_wintv_hvr_900_digital; + dev->tun_analog_gpio = default_callback; + dev->tun_digital_gpio = em2882_terratec_hybrid_xs_digital; + break; + + case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: + case EM2880_BOARD_TERRATEC_HYBRID_XS: + case EM2870_BOARD_TERRATEC_XS: + case EM2881_BOARD_PINNACLE_HYBRID_PRO: + case EM2880_BOARD_KWORLD_DVB_310U: + case EM2870_BOARD_KWORLD_350U: + case EM2881_BOARD_DNT_DA2_HYBRID: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + msleep(50); + + /* NOTE: EM2881_DNT_DA2_HYBRID spend 140 msleep for digital + and analog commands. If this commands doesn't work, + add this timer. */ + + /* Sets GPO/GPIO sequences for this device */ + dev->analog_gpio = default_analog; + dev->digital_gpio = default_digital; + dev->tun_analog_gpio = default_callback; + dev->tun_digital_gpio = default_callback; + break; + + case EM2880_BOARD_MSI_DIGIVOX_AD: + case EM2880_BOARD_MSI_DIGIVOX_AD_II: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + msleep(50); + + /* Sets GPO/GPIO sequences for this device */ + dev->analog_gpio = em2880_msi_digivox_ad_analog; + dev->digital_gpio = em2880_msi_digivox_ad_digital; + dev->tun_analog_gpio = default_callback; + dev->tun_digital_gpio = default_callback; + break; + case EM2750_BOARD_UNKNOWN: + case EM2750_BOARD_DLCW_130: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x0a", 1); + break; + + case EM2861_BOARD_PLEXTOR_PX_TV100U: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* FIXME guess */ + /* Turn on analog audio output */ + em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); + break; + + case EM2861_BOARD_KWORLD_PVRTV_300U: + case EM2880_BOARD_KWORLD_DVB_305U: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x4c", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\x6d", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\x7d", 1); + msleep(10); + break; + + case EM2870_BOARD_KWORLD_355U: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + msleep(50); + + /* Sets GPO/GPIO sequences for this device */ + dev->digital_gpio = em2870_kworld_355u_digital; + break; + + case EM2870_BOARD_COMPRO_VIDEOMATE: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* TODO: someone can do some cleanup here... + not everything's needed */ + em28xx_write_regs(dev, 0x04, "\x00", 1); + msleep(10); + em28xx_write_regs(dev, 0x04, "\x01", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\xfd", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xfc", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xdc", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xfc", 1); + mdelay(70); + break; + + case EM2870_BOARD_TERRATEC_XS_MT2060: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* this device needs some gpio writes to get the DVB-T + demod work */ + em28xx_write_regs(dev, 0x08, "\xfe", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xde", 1); + mdelay(70); + dev->em28xx_write_regs(dev, 0x08, "\xfe", 1); + mdelay(70); + break; + + case EM2870_BOARD_PINNACLE_PCTV_DVB: + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* this device needs some gpio writes to get the + DVB-T demod work */ + em28xx_write_regs(dev, 0x08, "\xfe", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xde", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xfe", 1); + mdelay(70); + /* switch em2880 rc protocol */ + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x22", 1); + /* should be added ir_codes here */ + break; + + case EM2820_BOARD_GADMEI_UTV310: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* Turn on analog audio output */ + em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); + break; + + case EM2860_BOARD_GADMEI_UTV330: + /* Turn on IR */ + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* should be added ir_codes here */ + break; + + case EM2820_BOARD_MSI_VOX_USB_2: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* enables audio for that device */ + em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); break; } @@ -928,11 +1795,21 @@ void em28xx_card_setup(struct em28xx *dev) case EM2800_BOARD_UNKNOWN: if (!em28xx_hint_board(dev)) em28xx_set_model(dev); + break; } if (dev->has_snapshot_button) em28xx_register_snapshot_button(dev); + if (dev->valid == EM28XX_BOARD_NOT_VALIDATED) { + em28xx_errdev("\n\n"); + em28xx_errdev("The support for this board weren't " + "valid yet.\n"); + em28xx_errdev("Please send a report of having this working\n"); + em28xx_errdev("not to V4L mailing list (and/or to other " + "addresses)\n\n"); + } + /* Allow override tuner type by a module parameter */ if (tuner >= 0) dev->tuner_type = tuner; diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 7d397fc12..efc691b98 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -61,11 +61,52 @@ #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 #define EM2800_BOARD_GRABBEEX_USB2800 21 +#define EM2750_BOARD_UNKNOWN 22 +#define EM2750_BOARD_DLCW_130 23 +#define EM2820_BOARD_DLINK_USB_TV 24 +#define EM2820_BOARD_GADMEI_UTV310 25 +#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26 +#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27 +#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28 +#define EM2820_BOARD_PINNACLE_DVC_100 29 +#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 +#define EM2821_BOARD_USBGEAR_VD204 31 +#define EM2821_BOARD_SUPERCOMP_USB_2 32 +#define EM2821_BOARD_PROLINK_PLAYTV_USB2 33 +#define EM2860_BOARD_TERRATEC_HYBRID_XS 34 +#define EM2860_BOARD_TYPHOON_DVD_MAKER 35 +#define EM2860_BOARD_NETGMBH_CAM 36 +#define EM2860_BOARD_GADMEI_UTV330 37 +#define EM2861_BOARD_YAKUMO_MOVIE_MIXER 38 +#define EM2861_BOARD_KWORLD_PVRTV_300U 39 +#define EM2861_BOARD_PLEXTOR_PX_TV100U 40 +#define EM2870_BOARD_KWORLD_350U 41 +#define EM2870_BOARD_KWORLD_355U 42 +#define EM2870_BOARD_TERRATEC_XS 43 +#define EM2870_BOARD_TERRATEC_XS_MT2060 44 +#define EM2870_BOARD_PINNACLE_PCTV_DVB 45 +#define EM2870_BOARD_COMPRO_VIDEOMATE 46 +#define EM2880_BOARD_KWORLD_DVB_305U 47 +#define EM2880_BOARD_KWORLD_DVB_310U 48 +#define EM2880_BOARD_MSI_DIGIVOX_AD 49 +#define EM2880_BOARD_MSI_DIGIVOX_AD_II 50 +#define EM2880_BOARD_TERRATEC_HYBRID_XS_FR 51 +#define EM2881_BOARD_DNT_DA2_HYBRID 52 +#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53 +#define EM2882_BOARD_KWORLD_VS_DVBT 54 +#define EM2882_BOARD_TERRATEC_HYBRID_XS 55 +#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 +#define EM2883_BOARD_KWORLD_HYBRID_A316 57 +#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 58 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 #define EM28XX_DEF_BUF 8 +/* Params for validated field */ +#define EM28XX_BOARD_NOT_VALIDATED 1 +#define EM28XX_BOARD_VALIDATED 0 + /* maximum number of em28xx boards */ #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ @@ -254,6 +295,7 @@ struct em28xx_board { unsigned int max_range_640_480:1; unsigned int has_dvb:1; unsigned int has_snapshot_button:1; + unsigned int valid:1; enum em28xx_decoder decoder; @@ -342,6 +384,7 @@ struct em28xx { unsigned int max_range_640_480:1; unsigned int has_dvb:1; unsigned int has_snapshot_button:1; + unsigned int valid:1; /* report for validated boards */ /* Some older em28xx chips needs a waiting time after writing */ unsigned int wait_after_write; @@ -371,7 +414,7 @@ struct em28xx { v4l2_std_id norm; /* selected tv norm */ int ctl_freq; /* selected frequency */ unsigned int ctl_input; /* selected input */ - unsigned int ctl_ainput; /* slected audio input */ + unsigned int ctl_ainput;/* selected audio input */ int mute; int volume; /* frame properties */ -- cgit v1.2.3 From 89e2fea073c15a3f72ec74c3859e7a3b271e7db3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 27 Jul 2008 19:08:54 +0200 Subject: saa7146: fix read from uninitialized memory From: Hans Verkuil The offset field of the scatterlist entry *after* the last valid scatterlist entry was used instead of the first scatterlist entry (as was the intention of this code). This worked fine until the kzalloc of the sglist was replaced with kmalloc and sg_init_table only zeroed the exact needed length. Apparently kzalloc zeroes a bit more than is strictly necessary so the offset field was always 0 in the past. But now the offset field was suddenly random and this led to broken captures. Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index a2333bff8..1c22c39c2 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -657,7 +657,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu /* if we have a user buffer, the first page may not be aligned to a page boundary. */ - pt1->offset = list->offset; + pt1->offset = dma->sglist->offset; pt2->offset = pt1->offset+o1; pt3->offset = pt1->offset+o2; -- cgit v1.2.3 From 6c3a536a4c83388df468f1e2948bb0a03d93b949 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 14:10:11 -0300 Subject: em28xx-cards: Add Compro VideoMate ForYou/Stereo model From: Vitaly Wool Added Compro VideoMate ForYou/Stereo model (analog only) Signed-off-by: Vitaly Wool [dougsland@gmail.com: Solved conflicts with v4l-dvb devel tree] Signed-off-by: Douglas Schilling Landgraf [mchehab@infradead.org: Need to fix some merge conflicts] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 18 ++++++++++++++++++ linux/drivers/media/video/em28xx/em28xx.h | 1 + 2 files changed, 19 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index b2b017afc..bc7ff8420 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1135,6 +1135,22 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2820_BOARD_COMPRO_VIDEO_MATE] = { + .name = "Compro VideoMate ForYou/Stereo", + .vchannels = 2, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -1196,6 +1212,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, { USB_DEVICE(0x185b, 0x2870), .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, + { USB_DEVICE(0x185b, 0x2041), + .driver_info = EM2820_BOARD_COMPRO_VIDEO_MATE }, { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, { USB_DEVICE(0x2040, 0x4201), diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index efc691b98..06c94f77d 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -98,6 +98,7 @@ #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 #define EM2883_BOARD_KWORLD_HYBRID_A316 57 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 58 +#define EM2820_BOARD_COMPRO_VIDEO_MATE 59 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From b36bfcb16f614a7e44f2a56e8b91ccdf70facb36 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 14:58:58 -0300 Subject: em28xx: HVR-950 entry is duplicated. From: Mauro Carvalho Chehab Thanks to "Devin Heitmueller" for pointing this issue. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 37 ++++++------------------- linux/drivers/media/video/em28xx/em28xx-dvb.c | 2 +- linux/drivers/media/video/em28xx/em28xx.h | 5 ++-- 3 files changed, 11 insertions(+), 33 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index bc7ff8420..f7566783b 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -607,7 +607,7 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { + [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { .name = "Hauppauge WinTV HVR 950", .vchannels = 3, .tda9887_conf = TDA9887_PRESENT, @@ -1094,26 +1094,6 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { - .name = "Hauppauge WinTV HVR 950", - .valid = EM28XX_BOARD_NOT_VALIDATED, - .vchannels = 3, - .tuner_type = TUNER_XC2028, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = TVP5150_COMPOSITE0, - .amux = 0, - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = TVP5150_COMPOSITE1, - .amux = 1, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = TVP5150_SVIDEO, - .amux = 1, - } }, - }, [EM2883_BOARD_KWORLD_HYBRID_A316] = { .name = "Kworld PlusTV HD Hybrid 330", .valid = EM28XX_BOARD_NOT_VALIDATED, @@ -1223,13 +1203,13 @@ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0x2040, 0x6502), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 }, { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */ - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */ - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */ - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */ - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x0438, 0xb002), .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, { USB_DEVICE(0x2001, 0xf112), @@ -1405,10 +1385,9 @@ void em28xx_pre_card_setup(struct em28xx *dev) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2860_BOARD_TERRATEC_HYBRID_XS: - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2882_BOARD_PINNACLE_HYBRID_PRO: - case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2883_BOARD_KWORLD_HYBRID_A316: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); @@ -1599,7 +1578,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) /* djh - Not sure which demod we need here */ ctl->demod = XC3028_FE_DEFAULT; break; - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: /* FIXME: Better to specify the needed IF */ @@ -1782,7 +1761,7 @@ void em28xx_card_setup(struct em28xx *dev) case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: { struct tveeprom tv; #ifdef CONFIG_MODULES diff --git a/linux/drivers/media/video/em28xx/em28xx-dvb.c b/linux/drivers/media/video/em28xx/em28xx-dvb.c index 7edec4618..5b532ccec 100644 --- a/linux/drivers/media/video/em28xx/em28xx-dvb.c +++ b/linux/drivers/media/video/em28xx/em28xx-dvb.c @@ -411,7 +411,7 @@ static int dvb_init(struct em28xx *dev) em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); /* init frontend */ switch (dev->model) { - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->frontend = dvb_attach(lgdt330x_attach, diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 06c94f77d..3c3e55d9c 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -55,7 +55,7 @@ #define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 #define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 #define EM2800_BOARD_VGEAR_POCKETTV 15 -#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 +#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 @@ -97,8 +97,7 @@ #define EM2882_BOARD_TERRATEC_HYBRID_XS 55 #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 #define EM2883_BOARD_KWORLD_HYBRID_A316 57 -#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 58 -#define EM2820_BOARD_COMPRO_VIDEO_MATE 59 +#define EM2820_BOARD_COMPRO_VIDEO_MATE 58 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From 03cfb9b591a8fd336db578b57ff3907f3a136a5c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 15:00:23 -0300 Subject: em28xx: AMD ATI TV Wonder HD 600 entry at cards struct is duplicated From: Mauro Carvalho Chehab Thanks to "Devin Heitmueller" for pointing this issue. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index f7566783b..c40f97b3f 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -676,29 +676,6 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { - .name = "AMD ATI TV Wonder HD 600", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = TVP5150_COMPOSITE0, - .amux = 0, - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = TVP5150_COMPOSITE1, - .amux = 1, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = TVP5150_SVIDEO, - .amux = 1, - } }, - }, [EM2880_BOARD_TERRATEC_HYBRID_XS] = { .name = "Terratec Hybrid XS", .vchannels = 3, -- cgit v1.2.3 From 8aa42788bd13fff2951d3ec89d1f2af73932d278 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 16:58:04 -0300 Subject: em28xx: Rename #define for Compro VideoMate ForYou/Stereo From: Mauro Carvalho Chehab There are two videomate boards supporded by em28xx. The names are almost identical. This patch renames one of such entries to something else. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 4 ++-- linux/drivers/media/video/em28xx/em28xx.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index c40f97b3f..44b3ae23d 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1092,7 +1092,7 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2820_BOARD_COMPRO_VIDEO_MATE] = { + [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { .name = "Compro VideoMate ForYou/Stereo", .vchannels = 2, .tuner_type = TUNER_LG_PAL_NEW_TAPC, @@ -1170,7 +1170,7 @@ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0x185b, 0x2870), .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, { USB_DEVICE(0x185b, 0x2041), - .driver_info = EM2820_BOARD_COMPRO_VIDEO_MATE }, + .driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU }, { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, { USB_DEVICE(0x2040, 0x4201), diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 3c3e55d9c..e5e47fe66 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -97,7 +97,7 @@ #define EM2882_BOARD_TERRATEC_HYBRID_XS 55 #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 #define EM2883_BOARD_KWORLD_HYBRID_A316 57 -#define EM2820_BOARD_COMPRO_VIDEO_MATE 58 +#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From cfc8abd9b55723cd9479aeb09ef1762aab9fa8bc Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 27 Jul 2008 17:11:28 -0400 Subject: au8522: add mechanism to configure IF frequency for vsb and qam From: Michael Krufky Add a mechanism to configure IF frequency for vsb and qam. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/au8522.c | 66 ++++++++++++++++++++++++++++++ linux/drivers/media/dvb/frontends/au8522.h | 9 ++++ 2 files changed, 75 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/frontends/au8522.c b/linux/drivers/media/dvb/frontends/au8522.c index 37f6260e1..d968a1000 100644 --- a/linux/drivers/media/dvb/frontends/au8522.c +++ b/linux/drivers/media/dvb/frontends/au8522.c @@ -304,6 +304,70 @@ static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, return ret; } +/* 3.25 MHz IF Frequency table */ +static struct { + u16 reg; + u16 data; +} if_3_25_mhz_tab[] = { + { 0x80b5, 0x00 }, + { 0x80b6, 0x3d }, + { 0x80b7, 0xa0 }, +}; + +/* 4.00 MHz IF Frequency table */ +static struct { + u16 reg; + u16 data; +} if_4_mhz_tab[] = { + { 0x80b5, 0x00 }, + { 0x80b6, 0x4b }, + { 0x80b7, 0xd9 }, +}; + +/* 6.00 MHz IF Frequency table */ +static struct { + u16 reg; + u16 data; +} if_6_mhz_tab[] = { + { 0x80b5, 0xfb }, + { 0x80b6, 0x8e }, + { 0x80b7, 0x39 }, +}; + +static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq) +{ + struct au8522_state *state = fe->demodulator_priv; + int i; + + switch (if_freq) { + case AU8522_IF_3_25MHZ: + dprintk("%s() 3.25 MHz\n", __func__); + for (i = 0; i < ARRAY_SIZE(if_3_25_mhz_tab); i++) + au8522_writereg(state, + if_3_25_mhz_tab[i].reg, + if_3_25_mhz_tab[i].data); + break; + case AU8522_IF_4MHZ: + dprintk("%s() 4.00 MHz\n", __func__); + for (i = 0; i < ARRAY_SIZE(if_4_mhz_tab); i++) + au8522_writereg(state, + if_4_mhz_tab[i].reg, + if_4_mhz_tab[i].data); + break; + case AU8522_IF_6MHZ: + dprintk("%s() 6.00 MHz\n", __func__); + for (i = 0; i < ARRAY_SIZE(if_6_mhz_tab); i++) + au8522_writereg(state, + if_6_mhz_tab[i].reg, + if_6_mhz_tab[i].data); + break; + default: + dprintk("%s() IF Frequency not supported\n", __func__); + return -EINVAL; + } + return 0; +} + /* VSB Modulation table */ static struct { u16 reg; @@ -438,6 +502,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, au8522_writereg(state, VSB_mod_tab[i].reg, VSB_mod_tab[i].data); + au8522_set_if(fe, state->config->vsb_if); break; case QAM_64: case QAM_256: @@ -446,6 +511,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, au8522_writereg(state, QAM_mod_tab[i].reg, QAM_mod_tab[i].data); + au8522_set_if(fe, state->config->qam_if); break; default: dprintk("%s() Invalid modulation\n", __func__); diff --git a/linux/drivers/media/dvb/frontends/au8522.h b/linux/drivers/media/dvb/frontends/au8522.h index d7affa3cd..afc9af26e 100644 --- a/linux/drivers/media/dvb/frontends/au8522.h +++ b/linux/drivers/media/dvb/frontends/au8522.h @@ -24,6 +24,12 @@ #include +enum au8522_if_freq { + AU8522_IF_6MHZ = 0, + AU8522_IF_4MHZ, + AU8522_IF_3_25MHZ, +}; + struct au8522_config { /* the demodulator's i2c address */ u8 demod_address; @@ -32,6 +38,9 @@ struct au8522_config { #define AU8522_TUNERLOCKING 0 #define AU8522_DEMODLOCKING 1 u8 status_mode; + + enum au8522_if_freq vsb_if; + enum au8522_if_freq qam_if; }; #if defined(CONFIG_DVB_AU8522) || \ -- cgit v1.2.3 From b56bf8a6147de81da31ee2fde96fe8367386383c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 27 Jul 2008 17:13:20 -0400 Subject: au0828: add support for Hauppauge Woodbury From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/video/au0828/Kconfig | 1 + linux/drivers/media/video/au0828/au0828-cards.c | 7 +++++++ linux/drivers/media/video/au0828/au0828-cards.h | 1 + linux/drivers/media/video/au0828/au0828-dvb.c | 21 +++++++++++++++++++++ 4 files changed, 30 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/au0828/Kconfig b/linux/drivers/media/video/au0828/Kconfig index ed9a50f18..018f72b8e 100644 --- a/linux/drivers/media/video/au0828/Kconfig +++ b/linux/drivers/media/video/au0828/Kconfig @@ -7,6 +7,7 @@ config VIDEO_AU0828 select DVB_AU8522 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE ---help--- This is a video4linux driver for Auvitek's USB device. diff --git a/linux/drivers/media/video/au0828/au0828-cards.c b/linux/drivers/media/video/au0828/au0828-cards.c index 443e59009..14b9fc9bb 100644 --- a/linux/drivers/media/video/au0828/au0828-cards.c +++ b/linux/drivers/media/video/au0828/au0828-cards.c @@ -38,6 +38,9 @@ struct au0828_board au0828_boards[] = { [AU0828_BOARD_DVICO_FUSIONHDTV7] = { .name = "DViCO FusionHDTV USB", }, + [AU0828_BOARD_HAUPPAUGE_WOODBURY] = { + .name = "Hauppauge Woodbury", + }, }; /* Tuner callback function for au0828 boards. Currently only needed @@ -115,6 +118,7 @@ void au0828_card_setup(struct au0828_dev *dev) case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: + case AU0828_BOARD_HAUPPAUGE_WOODBURY: if (dev->i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xa0); break; @@ -134,6 +138,7 @@ void au0828_gpio_setup(struct au0828_dev *dev) case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: + case AU0828_BOARD_HAUPPAUGE_WOODBURY: /* GPIO's * 4 - CS5340 * 5 - AU8522 Demodulator @@ -205,6 +210,8 @@ struct usb_device_id au0828_usb_id_table [] = { .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, { USB_DEVICE(0x2040, 0x7281), .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, + { USB_DEVICE(0x2040, 0x8200), + .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY }, { }, }; diff --git a/linux/drivers/media/video/au0828/au0828-cards.h b/linux/drivers/media/video/au0828/au0828-cards.h index c37f5fd0f..102ed03dc 100644 --- a/linux/drivers/media/video/au0828/au0828-cards.h +++ b/linux/drivers/media/video/au0828/au0828-cards.h @@ -24,3 +24,4 @@ #define AU0828_BOARD_HAUPPAUGE_HVR850 2 #define AU0828_BOARD_DVICO_FUSIONHDTV7 3 #define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4 +#define AU0828_BOARD_HAUPPAUGE_WOODBURY 5 diff --git a/linux/drivers/media/video/au0828/au0828-dvb.c b/linux/drivers/media/video/au0828/au0828-dvb.c index 4c1dfdd8d..b7b0591ef 100644 --- a/linux/drivers/media/video/au0828/au0828-dvb.c +++ b/linux/drivers/media/video/au0828/au0828-dvb.c @@ -30,6 +30,7 @@ #include "au8522.h" #include "xc5000.h" #include "mxl5007t.h" +#include "tda18271.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -41,6 +42,13 @@ static struct au8522_config hauppauge_hvr950q_config = { .status_mode = AU8522_DEMODLOCKING, }; +static struct au8522_config hauppauge_woodbury_config = { + .demod_address = 0x8e >> 1, + .status_mode = AU8522_DEMODLOCKING, + .qam_if = AU8522_IF_4MHZ, + .vsb_if = AU8522_IF_3_25MHZ, +}; + static struct xc5000_config hauppauge_hvr950q_tunerconfig = { .i2c_address = 0x61, .if_khz = 6000, @@ -52,6 +60,10 @@ static struct mxl5007t_config mxl5007t_hvr950q_config = { .if_freq_hz = MxL_IF_6_MHZ, }; +static struct tda18271_config hauppauge_woodbury_tunerconfig = { + .gate = TDA18271_GATE_DIGITAL, +}; + /*-------------------------------------------------------------------*/ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static void urb_completion(struct urb *purb, struct pt_regs *regs) @@ -362,6 +374,15 @@ int au0828_dvb_register(struct au0828_dev *dev) &dev->i2c_adap, 0x60, &mxl5007t_hvr950q_config); break; + case AU0828_BOARD_HAUPPAUGE_WOODBURY: + dvb->frontend = dvb_attach(au8522_attach, + &hauppauge_woodbury_config, + &dev->i2c_adap); + if (dvb->frontend != NULL) + dvb_attach(tda18271_attach, dvb->frontend, + 0x60, &dev->i2c_adap, + &hauppauge_woodbury_tunerconfig); + break; default: printk(KERN_WARNING "The frontend of your DVB/ATSC card " "isn't supported yet\n"); -- cgit v1.2.3 From a93b15a7383b09ba2a69ade165de9baf87eecc1d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 19:02:30 -0300 Subject: pwc: Fix compilation From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/pwc/pwc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/pwc/pwc.h b/linux/drivers/media/video/pwc/pwc.h index 977700416..926defb11 100644 --- a/linux/drivers/media/video/pwc/pwc.h +++ b/linux/drivers/media/video/pwc/pwc.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "compat.h" #include -- cgit v1.2.3 From e33ff2ca43bae04e2643c75728a14eb2ef4240fa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 19:30:46 -0300 Subject: mxl5007: Fix an error at include file From: Mauro Carvalho Chehab mxl5007 was forcing for its compilation: In file included from drivers/media/common/tuners/mxl5007t.c:25:drivers/media/common/tuners/mxl5007t.h:80:1: warning: "CONFIG_MEDIA_TUNER_MXL5007T" redefined In file included from :0: ./include/linux/autoconf.h:2782:1: warning: this is the location of the previous definition Probably, some temporary hack for testing. CC: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/mxl5007t.h | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/mxl5007t.h b/linux/drivers/media/common/tuners/mxl5007t.h index a1ee3628b..aa3eea0b5 100644 --- a/linux/drivers/media/common/tuners/mxl5007t.h +++ b/linux/drivers/media/common/tuners/mxl5007t.h @@ -77,7 +77,6 @@ struct mxl5007t_config { unsigned int clk_out_enable:1; }; -#define CONFIG_MEDIA_TUNER_MXL5007T #if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE)) extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 addr, -- cgit v1.2.3 From 097081d7ddc12f5989d3883f05f91e263580f6a5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 28 Jul 2008 11:41:51 +0200 Subject: gspca: Change a bit the init of ov7660 and Sonix JPEG bridges. From: Jean-Francois Moine Set back some values of gspcav1 in init of sonixj sensor ov7660. Add some comments. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 46 +++++++++++++++----------------- 1 file changed, 21 insertions(+), 25 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 6abab94fb..e5b170c6b 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -371,17 +371,15 @@ static const __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ /* (delay 20ms) */ {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, - /* Outformat ?? rawRGB */ + /* Outformat = rawRGB */ {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ - {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, -/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */ + {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, /* GAIN BLUE RED VREF */ {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, /* COM 1 BAVE GEAVE AECHH */ {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ - {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, -/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */ + {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, /* AECH CLKRC COM7 COM8 */ {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, @@ -390,8 +388,8 @@ static const __u8 ov7660_sensor_init[][8] = { {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, /* BOS GBOS GROS ROS (BGGR offset) */ - {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, -/* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */ +/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */ + {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, /* AEW AEB VPT BBIAS */ {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, /* GbBIAS RSVD EXHCH EXHCL */ @@ -418,9 +416,9 @@ static const __u8 ov7660_sensor_init[][8] = { {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, /* LCC1 LCC2 LCC3 LCC4 */ {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ - {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, + {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */ {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, - /* band gap reference [0..3] DBLV */ + /* band gap reference [0:3] DBLV */ {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ @@ -430,37 +428,35 @@ static const __u8 ov7660_sensor_init[][8] = { {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ - {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ /****** (some exchanges in the win trace) ******/ - {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ /* bits[3..0]reserved */ {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, /* VREF vertical frame ctrl */ {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ - {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, -/* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */ - {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */ + {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */ + {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */ + {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */ +/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */ /****** (some exchanges in the win trace) ******/ {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ - {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ - {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */ + {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */ + {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */ +/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */ /****** (some exchanges in the win trace) ******/ -/**********startsensor KO if changed !!****/ +/******!! startsensor KO if changed !!****/ {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, -/* here may start the isoc exchanges */ {} }; -/* reg0x04 reg0x07 reg 0x10 */ -/* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ +/* reg 0x04 reg 0x07 reg 0x10 */ +/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */ static const __u8 ov7648_sensor_init[][8] = { {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, -- cgit v1.2.3 From e218072abb7a7bb8e810612a9573d9064f3d64f1 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 28 Jul 2008 12:52:27 +0200 Subject: gspca: Bad pixel format in the spca508 subdriver. From: Jean-Francois Moine The pixel format should have been changed in changeset 6de914aaad86. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca508.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index 9fca74ad1..672e0feb7 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -63,22 +63,22 @@ static struct ctrl sd_ctrls[] = { }; static struct v4l2_pix_format sif_mode[] = { - {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, .bytesperline = 160 * 3, .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 3}, - {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, .bytesperline = 176 * 3, .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, - {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, .bytesperline = 320 * 3, .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, - {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, .bytesperline = 352 * 3, .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, -- cgit v1.2.3 From bf1df3fec5f8b21e8582a4af850615b540ead06a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jul 2008 12:58:53 -0300 Subject: media/video/Kconfig: get rid of a select From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index d4a6e56a7..93fdb8fa1 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -822,8 +822,7 @@ config VIDEO_OVCAMCHIP config USB_W9968CF tristate "USB W996[87]CF JPEG Dual Mode Camera support" - depends on VIDEO_V4L1 && I2C - select VIDEO_OVCAMCHIP + depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP ---help--- Say Y here if you want support for cameras based on OV681 or Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. -- cgit v1.2.3 From c0f201cc9dd7be8c8951ecf09e97b783ff10b9b2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jul 2008 13:07:42 -0300 Subject: media/video/Kconfig: cosmetic changes and convert select into depends on It seems cosmetically better to let USB drivers be the last one. Also, two SOC drivers were using select, instead of depends on SOC_CAMERA. Since select has some drawbacks when checking for dependencies, convert those two into depends on. From: Mauro Carvalho Chehab CC: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 118 +++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 60 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 93fdb8fa1..aeaa54f3e 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -784,6 +784,64 @@ config VIDEO_CAFE_CCIC CMOS camera controller. This is the controller found on first- generation OLPC systems. +config SOC_CAMERA + tristate "SoC camera support" + depends on VIDEO_V4L2 && HAS_DMA + select VIDEOBUF_GEN + help + SoC Camera is a common API to several cameras, not connecting + over a bus like PCI or USB. For example some i2c camera connected + directly to the data bus of an SoC. + +config SOC_CAMERA_MT9M001 + tristate "mt9m001 support" + depends on SOC_CAMERA && I2C + select GPIO_PCA953X if MT9M001_PCA9536_SWITCH + help + This driver supports MT9M001 cameras from Micron, monochrome + and colour models. + +config MT9M001_PCA9536_SWITCH + bool "pca9536 datawidth switch for mt9m001" + depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO + help + Select this if your MT9M001 camera uses a PCA9536 I2C GPIO + extender to switch between 8 and 10 bit datawidth modes + +config SOC_CAMERA_MT9V022 + tristate "mt9v022 support" + depends on SOC_CAMERA && I2C + select GPIO_PCA953X if MT9V022_PCA9536_SWITCH + help + This driver supports MT9V022 cameras from Micron + +config MT9V022_PCA9536_SWITCH + bool "pca9536 datawidth switch for mt9v022" + depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO + help + Select this if your MT9V022 camera uses a PCA9536 I2C GPIO + extender to switch between 8 and 10 bit datawidth modes + +config SOC_CAMERA_PLATFORM + tristate "platform camera support" + depends on SOC_CAMERA + help + This is a generic SoC camera platform driver, useful for testing + +config VIDEO_PXA27x + tristate "PXA27x Quick Capture Interface driver" + depends on VIDEO_DEV && PXA27x && SOC_CAMERA + select VIDEOBUF_DMA_SG + ---help--- + This is a v4l2 driver for the PXA27x Quick Capture Interface + +config VIDEO_SH_MOBILE_CEU + tristate "SuperH Mobile CEU Interface driver" + depends on VIDEO_DEV && SOC_CAMERA + select VIDEOBUF_DMA_CONTIG + ---help--- + This is a v4l2 driver for the SuperH Mobile CEU Interface + # # USB Multimedia device configuration # @@ -913,64 +971,4 @@ config USB_S2255 endif # V4L_USB_DRIVERS -config SOC_CAMERA - tristate "SoC camera support" - depends on VIDEO_V4L2 && HAS_DMA - select VIDEOBUF_GEN - help - SoC Camera is a common API to several cameras, not connecting - over a bus like PCI or USB. For example some i2c camera connected - directly to the data bus of an SoC. - -config SOC_CAMERA_MT9M001 - tristate "mt9m001 support" - depends on SOC_CAMERA && I2C - select GPIO_PCA953X if MT9M001_PCA9536_SWITCH - help - This driver supports MT9M001 cameras from Micron, monochrome - and colour models. - -config MT9M001_PCA9536_SWITCH - bool "pca9536 datawidth switch for mt9m001" - depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO - help - Select this if your MT9M001 camera uses a PCA9536 I2C GPIO - extender to switch between 8 and 10 bit datawidth modes - -config SOC_CAMERA_MT9V022 - tristate "mt9v022 support" - depends on SOC_CAMERA && I2C - select GPIO_PCA953X if MT9V022_PCA9536_SWITCH - help - This driver supports MT9V022 cameras from Micron - -config MT9V022_PCA9536_SWITCH - bool "pca9536 datawidth switch for mt9v022" - depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO - help - Select this if your MT9V022 camera uses a PCA9536 I2C GPIO - extender to switch between 8 and 10 bit datawidth modes - -config SOC_CAMERA_PLATFORM - tristate "platform camera support" - depends on SOC_CAMERA - help - This is a generic SoC camera platform driver, useful for testing - -config VIDEO_PXA27x - tristate "PXA27x Quick Capture Interface driver" - depends on VIDEO_DEV && PXA27x - select SOC_CAMERA - select VIDEOBUF_DMA_SG - ---help--- - This is a v4l2 driver for the PXA27x Quick Capture Interface - -config VIDEO_SH_MOBILE_CEU - tristate "SuperH Mobile CEU Interface driver" - depends on VIDEO_DEV - select SOC_CAMERA - select VIDEOBUF_DMA_CONTIG - ---help--- - This is a v4l2 driver for the SuperH Mobile CEU Interface - endif # VIDEO_CAPTURE_DRIVERS -- cgit v1.2.3 From 7f64ee6b1f1b9d62a97a5f605ced101aa4fe5f5b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jul 2008 19:58:05 +0000 Subject: DVB_DRX397XD: remove FW_LOADER select From: Adrian Bunk Also for the new DVB_DRX397XD driver the FW_LOADER select and the corresponding dependency on HOTPLUG can be removed. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 574dffe91..7dbb4a223 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -135,9 +135,8 @@ config DVB_CX22702 config DVB_DRX397XD tristate "Micronas DRX3975D/DRX3977D based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. -- cgit v1.2.3 From f28f00d9ea8a5fcfce6de0b9ec0b5b918cf14077 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jul 2008 19:58:19 +0000 Subject: fix drivers/media/video/arv.c compilation From: Adrian Bunk This patch fixes the following compile errors: <-- snip --> ... CC [M] drivers/media/video/arv.o /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/media/video/arv.c: In function 'ar_ioctl': /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/media/video/arv.c:544: error: implicit declaration of function 'video_usercopy' /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/media/video/arv.c: At top level: /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/media/video/arv.c:758: error: unknown field 'type' specified in initializer make[4]: *** [drivers/media/video/arv.o] Error 1 <-- snip --> Reported-by: Adrian Bunk Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/arv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/arv.c b/linux/drivers/media/video/arv.c index 2832070ed..e100d4cfb 100644 --- a/linux/drivers/media/video/arv.c +++ b/linux/drivers/media/video/arv.c @@ -30,6 +30,7 @@ #include "compat.h" #include #include +#include #include #include @@ -760,7 +761,6 @@ static const struct file_operations ar_fops = { static struct video_device ar_template = { .name = "Colour AR VGA", - .type = VID_TYPE_CAPTURE, .fops = &ar_fops, .release = ar_release, .minor = -1, -- cgit v1.2.3 From 9cf7e31ad91e94574361a556d5d599aca8d565a6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Jul 2008 18:07:35 -0300 Subject: media/video/Kconfig: fix a typo From: Mauro Carvalho Chehab Thanks to Hermann Gausterer for pointing this issue. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index aeaa54f3e..d6b1a106a 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -630,7 +630,7 @@ config VIDEO_ZORAN_ZR36060 depends on VIDEO_ZORAN help Say Y to support Zoran boards based on 36060 chips. - This includes Iomega Bus, Pinnacle DC10, Linux media Labs 33 + This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33 and 33 R10 and AverMedia 6 boards. config VIDEO_ZORAN_BUZ -- cgit v1.2.3 From 67c7cea408df5b3154ea75375c8e212b643c8860 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 29 Jul 2008 10:25:28 +0200 Subject: gspca: hflip and vflip controls added for ov519 - ov7670 plus init cleanup. From: Jean-Francois Moine The hflip and vflip controls work for ov7670 only. This bridge/sensor inverts blue and red - not fixed. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/ov519.c | 103 +++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/ov519.c b/linux/drivers/media/video/gspca/ov519.c index 5864656e3..97d3a063f 100644 --- a/linux/drivers/media/video/gspca/ov519.c +++ b/linux/drivers/media/video/gspca/ov519.c @@ -48,6 +48,8 @@ struct sd { unsigned char brightness; unsigned char contrast; unsigned char colors; + __u8 hflip; + __u8 vflip; char compress; /* Should the next frame be compressed? */ char compress_inited; /* Are compression params uploaded? */ @@ -77,6 +79,10 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { #define SD_BRIGHTNESS 0 @@ -121,6 +127,35 @@ static struct ctrl sd_ctrls[] = { .set = sd_setcolors, .get = sd_getcolors, }, +/* next controls work with ov7670 only */ + { + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror", + .minimum = 0, + .maximum = 1, + .step = 1, +#define HFLIP_DEF 0 + .default_value = HFLIP_DEF, + }, + .set = sd_sethflip, + .get = sd_gethflip, + }, + { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Vflip", + .minimum = 0, + .maximum = 1, + .step = 1, +#define VFLIP_DEF 0 + .default_value = VFLIP_DEF, + }, + .set = sd_setvflip, + .get = sd_getvflip, + }, }; static struct v4l2_pix_format vga_mode[] = { @@ -225,6 +260,7 @@ static struct v4l2_pix_format sif_mode[] = { #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ +#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */ #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ #define OV7670_REG_AEW 0x24 /* AGC upper limit */ #define OV7670_REG_AEB 0x25 /* AGC lower limit */ @@ -930,7 +966,10 @@ static int ov7xx0_configure(struct sd *sd) { OV7670_REG_EDGE, 0 }, { 0x75, 0x05 }, { 0x76, 0xe1 }, { 0x4c, 0 }, { 0x77, 0x01 }, - { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, + { OV7670_REG_COM13, OV7670_COM13_GAMMA + | OV7670_COM13_UVSAT + | 2}, /* was 3 */ + { 0x4b, 0x09 }, { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, { 0x56, 0x40 }, @@ -957,6 +996,7 @@ static int ov7xx0_configure(struct sd *sd) { 0x79, 0x05 }, { 0xc8, 0x30 }, { 0x79, 0x26 }, +#if 0 /* (already done) */ /* Format YUV422 */ { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */ { OV7670_REG_RGB444, 0 }, /* No RGB444 please */ @@ -970,6 +1010,7 @@ static int ov7xx0_configure(struct sd *sd) { 0x53, 0x5e }, /* "matrix coefficient 5" */ { 0x54, 0x80 }, /* "matrix coefficient 6" */ { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT }, +#endif }; PDEBUG(D_PROBE, "starting OV7xx0 configuration"); @@ -1375,6 +1416,8 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->hflip = HFLIP_DEF; + sd->vflip = VFLIP_DEF; return 0; error: PDEBUG(D_ERR, "OV519 Config failed"); @@ -1728,6 +1771,26 @@ static int mode_init_ov_sensor_regs(struct sd *sd, return 0; } +static void sethflip(struct sd *sd) +{ + if (sd->gspca_dev.streaming) + ov51x_stop(sd); + i2c_w_mask(sd, OV7670_REG_MVFP, + OV7670_MVFP_MIRROR * sd->hflip, OV7670_MVFP_MIRROR); + if (sd->gspca_dev.streaming) + ov51x_restart(sd); +} + +static void setvflip(struct sd *sd) +{ + if (sd->gspca_dev.streaming) + ov51x_stop(sd); + i2c_w_mask(sd, OV7670_REG_MVFP, + OV7670_MVFP_VFLIP * sd->vflip, OV7670_MVFP_VFLIP); + if (sd->gspca_dev.streaming) + ov51x_restart(sd); +} + static int set_ov_sensor_window(struct sd *sd, struct ovsensor_window *win) { @@ -1857,7 +1920,8 @@ static int set_ov_sensor_window(struct sd *sd, msleep(10); /* need to sleep between read and write to * same reg! */ i2c_w(sd, OV7670_REG_VREF, v); - + sethflip(sd); + setvflip(sd); } else { i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); @@ -2163,6 +2227,40 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hflip = val; + sethflip(sd); + return 0; +} + +static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->hflip; + return 0; +} + +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->vflip = val; + setvflip(sd); + return 0; +} + +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->vflip; + return 0; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -2231,4 +2329,3 @@ module_exit(sd_mod_exit); module_param(frame_rate, int, 0644); MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); - -- cgit v1.2.3 From 324ec1431fd4e714819fa67a36ac613c293b6dbb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Jul 2008 08:30:58 +0000 Subject: fix vino driver build error From: Yoichi Yuasa The vino driver needs #include drivers/media/video/vino.c: In function 'vino_ioctl': drivers/media/video/vino.c:4364: error: implicit declaration of function 'video_usercopy' make[3]: *** [drivers/media/video/vino.o] Error 1 Signed-off-by: Yoichi Yuasa Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/vino.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index cde8bf65a..9ada3fff2 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -40,6 +40,7 @@ #include #include +#include #include #include -- cgit v1.2.3 From 1d8ba1894747a54e41b95de82fdb0288aed65c3d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jul 2008 14:17:11 +0200 Subject: tvmixer: remove obsolete semaphore header From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/drivers/media/video/tvmixer.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/tvmixer.c b/linux/drivers/media/video/tvmixer.c index d7b931fd3..6233bf391 100644 --- a/linux/drivers/media/video/tvmixer.c +++ b/linux/drivers/media/video/tvmixer.c @@ -16,7 +16,6 @@ #include #include -#include #include #define DEV_MAX 4 -- cgit v1.2.3 From f317c36602dc0db74f8dbba71ad1db183f2ad7f2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 29 Jul 2008 19:14:04 +0200 Subject: gspca: Set back the old values of Sonix sn9c120 and cleanup source. From: Jean-Francois Moine The values from win traces do not seem to work while the webcams did work with gspca v1. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 204 ++++++++++++------------------- 1 file changed, 77 insertions(+), 127 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index e5b170c6b..16c866e4e 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -148,65 +148,69 @@ static struct v4l2_pix_format vga_mode[] = { /*Data from sn9c102p+hv71331r */ static const __u8 sn_hv7131[] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ - 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, -/* rega regb regc regd rege regf reg10 reg11 */ - 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ -/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ - 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, -/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, +/* reg8 reg9 rega regb regc regd rege regf */ + 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const __u8 sn_mi0360[] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ - 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, -/* rega regb regc regd rege regf reg10 reg11 */ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, -/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ - 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, -/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, +/* reg8 reg9 rega regb regc regd rege regf */ + 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const __u8 sn_mo4000[] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ - 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, -/* reg9 rega regb regc regd rege regf reg10 reg11*/ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ - 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, -/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, - 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7, - 0xd3, 0xdf, 0xea, 0xf5 +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, +/* reg8 reg9 rega regb regc regd rege regf */ + 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const __u8 sn_ov7648[] = { - 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, - 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, +/* reg8 reg9 rega regb regc regd rege regf */ + 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82, +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const __u8 sn_ov7660[] = { -# if 1 /*jfm: from win trace */ -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ - 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, -/* reg9 rega regb regc regd rege regf reg10 reg11*/ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ - 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00, -/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#if 0 +/*jfm: from win trace */ +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, +/* reg8 reg9 rega regb regc regd rege regf */ + 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, #else -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ - 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x81, -/* reg9 rega regb regc regd rege regf reg10 reg11*/ - 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, -/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ - 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, 0x07, 0x00, 0x00, -/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, +/* reg8 reg9 rega regb regc regd rege regf */ + 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, #endif }; @@ -223,10 +227,6 @@ static const __u8 regsn20[] = { 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; -static const __u8 regsn20_sn9c120[] = { - 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90, - 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff -}; static const __u8 regsn20_sn9c325[] = { 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 @@ -238,21 +238,6 @@ static const __u8 reg84[] = { /* 0x00, 0x00, 0x00, 0x00, 0x00 */ 0xf7, 0x0f, 0x0a, 0x00, 0x00 }; -static const __u8 reg84_sn9c120_1[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x00, 0x00 -}; -static const __u8 reg84_sn9c120_2[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x02, 0x3b -}; -static const __u8 reg84_sn9c120_3[] = { - 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f, - 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f, - 0xf5, 0x0f, 0x0c, 0x02, 0x3b -}; static const __u8 reg84_sn9c325[] = { 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, @@ -687,13 +672,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev, const __u8 *reg9a; static const __u8 reg9a_def[] = {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; - static const __u8 reg9a_sn9c120[] = /* from win trace */ - {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; static const __u8 reg9a_sn9c325[] = {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; + static const __u8 regd4[] = {0x60, 0x00, 0x00}; reg_w1(gspca_dev, 0xf1, 0x00); - reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/ + reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ /* configure gpio */ reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); @@ -703,25 +687,25 @@ static int configure_gpio(struct gspca_dev *gspca_dev, case BRIDGE_SN9C325: reg9a = reg9a_sn9c325; break; - case BRIDGE_SN9C120: - reg9a = reg9a_sn9c120; - break; default: reg9a = reg9a_def; break; } reg_w(gspca_dev, 0x9a, reg9a, 6); - reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */ + reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/ reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); switch (sd->bridge) { - case BRIDGE_SN9C120: /* from win trace */ +#if 0 +/*jfm: from win trace */ + case BRIDGE_SN9C120: reg_w1(gspca_dev, 0x01, 0x61); reg_w1(gspca_dev, 0x17, 0x20); reg_w1(gspca_dev, 0x01, 0x60); break; +#endif case BRIDGE_SN9C325: reg_w1(gspca_dev, 0x01, 0x43); reg_w1(gspca_dev, 0x17, 0xae); @@ -830,10 +814,11 @@ static int sd_open(struct gspca_dev *gspca_dev) /* setup a selector by bridge */ reg_w1(gspca_dev, 0xf1, 0x01); - reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */ - reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); reg_r(gspca_dev, 0x00, 1); + reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); + reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ regF1 = gspca_dev->usb_buf[0]; + PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); switch (sd->bridge) { case BRIDGE_SN9C102P: if (regF1 != 0x11) @@ -949,15 +934,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) sd->exposure = setexposure(gspca_dev, expo); break; case SENSOR_MI0360: - expo = sd->brightness >> 4; - sd->exposure = setexposure(gspca_dev, expo); - break; case SENSOR_MO4000: expo = sd->brightness >> 4; sd->exposure = setexposure(gspca_dev, expo); break; - case SENSOR_OV7660: - return; /*jfm??*/ } k2 = sd->brightness >> 10; @@ -970,8 +950,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) __u8 k2; __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; - if (sd->sensor == SENSOR_OV7660) - return; /*jfm??*/ k2 = sd->contrast; contrast[2] = k2; contrast[0] = (k2 + 1) >> 1; @@ -998,15 +976,11 @@ static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i; - __u8 data; - __u8 reg1; - __u8 reg17; + __u8 reg1, reg17, reg18; const __u8 *sn9c1xx; int mode; static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; - static const __u8 CA_sn9c120[] = - { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ static const __u8 CE_sn9c325[] = { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ @@ -1014,9 +988,7 @@ static void sd_start(struct gspca_dev *gspca_dev) sn9c1xx = sn_tb[(int) sd->sensor]; configure_gpio(gspca_dev, sn9c1xx); -/*fixme:jfm this sequence should appear at end of sd_start */ -/* with - reg_w1(gspca_dev, 0x01, 0x44); */ +/* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/ reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); @@ -1028,20 +1000,22 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0xc7, 0x00); reg_w1(gspca_dev, 0xc8, 0x50); reg_w1(gspca_dev, 0xc9, 0x3c); -/*fixme:jfm end of ending sequence */ reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); switch (sd->bridge) { case BRIDGE_SN9C325: - data = 0xae; + reg17 = 0xae; break; +#if 0 +/*jfm: from win trace */ case BRIDGE_SN9C120: - data = 0xa0; + reg17 = 0xa0; break; +#endif default: - data = 0x60; + reg17 = 0x60; break; } - reg_w1(gspca_dev, 0x17, data); + reg_w1(gspca_dev, 0x17, reg17); reg_w1(gspca_dev, 0x05, sn9c1xx[5]); reg_w1(gspca_dev, 0x07, sn9c1xx[7]); reg_w1(gspca_dev, 0x06, sn9c1xx[6]); @@ -1056,20 +1030,6 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x9a, 0x0a); reg_w1(gspca_dev, 0x99, 0x60); break; - case BRIDGE_SN9C120: - reg_w(gspca_dev, 0x20, regsn20_sn9c120, - sizeof regsn20_sn9c120); - for (i = 0; i < 2; i++) - reg_w(gspca_dev, 0x84, reg84_sn9c120_1, - sizeof reg84_sn9c120_1); - for (i = 0; i < 6; i++) - reg_w(gspca_dev, 0x84, reg84_sn9c120_2, - sizeof reg84_sn9c120_2); - reg_w(gspca_dev, 0x84, reg84_sn9c120_3, - sizeof reg84_sn9c120_3); - reg_w1(gspca_dev, 0x9a, 0x05); - reg_w1(gspca_dev, 0x99, 0x5b); - break; default: reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); for (i = 0; i < 8; i++) @@ -1119,7 +1079,8 @@ static void sd_start(struct gspca_dev *gspca_dev) /* reg1 = 0x44; */ /* reg1 = 0x46; (done) */ } else { -#if 1 +#if 0 +/*jfm: from win trace */ reg17 = 0xa2; /* 640 */ reg1 = 0x40; #else @@ -1130,16 +1091,8 @@ static void sd_start(struct gspca_dev *gspca_dev) break; } reg_w(gspca_dev, 0xc0, C0, 6); + reg_w(gspca_dev, 0xca, CA, 4); switch (sd->bridge) { - case BRIDGE_SN9C120: /*jfm ?? */ - reg_w(gspca_dev, 0xca, CA_sn9c120, 4); - break; - default: - reg_w(gspca_dev, 0xca, CA, 4); - break; - } - switch (sd->bridge) { - case BRIDGE_SN9C120: /*jfm ?? */ case BRIDGE_SN9C325: reg_w(gspca_dev, 0xce, CE_sn9c325, 4); break; @@ -1150,14 +1103,13 @@ static void sd_start(struct gspca_dev *gspca_dev) } /* here change size mode 0 -> VGA; 1 -> CIF */ - data = 0x40 | sn9c1xx[0x18] | (mode << 4); - reg_w1(gspca_dev, 0x18, data); + reg18 = sn9c1xx[0x18] | (mode << 4); + reg_w1(gspca_dev, 0x18, reg18 | 0x40); reg_w(gspca_dev, 0x100, qtable4, 0x40); reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); - data = sn9c1xx[0x18] | (mode << 4); - reg_w1(gspca_dev, 0x18, data); + reg_w1(gspca_dev, 0x18, reg18); reg_w1(gspca_dev, 0x17, reg17); reg_w1(gspca_dev, 0x01, reg1); @@ -1185,12 +1137,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) i2c_w8(gspca_dev, stopmi0360); data = 0x29; break; - case SENSOR_MO4000: - break; case SENSOR_OV7648: data = 0x29; break; default: +/* case SENSOR_MO4000: */ /* case SENSOR_OV7660: */ break; } @@ -1317,6 +1268,7 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) (hexpo << 10) | (mexpo << 2) | lexpo); return (hexpo << 10) | (mexpo << 2) | lexpo; default: +/* case SENSOR_OV7648: * jfm: is it ok for 7648? */ /* case SENSOR_OV7660: */ /* read sensor exposure */ i2c_r5(gspca_dev, 0x04); @@ -1335,14 +1287,12 @@ static void getbrightness(struct gspca_dev *gspca_dev) /* hardcoded registers seem not readable */ switch (sd->sensor) { case SENSOR_HV7131R: -/* sd->brightness = 0x7fff; */ sd->brightness = getexposure(gspca_dev) >> 4; break; case SENSOR_MI0360: sd->brightness = getexposure(gspca_dev) << 4; break; case SENSOR_MO4000: -/* sd->brightness = 0x1fff; */ sd->brightness = getexposure(gspca_dev) << 4; break; } -- cgit v1.2.3 From abf4d1bfa93f14a0b50d1a51ed0df6a608ee62ca Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 30 Jul 2008 09:53:02 +0200 Subject: gspca: Don't use CONFIG_VIDEO_ADV_DEBUG as a compile option. From: Jean-Francois Moine This option is changed to GSPCA_DEBUG and it is set by default in gspca.h. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/conex.c | 4 ++-- linux/drivers/media/video/gspca/etoms.c | 4 ++-- linux/drivers/media/video/gspca/gspca.c | 10 +++++----- linux/drivers/media/video/gspca/gspca.h | 5 ++++- linux/drivers/media/video/gspca/sonixb.c | 2 +- linux/drivers/media/video/gspca/zc3xx.c | 6 +++--- 6 files changed, 17 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/conex.c b/linux/drivers/media/video/gspca/conex.c index 44b0bffeb..cd3a3f582 100644 --- a/linux/drivers/media/video/gspca/conex.c +++ b/linux/drivers/media/video/gspca/conex.c @@ -123,7 +123,7 @@ static void reg_r(struct gspca_dev *gspca_dev, { struct usb_device *dev = gspca_dev->dev; -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (len > sizeof gspca_dev->usb_buf) { err("reg_r: buffer overflow"); return; @@ -163,7 +163,7 @@ static void reg_w(struct gspca_dev *gspca_dev, { struct usb_device *dev = gspca_dev->dev; -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (len > sizeof gspca_dev->usb_buf) { err("reg_w: buffer overflow"); return; diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index 4e15e7dff..94f9c6690 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -233,7 +233,7 @@ static void reg_r(struct gspca_dev *gspca_dev, { struct usb_device *dev = gspca_dev->dev; -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (len > sizeof gspca_dev->usb_buf) { err("reg_r: buffer overflow"); return; @@ -271,7 +271,7 @@ static void reg_w(struct gspca_dev *gspca_dev, { struct usb_device *dev = gspca_dev->dev; -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (len > sizeof gspca_dev->usb_buf) { err("reg_w: buffer overflow"); return; diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index ffa2d7de0..600112ede 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -51,7 +51,7 @@ MODULE_LICENSE("GPL"); static int video_nr = -1; -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG int gspca_debug = D_ERR | D_PROBE; EXPORT_SYMBOL(gspca_debug); @@ -684,7 +684,7 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, w = fmt->fmt.pix.width; h = fmt->fmt.pix.height; -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (gspca_debug & D_CONF) PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); #endif @@ -792,7 +792,7 @@ static int dev_open(struct inode *inode, struct file *file) } gspca_dev->users++; file->private_data = gspca_dev; -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG /* activate the v4l2 debug */ if (gspca_debug & D_V4L2) gspca_dev->vdev.debug |= 3; @@ -1087,7 +1087,7 @@ static int vidioc_streamon(struct file *file, void *priv, if (ret < 0) goto out; } -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (gspca_debug & D_STREAM) { PDEBUG_MODE("stream on OK", gspca_dev->pixfmt, @@ -1920,7 +1920,7 @@ static void __exit gspca_exit(void) module_init(gspca_init); module_exit(gspca_exit); -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG module_param_named(debug, gspca_debug, int, 0644); MODULE_PARM_DESC(debug, "Debug (bit) 0x01:error 0x02:probe 0x04:config" diff --git a/linux/drivers/media/video/gspca/gspca.h b/linux/drivers/media/video/gspca/gspca.h index 3fd2c4eee..67e448940 100644 --- a/linux/drivers/media/video/gspca/gspca.h +++ b/linux/drivers/media/video/gspca/gspca.h @@ -9,7 +9,10 @@ #include #include -#ifdef CONFIG_VIDEO_ADV_DEBUG +/* compilation option */ +#define GSPCA_DEBUG 1 + +#ifdef GSPCA_DEBUG /* GSPCA our debug messages */ extern int gspca_debug; #define PDEBUG(level, fmt, args...) \ diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index b249015f2..4d979fa39 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -441,7 +441,7 @@ static void reg_w(struct gspca_dev *gspca_dev, const __u8 *buffer, int len) { -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (len > sizeof gspca_dev->usb_buf) { PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); return; diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 0c7b20598..ff0c30e4a 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -6474,7 +6474,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) NULL, Tgradient_1, Tgradient_2, Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 }; -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG __u8 v[16]; #endif @@ -6492,7 +6492,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) else if (g <= 0) g = 1; reg_w(dev, g, 0x0120 + i); /* gamma */ -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (gspca_debug & D_CONF) v[i] = g; #endif @@ -6512,7 +6512,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) g = 1; } reg_w(dev, g, 0x0130 + i); /* gradient */ -#ifdef CONFIG_VIDEO_ADV_DEBUG +#ifdef GSPCA_DEBUG if (gspca_debug & D_CONF) v[i] = g; #endif -- cgit v1.2.3 From 89de699923f6881c68e0e4ce483bbdd87e82b252 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 30 Jul 2008 10:33:11 +0200 Subject: gspca: Bad scan of frame in spca505/506/508. From: Jean-Francois Moine Bug introduced in changeset 6de914aaad86. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca505.c | 2 +- linux/drivers/media/video/gspca/spca506.c | 2 +- linux/drivers/media/video/gspca/spca508.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index c19cfebc1..3d25ade05 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -845,7 +845,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, default: data += 1; len -= 1; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); break; } diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index 6fe715c80..b4cf36a80 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -588,7 +588,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, default: data += 1; len -= 1; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); break; } diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index 672e0feb7..2d1e9f57a 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1621,7 +1621,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, default: data += 1; len -= 1; - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); break; } -- cgit v1.2.3 From 4f62f8819a8391344524a46b08581fa22e528a1c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 30 Jul 2008 10:47:54 +0200 Subject: gspca: Bad bytesperlines of pixelformat in spca505/506/508 and vc023x. From: Jean-Francois Moine Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca505.c | 10 +++++----- linux/drivers/media/video/gspca/spca506.c | 10 +++++----- linux/drivers/media/video/gspca/spca508.c | 8 ++++---- linux/drivers/media/video/gspca/vc032x.c | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index 3d25ade05..1cde4b34f 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -61,27 +61,27 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format vga_mode[] = { {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 160 * 3, + .bytesperline = 160, .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 5}, {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 176 * 3, + .bytesperline = 176, .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 4}, {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 320 * 3, + .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 352 * 3, + .bytesperline = 352, .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 640 * 3, + .bytesperline = 640, .sizeimage = 640 * 480 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index b4cf36a80..f622fa757 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -112,27 +112,27 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format vga_mode[] = { {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 160 * 3, + .bytesperline = 160, .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 5}, {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 176 * 3, + .bytesperline = 176, .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 4}, {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 320 * 3, + .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 352 * 3, + .bytesperline = 352, .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 640 * 3, + .bytesperline = 640, .sizeimage = 640 * 480 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index 2d1e9f57a..52e2f7462 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -64,22 +64,22 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format sif_mode[] = { {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, - .bytesperline = 160 * 3, + .bytesperline = 160, .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 3}, {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, - .bytesperline = 176 * 3, + .bytesperline = 176, .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, - .bytesperline = 320 * 3, + .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, - .bytesperline = 352 * 3, + .bytesperline = 352, .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 4c4daf6ec..0e23edb16 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -88,12 +88,12 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format vc0321_mode[] = { {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, + .bytesperline = 320, .sizeimage = 320 * 240 * 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, - .bytesperline = 640 * 2, + .bytesperline = 640, .sizeimage = 640 * 480 * 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, -- cgit v1.2.3 From c8b5c505811fd4797e0ea35bcc60478d626a0971 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 30 Jul 2008 13:43:36 +0200 Subject: v4l: move BKL down to the driver level. From: Hans Verkuil The BKL is now moved from the video_open function in v4l2-dev.c to the various drivers. It seems about a third of the drivers already has a lock of some sort protecting the open(), another third uses video_exclusive_open (yuck!) and the last third required adding the BKL in their open function. Signed-off-by: Hans Verkuil --- linux/drivers/media/radio/dsbr100.c | 3 +++ linux/drivers/media/radio/radio-si470x.c | 2 ++ linux/drivers/media/video/bt8xx/bttv-driver.c | 20 ++++++++++++++++---- linux/drivers/media/video/cafe_ccic.c | 6 +++++- linux/drivers/media/video/cx23885/cx23885-417.c | 10 ++++++++-- linux/drivers/media/video/cx23885/cx23885-video.c | 10 ++++++++-- linux/drivers/media/video/cx88/cx88-blackbird.c | 8 +++++++- linux/drivers/media/video/cx88/cx88-video.c | 10 ++++++++-- linux/drivers/media/video/em28xx/em28xx-video.c | 7 ++++++- linux/drivers/media/video/meye.c | 7 ++++++- linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 6 ++++++ linux/drivers/media/video/s2255drv.c | 6 ++++++ linux/drivers/media/video/saa5246a.c | 8 +++++++- linux/drivers/media/video/saa5249.c | 8 +++++++- linux/drivers/media/video/saa7134/saa7134-empress.c | 3 +++ linux/drivers/media/video/saa7134/saa7134-video.c | 8 +++++++- linux/drivers/media/video/se401.c | 6 +++++- linux/drivers/media/video/stk-webcam.c | 6 +++++- linux/drivers/media/video/stradis.c | 6 +++++- linux/drivers/media/video/stv680.c | 2 ++ linux/drivers/media/video/tvmixer.c | 6 +++++- linux/drivers/media/video/usbvideo/vicam.c | 6 ++++++ .../drivers/media/video/usbvision/usbvision-video.c | 2 ++ linux/drivers/media/video/v4l2-dev.c | 3 --- linux/drivers/media/video/vivi.c | 7 ++++++- linux/drivers/media/video/zoran_driver.c | 3 +++ linux/drivers/media/video/zr364xx.c | 8 +++++++- 27 files changed, 151 insertions(+), 26 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/radio/dsbr100.c b/linux/drivers/media/radio/dsbr100.c index d223846d5..93a871985 100644 --- a/linux/drivers/media/radio/dsbr100.c +++ b/linux/drivers/media/radio/dsbr100.c @@ -408,15 +408,18 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) { struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); + lock_kernel(); radio->users = 1; radio->muted = 1; if (dsbr100_start(radio)<0) { warn("Radio did not start up properly"); radio->users = 0; + unlock_kernel(); return -EIO; } dsbr100_setfreq(radio, radio->curfreq); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index afff1345b..3b1f630a9 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -1079,6 +1079,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file) struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; + lock_kernel(); radio->users++; retval = usb_autopm_get_interface(radio->intf); @@ -1095,6 +1096,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file) } done: + unlock_kernel(); return retval; } diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 40f8a0332..d5cb13e40 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -3248,6 +3248,7 @@ static int bttv_open(struct inode *inode, struct file *file) dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor); + lock_kernel(); for (i = 0; i < bttv_num; i++) { if (bttvs[i].video_dev && bttvs[i].video_dev->minor == minor) { @@ -3262,16 +3263,20 @@ static int bttv_open(struct inode *inode, struct file *file) break; } } - if (NULL == btv) + if (NULL == btv) { + unlock_kernel(); return -ENODEV; + } dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", btv->c.nr,v4l2_type_names[type]); /* allocate per filehandle data */ fh = kmalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) + if (NULL == fh) { + unlock_kernel(); return -ENOMEM; + } file->private_data = fh; *fh = btv->init; fh->type = type; @@ -3311,6 +3316,7 @@ static int bttv_open(struct inode *inode, struct file *file) bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); bttv_field_count(btv); + unlock_kernel(); return 0; } @@ -3451,21 +3457,26 @@ static int radio_open(struct inode *inode, struct file *file) dprintk("bttv: open minor=%d\n",minor); + lock_kernel(); for (i = 0; i < bttv_num; i++) { if (bttvs[i].radio_dev->minor == minor) { btv = &bttvs[i]; break; } } - if (NULL == btv) + if (NULL == btv) { + unlock_kernel(); return -ENODEV; + } dprintk("bttv%d: open called (radio)\n",btv->c.nr); /* allocate per filehandle data */ fh = kmalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) + if (NULL == fh) { + unlock_kernel(); return -ENOMEM; + } file->private_data = fh; *fh = btv->init; v4l2_prio_open(&btv->prio, &fh->prio); @@ -3478,6 +3489,7 @@ static int radio_open(struct inode *inode, struct file *file) audio_input(btv,TVAUDIO_INPUT_RADIO); mutex_unlock(&btv->lock); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c index 35ecaa0c1..4c0d44c5d 100644 --- a/linux/drivers/media/video/cafe_ccic.c +++ b/linux/drivers/media/video/cafe_ccic.c @@ -1482,9 +1482,12 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) { struct cafe_camera *cam; + lock_kernel(); cam = cafe_find_dev(iminor(inode)); - if (cam == NULL) + if (cam == NULL) { + unlock_kernel(); return -ENODEV; + } filp->private_data = cam; mutex_lock(&cam->s_mutex); @@ -1496,6 +1499,7 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) } (cam->users)++; mutex_unlock(&cam->s_mutex); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/cx23885/cx23885-417.c b/linux/drivers/media/video/cx23885/cx23885-417.c index a8ca3bd9f..106b594ed 100644 --- a/linux/drivers/media/video/cx23885/cx23885-417.c +++ b/linux/drivers/media/video/cx23885/cx23885-417.c @@ -1591,6 +1591,7 @@ static int mpeg_open(struct inode *inode, struct file *file) dprintk(2, "%s()\n", __func__); + lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); if (h->v4l_device->minor == minor) { @@ -1599,13 +1600,17 @@ static int mpeg_open(struct inode *inode, struct file *file) } } - if (dev == NULL) + if (dev == NULL) { + unlock_kernel(); return -ENODEV; + } /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) + if (NULL == fh) { + unlock_kernel(); return -ENOMEM; + } file->private_data = fh; fh->dev = dev; @@ -1616,6 +1621,7 @@ static int mpeg_open(struct inode *inode, struct file *file) V4L2_FIELD_INTERLACED, sizeof(struct cx23885_buffer), fh); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index 3f1765de0..98a7dc1c0 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -787,6 +787,7 @@ static int video_open(struct inode *inode, struct file *file) enum v4l2_buf_type type = 0; int radio = 0; + lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); if (h->video_dev->minor == minor) { @@ -804,16 +805,20 @@ static int video_open(struct inode *inode, struct file *file) dev = h; } } - if (NULL == dev) + if (NULL == dev) { + unlock_kernel(); return -ENODEV; + } dprintk(1, "open minor=%d radio=%d type=%s\n", minor, radio, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) + if (NULL == fh) { + unlock_kernel(); return -ENOMEM; + } file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -846,6 +851,7 @@ static int video_open(struct inode *inode, struct file *file) AUDC_SET_RADIO, NULL); } #endif + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c index 696a8752a..0cd510814 100644 --- a/linux/drivers/media/video/cx88/cx88-blackbird.c +++ b/linux/drivers/media/video/cx88/cx88-blackbird.c @@ -1076,12 +1076,15 @@ static int mpeg_open(struct inode *inode, struct file *file) struct cx8802_driver *drv = NULL; int err; + lock_kernel(); dev = cx8802_get_device(inode); dprintk( 1, "%s\n", __func__); - if (dev == NULL) + if (dev == NULL) { + unlock_kernel(); return -ENODEV; + } /* Make sure we can acquire the hardware */ drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); @@ -1096,6 +1099,7 @@ static int mpeg_open(struct inode *inode, struct file *file) if (blackbird_initialize_codec(dev) < 0) { if (drv) drv->request_release(drv); + unlock_kernel(); return -EINVAL; } dprintk(1,"open minor=%d\n",minor); @@ -1105,6 +1109,7 @@ static int mpeg_open(struct inode *inode, struct file *file) if (NULL == fh) { if (drv) drv->request_release(drv); + unlock_kernel(); return -ENOMEM; } file->private_data = fh; @@ -1120,6 +1125,7 @@ static int mpeg_open(struct inode *inode, struct file *file) /* FIXME: locking against other video device */ cx88_set_scale(dev->core, dev->width, dev->height, fh->mpegq.field); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 5dafb7d73..3a7a9ed17 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -999,6 +999,7 @@ static int video_open(struct inode *inode, struct file *file) enum v4l2_buf_type type = 0; int radio = 0; + lock_kernel(); list_for_each_entry(h, &cx8800_devlist, devlist) { if (h->video_dev->minor == minor) { dev = h; @@ -1014,8 +1015,10 @@ static int video_open(struct inode *inode, struct file *file) dev = h; } } - if (NULL == dev) + if (NULL == dev) { + unlock_kernel(); return -ENODEV; + } core = dev->core; @@ -1024,8 +1027,10 @@ static int video_open(struct inode *inode, struct file *file) /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) + if (NULL == fh) { + unlock_kernel(); return -ENOMEM; + } file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -1058,6 +1063,7 @@ static int video_open(struct inode *inode, struct file *file) cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); } + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 81d942e39..c9a2d4808 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1555,6 +1555,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) struct em28xx_fh *fh; enum v4l2_buf_type fh_type = 0; + lock_kernel(); list_for_each_entry(h, &em28xx_devlist, devlist) { if (h->vdev->minor == minor) { dev = h; @@ -1570,8 +1571,10 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) dev = h; } } - if (NULL == dev) + if (NULL == dev) { + unlock_kernel(); return -ENODEV; + } em28xx_videodbg("open minor=%d type=%s users=%d\n", minor, v4l2_type_names[fh_type], dev->users); @@ -1587,6 +1590,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); if (!fh) { em28xx_errdev("em28xx-video.c: Out of memory?!\n"); + unlock_kernel(); return -ENOMEM; } mutex_lock(&dev->lock); @@ -1630,6 +1634,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) sizeof(struct em28xx_buffer), fh); mutex_unlock(&dev->lock); + unlock_kernel(); return errCode; } diff --git a/linux/drivers/media/video/meye.c b/linux/drivers/media/video/meye.c index d128a611e..a0cdae0c1 100644 --- a/linux/drivers/media/video/meye.c +++ b/linux/drivers/media/video/meye.c @@ -850,15 +850,19 @@ static int meye_open(struct inode *inode, struct file *file) { int i, err; + lock_kernel(); err = video_exclusive_open(inode, file); - if (err < 0) + if (err < 0) { + unlock_kernel(); return err; + } mchip_hic_stop(); if (mchip_dma_alloc()) { printk(KERN_ERR "meye: mchip framebuffer allocation failed\n"); video_exclusive_release(inode, file); + unlock_kernel(); return -ENOBUFS; } @@ -866,6 +870,7 @@ static int meye_open(struct inode *inode, struct file *file) meye.grab_buffer[i].state = MEYE_BUF_UNUSED; kfifo_reset(meye.grabq); kfifo_reset(meye.doneq); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 1619c2756..c1cc0e88b 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -933,6 +933,7 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) unsigned int input_cnt,idx; int ret = 0; + lock_kernel(); dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase); vp = dip->v4lp; @@ -943,11 +944,13 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) if (!pvr2_hdw_dev_ok(hdw)) { pvr2_trace(PVR2_TRACE_OPEN_CLOSE, "pvr2_v4l2_open: hardware not ready"); + unlock_kernel(); return -EIO; } fhp = kzalloc(sizeof(*fhp),GFP_KERNEL); if (!fhp) { + unlock_kernel(); return -ENOMEM; } @@ -977,6 +980,7 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) fhp); kfree(fhp); + unlock_kernel(); return ret; } @@ -993,6 +997,7 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) "Destroying pvr_v4l2_fh id=%p (input map failure)", fhp); kfree(fhp); + unlock_kernel(); return -ENOMEM; } input_cnt = 0; @@ -1016,6 +1021,7 @@ static int pvr2_v4l2_open(struct inode *inode, struct file *file) v4l2_prio_open(&vp->prio,&fhp->prio); fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c index 85e98c9d2..939edff48 100644 --- a/linux/drivers/media/video/s2255drv.c +++ b/linux/drivers/media/video/s2255drv.c @@ -1457,6 +1457,7 @@ static int s2255_open(struct inode *inode, struct file *file) int cur_channel = -1; dprintk(1, "s2255: open called (minor=%d)\n", minor); + lock_kernel(); list_for_each(list, &s2255_devlist) { h = list_entry(list, struct s2255_dev, s2255_devlist); for (i = 0; i < MAX_CHANNELS; i++) { @@ -1469,6 +1470,7 @@ static int s2255_open(struct inode *inode, struct file *file) } if ((NULL == dev) || (cur_channel == -1)) { + unlock_kernel(); dprintk(1, "s2255: openv4l no dev\n"); return -ENODEV; } @@ -1490,6 +1492,7 @@ static int s2255_open(struct inode *inode, struct file *file) printk(KERN_INFO "2255 FW load failed.\n"); dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); + unlock_kernel(); return -EFAULT; } } else if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_NOTLOADED) { @@ -1506,6 +1509,7 @@ static int s2255_open(struct inode *inode, struct file *file) "try again\n"); dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); + unlock_kernel(); return -EBUSY; } } @@ -1515,6 +1519,7 @@ static int s2255_open(struct inode *inode, struct file *file) if (NULL == fh) { dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); + unlock_kernel(); return -ENOMEM; } @@ -1548,6 +1553,7 @@ static int s2255_open(struct inode *inode, struct file *file) kref_get(&dev->kref); mutex_unlock(&dev->open_lock); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/saa5246a.c b/linux/drivers/media/video/saa5246a.c index 3765dcee9..1bfc49822 100644 --- a/linux/drivers/media/video/saa5246a.c +++ b/linux/drivers/media/video/saa5246a.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "compat.h" #include #include @@ -738,9 +739,12 @@ static int saa5246a_open(struct inode *inode, struct file *file) struct saa5246a_device *t = vd->priv; int err; + lock_kernel(); err = video_exclusive_open(inode,file); - if (err < 0) + if (err < 0) { + unlock_kernel(); return err; + } if (t->client==NULL) { err = -ENODEV; @@ -777,11 +781,13 @@ static int saa5246a_open(struct inode *inode, struct file *file) err = -EIO; goto fail; } + unlock_kernel(); return 0; fail: video_exclusive_release(inode,file); + unlock_kernel(); return err; } diff --git a/linux/drivers/media/video/saa5249.c b/linux/drivers/media/video/saa5249.c index 662690c8b..81d341a80 100644 --- a/linux/drivers/media/video/saa5249.c +++ b/linux/drivers/media/video/saa5249.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -634,9 +635,12 @@ static int saa5249_open(struct inode *inode, struct file *file) struct saa5249_device *t=vd->priv; int err,pgbuf; + lock_kernel(); err = video_exclusive_open(inode,file); - if (err < 0) + if (err < 0) { + unlock_kernel(); return err; + } if (t->client==NULL) { err = -ENODEV; @@ -665,10 +669,12 @@ static int saa5249_open(struct inode *inode, struct file *file) t->is_searching[pgbuf] = false; } t->virtual_mode = false; + unlock_kernel(); return 0; fail: video_exclusive_release(inode,file); + unlock_kernel(); return err; } diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 45bd752a9..a454968f7 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -79,9 +79,11 @@ static int ts_open(struct inode *inode, struct file *file) struct saa7134_dev *dev; int err; + lock_kernel(); list_for_each_entry(dev, &saa7134_devlist, devlist) if (dev->empress_dev && dev->empress_dev->minor == minor) goto found; + unlock_kernel(); return -ENODEV; found: @@ -103,6 +105,7 @@ static int ts_open(struct inode *inode, struct file *file) done_up: mutex_unlock(&dev->empress_tsq.vb_lock); done: + unlock_kernel(); return err; } diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 2b4d9c697..547c0401a 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -1330,6 +1330,8 @@ static int video_open(struct inode *inode, struct file *file) struct saa7134_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int radio = 0; + + lock_kernel(); list_for_each_entry(dev, &saa7134_devlist, devlist) { if (dev->video_dev && (dev->video_dev->minor == minor)) goto found; @@ -1342,6 +1344,7 @@ static int video_open(struct inode *inode, struct file *file) goto found; } } + unlock_kernel(); return -ENODEV; found: @@ -1350,8 +1353,10 @@ static int video_open(struct inode *inode, struct file *file) /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) + if (NULL == fh) { + unlock_kernel(); return -ENOMEM; + } file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -1384,6 +1389,7 @@ static int video_open(struct inode *inode, struct file *file) /* switch to video/vbi mode */ video_mux(dev,dev->ctl_input); } + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/se401.c b/linux/drivers/media/video/se401.c index f59d63618..04897413d 100644 --- a/linux/drivers/media/video/se401.c +++ b/linux/drivers/media/video/se401.c @@ -944,14 +944,18 @@ static int se401_open(struct inode *inode, struct file *file) struct usb_se401 *se401 = (struct usb_se401 *)dev; int err = 0; - if (se401->user) + lock_kernel(); + if (se401->user) { + unlock_kernel(); return -EBUSY; + } se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES); if (se401->fbuf) file->private_data = dev; else err = -ENOMEM; se401->user = !err; + unlock_kernel(); return err; } diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index e18745a67..c6660b363 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -690,11 +690,15 @@ static int v4l_stk_open(struct inode *inode, struct file *fp) vdev = video_devdata(fp); dev = vdev_to_camera(vdev); - if (dev == NULL || !is_present(dev)) + lock_kernel(); + if (dev == NULL || !is_present(dev)) { + unlock_kernel(); return -ENXIO; + } fp->private_data = vdev; kref_get(&dev->kref); usb_autopm_get_interface(dev->interface); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/stradis.c b/linux/drivers/media/video/stradis.c index 19243ac19..a081307c7 100644 --- a/linux/drivers/media/video/stradis.c +++ b/linux/drivers/media/video/stradis.c @@ -1887,12 +1887,16 @@ static int saa_open(struct inode *inode, struct file *file) struct video_device *vdev = video_devdata(file); struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev); + lock_kernel(); file->private_data = saa; saa->user++; - if (saa->user > 1) + if (saa->user > 1) { + unlock_kernel(); return 0; /* device open already, don't reset */ + } saa->writemode = VID_WRITE_MPEG_VID; /* default to video */ + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/stv680.c b/linux/drivers/media/video/stv680.c index 34844ffec..de32a5266 100644 --- a/linux/drivers/media/video/stv680.c +++ b/linux/drivers/media/video/stv680.c @@ -1091,6 +1091,7 @@ static int stv_open (struct inode *inode, struct file *file) int err = 0; /* we are called with the BKL held */ + lock_kernel(); stv680->user = 1; err = stv_init (stv680); /* main initialization routine for camera */ @@ -1104,6 +1105,7 @@ static int stv_open (struct inode *inode, struct file *file) } if (err) stv680->user = 0; + unlock_kernel(); return err; } diff --git a/linux/drivers/media/video/tvmixer.c b/linux/drivers/media/video/tvmixer.c index 6233bf391..7c1e1a850 100644 --- a/linux/drivers/media/video/tvmixer.c +++ b/linux/drivers/media/video/tvmixer.c @@ -182,6 +182,7 @@ static int tvmixer_open(struct inode *inode, struct file *file) struct TVMIXER *mix = NULL; struct i2c_client *client = NULL; + lock_kernel(); for (i = 0; i < DEV_MAX; i++) { if (devices[i].minor == minor) { mix = devices+i; @@ -190,13 +191,16 @@ static int tvmixer_open(struct inode *inode, struct file *file) } } - if (NULL == client) + if (NULL == client) { + unlock_kernel(); return -ENODEV; + } /* lock bttv in memory while the mixer is in use */ file->private_data = mix; if (client->adapter->owner) try_module_get(client->adapter->owner); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/usbvideo/vicam.c b/linux/drivers/media/video/usbvideo/vicam.c index e31b64f17..e7330fe4f 100644 --- a/linux/drivers/media/video/usbvideo/vicam.c +++ b/linux/drivers/media/video/usbvideo/vicam.c @@ -798,20 +798,24 @@ vicam_open(struct inode *inode, struct file *file) * rely on this fact forever. */ + lock_kernel(); if (cam->open_count > 0) { printk(KERN_INFO "vicam_open called on already opened camera"); + unlock_kernel(); return -EBUSY; } cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL); if (!cam->raw_image) { + unlock_kernel(); return -ENOMEM; } cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); if (!cam->framebuf) { kfree(cam->raw_image); + unlock_kernel(); return -ENOMEM; } @@ -819,6 +823,7 @@ vicam_open(struct inode *inode, struct file *file) if (!cam->cntrlbuf) { kfree(cam->raw_image); rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); + unlock_kernel(); return -ENOMEM; } @@ -836,6 +841,7 @@ vicam_open(struct inode *inode, struct file *file) cam->open_count++; file->private_data = cam; + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index b977116a0..b76295a5b 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -367,6 +367,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) PDEBUG(DBG_IO, "open"); + lock_kernel(); usbvision_reset_powerOffTimer(usbvision); if (usbvision->user) @@ -424,6 +425,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) usbvision_empty_framequeues(usbvision); PDEBUG(DBG_IO, "success"); + unlock_kernel(); return errCode; } diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index d7aa8f6a4..c3d3212fd 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -150,7 +150,6 @@ static int video_open(struct inode *inode, struct file *file) if (minor >= VIDEO_NUM_DEVICES) return -ENODEV; - lock_kernel(); mutex_lock(&videodev_lock); vfl = video_device[minor]; if (vfl == NULL) { @@ -160,7 +159,6 @@ static int video_open(struct inode *inode, struct file *file) vfl = video_device[minor]; if (vfl == NULL) { mutex_unlock(&videodev_lock); - unlock_kernel(); return -ENODEV; } } @@ -178,7 +176,6 @@ static int video_open(struct inode *inode, struct file *file) } fops_put(old_fops); mutex_unlock(&videodev_lock); - unlock_kernel(); return err; } diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 573149cc0..2f18381b6 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -901,9 +901,11 @@ static int vivi_open(struct inode *inode, struct file *file) printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); + lock_kernel(); list_for_each_entry(dev, &vivi_devlist, vivi_devlist) if (dev->vfd->minor == minor) goto found; + unlock_kernel(); return -ENODEV; found: @@ -928,8 +930,10 @@ found: } unlock: mutex_unlock(&dev->mutex); - if (retval) + if (retval) { + unlock_kernel(); return retval; + } file->private_data = fh; fh->dev = dev; @@ -958,6 +962,7 @@ unlock: sizeof(struct vivi_buffer), fh); vivi_start_thread(fh); + unlock_kernel(); return 0; } diff --git a/linux/drivers/media/video/zoran_driver.c b/linux/drivers/media/video/zoran_driver.c index 0c1c349cd..78e8430f4 100644 --- a/linux/drivers/media/video/zoran_driver.c +++ b/linux/drivers/media/video/zoran_driver.c @@ -1276,6 +1276,7 @@ zoran_open (struct inode *inode, struct zoran_fh *fh; int i, res, first_open = 0, have_module_locks = 0; + lock_kernel(); /* find the device */ for (i = 0; i < zoran_num; i++) { if (zoran[i]->video_dev->minor == minor) { @@ -1386,6 +1387,7 @@ zoran_open (struct inode *inode, file->private_data = fh; fh->zr = zr; zoran_open_init_session(file); + unlock_kernel(); return 0; @@ -1403,6 +1405,7 @@ open_unlock_and_return: if (zr) { /*mutex_unlock(&zr->resource_lock);*/ } + unlock_kernel(); return res; } diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index 53a934daa..dbfdd6966 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -644,14 +644,18 @@ static int zr364xx_open(struct inode *inode, struct file *file) cam->skip = 2; + lock_kernel(); err = video_exclusive_open(inode, file); - if (err < 0) + if (err < 0) { + unlock_kernel(); return err; + } if (!cam->framebuf) { cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES); if (!cam->framebuf) { info("vmalloc_32 failed!"); + unlock_kernel(); return -ENOMEM; } } @@ -665,6 +669,7 @@ static int zr364xx_open(struct inode *inode, struct file *file) if (err < 0) { info("error during open sequence: %d", i); mutex_unlock(&cam->lock); + unlock_kernel(); return err; } } @@ -677,6 +682,7 @@ static int zr364xx_open(struct inode *inode, struct file *file) mdelay(100); mutex_unlock(&cam->lock); + unlock_kernel(); return 0; } -- cgit v1.2.3 From b8e0b401a66a9c16cbf82b5b6ded4f43f3049ad5 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 30 Jul 2008 18:43:11 -0400 Subject: cxusb: fix OOPS and broken tuning regression on FusionHDTV Dual Digital 4 From: Robert Lowery quoting Robert Lowery: I think I've found the cause of the oops. [...] BTW it appears I have fixed my tuning problems with the updated patch below. This reverts a change Mauro made a while back. All is good now :) [...] The good news is that I've got a better patch that definitely works this time and even better, makes use of the standard firmware (rather than the Australian specific one). ...based on an earlier patch by Hans-Frieder Vogt: http://www.linuxtv.org/pipermail/linux-dvb/2008-May/026280.html Signed-off-by: Robert Lowery Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/cxusb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/dvb-usb/cxusb.c b/linux/drivers/media/dvb/dvb-usb/cxusb.c index 578afce68..aaa0b6f0b 100644 --- a/linux/drivers/media/dvb/dvb-usb/cxusb.c +++ b/linux/drivers/media/dvb/dvb-usb/cxusb.c @@ -565,7 +565,8 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) { - struct dvb_usb_device *d = ptr; + struct dvb_usb_adapter *adap = ptr; + struct dvb_usb_device *d = adap->dev; switch (command) { case XC2028_TUNER_RESET: @@ -593,9 +594,9 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) .callback = dvico_bluebird_xc2028_callback, }; static struct xc2028_ctrl ctl = { - .fname = "xc3028-dvico-au-01.fw", + .fname = "xc3028-v27.fw", .max_len = 64, - .scode_table = XC3028_FE_ZARLINK456, + .demod = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, adap->fe, &cfg); -- cgit v1.2.3 From 2582e88cefde7d842e1265fc188a31868e1466e5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 1 Aug 2008 11:37:51 +0200 Subject: gspca: Fix small bugs, simplify and cleanup ov519. From: Jean-Francois Moine The hflip and vflip controls work for ov519 - ov7670 only. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/ov519.c | 437 +++++++++++--------------------- 1 file changed, 143 insertions(+), 294 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/ov519.c b/linux/drivers/media/video/gspca/ov519.c index 97d3a063f..2379433f0 100644 --- a/linux/drivers/media/video/gspca/ov519.c +++ b/linux/drivers/media/video/gspca/ov519.c @@ -40,8 +40,7 @@ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ /* Determined by sensor type */ - short maxwidth; - short maxheight; + char sif; unsigned char primary_i2c_slave; /* I2C write id of sensor */ @@ -85,7 +84,6 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -94,12 +92,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define BRIGHTNESS_DEF 127 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -108,21 +106,22 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define CONTRAST_DEF 127 + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", + .name = "Color", .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define COLOR_DEF 127 + .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, @@ -161,7 +160,7 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format vga_mode[] = { {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 589, + .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1}, {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, @@ -173,12 +172,12 @@ static struct v4l2_pix_format vga_mode[] = { static struct v4l2_pix_format sif_mode[] = { {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 8 + 589, + .sizeimage = 176 * 144 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1}, {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 8 + 589, + .sizeimage = 352 * 288 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, }; @@ -294,16 +293,6 @@ static struct v4l2_pix_format sif_mode[] = { #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ -struct ovsensor_window { - short x; - short y; - short width; - short height; -/* int format; */ - short quarter; /* Scale width and height down 2x */ - short clockdiv; /* Clock divisor setting */ -}; - static unsigned char ov7670_abs_to_sm(unsigned char v) { if (v > 127) @@ -535,19 +524,6 @@ static int init_ov_sensor(struct sd *sd) return 0; } -/* Switch on standard JPEG compression. Returns 0 for success. */ -static int ov519_init_compression(struct sd *sd) -{ - if (!sd->compress_inited) { - if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) { - PDEBUG(D_ERR, "Error switching to compressed mode"); - return -EIO; - } - sd->compress_inited = 1; - } - return 0; -} - /* Set the read and write slave IDs. The "slave" argument is the write slave, * and the read slave will be set to (slave + 1). * This should not be called from outside the i2c I/O functions. @@ -717,21 +693,17 @@ static int ov8xx0_configure(struct sd *sd) return -1; } if ((rc & 3) == 1) { - PDEBUG(D_PROBE, "Sensor is an OV8610"); sd->sensor = SEN_OV8610; } else { PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); return -1; } PDEBUG(D_PROBE, "Writing 8610 registers"); - if (write_i2c_regvals(sd, - norm_8610, - sizeof norm_8610 / sizeof norm_8610[0])) + if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610))) return -1; /* Set sensor-specific vars */ - sd->maxwidth = 640; - sd->maxheight = 480; +/* sd->sif = 0; already done */ return 0; } @@ -861,7 +833,7 @@ static int ov7xx0_configure(struct sd *sd) { OV7670_REG_COM7, OV7670_COM7_RESET }, { OV7670_REG_TSLB, 0x04 }, /* OV */ { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ - { OV7670_REG_CLKRC, 0x1 }, + { OV7670_REG_CLKRC, 0x01 }, /* * Set the hardware window. These values from OV don't entirely * make sense - hstop is less than hstart. But they work... @@ -875,16 +847,12 @@ static int ov7xx0_configure(struct sd *sd) { 0x70, 0x3a }, { 0x71, 0x35 }, { 0x72, 0x11 }, { 0x73, 0xf0 }, { 0xa2, 0x02 }, -/* jfm */ -/* { OV7670_REG_COM10, 0x0 }, */ +/* { OV7670_REG_COM10, 0x0 }, */ /* Gamma curve values */ { 0x7a, 0x20 }, -/* jfm:win 7b=1c */ { 0x7b, 0x10 }, -/* jfm:win 7c=28 */ { 0x7c, 0x1e }, -/* jfm:win 7d=3c */ { 0x7d, 0x35 }, { 0x7e, 0x5a }, { 0x7f, 0x69 }, { 0x80, 0x76 }, { 0x81, 0x80 }, @@ -900,13 +868,11 @@ static int ov7xx0_configure(struct sd *sd) | OV7670_COM8_BFILT }, { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ -/* jfm:win 14=38 */ { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, { OV7670_REG_HAECC2, 0x68 }, -/* jfm:win a1=0b */ { 0xa1, 0x03 }, /* magic */ { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, @@ -920,8 +886,6 @@ static int ov7xx0_configure(struct sd *sd) /* Almost all of these are magic "reserved" values. */ { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, { 0x16, 0x02 }, -/* jfm */ -/* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */ { OV7670_REG_MVFP, 0x07 }, { 0x21, 0x02 }, { 0x22, 0x91 }, { 0x29, 0x07 }, { 0x33, 0x0b }, @@ -995,32 +959,10 @@ static int ov7xx0_configure(struct sd *sd) { 0x79, 0x03 }, { 0xc8, 0x40 }, { 0x79, 0x05 }, { 0xc8, 0x30 }, { 0x79, 0x26 }, - -#if 0 /* (already done) */ - /* Format YUV422 */ - { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */ - { OV7670_REG_RGB444, 0 }, /* No RGB444 please */ - { OV7670_REG_COM1, 0 }, - { OV7670_REG_COM15, OV7670_COM15_R00FF }, - { OV7670_REG_COM9, 0x18 }, - /* 4x gain ceiling; 0x8 is reserved bit */ - { 0x4f, 0x80 }, /* "matrix coefficient 1" */ - { 0x50, 0x80 }, /* "matrix coefficient 2" */ - { 0x52, 0x22 }, /* "matrix coefficient 4" */ - { 0x53, 0x5e }, /* "matrix coefficient 5" */ - { 0x54, 0x80 }, /* "matrix coefficient 6" */ - { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT }, -#endif -}; + }; PDEBUG(D_PROBE, "starting OV7xx0 configuration"); -/* jfm:already done? */ - if (init_ov_sensor(sd) < 0) - PDEBUG(D_ERR, "Failed to read sensor ID"); - else - PDEBUG(D_PROBE, "OV7xx0 initialized"); - /* Detect sensor (sub)type */ rc = i2c_r(sd, OV7610_REG_COM_I); @@ -1066,20 +1008,25 @@ static int ov7xx0_configure(struct sd *sd) return low; } if (high == 0x76) { - if (low == 0x30) { + switch (low) { + case 0x30: PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); sd->sensor = SEN_OV7630; - } else if (low == 0x40) { + break; + case 0x40: PDEBUG(D_PROBE, "Sensor is an OV7645"); sd->sensor = SEN_OV7640; /* FIXME */ - } else if (low == 0x45) { + break; + case 0x45: PDEBUG(D_PROBE, "Sensor is an OV7645B"); sd->sensor = SEN_OV7640; /* FIXME */ - } else if (low == 0x48) { + break; + case 0x48: PDEBUG(D_PROBE, "Sensor is an OV7648"); sd->sensor = SEN_OV7640; /* FIXME */ - } else { - PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); + break; + default: + PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); return -1; } } else { @@ -1091,34 +1038,34 @@ static int ov7xx0_configure(struct sd *sd) return -1; } - if (sd->sensor == SEN_OV7620) { + switch (sd->sensor) { + case SEN_OV7620: PDEBUG(D_PROBE, "Writing 7620 registers"); - if (write_i2c_regvals(sd, norm_7620, - sizeof norm_7620 / sizeof norm_7620[0])) + if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) return -1; - } else if (sd->sensor == SEN_OV7630) { + break; + case SEN_OV7630: PDEBUG(D_ERR, "7630 is not supported by this driver version"); return -1; - } else if (sd->sensor == SEN_OV7640) { + case SEN_OV7640: PDEBUG(D_PROBE, "Writing 7640 registers"); - if (write_i2c_regvals(sd, norm_7640, - sizeof norm_7640 / sizeof norm_7640[0])) + if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) return -1; - } else if (sd->sensor == SEN_OV7670) { + break; + case SEN_OV7670: PDEBUG(D_PROBE, "Writing 7670 registers"); - if (write_i2c_regvals(sd, norm_7670, - sizeof norm_7670 / sizeof norm_7670[0])) + if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670))) return -1; - } else { + break; + default: PDEBUG(D_PROBE, "Writing 7610 registers"); - if (write_i2c_regvals(sd, norm_7610, - sizeof norm_7610 / sizeof norm_7610[0])) + if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610))) return -1; + break; } /* Set sensor-specific vars */ - sd->maxwidth = 640; - sd->maxheight = 480; +/* sd->sif = 0; already done */ return 0; } @@ -1272,43 +1219,45 @@ static int ov6xx0_configure(struct sd *sd) /* Ugh. The first two bits are the version bits, but * the entire register value must be used. I guess OVT * underestimated how many variants they would make. */ - if (rc == 0x00) { + switch (rc) { + case 0x00: sd->sensor = SEN_OV6630; PDEBUG(D_ERR, "WARNING: Sensor is an OV66308. Your camera may have"); PDEBUG(D_ERR, "been misdetected in previous driver versions."); - } else if (rc == 0x01) { + break; + case 0x01: sd->sensor = SEN_OV6620; - PDEBUG(D_PROBE, "Sensor is an OV6620"); - } else if (rc == 0x02) { + break; + case 0x02: sd->sensor = SEN_OV6630; PDEBUG(D_PROBE, "Sensor is an OV66308AE"); - } else if (rc == 0x03) { + break; + case 0x03: sd->sensor = SEN_OV6630; PDEBUG(D_PROBE, "Sensor is an OV66308AF"); - } else if (rc == 0x90) { + break; + case 0x90: sd->sensor = SEN_OV6630; PDEBUG(D_ERR, "WARNING: Sensor is an OV66307. Your camera may have"); PDEBUG(D_ERR, "been misdetected in previous driver versions."); - } else { + break; + default: PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); return -1; } /* Set sensor-specific vars */ - sd->maxwidth = 352; - sd->maxheight = 288; + sd->sif = 1; if (sd->sensor == SEN_OV6620) { PDEBUG(D_PROBE, "Writing 6x20 registers"); - if (write_i2c_regvals(sd, norm_6x20, - sizeof norm_6x20 / sizeof norm_6x20[0])) + if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) return -1; } else { PDEBUG(D_PROBE, "Writing 6x30 registers"); - if (write_i2c_regvals(sd, norm_6x30, - sizeof norm_6x30 / sizeof norm_6x30[0])) + if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) return -1; } return 0; @@ -1317,14 +1266,8 @@ static int ov6xx0_configure(struct sd *sd) /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ static void ov51x_led_control(struct sd *sd, int on) { - PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); - -/* if (sd->bridge == BRG_OV511PLUS) */ -/* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */ -/* else if (sd->bridge == BRG_OV519) */ - reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ -/* else if (sd->bclass == BCL_OV518) */ -/* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */ +/* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */ + reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ } /* this function is called at probe time */ @@ -1334,11 +1277,8 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; -/* (from ov519_configure) */ static const struct ov_regvals init_519[] = { { 0x5a, 0x6d }, /* EnableSystem */ -/* jfm trace usbsnoop3-1.txt */ -/* jfm 53 = fb */ { 0x53, 0x9b }, { 0x54, 0xff }, /* set bit2 to enable jpeg */ { 0x5d, 0x03 }, @@ -1355,9 +1295,6 @@ static int sd_config(struct gspca_dev *gspca_dev, if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) goto error; -/* jfm: not seen in windows trace */ - if (ov519_init_compression(sd)) - goto error; ov51x_led_control(sd, 0); /* turn LED off */ /* Test for 76xx */ @@ -1406,16 +1343,16 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; cam->epaddr = OV511_ENDPOINT_ADDRESS; - if (sd->maxwidth == 640) { + if (!sd->sif) { cam->cam_mode = vga_mode; - cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + cam->nmodes = ARRAY_SIZE(vga_mode); } else { cam->cam_mode = sif_mode; - cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + cam->nmodes = ARRAY_SIZE(sif_mode); } - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLOR_DEF; sd->hflip = HFLIP_DEF; sd->vflip = VFLIP_DEF; return 0; @@ -1437,8 +1374,7 @@ static int sd_open(struct gspca_dev *gspca_dev) * * Do not put any sensor-specific code in here (including I2C I/O functions) */ -static int ov519_mode_init_regs(struct sd *sd, - int width, int height) +static int ov519_mode_init_regs(struct sd *sd) { static const struct ov_regvals mode_init_519_ov7670[] = { { 0x5d, 0x03 }, /* Turn off suspend mode */ @@ -1484,36 +1420,23 @@ static int ov519_mode_init_regs(struct sd *sd, /* windows reads 0x55 at this point, why? */ }; -/* int hi_res; */ - - PDEBUG(D_CONF, "mode init %dx%d", width, height); - -/* if (width >= 800 && height >= 600) - hi_res = 1; - else - hi_res = 0; */ - -/* if (ov51x_stop(sd) < 0) - return -EIO; */ - /******** Set the mode ********/ if (sd->sensor != SEN_OV7670) { if (write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519))) return -EIO; + if (sd->sensor == SEN_OV7640) { + /* Select 8-bit input mode */ + reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); + } } else { if (write_regvals(sd, mode_init_519_ov7670, ARRAY_SIZE(mode_init_519_ov7670))) return -EIO; } - if (sd->sensor == SEN_OV7640) { - /* Select 8-bit input mode */ - reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); - } - - reg_w(sd, OV519_CAM_H_SIZE, width >> 4); - reg_w(sd, OV519_CAM_V_SIZE, height >> 3); + reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4); + reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3); reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); @@ -1528,9 +1451,10 @@ static int ov519_mode_init_regs(struct sd *sd, /* FIXME: These are only valid at the max resolution. */ sd->clockdiv = 0; - if (sd->sensor == SEN_OV7640) { + switch (sd->sensor) { + case SEN_OV7640: switch (sd->frame_rate) { -/*jfm: default was 30 fps */ +/*fixme: default was 30 fps */ case 30: reg_w(sd, 0xa4, 0x0c); reg_w(sd, 0x23, 0xff); @@ -1560,7 +1484,8 @@ static int ov519_mode_init_regs(struct sd *sd, sd->clockdiv = 1; break; } - } else if (sd->sensor == SEN_OV8610) { + break; + case SEN_OV8610: switch (sd->frame_rate) { default: /* 15 fps */ /* case 15: */ @@ -1576,41 +1501,37 @@ static int ov519_mode_init_regs(struct sd *sd, reg_w(sd, 0x23, 0x1b); break; } - sd->clockdiv = 0; - } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ + break; + case SEN_OV7670: /* guesses, based on 7640 */ PDEBUG(D_STREAM, "Setting framerate to %d fps", (sd->frame_rate == 0) ? 15 : sd->frame_rate); + reg_w(sd, 0xa4, 0x10); switch (sd->frame_rate) { case 30: - reg_w(sd, 0xa4, 0x10); reg_w(sd, 0x23, 0xff); break; case 20: - reg_w(sd, 0xa4, 0x10); reg_w(sd, 0x23, 0x1b); break; - default: /* 15 fps */ -/* case 15: */ - reg_w(sd, 0xa4, 0x10); + default: +/* case 15: */ reg_w(sd, 0x23, 0xff); sd->clockdiv = 1; break; } + break; } -/* if (ov51x_restart(sd) < 0) - return -EIO; */ - - /* Reset it just for good measure */ -/* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0) - return -EIO; */ return 0; } -static int mode_init_ov_sensor_regs(struct sd *sd, - struct ovsensor_window *win) +static int mode_init_ov_sensor_regs(struct sd *sd) { - int qvga = win->quarter; + struct gspca_dev *gspca_dev; + int qvga; + + gspca_dev = &sd->gspca_dev; + qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; /******** Mode (VGA/QVGA) and sensor specific regs ********/ switch (sd->sensor) { @@ -1679,8 +1600,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd, OV7670_COM7_FMT_MASK); break; case SEN_OV6620: - i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); - break; case SEN_OV6630: i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); break; @@ -1689,39 +1608,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd, } /******** Palette-specific regs ********/ -/* Need to do work here for the OV7670 */ - -#if 0 - if (win->format == VIDEO_PALETTE_GREY) { - if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { - /* these aren't valid on the OV6620/OV7620/6630? */ - i2c_w_mask(sd, 0x0e, 0x40, 0x40); - } - - /* OV6630 default reg 0x13 value is always right */ - /* OV7640 is 8-bit only */ - if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) - i2c_w_mask(sd, 0x13, 0x20, 0x20); - else - return -EINVAL; /* No OV6630 greyscale support yet */ - } else { -#endif - if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { - /* not valid on the OV6620/OV7620/6630? */ - i2c_w_mask(sd, 0x0e, 0x00, 0x40); - } + if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { + /* not valid on the OV6620/OV7620/6630? */ + i2c_w_mask(sd, 0x0e, 0x00, 0x40); + } - /* The OV518 needs special treatment. Although both the OV518 - * and the OV6630 support a 16-bit video bus, only the 8 bit Y - * bus is actually used. The UV bus is tied to ground. - * Therefore, the OV6630 needs to be in 8-bit multiplexed - * output mode */ + /* The OV518 needs special treatment. Although both the OV518 + * and the OV6630 support a 16-bit video bus, only the 8 bit Y + * bus is actually used. The UV bus is tied to ground. + * Therefore, the OV6630 needs to be in 8-bit multiplexed + * output mode */ - /* OV7640 is 8-bit only */ + /* OV7640 is 8-bit only */ - if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) - i2c_w_mask(sd, 0x13, 0x00, 0x20); -/* } */ + if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) + i2c_w_mask(sd, 0x13, 0x00, 0x20); /******** Clock programming ********/ /* The OV6620 needs special handling. This prevents the @@ -1730,23 +1631,17 @@ static int mode_init_ov_sensor_regs(struct sd *sd, /* Clock down */ i2c_w(sd, 0x2a, 0x04); - i2c_w(sd, 0x11, win->clockdiv); + i2c_w(sd, 0x11, sd->clockdiv); i2c_w(sd, 0x2a, 0x84); /* This next setting is critical. It seems to improve * the gain or the contrast. The "reserved" bits seem * to have some effect in this case. */ i2c_w(sd, 0x2d, 0x85); - } else if (win->clockdiv >= 0) { - i2c_w(sd, 0x11, win->clockdiv); + } else if (sd->clockdiv >= 0) { + i2c_w(sd, 0x11, sd->clockdiv); } /******** Special Features ********/ -#if 0 -/* not how OV7670 does it! */ - if (framedrop >= 0 && sd->sensor != SEN_OV7640 - && sd->sensor != SEN_OV7670) - i2c_w(sd, 0x16, framedrop); -#endif /* no evidence this is possible with OV7670, either */ /* Test Pattern */ if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670) @@ -1763,7 +1658,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd, /* is fully tested. */ /* 7620/6620/6630? don't have register 0x35, so play it safe */ if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { - if (win->width == 640 /*&& win->height == 480*/) + if (!qvga) i2c_w(sd, 0x35, 0x9e); else i2c_w(sd, 0x35, 0x1e); @@ -1771,33 +1666,31 @@ static int mode_init_ov_sensor_regs(struct sd *sd, return 0; } -static void sethflip(struct sd *sd) +static void sethvflip(struct sd *sd) { + if (sd->sensor != SEN_OV7670) + return; if (sd->gspca_dev.streaming) ov51x_stop(sd); i2c_w_mask(sd, OV7670_REG_MVFP, - OV7670_MVFP_MIRROR * sd->hflip, OV7670_MVFP_MIRROR); + OV7670_MVFP_MIRROR * sd->hflip + | OV7670_MVFP_VFLIP * sd->vflip, + OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); if (sd->gspca_dev.streaming) ov51x_restart(sd); } -static void setvflip(struct sd *sd) -{ - if (sd->gspca_dev.streaming) - ov51x_stop(sd); - i2c_w_mask(sd, OV7670_REG_MVFP, - OV7670_MVFP_VFLIP * sd->vflip, OV7670_MVFP_VFLIP); - if (sd->gspca_dev.streaming) - ov51x_restart(sd); -} - -static int set_ov_sensor_window(struct sd *sd, - struct ovsensor_window *win) +static int set_ov_sensor_window(struct sd *sd) { + struct gspca_dev *gspca_dev; + int qvga; int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; int ret, hstart, hstop, vstop, vstart; __u8 v; + gspca_dev = &sd->gspca_dev; + qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; + /* The different sensor ICs handle setting up of window differently. * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ switch (sd->sensor) { @@ -1842,7 +1735,7 @@ static int set_ov_sensor_window(struct sd *sd, switch (sd->sensor) { case SEN_OV6620: case SEN_OV6630: - if (win->quarter) { /* QCIF */ + if (qvga) { /* QCIF */ hwscale = 0; vwscale = 0; } else { /* CIF */ @@ -1852,7 +1745,7 @@ static int set_ov_sensor_window(struct sd *sd, } break; case SEN_OV8610: - if (win->quarter) { /* QSVGA */ + if (qvga) { /* QSVGA */ hwscale = 1; vwscale = 1; } else { /* SVGA */ @@ -1861,7 +1754,7 @@ static int set_ov_sensor_window(struct sd *sd, } break; default: /* SEN_OV7xx0 */ - if (win->quarter) { /* QVGA */ + if (qvga) { /* QVGA */ hwscale = 1; vwscale = 0; } else { /* VGA */ @@ -1870,7 +1763,7 @@ static int set_ov_sensor_window(struct sd *sd, } } - ret = mode_init_ov_sensor_regs(sd, win); + ret = mode_init_ov_sensor_regs(sd); if (ret < 0) return ret; @@ -1891,7 +1784,7 @@ static int set_ov_sensor_window(struct sd *sd, /* I can hard code this for OV7670s */ /* Yes, these numbers do look odd, but they're tested and work! */ if (sd->sensor == SEN_OV7670) { - if (win->quarter) { /* QVGA from ov7670.c by + if (qvga) { /* QVGA from ov7670.c by * Jonathan Corbet */ hstart = 164; hstop = 20; @@ -1905,83 +1798,45 @@ static int set_ov_sensor_window(struct sd *sd, } /* OV7670 hardware window registers are split across * multiple locations */ - i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); - i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); + i2c_w(sd, OV7670_REG_HSTART, hstart >> 3); + i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3); v = i2c_r(sd, OV7670_REG_HREF); v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); msleep(10); /* need to sleep between read and write to * same reg! */ i2c_w(sd, OV7670_REG_HREF, v); - i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); - i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); + i2c_w(sd, OV7670_REG_VSTART, vstart >> 2); + i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2); v = i2c_r(sd, OV7670_REG_VREF); v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); msleep(10); /* need to sleep between read and write to * same reg! */ i2c_w(sd, OV7670_REG_VREF, v); - sethflip(sd); - setvflip(sd); + sethvflip(sd); } else { - i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); - i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); - i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); - i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); + i2c_w(sd, 0x17, hwsbase); + i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); + i2c_w(sd, 0x19, vwsbase); + i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); } return 0; } -static int ov_sensor_mode_setup(struct sd *sd, - int width, int height) -{ - struct ovsensor_window win; - -/* win.format = mode; */ - - /* Unless subcapture is enabled, - * center the image window and downsample - * if possible to increase the field of view */ - /* NOTE: OV518(+) and OV519 does downsampling on its own */ - win.width = width; - win.height = height; - if (width == sd->maxwidth) - win.quarter = 0; - else - win.quarter = 1; - - /* Center it */ - win.x = (win.width - width) / 2; - win.y = (win.height - height) / 2; - - /* Clock is determined by OV519 frame rate code */ - win.clockdiv = sd->clockdiv; - - PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv); - return set_ov_sensor_window(sd, &win); -} - /* -- start the camera -- */ static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int ret; -#if 0 - ret = usb_set_interface(gspca_dev->dev, - gspca_dev->iface, - gspca_dev->alt); - if (ret < 0) - goto out; -#endif - - ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height); + ret = ov519_mode_init_regs(sd); if (ret < 0) goto out; - ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); + ret = set_ov_sensor_window(sd); if (ret < 0) goto out; - ret = ov51x_restart((struct sd *) gspca_dev); + ret = ov51x_restart(sd); if (ret < 0) goto out; PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); @@ -2055,12 +1910,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int val; -/* int was_streaming; */ val = sd->brightness; PDEBUG(D_CONF, "brightness:%d", val); -/* was_streaming = gspca_dev->streaming; - * if (was_streaming) +/* if (gspca_dev->streaming) * ov51x_stop(sd); */ switch (sd->sensor) { case SEN_OV8610: @@ -2078,12 +1931,12 @@ static void setbrightness(struct gspca_dev *gspca_dev) i2c_w(sd, OV7610_REG_BRT, val); break; case SEN_OV7670: -/*jfm - from windblows +/*win trace * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); break; } -/* if (was_streaming) +/* if (gspca_dev->streaming) * ov51x_restart(sd); */ } @@ -2091,12 +1944,10 @@ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int val; -/* int was_streaming; */ val = sd->contrast; PDEBUG(D_CONF, "contrast:%d", val); -/* was_streaming = gspca_dev->streaming; - if (was_streaming) +/* if (gspca_dev->streaming) ov51x_stop(sd); */ switch (sd->sensor) { case SEN_OV7610: @@ -2133,7 +1984,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); break; } -/* if (was_streaming) +/* if (gspca_dev->streaming) ov51x_restart(sd); */ } @@ -2141,12 +1992,10 @@ static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int val; -/* int was_streaming; */ val = sd->colors; PDEBUG(D_CONF, "saturation:%d", val); -/* was_streaming = gspca_dev->streaming; - if (was_streaming) +/* if (gspca_dev->streaming) ov51x_stop(sd); */ switch (sd->sensor) { case SEN_OV8610: @@ -2172,7 +2021,7 @@ static void setcolors(struct gspca_dev *gspca_dev) /* set REG_COM13 values for UV sat auto mode */ break; } -/* if (was_streaming) +/* if (gspca_dev->streaming) ov51x_restart(sd); */ } @@ -2232,7 +2081,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->hflip = val; - sethflip(sd); + sethvflip(sd); return 0; } @@ -2249,7 +2098,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->vflip = val; - setvflip(sd); + sethvflip(sd); return 0; } -- cgit v1.2.3 From 19d2f9616a504133894ca30eb1f22cb92a87e724 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 Aug 2008 08:23:41 -0300 Subject: set mts_firmware for em2882 based Pinnacle Hybrid Pro From: Eugeniy Meshcheryakov Pinnacle Hybrid Pro (2304:0226) requires mts_firmware flag to have any sound. Without this flag it is useful only for watching silent movies. Signed-off-by: Eugeniy Meshcheryakov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/em28xx/em28xx-cards.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 44b3ae23d..eae5ebd0e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1016,6 +1016,7 @@ struct em28xx_board em28xx_boards[] = { .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, .tuner_type = TUNER_XC2028, + .mts_firmware = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, -- cgit v1.2.3 From ef1a5a79cd8e82b51422ca66992bbd483a8ebe5b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 2 Aug 2008 00:48:51 +0200 Subject: media: Clean up platform_driver_unregister() bogosity. So, platform_driver_unregister() doesn't actually have a return value, nor do any of the void __exit routines. It's reassuring to know that people copy and paste blindly. This completely blew up my compiler. Signed-off-by: Paul Mundt Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/pxa_camera.c | 2 +- drivers/media/video/sh_mobile_ceu_camera.c | 2 +- drivers/media/video/soc_camera_platform.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) --- linux/drivers/media/video/pxa_camera.c | 2 +- linux/drivers/media/video/sh_mobile_ceu_camera.c | 2 +- linux/drivers/media/video/soc_camera_platform.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index b15f82c49..28d8fd067 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -1198,7 +1198,7 @@ static int __devinit pxa_camera_init(void) static void __exit pxa_camera_exit(void) { - return platform_driver_unregister(&pxa_camera_driver); + platform_driver_unregister(&pxa_camera_driver); } module_init(pxa_camera_init); diff --git a/linux/drivers/media/video/sh_mobile_ceu_camera.c b/linux/drivers/media/video/sh_mobile_ceu_camera.c index f7ca3cb93..318754e73 100644 --- a/linux/drivers/media/video/sh_mobile_ceu_camera.c +++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c @@ -647,7 +647,7 @@ static int __init sh_mobile_ceu_init(void) static void __exit sh_mobile_ceu_exit(void) { - return platform_driver_unregister(&sh_mobile_ceu_driver); + platform_driver_unregister(&sh_mobile_ceu_driver); } module_init(sh_mobile_ceu_init); diff --git a/linux/drivers/media/video/soc_camera_platform.c b/linux/drivers/media/video/soc_camera_platform.c index eefb0327e..1adc257eb 100644 --- a/linux/drivers/media/video/soc_camera_platform.c +++ b/linux/drivers/media/video/soc_camera_platform.c @@ -187,7 +187,7 @@ static int __init soc_camera_platform_module_init(void) static void __exit soc_camera_platform_module_exit(void) { - return platform_driver_unregister(&soc_camera_platform_driver); + platform_driver_unregister(&soc_camera_platform_driver); } module_init(soc_camera_platform_module_init); -- cgit v1.2.3 From 65041def75fa0ce51a0df92d47ce90e8789b55ac Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 2 Aug 2008 01:14:50 +0200 Subject: Add suspend/resume capabilities to soc_camera. Add suspend/resume hooks to call soc operation specific suspend and resume functions. This ensures the camera chip has been previously resumed, as well as the camera bus. These hooks in camera chip drivers should save/restore chip context between suspend and resume time. Signed-off-by: Robert Jarzmik Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/soc_camera.c | 26 ++++++++++++++++++++++++++ include/media/soc_camera.h | 5 +++++ 2 files changed, 31 insertions(+), 0 deletions(-) --- linux/drivers/media/video/soc_camera.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c index b6be5ee67..66ebe5956 100644 --- a/linux/drivers/media/video/soc_camera.c +++ b/linux/drivers/media/video/soc_camera.c @@ -732,10 +732,36 @@ static int soc_camera_remove(struct device *dev) return 0; } +static int soc_camera_suspend(struct device *dev, pm_message_t state) +{ + struct soc_camera_device *icd = to_soc_camera_dev(dev); + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + int ret = 0; + + if (ici->ops->suspend) + ret = ici->ops->suspend(icd, state); + + return ret; +} + +static int soc_camera_resume(struct device *dev) +{ + struct soc_camera_device *icd = to_soc_camera_dev(dev); + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + int ret = 0; + + if (ici->ops->resume) + ret = ici->ops->resume(icd); + + return ret; +} + static struct bus_type soc_camera_bus_type = { .name = "soc-camera", .probe = soc_camera_probe, .remove = soc_camera_remove, + .suspend = soc_camera_suspend, + .resume = soc_camera_resume, }; static struct device_driver ic_drv = { -- cgit v1.2.3 From 54bd69d6b05133720993cc78bb9817d118e4ecc2 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 1 Aug 2008 22:42:33 -0400 Subject: au8522: clean up function au8522_set_if From: Michael Krufky re-write this function to make it simpler Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/au8522.c | 65 +++++++++--------------------- 1 file changed, 19 insertions(+), 46 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/frontends/au8522.c b/linux/drivers/media/dvb/frontends/au8522.c index d968a1000..71ee03c26 100644 --- a/linux/drivers/media/dvb/frontends/au8522.c +++ b/linux/drivers/media/dvb/frontends/au8522.c @@ -304,67 +304,40 @@ static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, return ret; } -/* 3.25 MHz IF Frequency table */ -static struct { - u16 reg; - u16 data; -} if_3_25_mhz_tab[] = { - { 0x80b5, 0x00 }, - { 0x80b6, 0x3d }, - { 0x80b7, 0xa0 }, -}; - -/* 4.00 MHz IF Frequency table */ -static struct { - u16 reg; - u16 data; -} if_4_mhz_tab[] = { - { 0x80b5, 0x00 }, - { 0x80b6, 0x4b }, - { 0x80b7, 0xd9 }, -}; - -/* 6.00 MHz IF Frequency table */ -static struct { - u16 reg; - u16 data; -} if_6_mhz_tab[] = { - { 0x80b5, 0xfb }, - { 0x80b6, 0x8e }, - { 0x80b7, 0x39 }, -}; - static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq) { struct au8522_state *state = fe->demodulator_priv; - int i; + u8 r0b5, r0b6, r0b7; + char *ifmhz; switch (if_freq) { case AU8522_IF_3_25MHZ: - dprintk("%s() 3.25 MHz\n", __func__); - for (i = 0; i < ARRAY_SIZE(if_3_25_mhz_tab); i++) - au8522_writereg(state, - if_3_25_mhz_tab[i].reg, - if_3_25_mhz_tab[i].data); + ifmhz = "3.25"; + r0b5 = 0x00; + r0b6 = 0x3d; + r0b7 = 0xa0; break; case AU8522_IF_4MHZ: - dprintk("%s() 4.00 MHz\n", __func__); - for (i = 0; i < ARRAY_SIZE(if_4_mhz_tab); i++) - au8522_writereg(state, - if_4_mhz_tab[i].reg, - if_4_mhz_tab[i].data); + ifmhz = "4.00"; + r0b5 = 0x00; + r0b6 = 0x4b; + r0b7 = 0xd9; break; case AU8522_IF_6MHZ: - dprintk("%s() 6.00 MHz\n", __func__); - for (i = 0; i < ARRAY_SIZE(if_6_mhz_tab); i++) - au8522_writereg(state, - if_6_mhz_tab[i].reg, - if_6_mhz_tab[i].data); + ifmhz = "6.00"; + r0b5 = 0xfb; + r0b6 = 0x8e; + r0b7 = 0x39; break; default: dprintk("%s() IF Frequency not supported\n", __func__); return -EINVAL; } + dprintk("%s() %s MHz\n", __func__, ifmhz); + au8522_writereg(state, 0x80b5, r0b5); + au8522_writereg(state, 0x80b6, r0b6); + au8522_writereg(state, 0x80b7, r0b7); + return 0; } -- cgit v1.2.3 From cbe89066e872a56e9fdf460fcf4cfc50d64369c9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 1 Aug 2008 22:54:57 -0400 Subject: au8522: remove if frequency settings from vsb/qam modulation tables From: Michael Krufky Since IF frequency is set after the vsb/qam modulation tables are written, remove the redundant register settings from the vsb/qam modulation tables. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/au8522.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/frontends/au8522.c b/linux/drivers/media/dvb/frontends/au8522.c index 71ee03c26..d946c8beb 100644 --- a/linux/drivers/media/dvb/frontends/au8522.c +++ b/linux/drivers/media/dvb/frontends/au8522.c @@ -371,9 +371,6 @@ static struct { { 0x80af, 0x66 }, { 0x821b, 0xcc }, { 0x821d, 0x80 }, - { 0x80b5, 0xfb }, - { 0x80b6, 0x8e }, - { 0x80b7, 0x39 }, { 0x80a4, 0xe8 }, { 0x8231, 0x13 }, }; @@ -387,9 +384,6 @@ static struct { { 0x80a4, 0x00 }, { 0x8081, 0xc4 }, { 0x80a5, 0x40 }, - { 0x80b5, 0xfb }, - { 0x80b6, 0x8e }, - { 0x80b7, 0x39 }, { 0x80aa, 0x77 }, { 0x80ad, 0x77 }, { 0x80a6, 0x67 }, -- cgit v1.2.3 From e0e78e09563f6a4feb5b0a186135bb365bc81ca8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 1 Aug 2008 23:19:53 -0400 Subject: au0828: explicitly set 6 MHz IF frequency in hauppauge_hvr950q_config From: Michael Krufky Explicitly set 6 MHz IF frequency for VSB and QAM in hauppauge_hvr950q_config. The default value is 6 MHz, so this patch doesn't change anything -- this only improves code readability and may prevent future bugs. Signed-off-by: Michael Krufky --- linux/drivers/media/video/au0828/au0828-dvb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/au0828/au0828-dvb.c b/linux/drivers/media/video/au0828/au0828-dvb.c index b7b0591ef..1fa77ba11 100644 --- a/linux/drivers/media/video/au0828/au0828-dvb.c +++ b/linux/drivers/media/video/au0828/au0828-dvb.c @@ -40,6 +40,8 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static struct au8522_config hauppauge_hvr950q_config = { .demod_address = 0x8e >> 1, .status_mode = AU8522_DEMODLOCKING, + .qam_if = AU8522_IF_6MHZ, + .vsb_if = AU8522_IF_6MHZ, }; static struct au8522_config hauppauge_woodbury_config = { -- cgit v1.2.3 From 9875dfc85aaa5f5404612ac9a5b4cf4071326097 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 2 Aug 2008 12:10:04 +0200 Subject: Add suspend/resume to pxa_camera driver PXA suspend switches off DMA core, which loses all context of previously assigned descriptors. As pxa_camera driver relies on DMA transfers, setup the lost descriptors on resume and retrigger frame acquisition if needed. Signed-off-by: Robert Jarzmik Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/pxa_camera.c | 56 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 56 insertions(+), 0 deletions(-) --- linux/drivers/media/video/pxa_camera.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index 28d8fd067..ead87ddaf 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -128,6 +128,8 @@ struct pxa_camera_dev { struct pxa_buffer *active; struct pxa_dma_desc *sg_tail[3]; + + u32 save_cicr[5]; }; static const char *pxa_cam_driver_description = "PXA_Camera"; @@ -997,10 +999,64 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, return 0; } +static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state) +{ + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + int i = 0, ret = 0; + + pcdev->save_cicr[i++] = CICR0; + pcdev->save_cicr[i++] = CICR1; + pcdev->save_cicr[i++] = CICR2; + pcdev->save_cicr[i++] = CICR3; + pcdev->save_cicr[i++] = CICR4; + + if ((pcdev->icd) && (pcdev->icd->ops->suspend)) + ret = pcdev->icd->ops->suspend(pcdev->icd, state); + + return ret; +} + +static int pxa_camera_resume(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + int i = 0, ret = 0; + + DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD; + DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD; + DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD; + + CICR0 = pcdev->save_cicr[i++] & ~CICR0_ENB; + CICR1 = pcdev->save_cicr[i++]; + CICR2 = pcdev->save_cicr[i++]; + CICR3 = pcdev->save_cicr[i++]; + CICR4 = pcdev->save_cicr[i++]; + + if ((pcdev->icd) && (pcdev->icd->ops->resume)) + ret = pcdev->icd->ops->resume(pcdev->icd); + + /* Restart frame capture if active buffer exists */ + if (!ret && pcdev->active) { + /* Reset the FIFOs */ + CIFR |= CIFR_RESET_F; + /* Enable End-Of-Frame Interrupt */ + CICR0 &= ~CICR0_EOFM; + /* Restart the Capture Interface */ + CICR0 |= CICR0_ENB; + } + + return ret; +} + static struct soc_camera_host_ops pxa_soc_camera_host_ops = { .owner = THIS_MODULE, .add = pxa_camera_add_device, .remove = pxa_camera_remove_device, + .suspend = pxa_camera_suspend, + .resume = pxa_camera_resume, .set_fmt_cap = pxa_camera_set_fmt_cap, .try_fmt_cap = pxa_camera_try_fmt_cap, .init_videobuf = pxa_camera_init_videobuf, -- cgit v1.2.3 From 48e03e6db17a7d53bd10cb2c9e75d7d49b364e14 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 3 Aug 2008 12:52:53 +0200 Subject: gspca: Fix of "scheduling while atomic" crash. From: Jean-Francois Moine The crash is due to USB exchanges done at interrupt level. These exchanges, tied to autogain, are now done by the application. Also, there is a fix about autogain start. Concerned subdrivers: etoms, pac7311, sonixj and spca561. Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/etoms.c | 133 ++++++++++++++++-------------- linux/drivers/media/video/gspca/pac7311.c | 54 +++++++----- linux/drivers/media/video/gspca/sonixj.c | 57 +++++++++---- linux/drivers/media/video/gspca/spca561.c | 42 ++++++---- 4 files changed, 171 insertions(+), 115 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index 94f9c6690..60b316a37 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -461,6 +461,52 @@ static void Et_init2(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ } +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + __u8 brightness = sd->brightness; + + for (i = 0; i < 4; i++) + reg_w_val(gspca_dev, ET_O_RED + i, brightness); +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + int brightness = 0; + + for (i = 0; i < 4; i++) { + reg_r(gspca_dev, ET_O_RED + i, 1); + brightness += gspca_dev->usb_buf[0]; + } + sd->brightness = brightness >> 3; +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; + __u8 contrast = sd->contrast; + + memset(RGBG, contrast, sizeof(RGBG) - 2); + reg_w(gspca_dev, ET_G_RED, RGBG, 6); +} + +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + int contrast = 0; + + for (i = 0; i < 4; i++) { + reg_r(gspca_dev, ET_G_RED + i, 1); + contrast += gspca_dev->usb_buf[0]; + } + sd->contrast = contrast >> 2; +} + static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -492,6 +538,16 @@ static void getcolors(struct gspca_dev *gspca_dev) } } +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->autogain) + sd->ag_cnt = AG_CNT_START; + else + sd->ag_cnt = -1; +} + static void Et_init1(struct gspca_dev *gspca_dev) { __u8 value; @@ -614,6 +670,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; sd->autogain = AUTOGAIN_DEF; + sd->ag_cnt = -1; return 0; } @@ -641,6 +698,8 @@ static void sd_start(struct gspca_dev *gspca_dev) else Et_init2(gspca_dev); + setautogain(gspca_dev); + reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); et_video(gspca_dev, 1); /* video on */ } @@ -658,52 +717,6 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -static void setbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - __u8 brightness = sd->brightness; - - for (i = 0; i < 4; i++) - reg_w_val(gspca_dev, ET_O_RED + i, brightness); -} - -static void getbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - int brightness = 0; - - for (i = 0; i < 4; i++) { - reg_r(gspca_dev, ET_O_RED + i, 1); - brightness += gspca_dev->usb_buf[0]; - } - sd->brightness = brightness >> 3; -} - -static void setcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; - __u8 contrast = sd->contrast; - - memset(RGBG, contrast, sizeof(RGBG) - 2); - reg_w(gspca_dev, ET_G_RED, RGBG, 6); -} - -static void getcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - int contrast = 0; - - for (i = 0; i < 4; i++) { - reg_r(gspca_dev, ET_G_RED + i, 1); - contrast += gspca_dev->usb_buf[0]; - } - sd->contrast = contrast >> 2; -} - static __u8 Et_getgainG(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -739,15 +752,22 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) #define LIMIT(color) \ (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) -static void setautogain(struct gspca_dev *gspca_dev) +static void do_autogain(struct gspca_dev *gspca_dev) { - __u8 luma = 0; + struct sd *sd = (struct sd *) gspca_dev; + __u8 luma; __u8 luma_mean = 128; __u8 luma_delta = 20; __u8 spring = 4; - int Gbright = 0; + int Gbright; __u8 r, g, b; + if (sd->ag_cnt < 0) + return; + if (--sd->ag_cnt >= 0) + return; + sd->ag_cnt = AG_CNT_START; + Gbright = Et_getgainG(gspca_dev); reg_r(gspca_dev, ET_LUMA_CENTER, 4); g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; @@ -774,7 +794,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd; int seqframe; seqframe = data[0] & 0x3f; @@ -789,13 +808,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); - sd = (struct sd *) gspca_dev; - if (sd->ag_cnt >= 0) { - if (--sd->ag_cnt < 0) { - sd->ag_cnt = AG_CNT_START; - setautogain(gspca_dev); - } - } return; } if (len) { @@ -868,10 +880,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->autogain = val; - if (val) - sd->ag_cnt = AG_CNT_START; - else - sd->ag_cnt = -1; + if (gspca_dev->streaming) + setautogain(gspca_dev); return 0; } @@ -895,6 +905,7 @@ static struct sd_desc sd_desc = { .stop0 = sd_stop0, .close = sd_close, .pkt_scan = sd_pkt_scan, + .dq_callback = do_autogain, }; /* -- module initialisation -- */ diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 9beea8205..1b3ea1e93 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -31,7 +31,9 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - int avg_lum; + int lum_sum; + atomic_t avg_lum; + atomic_t do_gain; unsigned char brightness; unsigned char contrast; @@ -271,6 +273,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; sd->autogain = AUTOGAIN_DEF; + sd->ag_cnt = -1; return 0; } @@ -311,6 +314,18 @@ static void setcolors(struct gspca_dev *gspca_dev) PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); } +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->autogain) { + sd->lum_sum = 0; + sd->ag_cnt = AG_CNT_START; + } else { + sd->ag_cnt = -1; + } +} + /* this function is called at open time */ static int sd_open(struct gspca_dev *gspca_dev) { @@ -320,8 +335,6 @@ static int sd_open(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - reg_w(gspca_dev, 0xff, 0x01); reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); @@ -394,6 +407,7 @@ static void sd_start(struct gspca_dev *gspca_dev) setcontrast(gspca_dev); setbrightness(gspca_dev); setcolors(gspca_dev); + setautogain(gspca_dev); /* set correct resolution */ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { @@ -431,13 +445,6 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x78, 0x04); reg_w(gspca_dev, 0x78, 0x05); - - if (sd->autogain) { - sd->ag_cnt = AG_CNT_START; - sd->avg_lum = 0; - } else { - sd->ag_cnt = -1; - } } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -473,13 +480,20 @@ static void sd_close(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ } -static void setautogain(struct gspca_dev *gspca_dev, int luma) +static void do_autogain(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; + int luma; int luma_mean = 128; int luma_delta = 20; __u8 spring = 5; int Gbright; + if (!atomic_read(&sd->do_gain)) + return; + atomic_set(&sd->do_gain, 0); + + luma = atomic_read(&sd->avg_lum); Gbright = reg_r(gspca_dev, 0x02); PDEBUG(D_FRAM, "luma mean %d", luma); if (luma < luma_mean - luma_delta || @@ -523,12 +537,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* start of frame */ if (sd->ag_cnt >= 0 && p > 28) { - sd->avg_lum += data[p - 23]; + sd->lum_sum += data[p - 23]; if (--sd->ag_cnt < 0) { sd->ag_cnt = AG_CNT_START; - setautogain(gspca_dev, - sd->avg_lum / AG_CNT_START); - sd->avg_lum = 0; + atomic_set(&sd->avg_lum, + sd->lum_sum / AG_CNT_START); + sd->lum_sum = 0; + atomic_set(&sd->do_gain, 1); } } @@ -690,12 +705,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->autogain = val; - if (val) { - sd->ag_cnt = AG_CNT_START; - sd->avg_lum = 0; - } else { - sd->ag_cnt = -1; - } + if (gspca_dev->streaming) + setautogain(gspca_dev); return 0; } @@ -719,6 +730,7 @@ static struct sd_desc sd_desc = { .stop0 = sd_stop0, .close = sd_close, .pkt_scan = sd_pkt_scan, + .dq_callback = do_autogain, }; /* -- module initialisation -- */ diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 16c866e4e..b30f7eeda 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - int avg_lum; + atomic_t avg_lum; unsigned int exposure; unsigned short brightness; @@ -801,6 +801,8 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; sd->autogain = AUTOGAIN_DEF; + sd->ag_cnt = -1; + return 0; } @@ -971,6 +973,22 @@ static void setcolors(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x05, data); } +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (sd->sensor) { + case SENSOR_HV7131R: + case SENSOR_MO4000: + case SENSOR_MI0360: + if (sd->autogain) + sd->ag_cnt = AG_CNT_START; + else + sd->ag_cnt = -1; + break; + } +} + /* -- start the camera -- */ static void sd_start(struct gspca_dev *gspca_dev) { @@ -1115,6 +1133,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x01, reg1); setbrightness(gspca_dev); setcontrast(gspca_dev); + setautogain(gspca_dev); } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -1161,16 +1180,23 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -static void setautogain(struct gspca_dev *gspca_dev) +static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - /* Thanks S., without your advice, autobright should not work :) */ int delta; - int expotimes = 0; + int expotimes; __u8 luma_mean = 130; __u8 luma_delta = 20; - delta = sd->avg_lum; + /* Thanks S., without your advice, autobright should not work :) */ + if (sd->ag_cnt < 0) + return; + if (--sd->ag_cnt >= 0) + return; + sd->ag_cnt = AG_CNT_START; + + delta = atomic_read(&sd->avg_lum); + PDEBUG(D_FRAM, "mean lum %d", delta); if (delta < luma_mean - luma_delta || delta > luma_mean + luma_delta) { switch (sd->sensor) { @@ -1182,8 +1208,9 @@ static void setautogain(struct gspca_dev *gspca_dev) sd->exposure = setexposure(gspca_dev, (unsigned int) (expotimes << 8)); break; - case SENSOR_MO4000: - case SENSOR_MI0360: + default: +/* case SENSOR_MO4000: */ +/* case SENSOR_MI0360: */ expotimes = sd->exposure; expotimes += (luma_mean - delta) >> 6; if (expotimes < 0) @@ -1196,6 +1223,8 @@ static void setautogain(struct gspca_dev *gspca_dev) } } +/* scan the URB packets */ +/* This function is run at interrupt level. */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ @@ -1212,9 +1241,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame, data, sof + 2); if (sd->ag_cnt < 0) return; - if (--sd->ag_cnt >= 0) - return; - sd->ag_cnt = AG_CNT_START; /* w1 w2 w3 */ /* w4 w5 w6 */ /* w7 w8 */ @@ -1229,9 +1255,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* w5 */ avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; avg_lum >>= 4; - sd->avg_lum = avg_lum; - PDEBUG(D_PACK, "mean lum %d", avg_lum); - setautogain(gspca_dev); + atomic_set(&sd->avg_lum, avg_lum); return; } if (gspca_dev->last_packet_type == LAST_PACKET) { @@ -1358,10 +1382,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->autogain = val; - if (val) - sd->ag_cnt = AG_CNT_START; - else - sd->ag_cnt = -1; + if (gspca_dev->streaming) + setautogain(gspca_dev); return 0; } @@ -1385,6 +1407,7 @@ static const struct sd_desc sd_desc = { .stop0 = sd_stop0, .close = sd_close, .pkt_scan = sd_pkt_scan, + .dq_callback = do_autogain, }; /* -- module initialisation -- */ diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index a26174508..1073ac3d2 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -644,6 +644,18 @@ static void setcontrast(struct gspca_dev *gspca_dev) } } +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->chip_revision == Rev072A) { + if (sd->autogain) + sd->ag_cnt = AG_CNT_START; + else + sd->ag_cnt = -1; + } +} + static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -671,6 +683,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w_val(dev, 0x8500, mode); /* mode */ reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ reg_w_val(dev, 0x8112, 0x10 | 0x20); + setautogain(gspca_dev); break; default: /* case Rev012A: */ @@ -720,18 +733,24 @@ static void sd_close(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev->dev, 0x8114, 0); } -static void setautogain(struct gspca_dev *gspca_dev) +static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int expotimes = 0; - int pixelclk = 0; - int gainG = 0; + int expotimes; + int pixelclk; + int gainG; __u8 R, Gr, Gb, B; int y; __u8 luma_mean = 110; __u8 luma_delta = 20; __u8 spring = 4; + if (sd->ag_cnt < 0) + return; + if (--sd->ag_cnt >= 0) + return; + sd->ag_cnt = AG_CNT_START; + switch (sd->chip_revision) { case Rev072A: reg_r(gspca_dev, 0x8621, 1); @@ -795,18 +814,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { case 0: /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - if (sd->ag_cnt >= 0) { - if (--sd->ag_cnt < 0) { - sd->ag_cnt = AG_CNT_START; - setautogain(gspca_dev); - } - } data += SPCA561_OFFSET_DATA; len -= SPCA561_OFFSET_DATA; if (data[1] & 0x10) { @@ -944,10 +955,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->autogain = val; - if (val) - sd->ag_cnt = AG_CNT_START; - else - sd->ag_cnt = -1; + if (gspca_dev->streaming) + setautogain(gspca_dev); return 0; } @@ -971,6 +980,7 @@ static const struct sd_desc sd_desc = { .stop0 = sd_stop0, .close = sd_close, .pkt_scan = sd_pkt_scan, + .dq_callback = do_autogain, }; /* -- module initialisation -- */ -- cgit v1.2.3 From fbc9468c72cac92d4b792aba7721520a92230677 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 3 Aug 2008 12:58:54 +0200 Subject: gspca: Fix of gspca_zc3xx oops - 2.6.27-rc1 From: Rabin Vincent Bad mini/max check in setting control values (the gamma in zc3xx could be set to null). Signed-off-by: Rabin Vincent Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 600112ede..61071a4f4 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -911,7 +911,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, if (ctrl->id != ctrls->qctrl.id) continue; if (ctrl->value < ctrls->qctrl.minimum - && ctrl->value > ctrls->qctrl.maximum) + || ctrl->value > ctrls->qctrl.maximum) return -ERANGE; PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); if (mutex_lock_interruptible(&gspca_dev->usb_lock)) -- cgit v1.2.3 From 504c08c86ac8248ffe1746bbf60833ebb4629684 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Jul 2008 21:54:48 +0000 Subject: uvcvideo: Add support for two Bison Electronics webcams From: Laurent Pinchart The Bison Electronics 5986:0300 and 5986:0303 webcams require the UVC_QUIRK_PROBE_MINMAX quirk. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/uvc/uvc_driver.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c index b3c4d75e8..7e102034d 100644 --- a/linux/drivers/media/video/uvc/uvc_driver.c +++ b/linux/drivers/media/video/uvc/uvc_driver.c @@ -1884,7 +1884,7 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Packard Bell OEM Webcam */ + /* Packard Bell OEM Webcam - Bison Electronics */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x5986, @@ -1893,7 +1893,7 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Acer Crystal Eye webcam */ + /* Acer Crystal Eye webcam - Bison Electronics */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x5986, @@ -1902,7 +1902,7 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Medion Akoya Mini E1210 */ + /* Medion Akoya Mini E1210 - Bison Electronics */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x5986, @@ -1911,7 +1911,7 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Acer OrbiCam - Unknown vendor */ + /* Acer OrbiCam - Bison Electronics */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x5986, @@ -1920,6 +1920,24 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* Bison Electronics */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x5986, + .idProduct = 0x0300, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* Clevo M570TU - Bison Electronics */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x5986, + .idProduct = 0x0303, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, {} -- cgit v1.2.3 From 4bd253361a4d78401fee5c40b508d2e23434df05 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jul 2008 20:11:12 +0000 Subject: uvcvideo: don't use stack-based buffers for USB transfers. From: Laurent Pinchart Data buffers on the stack are not allowed for USB I/O. Use dynamically allocated buffers instead. Signed-off-by: Bruce Schmid Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/uvc/uvc_ctrl.c | 33 ++++++++++++++++++++----------- linux/drivers/media/video/uvc/uvc_video.c | 33 ++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 23 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/uvc/uvc_ctrl.c b/linux/drivers/media/video/uvc/uvc_ctrl.c index 626f4ad7e..6ef3e5297 100644 --- a/linux/drivers/media/video/uvc/uvc_ctrl.c +++ b/linux/drivers/media/video/uvc/uvc_ctrl.c @@ -585,13 +585,17 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, struct uvc_control_mapping *mapping; struct uvc_menu_info *menu; unsigned int i; - __u8 data[8]; + __u8 *data; int ret; ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); if (ctrl == NULL) return -EINVAL; + data = kmalloc(8, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); v4l2_ctrl->id = mapping->id; v4l2_ctrl->type = mapping->v4l2_type; @@ -604,8 +608,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, video->dev->intfnum, ctrl->info->selector, - &data, ctrl->info->size)) < 0) - return ret; + data, ctrl->info->size)) < 0) + goto out; v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); } @@ -623,13 +627,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, } } - return 0; + ret = 0; + goto out; case V4L2_CTRL_TYPE_BOOLEAN: v4l2_ctrl->minimum = 0; v4l2_ctrl->maximum = 1; v4l2_ctrl->step = 1; - return 0; + ret = 0; + goto out; default: break; @@ -638,26 +644,29 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, video->dev->intfnum, ctrl->info->selector, - &data, ctrl->info->size)) < 0) - return ret; + data, ctrl->info->size)) < 0) + goto out; v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); } if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, video->dev->intfnum, ctrl->info->selector, - &data, ctrl->info->size)) < 0) - return ret; + data, ctrl->info->size)) < 0) + goto out; v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); } if (ctrl->info->flags & UVC_CONTROL_GET_RES) { if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, video->dev->intfnum, ctrl->info->selector, - &data, ctrl->info->size)) < 0) - return ret; + data, ctrl->info->size)) < 0) + goto out; v4l2_ctrl->step = uvc_get_le_value(data, mapping); } - return 0; + ret = 0; +out: + kfree(data); + return ret; } diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index ad63794fd..6854ac78a 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -90,17 +90,20 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video, static int uvc_get_video_ctrl(struct uvc_video_device *video, struct uvc_streaming_control *ctrl, int probe, __u8 query) { - __u8 data[34]; - __u8 size; + __u8 *data; + __u16 size; int ret; size = video->dev->uvc_version >= 0x0110 ? 34 : 26; + data = kmalloc(size, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, - probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, + probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, UVC_CTRL_STREAMING_TIMEOUT); - if (ret < 0) - return ret; + goto out; ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); ctrl->bFormatIndex = data[2]; @@ -136,17 +139,22 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, */ uvc_fixup_buffer_size(video, ctrl); - return 0; +out: + kfree(data); + return ret; } int uvc_set_video_ctrl(struct uvc_video_device *video, struct uvc_streaming_control *ctrl, int probe) { - __u8 data[34]; - __u8 size; + __u8 *data; + __u16 size; + int ret; size = video->dev->uvc_version >= 0x0110 ? 34 : 26; - memset(data, 0, sizeof data); + data = kzalloc(size, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); data[2] = ctrl->bFormatIndex; @@ -174,10 +182,13 @@ int uvc_set_video_ctrl(struct uvc_video_device *video, data[33] = ctrl->bMaxVersion; } - return __uvc_query_ctrl(video->dev, SET_CUR, 0, + ret = __uvc_query_ctrl(video->dev, SET_CUR, 0, video->streaming->intfnum, - probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, + probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, UVC_CTRL_STREAMING_TIMEOUT); + + kfree(data); + return ret; } int uvc_probe_video(struct uvc_video_device *video, -- cgit v1.2.3 From d80b9a6dbd8d4d3d0366b9ccb92e6afb51f45554 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 4 Aug 2008 14:28:46 -0300 Subject: backport changeset c9b1a9b0ec5cc30279fd51ea11f04432683961cc From: Mauro Carvalho Chehab kernel-sync: Author: Randy Dunlap Date: Mon Jul 28 15:39:38 2008 -0300 V4L/DVB (8549a): fix kernel-doc warning, function name, and docbook filename Change function name in kernel-doc and add kernel-doc for parameter @index: Warning(linhead//drivers/media/video/videodev.c:2090): No description found for parameter 'index' Also change source file name in DocBook/videobook.tmpl to match the new source file name. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index c3d3212fd..398376a40 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -257,11 +257,13 @@ int video_register_device(struct video_device *vfd, int type, int nr) EXPORT_SYMBOL(video_register_device); /** - * video_register_device - register video4linux devices + * video_register_device_index - register video4linux devices * @vfd: video device structure we want to register * @type: type of device to register * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... * -1 == first free) + * @index: stream number based on parent device; + * -1 if auto assign, requested number otherwise * * The registration code assigns minor numbers based on the type * requested. -ENFILE is returned in all the device slots for this -- cgit v1.2.3 From ac532d001dbd78c75ab437d4b1d975f11221c2b7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Aug 2008 19:32:35 +0200 Subject: v4l: fix compile errors/warnings. From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c | 4 ---- linux/drivers/media/video/tvmixer.c | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 0fdcb19cb..4c233c41f 100644 --- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -1284,11 +1284,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) u8 b1[] = { 0x61 }; u8 *b; char idstring[21]; -#ifndef TTUSB_KERNEL - u8 *firmware = NULL; -#else const u8 *firmware = NULL; -#endif size_t firmware_size = 0; u16 firmware_csum = 0; __be16 firmware_csum_ns; diff --git a/linux/drivers/media/video/tvmixer.c b/linux/drivers/media/video/tvmixer.c index 7c1e1a850..fd2e902ea 100644 --- a/linux/drivers/media/video/tvmixer.c +++ b/linux/drivers/media/video/tvmixer.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "compat.h" #include #include -- cgit v1.2.3 From 32c971ba6a7bcf28f668cc9fd363b3b8f7251b40 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 4 Aug 2008 20:36:49 -0400 Subject: cx23885: Factor out common cx23885 tuner callback From: Steven Toth Tuners currently hook different things to the private pointer in their callback function. Longer term we should make that private pointer consistent, but for now separate out the guts of the cx23885 tuner callback so we can reuse it. Signed-off-by: Steven Toth Signed-off-by: Anton Blanchard --- linux/drivers/media/video/cx23885/cx23885-cards.c | 20 ++++++++++++-------- linux/drivers/media/video/cx23885/cx23885-dvb.c | 4 ++-- linux/drivers/media/video/cx23885/cx23885.h | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index ee01ff8bf..e081428cd 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -320,13 +320,9 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) dev->name, tv.model); } -/* Tuner callback function for cx23885 boards. Currently only needed - * for HVR1500Q, which has an xc5000 tuner. - */ -int cx23885_tuner_callback(void *priv, int command, int arg) +static int cx23885_tuner_callback(struct cx23885_dev *dev, int port, + int command, int arg) { - struct cx23885_i2c *bus = priv; - struct cx23885_dev *dev = bus->dev; u32 bitmask = 0; if (command != 0) { @@ -346,9 +342,9 @@ int cx23885_tuner_callback(void *priv, int command, int arg) /* Two identical tuners on two different i2c buses, * we need to reset the correct gpio. */ - if (bus->nr == 0) + if (port == 0) bitmask = 0x01; - else if (bus->nr == 1) + else if (port == 1) bitmask = 0x04; } break; @@ -364,6 +360,14 @@ int cx23885_tuner_callback(void *priv, int command, int arg) return 0; } +int cx23885_xc5000_tuner_callback(void *priv, int command, int arg) +{ + struct cx23885_i2c *bus = priv; + struct cx23885_dev *dev = bus->dev; + + return cx23885_tuner_callback(dev, bus->nr, command, arg); +} + void cx23885_gpio_setup(struct cx23885_dev *dev) { switch(dev->board) { diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 3c01ef2bf..671922821 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -189,13 +189,13 @@ static struct s5h1411_config dvico_s5h1411_config = { static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { .i2c_address = 0x61, .if_khz = 5380, - .tuner_callback = cx23885_tuner_callback + .tuner_callback = cx23885_xc5000_tuner_callback, }; static struct xc5000_config dvico_xc5000_tunerconfig = { .i2c_address = 0x64, .if_khz = 5380, - .tuner_callback = cx23885_tuner_callback + .tuner_callback = cx23885_xc5000_tuner_callback, }; static struct tda829x_config tda829x_no_probe = { diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index 9a0b4bf3a..592a99c81 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -410,7 +410,7 @@ extern const unsigned int cx23885_bcount; extern struct cx23885_subid cx23885_subids[]; extern const unsigned int cx23885_idcount; -extern int cx23885_tuner_callback(void *priv, int command, int arg); +extern int cx23885_xc5000_tuner_callback(void *priv, int command, int arg); extern void cx23885_card_list(struct cx23885_dev *dev); extern int cx23885_ir_init(struct cx23885_dev *dev); extern void cx23885_gpio_setup(struct cx23885_dev *dev); -- cgit v1.2.3 From d969569e5e7121895a7417ae03568bdf5a832196 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 4 Aug 2008 20:38:46 -0400 Subject: Switch Hauppauge HVR1400 and HVR1500 to common cx23885 tuner callback From: Steven Toth The Hauppauge HVR1400 and HVR1500 can now use the common cx23885 tuner callback. Signed-off-by: Steven Toth Signed-off-by: Anton Blanchard --- linux/drivers/media/video/cx23885/cx23885-cards.c | 16 ++++++++++- linux/drivers/media/video/cx23885/cx23885-dvb.c | 34 ++--------------------- linux/drivers/media/video/cx23885/cx23885.h | 1 + 3 files changed, 18 insertions(+), 33 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index e081428cd..ee81222dc 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -27,6 +27,7 @@ #include "compat.h" #include "cx23885.h" +#include "tuner-xc2028.h" /* ------------------------------------------------------------------ */ /* board config info */ @@ -332,8 +333,10 @@ static int cx23885_tuner_callback(struct cx23885_dev *dev, int port, } switch(dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1400: + case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - /* Tuner Reset Command from xc5000 */ + /* Tuner Reset Command */ if (command == 0) bitmask = 0x04; break; @@ -368,6 +371,17 @@ int cx23885_xc5000_tuner_callback(void *priv, int command, int arg) return cx23885_tuner_callback(dev, bus->nr, command, arg); } +int cx23885_xc3028_tuner_callback(void *priv, int command, int arg) +{ + struct cx23885_tsport *port = priv; + struct cx23885_dev *dev = port->dev; + + if (command == XC2028_RESET_CLK) + return 0; + + return cx23885_tuner_callback(dev, port->nr, command, arg); +} + void cx23885_gpio_setup(struct cx23885_dev *dev) { switch(dev->board) { diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 671922821..35da86931 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -304,36 +304,6 @@ static struct dib7000p_config hauppauge_hvr1400_dib7000_config = { .output_mode = OUTMODE_MPEG2_SERIAL, }; -static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) -{ - struct cx23885_tsport *port = ptr; - struct cx23885_dev *dev = port->dev; - - switch (command) { - case XC2028_TUNER_RESET: - /* Send the tuner in then out of reset */ - /* GPIO-2 xc3028 tuner */ - dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); - - cx_set(GP0_IO, 0x00040000); - cx_clear(GP0_IO, 0x00000004); - msleep(5); - - cx_set(GP0_IO, 0x00040004); - msleep(5); - break; - case XC2028_RESET_CLK: - dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); - break; - default: - dprintk(1, "%s: unknown command %d, arg %d\n", __func__, - command, arg); - return -EINVAL; - } - - return 0; -} - static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; @@ -427,7 +397,7 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, - .callback = cx23885_hvr1500_xc3028_callback, + .callback = cx23885_xc3028_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028-v27.fw", @@ -466,7 +436,7 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, - .callback = cx23885_hvr1500_xc3028_callback, + .callback = cx23885_xc3028_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028L-v36.fw", diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index 592a99c81..931226290 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -411,6 +411,7 @@ extern struct cx23885_subid cx23885_subids[]; extern const unsigned int cx23885_idcount; extern int cx23885_xc5000_tuner_callback(void *priv, int command, int arg); +extern int cx23885_xc3028_tuner_callback(void *priv, int command, int arg); extern void cx23885_card_list(struct cx23885_dev *dev); extern int cx23885_ir_init(struct cx23885_dev *dev); extern void cx23885_gpio_setup(struct cx23885_dev *dev); -- cgit v1.2.3 From 54b460b47032aae6fe4ee63865486610efe38150 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 4 Aug 2008 20:39:53 -0400 Subject: Add support for DViCO FusionHDTV DVB-T Dual Express From: Steven Toth Add support for the DViCO FusionHDTV DVB-T Dual Express card, based on work by Chris Pascoe and Stephen Backway. Signed-off-by: Steven Toth Signed-off-by: Anton Blanchard --- linux/drivers/media/video/cx23885/cx23885-cards.c | 24 ++++++++++++++++ linux/drivers/media/video/cx23885/cx23885-dvb.c | 34 +++++++++++++++++++++++ linux/drivers/media/video/cx23885/cx23885.h | 1 + 3 files changed, 59 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index ee81222dc..ef74c5d29 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -150,6 +150,11 @@ struct cx23885_board cx23885_boards[] = { .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, + [CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP] = { + .name = "DViCO FusionHDTV DVB-T Dual Express", + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -221,6 +226,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x18ac, .subdevice = 0xd618, .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, + },{ + .subvendor = 0x18ac, + .subdevice = 0xdb78, + .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -341,6 +350,7 @@ static int cx23885_tuner_callback(struct cx23885_dev *dev, int port, bitmask = 0x04; break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: if (command == 0) { /* Two identical tuners on two different i2c buses, @@ -477,6 +487,19 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) /* GPIO-2 xc5000 tuner reset i2c bus 1 */ /* GPIO-3 s5h1409 demod reset i2c bus 0 */ + /* Put the parts into reset and back */ + cx_set(GP0_IO, 0x000f0000); + mdelay(20); + cx_clear(GP0_IO, 0x0000000f); + mdelay(20); + cx_set(GP0_IO, 0x000f000f); + break; + case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: + /* GPIO-0 portb xc3028 reset */ + /* GPIO-1 portb zl10353 reset */ + /* GPIO-2 portc xc3028 reset */ + /* GPIO-3 portc zl10353 reset */ + /* Put the parts into reset and back */ cx_set(GP0_IO, 0x000f0000); mdelay(20); @@ -535,6 +558,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) switch (dev->board) { case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: 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; diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 35da86931..1a4da1a4a 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -43,6 +43,7 @@ #include "tuner-simple.h" #include "dib7000p.h" #include "dibx000_common.h" +#include "zl10353.h" static unsigned int debug; @@ -304,6 +305,12 @@ static struct dib7000p_config hauppauge_hvr1400_dib7000_config = { .output_mode = OUTMODE_MPEG2_SERIAL, }; +static struct zl10353_config dvico_fusionhdtv_xc3028 = { + .demod_address = 0x0f, + .if2 = 45600, + .no_tuner = 1, +}; + static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; @@ -466,6 +473,33 @@ static int dvb_register(struct cx23885_tsport *port) &i2c_bus->i2c_adap, &dvico_xc5000_tunerconfig, i2c_bus); break; + case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { + i2c_bus = &dev->i2c_bus[port->nr - 1]; + + port->dvb.frontend = dvb_attach(zl10353_attach, + &dvico_fusionhdtv_xc3028, + &i2c_bus->i2c_adap); + if (port->dvb.frontend != NULL) { + struct dvb_frontend *fe; + struct xc2028_config cfg = { + .i2c_adap = &i2c_bus->i2c_adap, + .i2c_addr = 0x61, + .video_dev = port, + .callback = cx23885_xc3028_tuner_callback, + }; + static struct xc2028_ctrl ctl = { + .fname = "xc3028-v27.fw", + .max_len = 64, + .demod = XC3028_FE_ZARLINK456, + }; + + fe = dvb_attach(xc2028_attach, port->dvb.frontend, + &cfg); + if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) + fe->ops.tuner_ops.set_config(fe, &ctl); + } + break; + } default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index 931226290..22e4cc353 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -65,6 +65,7 @@ #define CX23885_BOARD_HAUPPAUGE_HVR1700 8 #define CX23885_BOARD_HAUPPAUGE_HVR1400 9 #define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10 +#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ #define CX23885_NORMS (\ -- cgit v1.2.3 From 161504777f62170b4b8bbec4d6581895b8337406 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 4 Aug 2008 20:41:06 -0400 Subject: Support IR remote on FusionHDTV DVB-T Dual Express From: Steven Toth From Chris Pascoe Support IR remote on FusionHDTV DVB-T Dual Express Signed-off-by: Steven Toth Signed-off-by: Anton Blanchard --- linux/drivers/media/video/cx23885/cx23885-cards.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index ef74c5d29..eed49ec9c 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -521,6 +521,9 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1400: /* FIXME: Implement me */ break; + case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: + request_module("ir-kbd-i2c"); + break; } return 0; -- cgit v1.2.3 From cca79797f72b6a2fd2d5a005fab10ba6066f9d69 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 4 Aug 2008 21:18:19 -0400 Subject: cx23885: Convert framework to use a single tuner callback function. From: Steven Toth Code reduction. Tuner callback now assumes that tsport is passed as the void arg. Signed-off-by: Steven Toth --- linux/drivers/media/video/cx23885/cx23885-cards.c | 31 ++++++----------------- linux/drivers/media/video/cx23885/cx23885-dvb.c | 16 +++++++----- linux/drivers/media/video/cx23885/cx23885.h | 3 +-- 3 files changed, 18 insertions(+), 32 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index eed49ec9c..f7cb19256 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -330,11 +330,15 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) dev->name, tv.model); } -static int cx23885_tuner_callback(struct cx23885_dev *dev, int port, - int command, int arg) +int cx23885_tuner_callback(void *priv, int command, int arg) { + struct cx23885_tsport *port = priv; + struct cx23885_dev *dev = port->dev; u32 bitmask = 0; + if (command == XC2028_RESET_CLK) + return 0; + if (command != 0) { printk(KERN_ERR "%s(): Unknown command 0x%x.\n", __func__, command); @@ -355,9 +359,9 @@ static int cx23885_tuner_callback(struct cx23885_dev *dev, int port, /* Two identical tuners on two different i2c buses, * we need to reset the correct gpio. */ - if (port == 0) + if (port->nr == 0) bitmask = 0x01; - else if (port == 1) + else if (port->nr == 1) bitmask = 0x04; } break; @@ -373,25 +377,6 @@ static int cx23885_tuner_callback(struct cx23885_dev *dev, int port, return 0; } -int cx23885_xc5000_tuner_callback(void *priv, int command, int arg) -{ - struct cx23885_i2c *bus = priv; - struct cx23885_dev *dev = bus->dev; - - return cx23885_tuner_callback(dev, bus->nr, command, arg); -} - -int cx23885_xc3028_tuner_callback(void *priv, int command, int arg) -{ - struct cx23885_tsport *port = priv; - struct cx23885_dev *dev = port->dev; - - if (command == XC2028_RESET_CLK) - return 0; - - return cx23885_tuner_callback(dev, port->nr, command, arg); -} - void cx23885_gpio_setup(struct cx23885_dev *dev) { switch(dev->board) { diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 1a4da1a4a..c0c5b5be7 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -190,13 +190,13 @@ static struct s5h1411_config dvico_s5h1411_config = { static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { .i2c_address = 0x61, .if_khz = 5380, - .tuner_callback = cx23885_xc5000_tuner_callback, + .tuner_callback = cx23885_tuner_callback, }; static struct xc5000_config dvico_xc5000_tunerconfig = { .i2c_address = 0x64, .if_khz = 5380, - .tuner_callback = cx23885_xc5000_tuner_callback, + .tuner_callback = cx23885_tuner_callback, }; static struct tda829x_config tda829x_no_probe = { @@ -392,7 +392,7 @@ static int dvb_register(struct cx23885_tsport *port) if (port->dvb.frontend != NULL) dvb_attach(xc5000_attach, port->dvb.frontend, &i2c_bus->i2c_adap, - &hauppauge_hvr1500q_tunerconfig, i2c_bus); + &hauppauge_hvr1500q_tunerconfig, port); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; @@ -404,7 +404,8 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, - .callback = cx23885_xc3028_tuner_callback, + .video_dev = port, + .callback = cx23885_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028-v27.fw", @@ -443,7 +444,8 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, - .callback = cx23885_xc3028_tuner_callback, + .video_dev = port, + .callback = cx23885_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028L-v36.fw", @@ -471,7 +473,7 @@ static int dvb_register(struct cx23885_tsport *port) if (port->dvb.frontend != NULL) dvb_attach(xc5000_attach, port->dvb.frontend, &i2c_bus->i2c_adap, - &dvico_xc5000_tunerconfig, i2c_bus); + &dvico_xc5000_tunerconfig, port); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { i2c_bus = &dev->i2c_bus[port->nr - 1]; @@ -485,7 +487,7 @@ static int dvb_register(struct cx23885_tsport *port) .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, .video_dev = port, - .callback = cx23885_xc3028_tuner_callback, + .callback = cx23885_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = "xc3028-v27.fw", diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index 22e4cc353..9b76a8acf 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -411,8 +411,7 @@ extern const unsigned int cx23885_bcount; extern struct cx23885_subid cx23885_subids[]; extern const unsigned int cx23885_idcount; -extern int cx23885_xc5000_tuner_callback(void *priv, int command, int arg); -extern int cx23885_xc3028_tuner_callback(void *priv, int command, int arg); +extern int cx23885_tuner_callback(void *priv, int command, int arg); extern void cx23885_card_list(struct cx23885_dev *dev); extern int cx23885_ir_init(struct cx23885_dev *dev); extern void cx23885_gpio_setup(struct cx23885_dev *dev); -- cgit v1.2.3 From 04874827dbbfe036d172dd2256a7ec88ddf9d1a7 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 5 Aug 2008 10:01:44 +0200 Subject: gspca: Simplify the scan of URB packets in pac7311. From: Jean-Francois Moine Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 206 ++++++++++++++++-------------- 1 file changed, 110 insertions(+), 96 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 1b3ea1e93..0fecf4ea7 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -40,7 +40,8 @@ struct sd { unsigned char colors; unsigned char autogain; - char ffseq; + char ffnb; /* number of 'ff' in the previous frame */ + char tosof; /* number of bytes before next start of frame */ signed char ag_cnt; #define AG_CNT_START 13 }; @@ -335,6 +336,10 @@ static int sd_open(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; + + sd->ffnb = 0; + sd->tosof = 0; reg_w(gspca_dev, 0xff, 0x01); reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); @@ -511,114 +516,123 @@ static void do_autogain(struct gspca_dev *gspca_dev) } } +/* output the jpeg header */ +static void put_jpeg_head(struct gspca_dev *gspca_dev, + struct gspca_frame *frame) +{ + unsigned char tmpbuf[4]; + + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + (__u8 *) pac7311_jpeg_header, + 12); + tmpbuf[0] = gspca_dev->height >> 8; + tmpbuf[1] = gspca_dev->height & 0xff; + tmpbuf[2] = gspca_dev->width >> 8; + tmpbuf[3] = gspca_dev->width & 0xff; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + tmpbuf, 4); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + (__u8 *) &pac7311_jpeg_header[16], + PAC7311_JPEG_HEADER_SIZE - 16); +} + +/* this function is run at interrupt level */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; - unsigned char tmpbuf[4]; - int i, p, ffseq; - -/* if (len < 5) { */ - if (len < 6) { -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; - } - - ffseq = sd->ffseq; - - for (p = 0; p < len - 6; p++) { - if ((data[0 + p] == 0xff) - && (data[1 + p] == 0xff) - && (data[2 + p] == 0x00) - && (data[3 + p] == 0xff) - && (data[4 + p] == 0x96)) { - - /* start of frame */ - if (sd->ag_cnt >= 0 && p > 28) { - sd->lum_sum += data[p - 23]; - if (--sd->ag_cnt < 0) { - sd->ag_cnt = AG_CNT_START; - atomic_set(&sd->avg_lum, - sd->lum_sum / AG_CNT_START); - sd->lum_sum = 0; - atomic_set(&sd->do_gain, 1); + int i; + +#define INTER_FRAME 0x53 +#define LUM_OFFSET 0x1e /* reverse offset / start of frame */ + + /* + * inside a frame, there may be: + * escaped ff ('ff 00') + * sequences'ff ff ff xx' to remove + * end of frame ('ff d9') + * at the end of frame, there are: + * ff d9 end of frame + * 0x33 bytes + * one byte luminosity + * 0x16 bytes + * ff ff 00 ff 96 62 44 start of frame header + */ + + if (sd->tosof == 0) { /* if inside a frame */ + + /* check for 'ff ff ff xx' at start and at end of packet */ + /* (len is always >= 3) */ + switch (sd->ffnb) { + case 1: + if (data[0] != 0xff) + break; /* keep 'ff 00' */ + /* fall thru */ + case 2: + case 3: + data += 4 - sd->ffnb; + len -= 4 - sd->ffnb; + sd->ffnb = 0; + break; + } + if (data[len - 1] == 0xff) { + if (data[len - 2] == 0xff) { + if (data[len - 3] == 0xff) { + sd->ffnb = 3; + len -= 3; + } else { + sd->ffnb = 2; + len -= 2; } + } else { + sd->ffnb = 1; + len--; } - - /* copy the end of data to the current frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, p); - - /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - (unsigned char *) pac7311_jpeg_header, - 12); - tmpbuf[0] = gspca_dev->height >> 8; - tmpbuf[1] = gspca_dev->height & 0xff; - tmpbuf[2] = gspca_dev->width >> 8; - tmpbuf[3] = gspca_dev->width & 0xff; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - tmpbuf, 4); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - (unsigned char *) &pac7311_jpeg_header[16], - PAC7311_JPEG_HEADER_SIZE - 16); - - data += p + 7; - len -= p + 7; - ffseq = 0; - break; } + } else { /* outside a frame */ + + /* + * get the luminosity + * and go to the start of frame + */ + data += sd->tosof; + len -= sd->tosof; + if (sd->tosof > LUM_OFFSET) + sd->lum_sum += data[-LUM_OFFSET]; + put_jpeg_head(gspca_dev, frame); + sd->tosof = 0; } - /* remove the 'ff ff ff xx' sequences */ - switch (ffseq) { - case 3: - data += 1; - len -= 1; - break; - case 2: - if (data[0] == 0xff) { - data += 2; - len -= 2; - frame->data_end -= 2; - } - break; - case 1: - if (data[0] == 0xff - && data[1] == 0xff) { - data += 3; - len -= 3; - frame->data_end -= 1; - } - break; - } - for (i = 0; i < len - 4; i++) { - if (data[i] == 0xff - && data[i + 1] == 0xff - && data[i + 2] == 0xff) { - memmove(&data[i], &data[i + 4], len - i - 4); - len -= 4; + for (i = 0; i < len; i++) { + if (data[i] != 0xff) + continue; + switch (data[i + 1]) { + case 0xd9: /* end of frame */ + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, data, i + 1); + data += INTER_FRAME; + len -= INTER_FRAME; + i = 0; + if (len > LUM_OFFSET) + sd->lum_sum += data[-LUM_OFFSET]; + if (len < 0) { + sd->tosof = -len; + break; + } + put_jpeg_head(gspca_dev, frame); + break; + case 0xff: /* 'ff ff ff xx' */ + gspca_frame_add(gspca_dev, INTER_PACKET, + frame, data, i); + data += i + 4; + len -= i + 4; + i = 0; + break; } } - ffseq = 0; - if (data[len - 4] == 0xff) { - if (data[len - 3] == 0xff - && data[len - 2] == 0xff) { - len -= 4; - } - } else if (data[len - 3] == 0xff) { - if (data[len - 2] == 0xff - && data[len - 1] == 0xff) - ffseq = 3; - } else if (data[len - 2] == 0xff) { - if (data[len - 1] == 0xff) - ffseq = 2; - } else if (data[len - 1] == 0xff) - ffseq = 1; - sd->ffseq = ffseq; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } static void getbrightness(struct gspca_dev *gspca_dev) -- cgit v1.2.3 From 2ff4bb725cf7b17813461842cd8b4d20e3fff28a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 5 Aug 2008 11:16:19 +0200 Subject: gspca: Bug in the previous changeset about pac7311. From: Jean-Francois Moine Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 0fecf4ea7..1648c948e 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -610,13 +610,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, continue; switch (data[i + 1]) { case 0xd9: /* end of frame */ + i += 2; frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, i + 1); - data += INTER_FRAME; - len -= INTER_FRAME; + frame, data, i); + data += i + INTER_FRAME; + len -= i + INTER_FRAME; i = 0; - if (len > LUM_OFFSET) + if (len > -LUM_OFFSET) sd->lum_sum += data[-LUM_OFFSET]; if (len < 0) { sd->tosof = -len; -- cgit v1.2.3 From b09fc65be0f74fa20c47c31d00ddf7553a4749ee Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Aug 2008 10:03:17 -0300 Subject: saa7134: Add NEC prococol IR decoding capability From: Mauro Carvalho Chehab This patch adds the capability of decoding NEC protocol, received via GPIO18 line. This GPIO port can trigger saa7134 IRQ. A future improvement would be to make it a little more generic to work also with GPIO16 line. A pure IRQ code didn't work, since some delays were introduced on the tests we did. A possible approach would be to use polling at a rate of 2.5 ms or less. If a new code were taken, a code similar to nec_task() could be used. However, this would add an extra overhead to kernel, and will consume more power. Due to that, we took an hybrid approach: an IRQ upper half to trigger when a new key is received and a bottom half to convert pulse-distance into a keycode. The bottom half is polling based, to improve performance. During the bottom half proccess, GPIO18 IRQ line is disabled, preventing IRQ reentrancy and improving performance a little bit. Thanks to Sistema Fenix (http://www.sistemafenix.com.br/) for sponsoring this development. Priority: normal Signed-off-by: Gilberto Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-input.c | 144 +++++++++++++++++++++- 1 file changed, 138 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c index f26fd7061..a9f6df2dd 100644 --- a/linux/drivers/media/video/saa7134/saa7134-input.c +++ b/linux/drivers/media/video/saa7134/saa7134-input.c @@ -62,8 +62,11 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of " #define i2cdprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) -/** rc5 functions */ +/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ static int saa7134_rc5_irq(struct saa7134_dev *dev); +static int saa7134_nec_irq(struct saa7134_dev *dev); +static void nec_task(unsigned long data); +static void saa7134_nec_timer(unsigned long data); /* -------------------- GPIO generic keycode builder -------------------- */ @@ -280,7 +283,9 @@ void saa7134_input_irq(struct saa7134_dev *dev) { struct card_ir *ir = dev->remote; - if (!ir->polling && !ir->rc5_gpio) { + if (ir->nec_gpio) { + saa7134_nec_irq(dev); + } else if (!ir->polling && !ir->rc5_gpio) { build_key(dev); } else if (ir->rc5_gpio) { saa7134_rc5_irq(dev); @@ -316,6 +321,10 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) ir->addr = 0x17; ir->rc5_key_timeout = ir_rc5_key_timeout; ir->rc5_remote_gap = ir_rc5_remote_gap; + } else if (ir->nec_gpio) { + setup_timer(&ir->timer_keyup, saa7134_nec_timer, + (unsigned long)dev); + tasklet_init(&ir->tlet, nec_task, (unsigned long)dev); } } @@ -335,6 +344,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) u32 mask_keyup = 0; int polling = 0; int rc5_gpio = 0; + int nec_gpio = 0; int ir_type = IR_TYPE_OTHER; int err; @@ -533,6 +543,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) ir->mask_keyup = mask_keyup; ir->polling = polling; ir->rc5_gpio = rc5_gpio; + ir->nec_gpio = nec_gpio; /* init input device */ snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", @@ -679,8 +690,129 @@ static int saa7134_rc5_irq(struct saa7134_dev *dev) return 1; } -/* ---------------------------------------------------------------------- - * Local variables: - * c-basic-offset: 8 - * End: + +/* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms + The first pulse (start) has 9 + 4.5 ms */ + +static void saa7134_nec_timer(unsigned long data) +{ + struct saa7134_dev *dev = (struct saa7134_dev *) data; + struct card_ir *ir = dev->remote; + + dprintk("Cancel key repeat\n"); + + ir_input_nokey(ir->dev, &ir->ir); +} + +static void nec_task(unsigned long data) +{ + struct saa7134_dev *dev = (struct saa7134_dev *) data; + struct card_ir *ir; + struct timeval tv; + int count, pulse, oldpulse, gap; + u32 ircode = 0, not_code = 0; + int ngap = 0; + + if (!data) { + printk(KERN_ERR "saa713x/ir: Can't recover dev struct\n"); + /* GPIO will be kept disabled */ + return; + } + + ir = dev->remote; + + /* rising SAA7134_GPIO_GPRESCAN reads the status */ + saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + + oldpulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; + pulse = oldpulse; + + do_gettimeofday(&tv); + ir->base_time = tv; + + /* Decode NEC pulsecode. This code can take up to 76.5 ms to run. + Unfortunately, using IRQ to decode pulse didn't work, since it uses + a pulse train of 38KHz. This means one pulse on each 52 us + */ + do { + /* Wait until the end of pulse/space or 5 ms */ + for (count = 0; count < 500; count++) { + udelay(10); + /* rising SAA7134_GPIO_GPRESCAN reads the status */ + saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) + & ir->mask_keydown; + if (pulse != oldpulse) + break; + } + + do_gettimeofday(&tv); + gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + + tv.tv_usec - ir->base_time.tv_usec; + + if (!pulse) { +#if 0 + if (!ngap && gap < 4000) + break; +#endif + /* Bit 0 has 560 us, while bit 1 has 1120 us. + Do something only if bit == 1 + */ + if (ngap && (gap > 560 + 280)) { + unsigned int shift = ngap - 1; + + /* Address first, then command */ + if (shift < 8) { + shift += 8; + ircode |= 1 << shift; + } else if (shift < 16) { + not_code |= 1 << shift; + } else if (shift < 24) { + shift -= 16; + ircode |= 1 << shift; + } else { + shift -= 24; + not_code |= 1 << shift; + } + } + ngap++; + } + + + ir->base_time = tv; + + /* TIMEOUT - Long pulse */ + if (gap >= 5000) + break; + oldpulse = pulse; + } while (ngap < 32); + + if (ngap == 32) { + /* FIXME: should check if not_code == ~ircode */ + ir->code = ir_extract_bits(ircode, ir->mask_keycode); + + dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n", + ir->code, ircode, not_code); + + ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code); + } else + dprintk("Repeat last key\n"); + + /* Keep repeating the last key */ + mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150)); + + saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); +} + +static int saa7134_nec_irq(struct saa7134_dev *dev) +{ + struct card_ir *ir = dev->remote; + + saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); + tasklet_schedule(&ir->tlet); + + return 1; +} -- cgit v1.2.3 From c6779d4098c7b706d36cb85aa23dce766af181d1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Aug 2008 10:11:25 -0300 Subject: Add support for TCL tuner MF02GIP-5N-E From: Mauro Carvalho Chehab Thanks to Sistema Fenix (http://www.sistemafenix.com.br/) and CDI Brasil (www.cdibrasil.com.br/) for sponsoring this development. Signed-off-by: Gilberto Signed-off-by: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-simple.c | 2 ++ linux/drivers/media/common/tuners/tuner-types.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/tuners/tuner-simple.c b/linux/drivers/media/common/tuners/tuner-simple.c index f352af87b..a709d6bee 100644 --- a/linux/drivers/media/common/tuners/tuner-simple.c +++ b/linux/drivers/media/common/tuners/tuner-simple.c @@ -143,6 +143,7 @@ static inline int tuner_stereo(const int type, const int status) case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FM1256_IH3: case TUNER_LG_NTSC_TAPE: + case TUNER_TCL_MF02GIP_5N: return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); default: return status & TUNER_STEREO; @@ -514,6 +515,7 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) case TUNER_PHILIPS_FMD1216ME_MK3: case TUNER_LG_NTSC_TAPE: case TUNER_PHILIPS_FM1256_IH3: + case TUNER_TCL_MF02GIP_5N: buffer[3] = 0x19; break; case TUNER_TNF_5335MF: diff --git a/linux/drivers/media/common/tuners/tuner-types.c b/linux/drivers/media/common/tuners/tuner-types.c index b3f0f62e0..861d23872 100644 --- a/linux/drivers/media/common/tuners/tuner-types.c +++ b/linux/drivers/media/common/tuners/tuner-types.c @@ -1217,6 +1217,23 @@ static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = { }, }; +/* ------------ TUNER_TCL_MF02GIP-5N-E - TCL MF02GIP-5N ------------ */ + +static struct tuner_range tuner_tcl_mf02gip_5n_ntsc_ranges[] = { + { 16 * 172.00 /*MHz*/, 0x8e, 0x01, }, + { 16 * 448.00 /*MHz*/, 0x8e, 0x02, }, + { 16 * 999.99 , 0x8e, 0x04, }, +}; + +static struct tuner_params tuner_tcl_mf02gip_5n_params[] = { + { + .type = TUNER_PARAM_TYPE_NTSC, + .ranges = tuner_tcl_mf02gip_5n_ntsc_ranges, + .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_ntsc_ranges), + .cb_first_if_lower_freq = 1, + }, +}; + /* --------------------------------------------------------------------- */ struct tunertype tuners[] = { @@ -1642,6 +1659,11 @@ struct tunertype tuners[] = { .name = "Xceive 5000 tuner", /* see xc5000.c for details */ }, + [TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */ + .name = "TCL tuner MF02GIP-5N-E", + .params = tuner_tcl_mf02gip_5n_params, + .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params), + }, }; EXPORT_SYMBOL(tuners); -- cgit v1.2.3 From 4fb662a69b9c53bd1f2f01bd045a6d944fd88209 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Aug 2008 10:12:35 -0300 Subject: Fix mute on bttv driver From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bt8xx/bttv-driver.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index d5cb13e40..012eeba5e 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -3296,6 +3296,7 @@ static int bttv_open(struct inode *inode, struct file *file) sizeof(struct bttv_buffer), fh); set_tvnorm(btv,btv->tvnorm); + set_input(btv, btv->input, btv->tvnorm); btv->users++; @@ -3357,6 +3358,10 @@ static int bttv_release(struct inode *inode, struct file *file) btv->users--; bttv_field_count(btv); + + if (!btv->users) + audio_mute(btv, 1); + return 0; } -- cgit v1.2.3 From d2dbf570f863476560875eda98a939a77984aa40 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Aug 2008 10:14:13 -0300 Subject: bttv: Add support for Encore ENLTV2-FM From: Mauro Carvalho Chehab Thanks to Sistema Fenix (http://www.sistemafenix.com.br/) and CDI Brasil (www.cdibrasil.com.br/) for sponsoring this development. Priority: normal Signed-off-by: Gilberto Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/ir-keymaps.c | 55 ++++++++++++++++++++++-- linux/drivers/media/video/bt8xx/bttv-cards.c | 27 +++++++++++- linux/drivers/media/video/bt8xx/bttv-input.c | 62 ++++++++++++++++++++++++++-- linux/drivers/media/video/bt8xx/bttv.h | 2 +- 4 files changed, 138 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index a464ad34e..f1d172a3f 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -1842,12 +1842,61 @@ IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = { [ 0x41 ] = KEY_GREEN, /* AP2 */ [ 0x47 ] = KEY_YELLOW, /* AP3 */ [ 0x57 ] = KEY_BLUE, /* AP4 */ - - }; - EXPORT_SYMBOL_GPL(ir_codes_encore_enltv); +/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton + Mauro Carvalho Chehab */ +IR_KEYTAB_TYPE ir_codes_encore_enltv2[IR_KEYTAB_SIZE] = { + [0x4c] = KEY_POWER2, + [0x4a] = KEY_TUNER, + [0x40] = KEY_1, + [0x60] = KEY_2, + [0x50] = KEY_3, + [0x70] = KEY_4, + [0x48] = KEY_5, + [0x68] = KEY_6, + [0x58] = KEY_7, + [0x78] = KEY_8, + [0x44] = KEY_9, + [0x54] = KEY_0, + + [0x64] = KEY_LAST, /* +100 */ + [0x4e] = KEY_AGAIN, /* Recall */ + + [0x6c] = KEY_SWITCHVIDEOMODE, /* Video Source */ + [0x5e] = KEY_MENU, + [0x56] = KEY_SCREEN, + [0x7a] = KEY_SETUP, + + [0x46] = KEY_MUTE, + [0x5c] = KEY_MODE, /* Stereo */ + [0x74] = KEY_INFO, + [0x7c] = KEY_CLEAR, + + [0x55] = KEY_UP, + [0x49] = KEY_DOWN, + [0x7e] = KEY_LEFT, + [0x59] = KEY_RIGHT, + [0x6a] = KEY_ENTER, + + [0x42] = KEY_VOLUMEUP, + [0x62] = KEY_VOLUMEDOWN, + [0x52] = KEY_CHANNELUP, + [0x72] = KEY_CHANNELDOWN, + + [0x41] = KEY_RECORD, + [0x51] = KEY_SHUFFLE, /* Snapshot */ + [0x75] = KEY_TIME, /* Timeshift */ + [0x71] = KEY_TV2, /* PIP */ + + [0x45] = KEY_REWIND, + [0x6f] = KEY_PAUSE, + [0x7d] = KEY_FORWARD, + [0x79] = KEY_STOP, +}; +EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2); + /* for the Technotrend 1500 bundled remotes (grey and black): */ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = { [ 0x01 ] = KEY_POWER, diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c index ff9d09f09..bf3339436 100644 --- a/linux/drivers/media/video/bt8xx/bttv-cards.c +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c @@ -309,7 +309,7 @@ static struct CARD { { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, { 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" }, - + { 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" }, { 0, -1, NULL } }; @@ -3069,6 +3069,31 @@ struct tvcard bttv_tvcards[] = { .has_radio = 1, .has_remote = 1, }, + [BTTV_BOARD_ENLTV_FM_2] = { + /* Encore TV Tuner Pro ENL TV-FM-2 + Mauro Carvalho Chehab IR disabled + bit 18/17 = 00 -> mute + 01 -> enable external audio input + 10 -> internal audio input (mono?) + 11 -> internal audio input + */ + .gpiomask = 0x060040, + .muxsel = { 2, 3, 3 }, + .gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 }, + .gpiomute = 0, + .tuner_type = TUNER_TCL_MF02GIP_5N, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .pll = PLL_28, + .has_radio = 1, + .has_remote = 1, + } }; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); diff --git a/linux/drivers/media/video/bt8xx/bttv-input.c b/linux/drivers/media/video/bt8xx/bttv-input.c index 09dc5ac77..a6b403a01 100644 --- a/linux/drivers/media/video/bt8xx/bttv-input.c +++ b/linux/drivers/media/video/bt8xx/bttv-input.c @@ -28,8 +28,8 @@ #include "bttvp.h" -static int debug; -module_param(debug, int, 0644); /* debug level (0,1,2) */ +static int ir_debug; +module_param(ir_debug, int, 0644); static int repeat_delay = 500; module_param(repeat_delay, int, 0644); static int repeat_period = 33; @@ -40,6 +40,12 @@ module_param(ir_rc5_remote_gap, int, 0644); static int ir_rc5_key_timeout = 200; module_param(ir_rc5_key_timeout, int, 0644); +#undef dprintk +#define dprintk(arg...) do { \ + if (ir_debug >= 1) \ + printk(arg); \ +} while (0) + #define DEVNAME "bttv-input" /* ---------------------------------------------------------------------- */ @@ -79,6 +85,45 @@ static void ir_handle_key(struct bttv *btv) } +static void ir_enltv_handle_key(struct bttv *btv) +{ + struct card_ir *ir = btv->remote; + u32 gpio, data, keyup; + + /* read gpio value */ + gpio = bttv_gpio_read(&btv->c); + + /* extract data */ + data = ir_extract_bits(gpio, ir->mask_keycode); + + /* Check if it is keyup */ + keyup = (gpio & ir->mask_keyup) ? 1 << 31 : 0; + + if ((ir->last_gpio & 0x7f) != data) { + dprintk(KERN_INFO DEVNAME ": gpio=0x%x code=%d | %s\n", + gpio, data, + (gpio & ir->mask_keyup) ? " up" : "up/down"); + + ir_input_keydown(ir->dev, &ir->ir, data, data); + if (keyup) + ir_input_nokey(ir->dev, &ir->ir); + } else { + if ((ir->last_gpio & 1 << 31) == keyup) + return; + + dprintk(KERN_INFO DEVNAME ":(cnt) gpio=0x%x code=%d | %s\n", + gpio, data, + (gpio & ir->mask_keyup) ? " up" : "down"); + + if (keyup) + ir_input_nokey(ir->dev, &ir->ir); + else + ir_input_keydown(ir->dev, &ir->ir, data, data); + } + + ir->last_gpio = data | keyup; +} + void bttv_input_irq(struct bttv *btv) { struct card_ir *ir = btv->remote; @@ -92,7 +137,10 @@ static void bttv_input_timer(unsigned long data) struct bttv *btv = (struct bttv*)data; struct card_ir *ir = btv->remote; - ir_handle_key(btv); + if (btv->c.type == BTTV_BOARD_ENLTV_FM_2) + ir_enltv_handle_key(btv); + else + ir_handle_key(btv); mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); } @@ -284,6 +332,14 @@ int bttv_input_init(struct bttv *btv) ir->mask_keyup = 0x006000; ir->polling = 50; /* ms */ break; + case BTTV_BOARD_ENLTV_FM_2: + ir_codes = ir_codes_encore_enltv2; + ir->mask_keycode = 0x00fd00; + ir->mask_keyup = 0x000080; + ir->polling = 1; /* ms */ + ir->last_gpio = ir_extract_bits(bttv_gpio_read(&btv->c), + ir->mask_keycode); + break; } if (NULL == ir_codes) { dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type); diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h index 3441c0226..0f2a33eb3 100644 --- a/linux/drivers/media/video/bt8xx/bttv.h +++ b/linux/drivers/media/video/bt8xx/bttv.h @@ -177,7 +177,7 @@ #define BTTV_BOARD_TYPHOON_TVTUNERPCI 0x95 #define BTTV_BOARD_GEOVISION_GV600 0x96 #define BTTV_BOARD_KOZUMI_KTV_01C 0x97 - +#define BTTV_BOARD_ENLTV_FM_2 0x98 /* more card-specific defines */ #define PT2254_L_CHANNEL 0x10 -- cgit v1.2.3 From a499d8eb7179d0990c06b89c3362af960c7d9eef Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Aug 2008 21:00:11 +0300 Subject: Remove the dead CONFIG_RADIO_MIROPCM20{,_RDS} code From: Adrian Bunk The CONFIG_RADIO_MIROPCM20{,_RDS} code became dead code 1.5 years ago. Priority: normal Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/Makefile | 4 - linux/drivers/media/radio/miropcm20-radio.c | 267 ------------------------- linux/drivers/media/radio/miropcm20-rds-core.c | 212 -------------------- linux/drivers/media/radio/miropcm20-rds-core.h | 19 -- linux/drivers/media/radio/miropcm20-rds.c | 140 ------------- 5 files changed, 642 deletions(-) delete mode 100644 linux/drivers/media/radio/miropcm20-radio.c delete mode 100644 linux/drivers/media/radio/miropcm20-rds-core.c delete mode 100644 linux/drivers/media/radio/miropcm20-rds-core.h delete mode 100644 linux/drivers/media/radio/miropcm20-rds.c (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/radio/Makefile b/linux/drivers/media/radio/Makefile index a30159f6f..7ca71ab96 100644 --- a/linux/drivers/media/radio/Makefile +++ b/linux/drivers/media/radio/Makefile @@ -2,8 +2,6 @@ # Makefile for the kernel character device drivers. # -miropcm20-objs := miropcm20-rds-core.o miropcm20-radio.o - obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o @@ -14,8 +12,6 @@ obj-$(CONFIG_RADIO_TERRATEC) += radio-terratec.o obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o -obj-$(CONFIG_RADIO_MIROPCM20) += miropcm20.o -obj-$(CONFIG_RADIO_MIROPCM20_RDS) += miropcm20-rds.o obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o diff --git a/linux/drivers/media/radio/miropcm20-radio.c b/linux/drivers/media/radio/miropcm20-radio.c deleted file mode 100644 index efbb9cce8..000000000 --- a/linux/drivers/media/radio/miropcm20-radio.c +++ /dev/null @@ -1,267 +0,0 @@ -/* Miro PCM20 radio driver for Linux radio support - * (c) 1998 Ruurd Reitsma - * Thanks to Norberto Pellici for the ACI device interface specification - * The API part is based on the radiotrack driver by M. Kirkwood - * This driver relies on the aci mixer (drivers/sound/aci.c) - * Look there for further info... - */ - -/* Revision history: - * - * 1998 Ruurd Reitsma - * 2000-09-05 Robert Siemer - * removed unfinished volume control (maybe adding it later again) - * use OSS-mixer; added stereo control - */ - -/* What ever you think about the ACI, version 0x07 is not very well! - * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono - * conditions... Robert - */ - -#include -#include -#include "compat.h" -#include -#include -#include -#include "oss/aci.h" -#include "miropcm20-rds-core.h" - -static int radio_nr = -1; -module_param(radio_nr, int, 0); - -struct pcm20_device { - unsigned long freq; - int muted; - int stereo; -}; - - -static int pcm20_mute(struct pcm20_device *dev, unsigned char mute) -{ - dev->muted = mute; - return aci_write_cmd(ACI_SET_TUNERMUTE, mute); -} - -static int pcm20_stereo(struct pcm20_device *dev, unsigned char stereo) -{ - dev->stereo = stereo; - return aci_write_cmd(ACI_SET_TUNERMONO, !stereo); -} - -static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq) -{ - unsigned char freql; - unsigned char freqh; - - dev->freq=freq; - - freq /= 160; - if (!(aci_version==0x07 || aci_version>=0xb0)) - freq /= 10; /* I don't know exactly which version - * needs this hack */ - freql = freq & 0xff; - freqh = freq >> 8; - - aci_rds_cmd(RDS_RESET, NULL, 0); - pcm20_stereo(dev, 1); - - return aci_rw_cmd(ACI_WRITE_TUNE, freql, freqh); -} - -static int pcm20_getflags(struct pcm20_device *dev, __u32 *flags, __u16 *signal) -{ - /* okay, check for signal, stereo and rds here... */ - int i; - unsigned char buf; - - if ((i=aci_rw_cmd(ACI_READ_TUNERSTATION, -1, -1))<0) - return i; - pr_debug("check_sig: 0x%x\n", i); - if (i & 0x80) { - /* no signal from tuner */ - *flags=0; - *signal=0; - return 0; - } else - *signal=0xffff; - - if ((i=aci_rw_cmd(ACI_READ_TUNERSTEREO, -1, -1))<0) - return i; - if (i & 0x40) { - *flags=0; - } else { - /* stereo */ - *flags=VIDEO_TUNER_STEREO_ON; - /* I can't see stereo, when forced to mono */ - dev->stereo=1; - } - - if ((i=aci_rds_cmd(RDS_STATUS, &buf, 1))<0) - return i; - if (buf & 1) - /* RDS available */ - *flags|=VIDEO_TUNER_RDS_ON; - else - return 0; - - if ((i=aci_rds_cmd(RDS_RXVALUE, &buf, 1))<0) - return i; - pr_debug("rds-signal: %d\n", buf); - if (buf > 15) { - printk("miropcm20-radio: RX strengths unexpected high...\n"); - buf=15; - } - /* refine signal */ - if ((*signal=SCALE(15, 0xffff, buf))==0) - *signal = 1; - - return 0; -} - -static int pcm20_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *dev = video_devdata(file); - struct pcm20_device *pcm20 = dev->priv; - int i; - - switch(cmd) - { - case VIDIOCGCAP: - { - struct video_capability *v = arg; - memset(v,0,sizeof(*v)); - v->type=VID_TYPE_TUNER; - strcpy(v->name, "Miro PCM20"); - v->channels=1; - v->audios=1; - return 0; - } - case VIDIOCGTUNER: - { - struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ - return -EINVAL; - v->rangelow=87*16000; - v->rangehigh=108*16000; - pcm20_getflags(pcm20, &v->flags, &v->signal); - v->flags|=VIDEO_TUNER_LOW; - v->mode=VIDEO_MODE_AUTO; - strcpy(v->name, "FM"); - return 0; - } - case VIDIOCSTUNER: - { - struct video_tuner *v = arg; - if(v->tuner!=0) - return -EINVAL; - /* Only 1 tuner so no setting needed ! */ - return 0; - } - case VIDIOCGFREQ: - { - unsigned long *freq = arg; - *freq = pcm20->freq; - return 0; - } - case VIDIOCSFREQ: - { - unsigned long *freq = arg; - pcm20->freq = *freq; - i=pcm20_setfreq(pcm20, pcm20->freq); - pr_debug("First view (setfreq): 0x%x\n", i); - return i; - } - case VIDIOCGAUDIO: - { - struct video_audio *v = arg; - memset(v,0, sizeof(*v)); - v->flags=VIDEO_AUDIO_MUTABLE; - if (pcm20->muted) - v->flags|=VIDEO_AUDIO_MUTE; - v->mode=VIDEO_SOUND_STEREO; - if (pcm20->stereo) - v->mode|=VIDEO_SOUND_MONO; - /* v->step=2048; */ - strcpy(v->name, "Radio"); - return 0; - } - case VIDIOCSAUDIO: - { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; - - pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE)); - if(v->flags&VIDEO_SOUND_MONO) - pcm20_stereo(pcm20, 0); - if(v->flags&VIDEO_SOUND_STEREO) - pcm20_stereo(pcm20, 1); - - return 0; - } - default: - return -ENOIOCTLCMD; - } -} - -static int pcm20_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return video_usercopy(inode, file, cmd, arg, pcm20_do_ioctl); -} - -static struct pcm20_device pcm20_unit = { - .freq = 87*16000, - .muted = 1, -}; - -static const struct file_operations pcm20_fops = { - .owner = THIS_MODULE, - .open = video_exclusive_open, - .release = video_exclusive_release, - .ioctl = pcm20_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, -}; - -static struct video_device pcm20_radio = { - .name = "Miro PCM 20 radio", - .fops = &pcm20_fops, - .priv = &pcm20_unit -}; - -static int __init pcm20_init(void) -{ - if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1) - goto video_register_device; - - if(attach_aci_rds()<0) - goto attach_aci_rds; - - printk(KERN_INFO "Miro PCM20 radio card driver.\n"); - - return 0; - - attach_aci_rds: - video_unregister_device(&pcm20_radio); - video_register_device: - return -EINVAL; -} - -MODULE_AUTHOR("Ruurd Reitsma"); -MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card."); -MODULE_LICENSE("GPL"); - -static void __exit pcm20_cleanup(void) -{ - unload_aci_rds(); - video_unregister_device(&pcm20_radio); -} - -module_init(pcm20_init); -module_exit(pcm20_cleanup); diff --git a/linux/drivers/media/radio/miropcm20-rds-core.c b/linux/drivers/media/radio/miropcm20-rds-core.c deleted file mode 100644 index e18e2a4a8..000000000 --- a/linux/drivers/media/radio/miropcm20-rds-core.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Many thanks to Fred Seidel , the - * designer of the RDS decoder hardware. With his help - * I was able to code this driver. - * Thanks also to Norberto Pellicci, Dominic Mounteney - * and www.teleauskunft.de - * for good hints on finding Fred. It was somewhat hard - * to locate him here in Germany... [: - * - * Revision history: - * - * 2000-08-09 Robert Siemer - * RDS support for MiroSound PCM20 radio - */ - -#include -#include -#include -#include -#include -#include "compat.h" -#include - -#include -#include "oss/aci.h" -#include "miropcm20-rds-core.h" - -#define DEBUG 0 - -static struct mutex aci_rds_mutex; - -#define RDS_DATASHIFT 2 /* Bit 2 */ -#define RDS_DATAMASK (1 << RDS_DATASHIFT) -#define RDS_BUSYMASK 0x10 /* Bit 4 */ -#define RDS_CLOCKMASK 0x08 /* Bit 3 */ - -#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1) - - -#if DEBUG -static void print_matrix(char array[], unsigned int length) -{ - int i, j; - - for (i=0; i=0; j--) { - printk("%d", (array[i] >> j) & 0x1); - } - if (i%8 == 0) - printk(" byte-border\n"); - else - printk("\n"); - } -} -#endif /* DEBUG */ - -static int byte2trans(unsigned char byte, unsigned char sendbuffer[], int size) -{ - int i; - - if (size != 8) - return -1; - for (i = 7; i >= 0; i--) - sendbuffer[7-i] = (byte & (1 << i)) ? RDS_DATAMASK : 0; - sendbuffer[0] |= RDS_CLOCKMASK; - - return 0; -} - -static int rds_waitread(void) -{ - unsigned char byte; - int i=2000; - - do { - byte=inb(RDS_REGISTER); - i--; - } - while ((byte & RDS_BUSYMASK) && i); - - if (i) { - #if DEBUG - printk(KERN_DEBUG "rds_waitread()"); - print_matrix(&byte, 1); - #endif - return (byte); - } else { - printk(KERN_WARNING "aci-rds: rds_waitread() timeout...\n"); - return -1; - } -} - -/* don't use any ..._nowait() function if you are not sure what you do... */ - -static inline void rds_rawwrite_nowait(unsigned char byte) -{ - #if DEBUG - printk(KERN_DEBUG "rds_rawwrite()"); - print_matrix(&byte, 1); - #endif - outb(byte, RDS_REGISTER); -} - -static int rds_rawwrite(unsigned char byte) -{ - if (rds_waitread() >= 0) { - rds_rawwrite_nowait(byte); - return 0; - } else - return -1; -} - -static int rds_write(unsigned char cmd) -{ - unsigned char sendbuffer[8]; - int i; - - if (byte2trans(cmd, sendbuffer, 8) != 0){ - return -1; - } else { - for (i=0; i<8; i++) { - rds_rawwrite(sendbuffer[i]); - } - } - return 0; -} - -static int rds_readcycle_nowait(void) -{ - rds_rawwrite_nowait(0); - return rds_waitread(); -} - -static int rds_readcycle(void) -{ - if (rds_rawwrite(0) < 0) - return -1; - return rds_waitread(); -} - -static int rds_read(unsigned char databuffer[], int datasize) -{ - #define READSIZE (8*datasize) - - int i,j; - - if (datasize < 1) /* nothing to read */ - return 0; - - /* to be able to use rds_readcycle_nowait() - I have to waitread() here */ - if (rds_waitread() < 0) - return -1; - - memset(databuffer, 0, datasize); - - for (i=0; i< READSIZE; i++) - if((j=rds_readcycle_nowait()) < 0) { - return -1; - } else { - databuffer[i/8]|=(RDS_DATA(j) << (7-(i%8))); - } - - return 0; -} - -static int rds_ack(void) -{ - int i=rds_readcycle(); - - if (i < 0) - return -1; - if (i & RDS_DATAMASK) { - return 0; /* ACK */ - } else { - printk(KERN_DEBUG "aci-rds: NACK\n"); - return 1; /* NACK */ - } -} - -int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize) -{ - int ret; - - if (mutex_lock_interruptible(&aci_rds_mutex)) - return -EINTR; - - rds_write(cmd); - - /* RDS_RESET doesn't need further processing */ - if (cmd!=RDS_RESET && (rds_ack() || rds_read(databuffer, datasize))) - ret = -1; - else - ret = 0; - - mutex_unlock(&aci_rds_mutex); - - return ret; -} -EXPORT_SYMBOL(aci_rds_cmd); - -int __init attach_aci_rds(void) -{ - mutex_init(&aci_rds_mutex); - return 0; -} - -void __exit unload_aci_rds(void) -{ -} -MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/radio/miropcm20-rds-core.h b/linux/drivers/media/radio/miropcm20-rds-core.h deleted file mode 100644 index aeb5761f0..000000000 --- a/linux/drivers/media/radio/miropcm20-rds-core.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _MIROPCM20_RDS_CORE_H_ -#define _MIROPCM20_RDS_CORE_H_ - -extern int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize); - -#define RDS_STATUS 0x01 -#define RDS_STATIONNAME 0x02 -#define RDS_TEXT 0x03 -#define RDS_ALTFREQ 0x04 -#define RDS_TIMEDATE 0x05 -#define RDS_PI_CODE 0x06 -#define RDS_PTYTATP 0x07 -#define RDS_RESET 0x08 -#define RDS_RXVALUE 0x09 - -extern void __exit unload_aci_rds(void); -extern int __init attach_aci_rds(void); - -#endif /* _MIROPCM20_RDS_CORE_H_ */ diff --git a/linux/drivers/media/radio/miropcm20-rds.c b/linux/drivers/media/radio/miropcm20-rds.c deleted file mode 100644 index af90cdcf2..000000000 --- a/linux/drivers/media/radio/miropcm20-rds.c +++ /dev/null @@ -1,140 +0,0 @@ -/* MiroSOUND PCM20 radio rds interface driver - * (c) 2001 Robert Siemer - * Thanks to Fred Seidel. See miropcm20-rds-core.c for further information. - */ - -/* Revision history: - * - * 2001-04-18 Robert Siemer - * separate file for user interface driver - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "miropcm20-rds-core.h" - -static char * text_buffer; -static int rds_users; - - -static int rds_f_open(struct inode *in, struct file *fi) -{ - if (rds_users) - return -EBUSY; - - lock_kernel(); - rds_users++; - if ((text_buffer=kmalloc(66, GFP_KERNEL)) == 0) { - rds_users--; - printk(KERN_NOTICE "aci-rds: Out of memory by open()...\n"); - unlock_kernel(); - return -ENOMEM; - } - - unlock_kernel(); - return 0; -} - -static int rds_f_release(struct inode *in, struct file *fi) -{ - kfree(text_buffer); - - rds_users--; - return 0; -} - -static void print_matrix(char *ch, char out[]) -{ - int j; - - for (j=7; j>=0; j--) { - out[7-j] = ((*ch >> j) & 0x1) + '0'; - } -} - -static ssize_t rds_f_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) -{ -// i = sprintf(text_buffer, "length: %d, offset: %d\n", length, *offset); - - char c; - char bits[8]; - - msleep(2000); - aci_rds_cmd(RDS_STATUS, &c, 1); - print_matrix(&c, bits); - if (copy_to_user(buffer, bits, 8)) - return -EFAULT; - -/* if ((c >> 3) & 1) { - aci_rds_cmd(RDS_STATIONNAME, text_buffer+1, 8); - text_buffer[0] = ' ' ; - text_buffer[9] = '\n'; - return copy_to_user(buffer+8, text_buffer, 10) ? -EFAULT: 18; - } -*/ -/* if ((c >> 6) & 1) { - aci_rds_cmd(RDS_PTYTATP, &c, 1); - if ( c & 1) - sprintf(text_buffer, " M"); - else - sprintf(text_buffer, " S"); - if ((c >> 1) & 1) - sprintf(text_buffer+2, " TA"); - else - sprintf(text_buffer+2, " --"); - if ((c >> 7) & 1) - sprintf(text_buffer+5, " TP"); - else - sprintf(text_buffer+5, " --"); - sprintf(text_buffer+8, " %2d\n", (c >> 2) & 0x1f); - return copy_to_user(buffer+8, text_buffer, 12) ? -EFAULT: 20; - } -*/ - - if ((c >> 4) & 1) { - aci_rds_cmd(RDS_TEXT, text_buffer, 65); - text_buffer[0] = ' ' ; - text_buffer[65] = '\n'; - return copy_to_user(buffer+8, text_buffer,66) ? -EFAULT : 66+8; - } else { - put_user('\n', buffer+8); - return 9; - } -} - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) -static const struct file_operations rds_fops = { -#else -static struct file_operations rds_fops = { -#endif - .owner = THIS_MODULE, - .read = rds_f_read, - .open = rds_f_open, - .release = rds_f_release -}; - -static struct miscdevice rds_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "radiotext", - .fops = &rds_fops, -}; - -static int __init miropcm20_rds_init(void) -{ - return misc_register(&rds_miscdev); -} - -static void __exit miropcm20_rds_cleanup(void) -{ - misc_deregister(&rds_miscdev); -} - -module_init(miropcm20_rds_init); -module_exit(miropcm20_rds_cleanup); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 6bfb80222fdb109200e71e0e0a50d88a8e3c9e90 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 6 Aug 2008 08:18:38 +0200 Subject: gspca: Webcam 0c45:6128 added in sonixj. From: Jean-Francois Moine Patch adapted from a patch to gspcav1 made by the google microdia group. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 138 ++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 22 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index b30f7eeda..953f17809 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -54,8 +54,9 @@ struct sd { #define SENSOR_HV7131R 0 #define SENSOR_MI0360 1 #define SENSOR_MO4000 2 -#define SENSOR_OV7648 3 -#define SENSOR_OV7660 4 +#define SENSOR_OM6802 3 +#define SENSOR_OV7648 4 +#define SENSOR_OV7660 5 unsigned char i2c_base; }; @@ -180,6 +181,20 @@ static const __u8 sn_mo4000[] = { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const __u8 sn_om6802[] = { +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, +/* reg8 reg9 rega regb regc regd rege regf */ + 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40, +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf, + 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef, + 0xf7 +}; + static const __u8 sn_ov7648[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, @@ -219,6 +234,7 @@ static const __u8 *sn_tb[] = { sn_hv7131, sn_mi0360, sn_mo4000, + sn_om6802, sn_ov7648, sn_ov7660 }; @@ -352,6 +368,40 @@ static const __u8 mo4000_sensor_init[][8] = { {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, {} }; +static __u8 om6802_sensor_init[][8] = { + {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10}, +/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */ + {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10}, + /* white balance & auto-exposure */ +/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10}, + * set color mode */ +/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10}, + * max AGC value in AE */ +/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10}, + * preset AGC */ +/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10}, + * preset brightness */ +/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10}, + * preset contrast */ +/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10}, + * preset gamma */ + {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10}, + /* luminance mode (0x4f = AE) */ + {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10}, + /* preset shutter */ +/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10}, + * auto frame rate */ +/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */ + +/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */ +/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */ +/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */ +/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */ + {} +}; static const __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ /* (delay 20ms) */ @@ -697,29 +747,35 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); - switch (sd->bridge) { + switch (sd->sensor) { + case SENSOR_OM6802: + reg_w1(gspca_dev, 0x02, 0x71); + reg_w1(gspca_dev, 0x01, 0x42); + reg_w1(gspca_dev, 0x17, 0x64); + reg_w1(gspca_dev, 0x01, 0x42); + break; + case SENSOR_OV7648: + reg_w1(gspca_dev, 0x01, 0x43); + reg_w1(gspca_dev, 0x17, 0xae); + reg_w1(gspca_dev, 0x01, 0x42); + break; #if 0 /*jfm: from win trace */ - case BRIDGE_SN9C120: + case SENSOR_OV7660: reg_w1(gspca_dev, 0x01, 0x61); reg_w1(gspca_dev, 0x17, 0x20); reg_w1(gspca_dev, 0x01, 0x60); break; #endif - case BRIDGE_SN9C325: - reg_w1(gspca_dev, 0x01, 0x43); - reg_w1(gspca_dev, 0x17, 0xae); - reg_w1(gspca_dev, 0x01, 0x42); - break; default: reg_w1(gspca_dev, 0x01, 0x43); reg_w1(gspca_dev, 0x17, 0x61); reg_w1(gspca_dev, 0x01, 0x42); - } - - if (sd->sensor == SENSOR_HV7131R) { - if (probesensor(gspca_dev) < 0) - return -ENODEV; + if (sd->sensor == SENSOR_HV7131R) { + if (probesensor(gspca_dev) < 0) + return -ENODEV; + } + break; } return 0; } @@ -757,6 +813,16 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev) } } +static void om6802_InitSensor(struct gspca_dev *gspca_dev) +{ + int i = 0; + + while (om6802_sensor_init[i][0]) { + i2c_w8(gspca_dev, om6802_sensor_init[i]); + i++; + } +} + static void ov7648_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; @@ -916,6 +982,20 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, | ((expoMo10[3] & 0x30) >> 4)); break; } + case SENSOR_OM6802: { + __u8 gainOm[] = + { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; + + if (expo > 0x03ff) + expo = 0x03ff; + if (expo < 0x0001) + expo = 0x0001; + gainOm[3] = expo >> 2; + i2c_w8(gspca_dev, gainOm); + reg_w1(gspca_dev, 0x96, expo >> 5); + PDEBUG(D_CONF, "set exposure %d", gainOm[3]); + break; + } } return expo; } @@ -926,6 +1006,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) unsigned int expo; __u8 k2; + k2 = sd->brightness >> 10; switch (sd->sensor) { case SENSOR_HV7131R: expo = sd->brightness << 4; @@ -940,9 +1021,13 @@ static void setbrightness(struct gspca_dev *gspca_dev) expo = sd->brightness >> 4; sd->exposure = setexposure(gspca_dev, expo); break; + case SENSOR_OM6802: + expo = sd->brightness >> 6; + sd->exposure = setexposure(gspca_dev, expo); + k2 = sd->brightness >> 11; + break; } - k2 = sd->brightness >> 10; reg_w1(gspca_dev, 0x96, k2); } @@ -1080,6 +1165,11 @@ static void sd_start(struct gspca_dev *gspca_dev) /* reg1 = 0x06; * 640 clk 24Mz (done) */ } break; + case SENSOR_OM6802: + om6802_InitSensor(gspca_dev); + reg1 = 0x46; /* 640 clk 24Mz */ + reg17 = 0x64; /* 640 MCKSIZE */ + break; case SENSOR_OV7648: ov7648_InitSensor(gspca_dev); reg17 = 0xa2; @@ -1211,6 +1301,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) default: /* case SENSOR_MO4000: */ /* case SENSOR_MI0360: */ +/* case SENSOR_OM6802: */ expotimes = sd->exposure; expotimes += (luma_mean - delta) >> 6; if (expotimes < 0) @@ -1283,7 +1374,8 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) i2c_r5(gspca_dev, 0x09); return (gspca_dev->usb_buf[0] << 8) | gspca_dev->usb_buf[1]; - case SENSOR_MO4000: + default: +/* case SENSOR_MO4000: */ i2c_r5(gspca_dev, 0x0e); hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */ mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */ @@ -1291,7 +1383,8 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) PDEBUG(D_CONF, "exposure %d", (hexpo << 10) | (mexpo << 2) | lexpo); return (hexpo << 10) | (mexpo << 2) | lexpo; - default: +#if 0 /* keep */ +/*jfm: not called*/ /* case SENSOR_OV7648: * jfm: is it ok for 7648? */ /* case SENSOR_OV7660: */ /* read sensor exposure */ @@ -1301,7 +1394,9 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) i2c_r5(gspca_dev, 0x08); mexpo = gspca_dev->usb_buf[2]; return (hexpo << 10) | (mexpo << 2) | lexpo; +#endif } + /* not reached */ } static void getbrightness(struct gspca_dev *gspca_dev) @@ -1314,9 +1409,8 @@ static void getbrightness(struct gspca_dev *gspca_dev) sd->brightness = getexposure(gspca_dev) >> 4; break; case SENSOR_MI0360: - sd->brightness = getexposure(gspca_dev) << 4; - break; case SENSOR_MO4000: + case SENSOR_OM6802: sd->brightness = getexposure(gspca_dev) << 4; break; } @@ -1443,9 +1537,9 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ - {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)}, -/* bw600.inf: - {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */ + {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ +/*bw600.inf:*/ + {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/ {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, /* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ -- cgit v1.2.3 From 68ba76cddf919051dfaf92ad1b0d130a6dfe0b32 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 6 Aug 2008 09:11:18 +0200 Subject: gspca: The bridge/sensor of the webcam 093a:2621 is a PAC 7302. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 431 ++++++++++++++++++++---------- 1 file changed, 294 insertions(+), 137 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 1648c948e..034c00d6c 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -44,6 +44,10 @@ struct sd { char tosof; /* number of bytes before next start of frame */ signed char ag_cnt; #define AG_CNT_START 13 + + __u8 sensor; +#define SENSOR_PAC7302 0 +#define SENSOR_PAC7311 1 }; /* V4L2 controls supported by the driver */ @@ -206,9 +210,158 @@ static const __u8 pac7311_jpeg_header[] = { 0x11, 0x00, 0x3f, 0x00 }; +/* pac 7302 */ +static const __u8 probe_7302[] = { +/* index,value */ + 0xff, 0x01, /* page 1 */ + 0x78, 0x00, /* deactivate */ + 0xff, 0x01, + 0x78, 0x40, /* led off */ +}; +static const __u8 start_7302[] = { +/* index, len, [value]* */ + 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, + 0x00, 0x00, 0x00, 0x00, + 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00, + 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7, + 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11, + 0x26, 2, 0xaa, 0xaa, + 0x2e, 1, 0x31, + 0x38, 1, 0x01, + 0x3a, 3, 0x14, 0xff, 0x5a, + 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, + 0x00, 0x54, 0x11, + 0x55, 1, 0x00, + 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, + 0x6b, 1, 0x00, + 0x6e, 3, 0x08, 0x06, 0x00, + 0x72, 3, 0x00, 0xff, 0x00, + 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c, + 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50, + 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00, + 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9, + 0xd2, 0xeb, + 0xaf, 1, 0x02, + 0xb5, 2, 0x08, 0x08, + 0xb8, 2, 0x08, 0x88, + 0xc4, 4, 0xae, 0x01, 0x04, 0x01, + 0xcc, 1, 0x00, + 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9, + 0xc1, 0xd7, 0xec, + 0xdc, 1, 0x01, + 0xff, 1, 0x01, + 0x12, 3, 0x02, 0x00, 0x01, + 0x3e, 2, 0x00, 0x00, + 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2, + 0x7c, 1, 0x00, + 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20, + 0x02, 0x00, + 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04, + 0xc8, 17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x07, 0x00, 0x01, 0x07, 0x04, 0x01, + 0x01, + 0xdb, 2, 0x00, 0x01, + 0xde, 8, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, + 0xe6, 4, 0x00, 0x00, 0x00, 0x01, + 0xeb, 1, 0x00, + 0xff, 1, 0x02, + 0x22, 1, 0x00, + 0xff, 1, 0x03, + 0x00, 255, /* load the page 3 */ + 0x11, 1, 0x01, + 0xff, 1, 0x02, + 0x13, 1, 0x00, + 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96, + 0x27, 2, 0x14, 0x0c, + 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22, + 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44, + 0x6e, 1, 0x08, + 0xff, 1, 0x03, + 0x78, 1, 0x00, + 0, 0 /* end of sequence */ +}; + +/* page 3 - the value 0xaa says skip the index - see reg_w_page() */ +static const __u8 page3_7302[] = { + 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, + 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, + 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54, + 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8, + 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, + 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00, + 0x00 +}; + +/* pac 7311 */ +static const __u8 probe_7311[] = { + 0x78, 0x40, /* Bit_0=start stream, Bit_7=LED */ + 0x78, 0x40, /* Bit_0=start stream, Bit_7=LED */ + 0x78, 0x44, /* Bit_0=start stream, Bit_7=LED */ + 0xff, 0x04, + 0x27, 0x80, + 0x28, 0xca, + 0x29, 0x53, + 0x2a, 0x0e, + 0xff, 0x01, + 0x3e, 0x20, +}; + +static const __u8 start_7311[] = { +/* index, len, [value]* */ + 0xff, 1, 0x01, + 0x02, 53, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c, + 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x3e, 52, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e, + 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49, + 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48, + 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78, + 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b, + 0xd0, 0xff, + 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80, + 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84, + 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14, + 0x18, 0x20, + 0x96, 3, 0x01, 0x08, 0x04, + 0xa0, 4, 0x44, 0x44, 0x44, 0x04, + 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00, + 0x3f, 0x00, 0x0a, 0x01, 0x00, + 0xff, 1, 0x04, + 0x00, 254, /* load the page 4 */ + 0x11, 1, 0x01, + 0, 0 /* end of sequence */ +}; + +/* page 4 - the value 0xaa says skip the index - see reg_w_page() */ +static const __u8 page4_7311[] = { + 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, + 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62, + 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa, + 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x01, + 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 +}; + static void reg_w_buf(struct gspca_dev *gspca_dev, - __u16 index, - const char *buffer, __u16 len) + __u8 index, + const char *buffer, int len) { memcpy(gspca_dev->usb_buf, buffer, len); usb_control_msg(gspca_dev->dev, @@ -221,7 +374,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, } static __u8 reg_r(struct gspca_dev *gspca_dev, - __u16 index) + __u8 index) { usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), @@ -234,7 +387,7 @@ static __u8 reg_r(struct gspca_dev *gspca_dev, } static void reg_w(struct gspca_dev *gspca_dev, - __u16 index, + __u8 index, __u8 value) { gspca_dev->usb_buf[0] = value; @@ -246,6 +399,74 @@ static void reg_w(struct gspca_dev *gspca_dev, 500); } +static void reg_w_seq(struct gspca_dev *gspca_dev, + const __u8 *seq, int len) +{ + while (--len >= 0) { + reg_w(gspca_dev, seq[0], seq[1]); + seq += 2; + } +} + +/* load the beginning of a page */ +static void reg_w_page(struct gspca_dev *gspca_dev, + const __u8 *page, int len) +{ + int index; + + for (index = 0; index < len; index++) { + if (page[index] == 0xaa) /* skip this index */ + continue; + gspca_dev->usb_buf[0] = page[index]; + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, index, gspca_dev->usb_buf, 1, + 500); + } +} + +/* output a variable sequence */ +static void reg_w_var(struct gspca_dev *gspca_dev, + const __u8 *seq) +{ + int index, len; + + for (;;) { + index = *seq++; + len = *seq++; + switch (len) { + case 0: + return; + case 254: + reg_w_page(gspca_dev, page4_7311, sizeof page4_7311); + break; + case 255: + reg_w_page(gspca_dev, page3_7302, sizeof page3_7302); + break; + default: + if (len > 32) { + PDEBUG(D_ERR|D_STREAM, + "Incorrect variable sequence"); + return; + } + while (len > 0) { + if (len < 8) { + reg_w_buf(gspca_dev, index, seq, len); + seq += len; + break; + } + reg_w_buf(gspca_dev, index, seq, 8); + seq += 8; + index += 8; + len -= 8; + } + } + } + /* not reached */ +} + /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) @@ -253,22 +474,23 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - PDEBUG(D_CONF, "Find Sensor PAC7311"); - reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ - reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ - reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x27, 0x80); - reg_w(gspca_dev, 0x28, 0xca); - reg_w(gspca_dev, 0x29, 0x53); - reg_w(gspca_dev, 0x2a, 0x0e); - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x3e, 0x20); - cam = &gspca_dev->cam; cam->epaddr = 0x05; - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); + + sd->sensor = id->driver_info; + if (sd->sensor == SENSOR_PAC7302) { + PDEBUG(D_CONF, "Find Sensor PAC7302"); + reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302); + + cam->cam_mode = &vga_mode[2]; /* only 640x480 */ + cam->nmodes = 1; + } else { + PDEBUG(D_CONF, "Find Sensor PAC7311"); + reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302); + + cam->cam_mode = vga_mode; + cam->nmodes = ARRAY_SIZE(vga_mode); + } sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; @@ -283,10 +505,11 @@ static void setbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int brightness; + if (sd->sensor == SENSOR_PAC7302) + return; /*jfm: inverted?*/ brightness = BRIGHTNESS_MAX - sd->brightness; reg_w(gspca_dev, 0xff, 0x04); -/* reg_w(gspca_dev, 0x0e, 0x00); */ reg_w(gspca_dev, 0x0f, brightness); /* load registers to sensor (Bit 0, auto clear) */ reg_w(gspca_dev, 0x11, 0x01); @@ -297,6 +520,8 @@ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + if (sd->sensor == SENSOR_PAC7302) + return; reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x80, sd->contrast); /* load registers to sensor (Bit 0, auto clear) */ @@ -308,6 +533,8 @@ static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + if (sd->sensor == SENSOR_PAC7302) + return; reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x10, sd->colors); /* load registers to sensor (Bit 0, auto clear) */ @@ -340,75 +567,12 @@ static void sd_start(struct gspca_dev *gspca_dev) sd->ffnb = 0; sd->tosof = 0; - reg_w(gspca_dev, 0xff, 0x01); - reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); - reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); - reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); - reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); - reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); - reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3); - reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); - reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); - reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); - reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); - reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); - reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2); - reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); - reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); - reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); - reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2); - reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3); - reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4); - reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); - reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); - reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x02, 0x04); - reg_w(gspca_dev, 0x03, 0x54); - reg_w(gspca_dev, 0x04, 0x07); - reg_w(gspca_dev, 0x05, 0x2b); - reg_w(gspca_dev, 0x06, 0x09); - reg_w(gspca_dev, 0x07, 0x0f); - reg_w(gspca_dev, 0x08, 0x09); - reg_w(gspca_dev, 0x09, 0x00); - reg_w(gspca_dev, 0x0c, 0x07); - reg_w(gspca_dev, 0x0d, 0x00); - reg_w(gspca_dev, 0x0e, 0x00); - reg_w(gspca_dev, 0x0f, 0x62); - reg_w(gspca_dev, 0x10, 0x08); - reg_w(gspca_dev, 0x12, 0x07); - reg_w(gspca_dev, 0x13, 0x00); - reg_w(gspca_dev, 0x14, 0x00); - reg_w(gspca_dev, 0x15, 0x00); - reg_w(gspca_dev, 0x16, 0x00); - reg_w(gspca_dev, 0x17, 0x00); - reg_w(gspca_dev, 0x18, 0x00); - reg_w(gspca_dev, 0x19, 0x00); - reg_w(gspca_dev, 0x1a, 0x00); - reg_w(gspca_dev, 0x1b, 0x03); - reg_w(gspca_dev, 0x1c, 0xa0); - reg_w(gspca_dev, 0x1d, 0x01); - reg_w(gspca_dev, 0x1e, 0xf4); - reg_w(gspca_dev, 0x21, 0x00); - reg_w(gspca_dev, 0x22, 0x08); - reg_w(gspca_dev, 0x24, 0x03); - reg_w(gspca_dev, 0x26, 0x00); - reg_w(gspca_dev, 0x27, 0x01); - reg_w(gspca_dev, 0x28, 0xca); - reg_w(gspca_dev, 0x29, 0x10); - reg_w(gspca_dev, 0x2a, 0x06); - reg_w(gspca_dev, 0x2b, 0x78); - reg_w(gspca_dev, 0x2c, 0x00); - reg_w(gspca_dev, 0x2d, 0x00); - reg_w(gspca_dev, 0x2e, 0x00); - reg_w(gspca_dev, 0x2f, 0x00); - reg_w(gspca_dev, 0x30, 0x23); - reg_w(gspca_dev, 0x31, 0x28); - reg_w(gspca_dev, 0x32, 0x04); - reg_w(gspca_dev, 0x33, 0x11); - reg_w(gspca_dev, 0x34, 0x00); - reg_w(gspca_dev, 0x35, 0x00); - reg_w(gspca_dev, 0x11, 0x01); + if (sd->sensor == SENSOR_PAC7302) + reg_w_var(gspca_dev, start_7302); + else + reg_w_var(gspca_dev, start_7311); + setcontrast(gspca_dev); setbrightness(gspca_dev); setcolors(gspca_dev); @@ -416,7 +580,7 @@ static void sd_start(struct gspca_dev *gspca_dev) /* set correct resolution */ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { - case 2: /* 160x120 */ + case 2: /* 160x120 pac7311 */ reg_w(gspca_dev, 0xff, 0x04); reg_w(gspca_dev, 0x02, 0x03); reg_w(gspca_dev, 0xff, 0x01); @@ -426,7 +590,7 @@ static void sd_start(struct gspca_dev *gspca_dev) /* reg_w(gspca_dev, 0x80, 0x69); */ reg_w(gspca_dev, 0x87, 0x10); break; - case 1: /* 320x240 */ + case 1: /* 320x240 pac7311 */ reg_w(gspca_dev, 0xff, 0x04); reg_w(gspca_dev, 0x02, 0x03); reg_w(gspca_dev, 0xff, 0x01); @@ -436,6 +600,8 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x87, 0x11); break; case 0: /* 640x480 */ + if (sd->sensor == SENSOR_PAC7302) + break; reg_w(gspca_dev, 0xff, 0x04); reg_w(gspca_dev, 0x02, 0x03); reg_w(gspca_dev, 0xff, 0x01); @@ -448,12 +614,25 @@ static void sd_start(struct gspca_dev *gspca_dev) /* start stream */ reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x04); - reg_w(gspca_dev, 0x78, 0x05); + if (sd->sensor == SENSOR_PAC7302) { + reg_w(gspca_dev, 0x78, 0x01); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x78, 0x01); + } else { + reg_w(gspca_dev, 0x78, 0x04); + reg_w(gspca_dev, 0x78, 0x05); + } } static void sd_stopN(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->sensor == SENSOR_PAC7302) { + reg_w(gspca_dev, 0x78, 0x00); + reg_w(gspca_dev, 0x78, 0x00); + return; + } reg_w(gspca_dev, 0xff, 0x04); reg_w(gspca_dev, 0x27, 0x80); reg_w(gspca_dev, 0x28, 0xca); @@ -468,21 +647,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->sensor == SENSOR_PAC7302) { + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x78, 0x40); + } } /* this function is called at close time */ static void sd_close(struct gspca_dev *gspca_dev) { - reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x27, 0x80); - reg_w(gspca_dev, 0x28, 0xca); - reg_w(gspca_dev, 0x29, 0x53); - reg_w(gspca_dev, 0x2a, 0x0e); - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x3e, 0x20); - reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ } static void do_autogain(struct gspca_dev *gspca_dev) @@ -509,10 +684,17 @@ static void do_autogain(struct gspca_dev *gspca_dev) else if (Gbright < 4) Gbright = 4; PDEBUG(D_FRAM, "gbright %d", Gbright); - reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x0f, Gbright); - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); + if (sd->sensor == SENSOR_PAC7302) { + reg_w(gspca_dev, 0xff, 0x03); + reg_w(gspca_dev, 0x10, Gbright); + /* load registers to sensor (Bit 0, auto clear) */ + reg_w(gspca_dev, 0x11, 0x01); + } else { + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x0f, Gbright); + /* load registers to sensor (Bit 0, auto clear) */ + reg_w(gspca_dev, 0x11, 0x01); + } } } @@ -636,28 +818,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } -static void getbrightness(struct gspca_dev *gspca_dev) -{ -/* sd->brightness = reg_r(gspca_dev, 0x08); - return sd->brightness; */ -/* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */ -} - -#if 0 -static void getcontrast(struct gspca_dev *gspca_dev) -{ -/* sd->contrast = reg_r(gspca_dev, 0x0e); - return sd->contrast; */ - PDEBUG(D_CONF, "getcontrast: Not implemented yet"); -} -#endif - -#if 0 -static void getcolors(struct gspca_dev *gspca_dev) -{ -} -#endif - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -672,7 +832,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -691,7 +850,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; -/* getcontrast(gspca_dev); */ *val = sd->contrast; return 0; } @@ -710,7 +868,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; -/* getcolors(gspca_dev); */ *val = sd->colors; return 0; } @@ -750,13 +907,13 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ static __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x093a, 0x2600)}, - {USB_DEVICE(0x093a, 0x2601)}, - {USB_DEVICE(0x093a, 0x2603)}, - {USB_DEVICE(0x093a, 0x2608)}, - {USB_DEVICE(0x093a, 0x260e)}, - {USB_DEVICE(0x093a, 0x260f)}, - {USB_DEVICE(0x093a, 0x2621)}, + {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311}, + {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311}, + {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311}, + {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311}, + {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311}, + {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311}, + {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From ff61b2c483facc6fd274ef18e96f60de9b2af4e4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 6 Aug 2008 15:45:38 +0200 Subject: gspca: Fix the 640x480 resolution of the webcam 093a:2621. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 953f17809..7b5b92094 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1167,7 +1167,6 @@ static void sd_start(struct gspca_dev *gspca_dev) break; case SENSOR_OM6802: om6802_InitSensor(gspca_dev); - reg1 = 0x46; /* 640 clk 24Mz */ reg17 = 0x64; /* 640 MCKSIZE */ break; case SENSOR_OV7648: -- cgit v1.2.3 From 387f6919b61c886b36fea9568a6ad6e0842c2e6f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Aug 2008 18:26:25 +0200 Subject: ivtv: update ivtv version number From: Hans Verkuil Since for 2.6.27 ivtvfb uses DMA for write it is important that you can identify which ivtv version supports this and which doesn't. Increase the version number so we can tell the difference. Thanks to Ian Armstrong for pointing this out to me. Priority: high Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/ivtv/ivtv-version.h b/linux/drivers/media/video/ivtv/ivtv-version.h index 442f43f11..8cd753d30 100644 --- a/linux/drivers/media/video/ivtv/ivtv-version.h +++ b/linux/drivers/media/video/ivtv/ivtv-version.h @@ -22,7 +22,7 @@ #define IVTV_DRIVER_NAME "ivtv" #define IVTV_DRIVER_VERSION_MAJOR 1 -#define IVTV_DRIVER_VERSION_MINOR 3 +#define IVTV_DRIVER_VERSION_MINOR 4 #define IVTV_DRIVER_VERSION_PATCHLEVEL 0 #define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL) -- cgit v1.2.3 From 3152cfe67c96844ba8c651a064533925c09107b8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 8 Aug 2008 07:59:04 +0200 Subject: gspca: Bad scanning of frames in pac7311. From: Jean-Francois Moine The previous change in packet scanning did not work, Also, autogain was no more treated at interrupt level. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 33 +++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 034c00d6c..730b4a1ae 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -702,8 +702,16 @@ static void do_autogain(struct gspca_dev *gspca_dev) static void put_jpeg_head(struct gspca_dev *gspca_dev, struct gspca_frame *frame) { + struct sd *sd = (struct sd *) gspca_dev; unsigned char tmpbuf[4]; + if (sd->ag_cnt >= 0) { + if (--sd->ag_cnt < 0) { + sd->ag_cnt = AG_CNT_START; + atomic_set(&sd->avg_lum, sd->lum_sum / AG_CNT_START); + atomic_set(&sd->do_gain, 1); + } + } gspca_frame_add(gspca_dev, FIRST_PACKET, frame, (__u8 *) pac7311_jpeg_header, 12); @@ -727,7 +735,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; int i; -#define INTER_FRAME 0x53 +#define INTER_FRAME 0x53 /* eof + inter frame + sof */ #define LUM_OFFSET 0x1e /* reverse offset / start of frame */ /* @@ -746,11 +754,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (sd->tosof == 0) { /* if inside a frame */ /* check for 'ff ff ff xx' at start and at end of packet */ - /* (len is always >= 3) */ + /* (len is always >= 3 and xx never ff) */ switch (sd->ffnb) { case 1: - if (data[0] != 0xff) + if (data[0] != 0xff) { /* can be '00' only */ + __u8 ff; + + sd->ffnb = 0; + ff = 0xff; + gspca_frame_add(gspca_dev, INTER_PACKET, + frame, &ff, 1); break; /* keep 'ff 00' */ + } /* fall thru */ case 2: case 3: @@ -775,16 +790,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } else { /* outside a frame */ - /* - * get the luminosity - * and go to the start of frame - */ + /* get the luminosity and go to the start of frame */ data += sd->tosof; len -= sd->tosof; if (sd->tosof > LUM_OFFSET) sd->lum_sum += data[-LUM_OFFSET]; - put_jpeg_head(gspca_dev, frame); sd->tosof = 0; + put_jpeg_head(gspca_dev, frame); } for (i = 0; i < len; i++) { @@ -792,10 +804,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, continue; switch (data[i + 1]) { case 0xd9: /* end of frame */ - i += 2; frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, i); + frame, data, i + 2); data += i + INTER_FRAME; len -= i + INTER_FRAME; i = 0; @@ -816,6 +827,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, break; } } + gspca_frame_add(gspca_dev, INTER_PACKET, + frame, data, i); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) -- cgit v1.2.3 From 84139cb9cd6b39f5bad49011990738d7a985e249 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 8 Aug 2008 09:31:36 +0200 Subject: gspca: Bad probe of Z-Star/Vimicro webcams with pas106 sensor. From: Hans de Goede This patch moves the detection of the 2wr SIF pas106b sensor to before detecting other sensors. Patch change by jfm: Check SIF for identified webcams only. Priority: normal Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/zc3xx.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index ff0c30e4a..468b01b8f 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -6969,8 +6969,13 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev) case SENSOR_MC501CB: return -1; /* don't probe */ case SENSOR_TAS5130C_VF0250: - /* may probe but with write in reg 0x0010 */ + /* may probe but with no write in reg 0x0010 */ return -1; /* don't probe */ + case SENSOR_PAS106: + sensor = sif_probe(gspca_dev); + if (sensor >= 0) + return sensor; + break; } sensor = vga_2wr_probe(gspca_dev); if (sensor >= 0) { @@ -6979,12 +6984,10 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev) /* next probe is needed for OmniVision ? */ } sensor2 = vga_3wr_probe(gspca_dev); - if (sensor2 >= 0) { - if (sensor >= 0) - return sensor; - return sensor2; - } - return sif_probe(gspca_dev); + if (sensor2 >= 0 + && sensor >= 0) + return sensor; + return sensor2; } /* this function is called at probe time */ @@ -7514,14 +7517,14 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x041e)}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x041e, 0x4017)}, - {USB_DEVICE(0x041e, 0x401c)}, + {USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106}, {USB_DEVICE(0x041e, 0x401e)}, {USB_DEVICE(0x041e, 0x401f)}, #endif {USB_DEVICE(0x041e, 0x4029)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x041e, 0x4034)}, - {USB_DEVICE(0x041e, 0x4035)}, + {USB_DEVICE(0x041e, 0x4034), .driver_info = SENSOR_PAS106}, + {USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106}, {USB_DEVICE(0x041e, 0x4036)}, {USB_DEVICE(0x041e, 0x403a)}, #endif @@ -7553,10 +7556,10 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x08d8)}, {USB_DEVICE(0x046d, 0x08da)}, {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, - {USB_DEVICE(0x0471, 0x0325)}, - {USB_DEVICE(0x0471, 0x0326)}, - {USB_DEVICE(0x0471, 0x032d)}, - {USB_DEVICE(0x0471, 0x032e)}, + {USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106}, + {USB_DEVICE(0x0471, 0x0326), .driver_info = SENSOR_PAS106}, + {USB_DEVICE(0x0471, 0x032d), .driver_info = SENSOR_PAS106}, + {USB_DEVICE(0x0471, 0x032e), .driver_info = SENSOR_PAS106}, {USB_DEVICE(0x055f, 0xc005)}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x055f, 0xd003)}, -- cgit v1.2.3 From edde91472f7b6a4ef4f8ea24f52a451b0650ccc4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 8 Aug 2008 09:35:25 +0200 Subject: gspca: Conflict GSPCA / ET61X251 for the webcam 102c:6251. From: Jean-Francois Moine Fix a double handling of 102c:6251 and no handling of 102c:6151 when both drivers GSPCA and ET61X251. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/etoms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index 60b316a37..a9d043606 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -910,10 +910,10 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ static __devinitdata struct usb_device_id device_table[] = { -#ifndef CONFIG_USB_ET61X251 {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, -#endif +#ifndef CONFIG_USB_ET61X251 {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, +#endif {} }; -- cgit v1.2.3 From ffc47339c2962593817aaa4015789dd7e6374981 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 8 Aug 2008 12:08:29 +0200 Subject: gspca: Add white balance control for spca561 rev 012A. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 110 +++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 18 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 1073ac3d2..02e274452 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -34,6 +34,7 @@ struct sd { unsigned short contrast; __u8 brightness; + __u8 white; __u8 autogain; __u8 chip_revision; @@ -46,11 +47,12 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -59,12 +61,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 63, .step = 1, - .default_value = 32, +#define BRIGHTNESS_DEF 32 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -73,12 +75,26 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 0x3fff, .step = 1, - .default_value = 0x2000, +#define CONTRAST_DEF 0x2000 + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_AUTOGAIN 2 + { + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "While Balance", + .minimum = 0, + .maximum = 0x7f, + .step = 1, +#define WHITE_DEF 40 + .default_value = WHITE_DEF, + }, + .set = sd_setwhite, + .get = sd_getwhite, + }, { { .id = V4L2_CID_AUTOGAIN, @@ -87,7 +103,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 1, +#define AUTOGAIN_DEF 1 + .default_value = AUTOGAIN_DEF, }, .set = sd_setautogain, .get = sd_getautogain, @@ -438,7 +455,7 @@ static const __u16 spca561_init_data[][2] = { {0x0035, 0x8801}, /* 0x14 - set gain general */ {0x001f, 0x8805}, /* 0x14 */ {0x0000, 0x8800}, - {0x0030, 0x8112}, + {0x000e, 0x8112}, /* white balance - was 30 */ {} }; @@ -478,9 +495,10 @@ static const __u16 Pb100_2map8300[][2] = { }; static const __u16 spca561_161rev12A_data1[][2] = { - {0x21, 0x8118}, - {0x01, 0x8114}, - {0x00, 0x8112}, + {0x29, 0x8118}, /* white balance - was 21 */ + {0x08, 0x8114}, /* white balance - was 01 */ + {0x0e, 0x8112}, /* white balance - was 00 */ + {0x00, 0x8102}, /* white balance - new */ {0x92, 0x8804}, {0x04, 0x8802}, /* windows uses 08 */ {} @@ -505,14 +523,16 @@ static const __u16 spca561_161rev12A_data2[][2] = { {0xb0, 0x8603}, /* sensor gains */ + {0x07, 0x8601}, /* white balance - new */ + {0x07, 0x8602}, /* white balance - new */ {0x00, 0x8610}, /* *red */ {0x00, 0x8611}, /* 3f *green */ {0x00, 0x8612}, /* green *blue */ {0x00, 0x8613}, /* blue *green */ - {0x35, 0x8614}, /* green *red */ - {0x35, 0x8615}, /* 40 *green */ - {0x35, 0x8616}, /* 7a *blue */ - {0x35, 0x8617}, /* 40 *green */ + {0x43, 0x8614}, /* green *red - white balance - was 0x35 */ + {0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */ + {0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */ + {0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */ {0x0c, 0x8620}, /* 0c */ {0xc8, 0x8631}, /* c8 */ @@ -527,6 +547,7 @@ static const __u16 spca561_161rev12A_data2[][2] = { {0xdf, 0x863c}, /* df */ {0xf0, 0x8505}, {0x32, 0x850a}, + {0x99, 0x8700}, /* - white balance - new */ {} }; @@ -588,9 +609,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; sd->chip_revision = id->driver_info; - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->autogain = AUTOGAIN_DEF; + sd->white = WHITE_DEF; return 0; } @@ -628,15 +650,18 @@ static void setcontrast(struct gspca_dev *gspca_dev) reg_w_val(dev, lowb, 0x8653); reg_w_val(dev, lowb, 0x8654); break; - case Rev012A: { + default: { +/* case Rev012A: { */ __u8 Reg8391[] = { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; /* Write camera sensor settings */ expotimes = (sd->contrast >> 5) & 0x07ff; + /* exposure is in 8309 2b, range 0120 - 5720 */ Reg8391[0] = expotimes & 0xff; /* exposure */ Reg8391[1] = 0x18 | (expotimes >> 8); Reg8391[2] = sd->brightness; /* gain */ + /* gain in 8335, 2b range 0000 - 2400 */ reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); break; @@ -644,6 +669,34 @@ static void setcontrast(struct gspca_dev *gspca_dev) } } +static void setwhite(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u16 white; + __u8 reg8614, reg8616; + + switch (sd->chip_revision) { + case Rev072A: + /* no such hardware */ + break; + default: +/* case Rev012A: */ + white = sd->white; + if (sd->white == 0) { + PDEBUG(D_CONF, "Discarding null whiteness"); + break; + } + /* try to emulate MS-win as possible */ + if (white < 0x45) + reg8616 = white; + else + reg8616 = 0x93 + (white >> 2); + reg8614 = 0x28 + (white >> 4); + reg_w_val(gspca_dev->dev, reg8616, 0x8616); + reg_w_val(gspca_dev->dev, reg8614, 0x8614); + } +} + static void setautogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -714,6 +767,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); reg_w_val(gspca_dev->dev, 0x850b, 0x03); setcontrast(gspca_dev); + setwhite(gspca_dev); break; } } @@ -721,6 +775,7 @@ static void sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { reg_w_val(gspca_dev->dev, 0x8112, 0x20); + reg_w_val(gspca_dev->dev, 0x8102, 0x00); /* white balance - new */ } static void sd_stop0(struct gspca_dev *gspca_dev) @@ -968,6 +1023,25 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +/* white balance - new */ +static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->white = val; + if (gspca_dev->streaming) + setwhite(gspca_dev); + return 0; +} + +static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->white; + return 0; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, -- cgit v1.2.3 From a938ca9971031bb3895c624e6bc26d92da85a960 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Aug 2008 12:21:00 +0200 Subject: v4l2: extend MPEG Encoding API with AVC and AAC From: Janne Grunau Adds Advanced Audio Coding (AAC) and MPEG-4 Advanced Video Coding (AVC/H.264) as audio/video codecs to the extended controls API. Updates cx2341x driver to the new values. Priority: normal Signed-off-by: Janne Grunau Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx2341x.c | 5 ++++- linux/drivers/media/video/v4l2-common.c | 14 ++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx2341x.c b/linux/drivers/media/video/cx2341x.c index 835062f5b..f31f11e3f 100644 --- a/linux/drivers/media/video/cx2341x.c +++ b/linux/drivers/media/video/cx2341x.c @@ -509,7 +509,10 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, /* this setting is read-only for the cx2341x since the V4L2_CID_MPEG_STREAM_TYPE really determines the MPEG-1/2 setting */ - err = v4l2_ctrl_query_fill_std(qctrl); + err = v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_VIDEO_ENCODING_MPEG_1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2); if (err == 0) qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; return err; diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index a027d9baa..486897b29 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -188,9 +188,10 @@ const char **v4l2_ctrl_get_menu(u32 id) NULL }; static const char *mpeg_audio_encoding[] = { - "Layer I", - "Layer II", - "Layer III", + "MPEG-1 Layer I", + "MPEG-1 Layer II", + "MPEG-1 Layer III", + "MPEG-4 AAC", NULL }; static const char *mpeg_audio_l1_bitrate[] = { @@ -272,6 +273,7 @@ const char **v4l2_ctrl_get_menu(u32 id) static const char *mpeg_video_encoding[] = { "MPEG-1", "MPEG-2", + "MPEG-4 AVC", NULL }; static const char *mpeg_video_aspect[] = { @@ -359,7 +361,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste /* MPEG controls */ case V4L2_CID_MPEG_CLASS: name = "MPEG Encoder Controls"; break; case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: name = "Audio Sampling Frequency"; break; - case V4L2_CID_MPEG_AUDIO_ENCODING: name = "Audio Encoding Layer"; break; + case V4L2_CID_MPEG_AUDIO_ENCODING: name = "Audio Encoding"; break; case V4L2_CID_MPEG_AUDIO_L1_BITRATE: name = "Audio Layer I Bitrate"; break; case V4L2_CID_MPEG_AUDIO_L2_BITRATE: name = "Audio Layer II Bitrate"; break; case V4L2_CID_MPEG_AUDIO_L3_BITRATE: name = "Audio Layer III Bitrate"; break; @@ -494,7 +496,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) case V4L2_CID_MPEG_AUDIO_ENCODING: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_ENCODING_LAYER_1, - V4L2_MPEG_AUDIO_ENCODING_LAYER_3, 1, + V4L2_MPEG_AUDIO_ENCODING_AAC, 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2); case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return v4l2_ctrl_query_fill(qctrl, @@ -536,7 +538,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) case V4L2_CID_MPEG_VIDEO_ENCODING: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_VIDEO_ENCODING_MPEG_1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1, V4L2_MPEG_VIDEO_ENCODING_MPEG_2); case V4L2_CID_MPEG_VIDEO_ASPECT: return v4l2_ctrl_query_fill(qctrl, -- cgit v1.2.3 From 12a7cf3b8b955b3d1e47e82b00515f9e3d00d91e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Aug 2008 12:38:07 +0200 Subject: v4l: add AC-3 audio support to the MPEG Encoding API From: Hans Verkuil Some models of the saa6752hs support AC-3. Extend the API with the necessary controls for AC-3. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-common.c | 42 +++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 486897b29..2559630df 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -188,10 +188,11 @@ const char **v4l2_ctrl_get_menu(u32 id) NULL }; static const char *mpeg_audio_encoding[] = { - "MPEG-1 Layer I", - "MPEG-1 Layer II", - "MPEG-1 Layer III", - "MPEG-4 AAC", + "MPEG-1/2 Layer I", + "MPEG-1/2 Layer II", + "MPEG-1/2 Layer III", + "MPEG-2/4 AAC", + "AC-3", NULL }; static const char *mpeg_audio_l1_bitrate[] = { @@ -245,6 +246,28 @@ const char **v4l2_ctrl_get_menu(u32 id) "320 kbps", NULL }; + static const char *mpeg_audio_ac3_bitrate[] = { + "32 kbps", + "40 kbps", + "48 kbps", + "56 kbps", + "64 kbps", + "80 kbps", + "96 kbps", + "112 kbps", + "128 kbps", + "160 kbps", + "192 kbps", + "224 kbps", + "256 kbps", + "320 kbps", + "384 kbps", + "448 kbps", + "512 kbps", + "576 kbps", + "640 kbps", + NULL + }; static const char *mpeg_audio_mode[] = { "Stereo", "Joint Stereo", @@ -314,6 +337,8 @@ const char **v4l2_ctrl_get_menu(u32 id) return mpeg_audio_l2_bitrate; case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return mpeg_audio_l3_bitrate; + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + return mpeg_audio_ac3_bitrate; case V4L2_CID_MPEG_AUDIO_MODE: return mpeg_audio_mode; case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: @@ -365,6 +390,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_MPEG_AUDIO_L1_BITRATE: name = "Audio Layer I Bitrate"; break; case V4L2_CID_MPEG_AUDIO_L2_BITRATE: name = "Audio Layer II Bitrate"; break; case V4L2_CID_MPEG_AUDIO_L3_BITRATE: name = "Audio Layer III Bitrate"; break; + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: name = "Audio AC-3 Bitrate"; break; case V4L2_CID_MPEG_AUDIO_MODE: name = "Audio Stereo Mode"; break; case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break; case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break; @@ -410,6 +436,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_MPEG_AUDIO_L1_BITRATE: case V4L2_CID_MPEG_AUDIO_L2_BITRATE: case V4L2_CID_MPEG_AUDIO_L3_BITRATE: + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: case V4L2_CID_MPEG_AUDIO_MODE: case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: case V4L2_CID_MPEG_AUDIO_EMPHASIS: @@ -496,7 +523,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) case V4L2_CID_MPEG_AUDIO_ENCODING: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_ENCODING_LAYER_1, - V4L2_MPEG_AUDIO_ENCODING_AAC, 1, + V4L2_MPEG_AUDIO_ENCODING_AC3, 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2); case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return v4l2_ctrl_query_fill(qctrl, @@ -513,6 +540,11 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) V4L2_MPEG_AUDIO_L3_BITRATE_32K, V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1, V4L2_MPEG_AUDIO_L3_BITRATE_192K); + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_AC3_BITRATE_32K, + V4L2_MPEG_AUDIO_AC3_BITRATE_640K, 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K); case V4L2_CID_MPEG_AUDIO_MODE: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_MODE_STEREO, -- cgit v1.2.3 From 7e060a1f1573031a7925ebba3789faf730c97ecb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Aug 2008 12:55:00 +0200 Subject: v4l2: add v4l2_ctrl_get_name control support function. From: Hans Verkuil Add function that returns the control name. Allows this to be used in places where the normal v4l2_ctrl_query_fill() function cannot be used (e.g. uvc). Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-common.c | 109 +++++++++++++++++--------------- 1 file changed, 59 insertions(+), 50 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 2559630df..596b66e30 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -363,63 +363,72 @@ const char **v4l2_ctrl_get_menu(u32 id) } EXPORT_SYMBOL(v4l2_ctrl_get_menu); -/* Fill in a struct v4l2_queryctrl */ -int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) +/* Return the control name. */ +const char *v4l2_ctrl_get_name(u32 id) { - const char *name; - - qctrl->flags = 0; - switch (qctrl->id) { + switch (id) { /* USER controls */ - case V4L2_CID_USER_CLASS: name = "User Controls"; break; - case V4L2_CID_AUDIO_VOLUME: name = "Volume"; break; - case V4L2_CID_AUDIO_MUTE: name = "Mute"; break; - case V4L2_CID_AUDIO_BALANCE: name = "Balance"; break; - case V4L2_CID_AUDIO_BASS: name = "Bass"; break; - case V4L2_CID_AUDIO_TREBLE: name = "Treble"; break; - case V4L2_CID_AUDIO_LOUDNESS: name = "Loudness"; break; - case V4L2_CID_BRIGHTNESS: name = "Brightness"; break; - case V4L2_CID_CONTRAST: name = "Contrast"; break; - case V4L2_CID_SATURATION: name = "Saturation"; break; - case V4L2_CID_HUE: name = "Hue"; break; + case V4L2_CID_USER_CLASS: return "User Controls"; + case V4L2_CID_AUDIO_VOLUME: return "Volume"; + case V4L2_CID_AUDIO_MUTE: return "Mute"; + case V4L2_CID_AUDIO_BALANCE: return "Balance"; + case V4L2_CID_AUDIO_BASS: return "Bass"; + case V4L2_CID_AUDIO_TREBLE: return "Treble"; + case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; + case V4L2_CID_BRIGHTNESS: return "Brightness"; + case V4L2_CID_CONTRAST: return "Contrast"; + case V4L2_CID_SATURATION: return "Saturation"; + case V4L2_CID_HUE: return "Hue"; /* MPEG controls */ - case V4L2_CID_MPEG_CLASS: name = "MPEG Encoder Controls"; break; - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: name = "Audio Sampling Frequency"; break; - case V4L2_CID_MPEG_AUDIO_ENCODING: name = "Audio Encoding"; break; - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: name = "Audio Layer I Bitrate"; break; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: name = "Audio Layer II Bitrate"; break; - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: name = "Audio Layer III Bitrate"; break; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: name = "Audio AC-3 Bitrate"; break; - case V4L2_CID_MPEG_AUDIO_MODE: name = "Audio Stereo Mode"; break; - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break; - case V4L2_CID_MPEG_AUDIO_CRC: name = "Audio CRC"; break; - case V4L2_CID_MPEG_AUDIO_MUTE: name = "Audio Mute"; break; - case V4L2_CID_MPEG_VIDEO_ENCODING: name = "Video Encoding"; break; - case V4L2_CID_MPEG_VIDEO_ASPECT: name = "Video Aspect"; break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: name = "Video B Frames"; break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: name = "Video GOP Size"; break; - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: name = "Video GOP Closure"; break; - case V4L2_CID_MPEG_VIDEO_PULLDOWN: name = "Video Pulldown"; break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: name = "Video Bitrate Mode"; break; - case V4L2_CID_MPEG_VIDEO_BITRATE: name = "Video Bitrate"; break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: name = "Video Peak Bitrate"; break; - case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: name = "Video Temporal Decimation"; break; - case V4L2_CID_MPEG_VIDEO_MUTE: name = "Video Mute"; break; - case V4L2_CID_MPEG_VIDEO_MUTE_YUV: name = "Video Mute YUV"; break; - case V4L2_CID_MPEG_STREAM_TYPE: name = "Stream Type"; break; - case V4L2_CID_MPEG_STREAM_PID_PMT: name = "Stream PMT Program ID"; break; - case V4L2_CID_MPEG_STREAM_PID_AUDIO: name = "Stream Audio Program ID"; break; - case V4L2_CID_MPEG_STREAM_PID_VIDEO: name = "Stream Video Program ID"; break; - case V4L2_CID_MPEG_STREAM_PID_PCR: name = "Stream PCR Program ID"; break; - case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: name = "Stream PES Audio ID"; break; - case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: name = "Stream PES Video ID"; break; - case V4L2_CID_MPEG_STREAM_VBI_FMT: name = "Stream VBI Format"; break; + case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency"; + case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding"; + case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate"; + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate"; + case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate"; + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; + case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode"; + case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension"; + case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis"; + case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC"; + case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute"; + case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding"; + case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect"; + case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames"; + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size"; + case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure"; + case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown"; + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode"; + case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate"; + case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate"; + case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation"; + case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute"; + case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; + case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type"; + case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID"; + case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID"; + case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID"; + case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID"; + case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID"; + case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID"; + case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format"; default: - return -EINVAL; + return NULL; } +} +EXPORT_SYMBOL(v4l2_ctrl_get_name); + +/* Fill in a struct v4l2_queryctrl */ +int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) +{ + const char *name = v4l2_ctrl_get_name(qctrl->id); + + qctrl->flags = 0; + if (name == NULL) + return -EINVAL; + switch (qctrl->id) { case V4L2_CID_AUDIO_MUTE: case V4L2_CID_AUDIO_LOUDNESS: -- cgit v1.2.3 From c43087924dbe5c50c0198979ed5a40e3e00c3bab Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Aug 2008 13:34:19 +0200 Subject: v4l2: add v4l2_ctrl_query_menu_valid_items support function From: Hans Verkuil v4l2_ctrl_query_menu_valid_items() makes it easy to handle control menus that have a lot of invalid 'holes'. For example, many MPEG encoders only support a limited subset of audio bitrates. In that case a driver can specify an array listing the set of valid bitrates and pass that to this function. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-common.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 596b66e30..8dfe3cb8b 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -644,6 +644,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc { int i; + qmenu->reserved = 0; if (menu_items == NULL || (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum))) return -EINVAL; @@ -651,11 +652,31 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc if (menu_items[i] == NULL || menu_items[i][0] == '\0') return -EINVAL; snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]); - qmenu->reserved = 0; return 0; } EXPORT_SYMBOL(v4l2_ctrl_query_menu); +/* Fill in a struct v4l2_querymenu based on the specified array of valid + menu items (terminated by V4L2_CTRL_MENU_IDS_END). + Use this if there are 'holes' in the list of valid menu items. */ +int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids) +{ + const char **menu_items = v4l2_ctrl_get_menu(qmenu->id); + + qmenu->reserved = 0; + if (menu_items == NULL || ids == NULL) + return -EINVAL; + while (*ids != V4L2_CTRL_MENU_IDS_END) { + if (*ids++ == qmenu->index) { + snprintf(qmenu->name, sizeof(qmenu->name), + menu_items[qmenu->index]); + return 0; + } + } + return -EINVAL; +} +EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items); + /* ctrl_classes points to an array of u32 pointers, the last element is a NULL pointer. Each u32 array is a 0-terminated array of control IDs. Each array must be sorted low to high and belong to the same control -- cgit v1.2.3 From 318078c04d44e4f178e788c083c76aea7180a084 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Aug 2008 17:43:59 +0200 Subject: saa6752hs: cleanup and add AC-3 support From: Hans Verkuil Cleaned up the saa6752hs i2c driver. Add AC-3 support. Add VIDIOC_CHIP_IDENT support. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7134/saa6752hs.c | 269 +++++++++++++-------- .../drivers/media/video/saa7134/saa7134-empress.c | 22 +- linux/drivers/media/video/v4l2-common.c | 6 +- 3 files changed, 194 insertions(+), 103 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/saa7134/saa6752hs.c b/linux/drivers/media/video/saa7134/saa6752hs.c index c5c19a2e3..42c5d1f76 100644 --- a/linux/drivers/media/video/saa7134/saa6752hs.c +++ b/linux/drivers/media/video/saa7134/saa6752hs.c @@ -1,3 +1,27 @@ + /* + saa6752hs - i2c-driver for the saa6752hs by Philips + + Copyright (C) 2004 Andrew de Quincey + + AC-3 support: + + Copyright (C) 2008 Hans Verkuil + + 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 #include #include @@ -11,6 +35,8 @@ #include "compat.h" #include #include +#include +#include #include #include @@ -28,9 +54,6 @@ MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); MODULE_AUTHOR("Andrew de Quincey"); MODULE_LICENSE("GPL"); -static struct i2c_driver driver; -static struct i2c_client client_template; - enum saa6752hs_videoformat { SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */ SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */ @@ -47,7 +70,9 @@ struct saa6752hs_mpeg_params { __u16 ts_pid_pcr; /* audio */ - enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; + 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; @@ -71,7 +96,9 @@ static const struct v4l2_format v4l2_format_table[] = }; struct saa6752hs_state { - struct i2c_client client; + int chip; + u32 revision; + int has_ac3; struct saa6752hs_mpeg_params params; enum saa6752hs_videoformat video_format; v4l2_std_id standard; @@ -158,7 +185,9 @@ static struct saa6752hs_mpeg_params param_defaults = .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_384K, }; /* ---------------------------------------------------------------------- */ @@ -231,8 +260,9 @@ static int saa6752hs_chip_command(struct i2c_client* client, static int saa6752hs_set_bitrate(struct i2c_client* client, - struct saa6752hs_mpeg_params* params) + struct saa6752hs_state *h) { + struct saa6752hs_mpeg_params *params = &h->params; u8 buf[3]; int tot_bitrate; @@ -264,11 +294,22 @@ static int saa6752hs_set_bitrate(struct i2c_client* client, tot_bitrate = params->vi_bitrate; } + /* set the audio encoding */ + buf[0] = 0x93; + if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) + buf[1] = 1; + else + buf[1] = 0; + i2c_master_send(client, buf, 2); + /* set the audio bitrate */ buf[0] = 0x94; - buf[1] = (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 0 : 1; + if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) + buf[1] = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate; + else + buf[1] = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate; + tot_bitrate += buf[1] ? 384 : 256; i2c_master_send(client, buf, 2); - tot_bitrate += (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 256 : 384; /* 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 @@ -333,7 +374,7 @@ static void saa6752hs_set_subsampling(struct i2c_client* client, } -static int handle_ctrl(struct saa6752hs_mpeg_params *params, +static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, struct v4l2_ext_control *ctrl, unsigned int cmd) { int old = 0, new; @@ -380,8 +421,9 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params, params->ts_pid_pcr = new; break; case V4L2_CID_MPEG_AUDIO_ENCODING: - old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; - if (set && new != old) + old = params->au_encoding; + if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && + (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3)) return -ERANGE; new = old; break; @@ -396,6 +438,19 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params, new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; params->au_l2_bitrate = new; break; + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + if (!has_ac3) + return -EINVAL; + old = params->au_ac3_bitrate; + if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K && + new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K) + return -ERANGE; + if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K) + new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K; + else + new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K; + params->au_ac3_bitrate = new; + break; case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; if (set && new != old) @@ -449,17 +504,19 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params, return 0; } -static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, +static int saa6752hs_qctrl(struct saa6752hs_state *h, struct v4l2_queryctrl *qctrl) { + struct saa6752hs_mpeg_params *params = &h->params; int err; switch (qctrl->id) { case V4L2_CID_MPEG_AUDIO_ENCODING: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2); + h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : + V4L2_MPEG_AUDIO_ENCODING_LAYER_2, + 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2); case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return v4l2_ctrl_query_fill(qctrl, @@ -467,6 +524,14 @@ static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, V4L2_MPEG_AUDIO_L2_BITRATE_256K); + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + if (!h->has_ac3) + return -EINVAL; + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_AC3_BITRATE_256K, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_256K); + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, @@ -513,38 +578,50 @@ static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, return -EINVAL; } -static int saa6752hs_qmenu(struct saa6752hs_mpeg_params *params, +static int saa6752hs_qmenu(struct saa6752hs_state *h, struct v4l2_querymenu *qmenu) { - static const char *mpeg_audio_l2_bitrate[] = { - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "256 kbps", - "", - "384 kbps", - NULL + static const u32 mpeg_audio_encoding[] = { + V4L2_MPEG_AUDIO_ENCODING_LAYER_2, + V4L2_CTRL_MENU_IDS_END + }; + static const u32 mpeg_audio_ac3_encoding[] = { + V4L2_MPEG_AUDIO_ENCODING_LAYER_2, + V4L2_MPEG_AUDIO_ENCODING_AC3, + V4L2_CTRL_MENU_IDS_END + }; + static u32 mpeg_audio_l2_bitrate[] = { + V4L2_MPEG_AUDIO_L2_BITRATE_256K, + V4L2_MPEG_AUDIO_L2_BITRATE_384K, + V4L2_CTRL_MENU_IDS_END + }; + static u32 mpeg_audio_ac3_bitrate[] = { + V4L2_MPEG_AUDIO_AC3_BITRATE_256K, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K, + V4L2_CTRL_MENU_IDS_END }; struct v4l2_queryctrl qctrl; int err; qctrl.id = qmenu->id; - err = saa6752hs_qctrl(params, &qctrl); + err = saa6752hs_qctrl(h, &qctrl); if (err) return err; - if (qmenu->id == V4L2_CID_MPEG_AUDIO_L2_BITRATE) - return v4l2_ctrl_query_menu(qmenu, &qctrl, + switch (qmenu->id) { + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: + return v4l2_ctrl_query_menu_valid_items(qmenu, mpeg_audio_l2_bitrate); - return v4l2_ctrl_query_menu(qmenu, &qctrl, - v4l2_ctrl_get_menu(qmenu->id)); + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + if (!h->has_ac3) + return -EINVAL; + return v4l2_ctrl_query_menu_valid_items(qmenu, + mpeg_audio_ac3_bitrate); + case V4L2_CID_MPEG_AUDIO_ENCODING: + return v4l2_ctrl_query_menu_valid_items(qmenu, + h->has_ac3 ? mpeg_audio_ac3_encoding : + mpeg_audio_encoding); + } + return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL); } static int saa6752hs_init(struct i2c_client* client) @@ -570,7 +647,7 @@ static int saa6752hs_init(struct i2c_client* client) i2c_master_send(client, buf, 2); /* set bitrate */ - saa6752hs_set_bitrate(client, &h->params); + saa6752hs_set_bitrate(client, h); /* Set GOP structure {3, 13} */ buf[0] = 0x72; @@ -689,45 +766,6 @@ static int saa6752hs_init(struct i2c_client* client) return 0; } -static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) -{ - struct saa6752hs_state *h; - - - if (NULL == (h = kzalloc(sizeof(*h), GFP_KERNEL))) - return -ENOMEM; - h->client = client_template; - h->params = param_defaults; - h->client.adapter = adap; - h->client.addr = addr; - - /* Assume 625 input lines */ - h->standard = 0; - - i2c_set_clientdata(&h->client, h); - i2c_attach_client(&h->client); - - v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1); - return 0; -} - -static int saa6752hs_probe(struct i2c_adapter *adap) -{ - if (adap->class & I2C_CLASS_TV_ANALOG) - return i2c_probe(adap, &addr_data, saa6752hs_attach); - return 0; -} - -static int saa6752hs_detach(struct i2c_client *client) -{ - struct saa6752hs_state *h; - - h = i2c_get_clientdata(client); - i2c_detach_client(client); - kfree(h); - return 0; -} - static int saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -753,7 +791,8 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) return -EINVAL; params = h->params; for (i = 0; i < ctrls->count; i++) { - if ((err = handle_ctrl(¶ms, ctrls->controls + i, cmd))) { + err = handle_ctrl(h->has_ac3, ¶ms, ctrls->controls + i, cmd); + if (err) { ctrls->error_idx = i; return err; } @@ -761,9 +800,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) h->params = params; break; case VIDIOC_QUERYCTRL: - return saa6752hs_qctrl(&h->params, arg); + return saa6752hs_qctrl(h, arg); case VIDIOC_QUERYMENU: - return saa6752hs_qmenu(&h->params, arg); + return saa6752hs_qmenu(h, arg); case VIDIOC_G_FMT: { struct v4l2_format *f = arg; @@ -786,6 +825,11 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) case VIDIOC_S_STD: h->standard = *((v4l2_std_id *) arg); break; + + case VIDIOC_G_CHIP_IDENT: + return v4l2_chip_ident_i2c_client(client, + arg, h->chip, h->revision); + default: /* nothing */ break; @@ -794,36 +838,59 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) return err; } -/* ----------------------------------------------------------------------- */ +static int saa6752hs_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL); + u8 addr = 0x13; + u8 data[12]; -static struct i2c_driver driver = { - .driver = { - .name = "saa6752hs", - }, - .id = I2C_DRIVERID_SAA6752HS, - .attach_adapter = saa6752hs_probe, - .detach_client = saa6752hs_detach, - .command = saa6752hs_command, -}; + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + if (h == NULL) + return -ENOMEM; -static struct i2c_client client_template = -{ - .name = "saa6752hs", - .driver = &driver, -}; + i2c_master_send(client, &addr, 1); + i2c_master_recv(client, data, sizeof(data)); + h->chip = V4L2_IDENT_SAA6752HS; + h->revision = (data[8] << 8) | data[9]; + h->has_ac3 = 0; + if (h->revision == 0x0206) { + h->chip = V4L2_IDENT_SAA6752HS_AC3; + h->has_ac3 = 1; + v4l_info(client, "support AC-3\n"); + } + h->params = param_defaults; + h->standard = 0; /* Assume 625 input lines */ -static int __init saa6752hs_init_module(void) -{ - return i2c_add_driver(&driver); + i2c_set_clientdata(client, h); + return 0; } -static void __exit saa6752hs_cleanup_module(void) +static int saa6752hs_remove(struct i2c_client *client) { - i2c_del_driver(&driver); + kfree(i2c_get_clientdata(client)); + return 0; } -module_init(saa6752hs_init_module); -module_exit(saa6752hs_cleanup_module); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id saa6752hs_id[] = { + { "saa6752hs", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, saa6752hs_id); + +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa6752hs", + .driverid = I2C_DRIVERID_SAA6752HS, + .command = saa6752hs_command, + .probe = saa6752hs_probe, + .remove = saa6752hs_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = saa6752hs_id, +#endif +}; /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index a454968f7..5225ed6b8 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -29,6 +29,7 @@ #include #include +#include /* ------------------------------------------------------------------ */ @@ -403,6 +404,25 @@ static int empress_querymenu(struct file *file, void *priv, return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c); } +static int empress_g_chip_ident(struct file *file, void *fh, + struct v4l2_chip_ident *chip) +{ + struct saa7134_dev *dev = file->private_data; + + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (dev->mpeg_i2c_client == NULL) + return -EINVAL; + if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER && + chip->match_chip == I2C_DRIVERID_SAA6752HS) + return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip); + if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR && + chip->match_chip == dev->mpeg_i2c_client->addr) + return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip); + return -EINVAL; +} + + static const struct file_operations ts_fops = { .owner = THIS_MODULE, @@ -431,11 +451,11 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { .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_g_chip_ident = empress_g_chip_ident, }; /* ----------------------------------------------------------- */ diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 8dfe3cb8b..0eb498a08 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -638,13 +638,17 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and - the menu. The qctrl pointer may be NULL, in which case it is ignored. */ + the menu. The qctrl pointer may be NULL, in which case it is ignored. + If menu_items is NULL, then the menu items are retrieved using + v4l2_ctrl_get_menu. */ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, const char **menu_items) { int i; qmenu->reserved = 0; + if (menu_items == NULL) + menu_items = v4l2_ctrl_get_menu(qmenu->id); if (menu_items == NULL || (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum))) return -EINVAL; -- cgit v1.2.3 From 5b343a7aef24076566088b82af54022c4742638c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Aug 2008 18:27:16 +0200 Subject: saa6752hs: add PMT table for AC3 From: Hans Verkuil The PMT table for AC3 audio is different. Thanks to Dmitry Belimov for providing the table data. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7134/saa6752hs.c | 63 +++++++++++++++++++++------ 1 file changed, 50 insertions(+), 13 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/saa7134/saa6752hs.c b/linux/drivers/media/video/saa7134/saa6752hs.c index 42c5d1f76..011fc19f6 100644 --- a/linux/drivers/media/video/saa7134/saa6752hs.c +++ b/linux/drivers/media/video/saa7134/saa6752hs.c @@ -173,6 +173,39 @@ static u8 PMT[] = { 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, @@ -187,7 +220,7 @@ static struct saa6752hs_mpeg_params param_defaults = .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_384K, + .au_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_256K, }; /* ---------------------------------------------------------------------- */ @@ -296,10 +329,7 @@ static int saa6752hs_set_bitrate(struct i2c_client* client, /* set the audio encoding */ buf[0] = 0x93; - if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) - buf[1] = 1; - else - buf[1] = 0; + buf[1] = (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3); i2c_master_send(client, buf, 2); /* set the audio bitrate */ @@ -628,6 +658,7 @@ static int saa6752hs_init(struct i2c_client* client) { unsigned char buf[9], buf2[4]; struct saa6752hs_state *h; + unsigned size; u32 crc; unsigned char localPAT[256]; unsigned char localPMT[256]; @@ -686,7 +717,13 @@ static int saa6752hs_init(struct i2c_client* client) localPAT[sizeof(PAT) - 1] = crc & 0xFF; /* compute PMT */ - memcpy(localPMT, PMT, sizeof(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); @@ -695,11 +732,11 @@ static int saa6752hs_init(struct i2c_client* client) 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], sizeof(PMT) - 7 - 4); - localPMT[sizeof(PMT) - 4] = (crc >> 24) & 0xFF; - localPMT[sizeof(PMT) - 3] = (crc >> 16) & 0xFF; - localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; - localPMT[sizeof(PMT) - 1] = crc & 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 */ buf[0] = 0xC1; @@ -720,8 +757,8 @@ static int saa6752hs_init(struct i2c_client* client) i2c_master_send(client,buf,3); /* Send SI tables */ - i2c_master_send(client,localPAT,sizeof(PAT)); - i2c_master_send(client,localPMT,sizeof(PMT)); + i2c_master_send(client, localPAT, sizeof(PAT)); + i2c_master_send(client, localPMT, size); /* mute then unmute audio. This removes buzzing artefacts */ buf[0] = 0xa4; -- cgit v1.2.3 From f4f1c18e1d6df3d203399aa181e7f1058d673ad3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Aug 2008 20:47:07 +0200 Subject: arv: fix compilation errors/warnings From: Hans Verkuil - add PCI dependency for btcx - fix compile errors (doesn't like ';' at the end of a #if 0) Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/Kconfig | 1 + linux/drivers/media/video/arv.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index d6b1a106a..4c96b690a 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -34,6 +34,7 @@ config VIDEOBUF_DVB select VIDEOBUF_GEN config VIDEO_BTCX + depends on PCI tristate config VIDEO_IR diff --git a/linux/drivers/media/video/arv.c b/linux/drivers/media/video/arv.c index e100d4cfb..9e96e7773 100644 --- a/linux/drivers/media/video/arv.c +++ b/linux/drivers/media/video/arv.c @@ -39,7 +39,7 @@ #include #include -#if 0 /* keep */; +#if 0 /* keep */ #define DEBUG(n, args...) printk(args) #define CHECK_LOST 1 #else @@ -579,11 +579,11 @@ static void ar_interrupt(int irq, void *dev) * we have to start capture. */ disable_dma(); -#if 0 /* keep */; +#if 0 /* keep */ ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* needless? */ #endif memcpy(ar->frame[0], ar->line_buff, ar->line_bytes); -#if 0 /* keep */; +#if 0 /* keep */ ar_outl(0xa1861300, M32R_DMA0CR0_PORTL); #endif enable_dma(); @@ -609,7 +609,7 @@ static void ar_interrupt(int irq, void *dev) ar_outl(arvcr1, ARVCR1); /* disable */ wake_up_interruptible(&ar->wait); } else { -#if 0 /* keep */; +#if 0 /* keep */ ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); ar_outl(0xa1861300, M32R_DMA0CR0_PORTL); #endif @@ -693,7 +693,7 @@ static int ar_initialize(struct video_device *dev) printk("."); iic(2,0x78,0x8e,0x0c,0x00); iic(2,0x78,0x8f,0x00,0x00); -#if 0 /* keep */; +#if 0 /* keep */ iic(2,0x78,0x90,0x00,0x00); /* AWB on=1 off=0 */ #endif iic(2,0x78,0x93,0x01,0x00); @@ -712,7 +712,7 @@ static int ar_initialize(struct video_device *dev) iic(2,0x78,0x9e,0x2e,0x00); iic(2,0x78,0xb8,0x78,0x00); iic(2,0x78,0xba,0x05,0x00); -#if 0 /* keep */; +#if 0 /* keep */ iic(2,0x78,0x83,0x8c,0x00); /* brightness */ #endif printk("."); -- cgit v1.2.3 From 8896d4269aa500bfa93d4a088bf12c470cfa5a2e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 16:44:54 -0700 Subject: saa7134-core.c: fix warning From: Alexander Beregalov drivers/media/video/saa7134/saa7134-core.c:366: warning: 'saa7134_buffer_requeue' defined but not used Signed-off-by: Alexander Beregalov Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-core.c | 52 ++++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index e02c3c1b1..62c9322aa 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -408,32 +408,6 @@ void saa7134_buffer_timeout(unsigned long data) spin_unlock_irqrestore(&dev->slock,flags); } -/* resends a current buffer in queue after resume */ - -static int saa7134_buffer_requeue(struct saa7134_dev *dev, - struct saa7134_dmaqueue *q) -{ - struct saa7134_buf *buf, *next; - - assert_spin_locked(&dev->slock); - - buf = q->curr; - next = buf; - dprintk("buffer_requeue\n"); - - if (!buf) - return 0; - - dprintk("buffer_requeue : resending active buffers \n"); - - if (!list_empty(&q->queue)) - next = list_entry(q->queue.next, struct saa7134_buf, - vb.queue); - buf->activate(dev, buf, next); - - return 0; -} - /* ------------------------------------------------------------------ */ int saa7134_set_dmabits(struct saa7134_dev *dev) @@ -1203,6 +1177,32 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) } #ifdef CONFIG_PM + +/* resends a current buffer in queue after resume */ +static int saa7134_buffer_requeue(struct saa7134_dev *dev, + struct saa7134_dmaqueue *q) +{ + struct saa7134_buf *buf, *next; + + assert_spin_locked(&dev->slock); + + buf = q->curr; + next = buf; + dprintk("buffer_requeue\n"); + + if (!buf) + return 0; + + dprintk("buffer_requeue : resending active buffers \n"); + + if (!list_empty(&q->queue)) + next = list_entry(q->queue.next, struct saa7134_buf, + vb.queue); + buf->activate(dev, buf, next); + + return 0; +} + static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) { -- cgit v1.2.3 From ea03de48c87e9209713cf3fb48848ab9cf138c0e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Aug 2008 19:09:42 -0300 Subject: v4l2-ioctl.c: fix warning From: Alexander Beregalov drivers/media/video/v4l2-ioctl.c:496: warning: format '%08ld' expects type 'long int', but argument 5 has type 'suseconds_t' Signed-off-by: Alexander Beregalov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-ioctl.c b/linux/drivers/media/video/v4l2-ioctl.c index 1c8fa257d..51569f888 100644 --- a/linux/drivers/media/video/v4l2-ioctl.c +++ b/linux/drivers/media/video/v4l2-ioctl.c @@ -500,7 +500,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd, p->timestamp.tv_sec / 3600, (int)(p->timestamp.tv_sec / 60) % 60, (int)(p->timestamp.tv_sec % 60), - p->timestamp.tv_usec, + (long)p->timestamp.tv_usec, p->index, prt_names(p->type, v4l2_type_names), p->bytesused, p->flags, -- cgit v1.2.3 From 189a39592e02ff2f9a387eff92dfc3a3a2e4ddfb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Aug 2008 08:54:24 +0200 Subject: V4L: fix return value of register video func From: Henrik Kretzschmar If a wrong device type is used with video_register_device_index() it should better return an error number, instead of a constant. Signed-off-by: Henrik Kretzschmar Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index d97320091..594f2477f 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -316,7 +316,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, default: printk(KERN_ERR "%s called with unknown type: %d\n", __func__, type); - return -1; + return -EINVAL; } /* pick a minor number */ -- cgit v1.2.3 From 2a8a9d09b348354fafcf42ad58d376429861fcab Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Aug 2008 14:46:55 +0200 Subject: ivtv: improve CC support From: Hans Verkuil - change the work-queue to a single threaded high prio workqueue - use DMA instead of PIO for the sliced VBI data. - remove some incorrect tests - increase the internal VBI capture queue size for sliced VBI packets - ignore duplicate VBI lines With these changes it should finally be possible to get reliable closed captions. Priority: high Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-driver.c | 2 +- linux/drivers/media/video/ivtv/ivtv-driver.h | 1 + linux/drivers/media/video/ivtv/ivtv-irq.c | 29 ++++++++------------------- linux/drivers/media/video/ivtv/ivtv-queue.h | 2 +- linux/drivers/media/video/ivtv/ivtv-streams.c | 2 +- linux/drivers/media/video/ivtv/ivtv-vbi.c | 4 +++- 6 files changed, 15 insertions(+), 25 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index efdb59193..89a16bfeb 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -688,7 +688,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) spin_lock_init(&itv->lock); spin_lock_init(&itv->dma_reg_lock); - itv->irq_work_queues = create_workqueue(itv->name); + itv->irq_work_queues = create_singlethread_workqueue(itv->name); if (itv->irq_work_queues == NULL) { IVTV_ERR("Could not create ivtv workqueue\n"); return -1; diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h index d66ee14b6..6e0ca223a 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.h +++ b/linux/drivers/media/video/ivtv/ivtv-driver.h @@ -252,6 +252,7 @@ struct ivtv_mailbox_data { #define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ #define IVTV_F_I_INITED 21 /* set after first open */ #define IVTV_F_I_FAILED 22 /* set if first open failed */ +#define IVTV_F_I_WORK_INITED 23 /* worker thread was initialized */ /* Event notifications */ #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ diff --git a/linux/drivers/media/video/ivtv/ivtv-irq.c b/linux/drivers/media/video/ivtv/ivtv-irq.c index d5ac766c1..59fe56171 100644 --- a/linux/drivers/media/video/ivtv/ivtv-irq.c +++ b/linux/drivers/media/video/ivtv/ivtv-irq.c @@ -82,6 +82,13 @@ void ivtv_irq_work_handler(void *arg) DEFINE_WAIT(wait); + if (test_and_clear_bit(IVTV_F_I_WORK_INITED, &itv->i_flags)) { + struct sched_param param = { .sched_priority = 99 }; + + /* This thread must use the FIFO scheduler as it + is realtime sensitive. */ + sched_setscheduler(current, SCHED_FIFO, ¶m); + } if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags)) ivtv_pio_work_handler(itv); @@ -684,34 +691,14 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv) static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) { - struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; u32 data[CX2341X_MBOX_MAX_DATA]; struct ivtv_stream *s; IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n"); s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; - /* If more than two VBI buffers are pending, then - clear the old ones and start with this new one. - This can happen during transition stages when MPEG capturing is - started, but the first interrupts haven't arrived yet. During - that period VBI requests can accumulate without being able to - DMA the data. Since at most four VBI DMA buffers are available, - we just drop the old requests when there are already three - requests queued. */ - if (s->sg_pending_size > 2) { - struct ivtv_buffer *buf; - list_for_each_entry(buf, &s->q_predma.list, list) - ivtv_buf_sync_for_cpu(s, buf); - ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0); - s->sg_pending_size = 0; - } - /* if we can append the data, and the MPEG stream isn't capturing, - then start a DMA request for just the VBI data. */ - if (!stream_enc_dma_append(s, data) && - !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) { + if (!stream_enc_dma_append(s, data)) set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); - } } static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv) diff --git a/linux/drivers/media/video/ivtv/ivtv-queue.h b/linux/drivers/media/video/ivtv/ivtv-queue.h index 7cfc0c9ab..476556afd 100644 --- a/linux/drivers/media/video/ivtv/ivtv-queue.h +++ b/linux/drivers/media/video/ivtv/ivtv-queue.h @@ -23,7 +23,7 @@ #define IVTV_QUEUE_H #define IVTV_DMA_UNMAPPED ((u32) -1) -#define SLICED_VBI_PIO 1 +#define SLICED_VBI_PIO 0 /* ivtv_buffer utility functions */ diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c index 54d2023b2..730e85d86 100644 --- a/linux/drivers/media/video/ivtv/ivtv-streams.c +++ b/linux/drivers/media/video/ivtv/ivtv-streams.c @@ -363,7 +363,7 @@ static void ivtv_vbi_setup(struct ivtv *itv) /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */ data[1] = 1; /* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */ - data[2] = raw ? 4 : 8; + data[2] = raw ? 4 : 4 * (itv->vbi.raw_size / itv->vbi.enc_size); /* The start/stop codes determine which VBI lines end up in the raw VBI data area. The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video) diff --git a/linux/drivers/media/video/ivtv/ivtv-vbi.c b/linux/drivers/media/video/ivtv/ivtv-vbi.c index 71798f0da..1ce9deb11 100644 --- a/linux/drivers/media/video/ivtv/ivtv-vbi.c +++ b/linux/drivers/media/video/ivtv/ivtv-vbi.c @@ -293,6 +293,7 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 u32 line_size = itv->vbi.sliced_decoder_line_size; struct v4l2_decode_vbi_line vbi; int i; + unsigned lines = 0; /* find the first valid line */ for (i = 0; i < size; i++, buf++) { @@ -313,7 +314,8 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 } vbi.p = p + 4; itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi); - if (vbi.type) { + if (vbi.type && !(lines & (1 << vbi.line))) { + lines |= 1 << vbi.line; itv->vbi.sliced_data[line].id = vbi.type; itv->vbi.sliced_data[line].field = vbi.is_second_field; itv->vbi.sliced_data[line].line = vbi.line; -- cgit v1.2.3 From 3526cfc71d1a4d69c4811d3bde136d4a70e2d929 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Aug 2008 15:35:29 +0200 Subject: v4l2: add AAC bitrate control From: Hans Verkuil If you can select AAC as audio encoder, then you should also be able to set the bitrate. Add this missing control. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-common.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 0eb498a08..b5baf8f7e 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -387,6 +387,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate"; case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate"; case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate"; + case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate"; case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode"; case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension"; @@ -549,6 +550,8 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) V4L2_MPEG_AUDIO_L3_BITRATE_32K, V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1, V4L2_MPEG_AUDIO_L3_BITRATE_192K); + case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: + return v4l2_ctrl_query_fill(qctrl, 0, 6400, 1, 3200000); case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_AC3_BITRATE_32K, -- cgit v1.2.3 From f35a6467b74ef21874ce7aee3bc2728fbb22742c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 9 Aug 2008 11:23:15 -0400 Subject: cxusb: add support for DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2) From: Anton Blanchard Add support for revision 2 of the DViCO FusionHDTV DVB-T Dual Digital 4 which has new tuners and demodulators (2 x DIB7070p). With this patch both DVB reception and IR works. The dib7000p driver currently hardwires the output mode to OUTMODE_MPEG2_SERIAL regardless of what we ask for. Modify it to allow OUTMODE_MPEG2_PAR_GATED_CLK to be set. Longer term we should remove the check completely and set the output mode correctly in all the callers. Add Kconfig bits to ensure the dib7000p and dib0070 modules are enabled. It would be nice to only do this for the !DVB_FE_CUSTOMISE case, but this is what the other DIB7070 module does (there are a number of module dependencies in the attach code). Priority: normal Signed-off-by: Anton Blanchard Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 + linux/drivers/media/dvb/dvb-usb/cxusb.c | 206 ++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + linux/drivers/media/dvb/frontends/dib7000p.c | 3 +- 4 files changed, 211 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index e84152b75..df9932368 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -108,6 +108,8 @@ config DVB_USB_CXUSB select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE + select DVB_DIB7000P + select DVB_TUNER_DIB0070 help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode diff --git a/linux/drivers/media/dvb/dvb-usb/cxusb.c b/linux/drivers/media/dvb/dvb-usb/cxusb.c index aaa0b6f0b..67a3bd350 100644 --- a/linux/drivers/media/dvb/dvb-usb/cxusb.c +++ b/linux/drivers/media/dvb/dvb-usb/cxusb.c @@ -36,6 +36,8 @@ #include "tuner-xc2028.h" #include "tuner-simple.h" #include "mxl5005s.h" +#include "dib7000p.h" +#include "dib0070.h" /* debug */ static int dvb_usb_cxusb_debug; @@ -726,6 +728,157 @@ no_IR: return 0; } +static struct dibx000_agc_config dib7070_agc_config = { + .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, + + /* + * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, + * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 + */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | + (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), + .inv_gain = 600, + .time_stabiliz = 10, + .alpha_level = 0, + .thlock = 118, + .wbd_inv = 0, + .wbd_ref = 3530, + .wbd_sel = 1, + .wbd_alpha = 5, + .agc1_max = 65535, + .agc1_min = 0, + .agc2_max = 65535, + .agc2_min = 0, + .agc1_pt1 = 0, + .agc1_pt2 = 40, + .agc1_pt3 = 183, + .agc1_slope1 = 206, + .agc1_slope2 = 255, + .agc2_pt1 = 72, + .agc2_pt2 = 152, + .agc2_slope1 = 88, + .agc2_slope2 = 90, + .alpha_mant = 17, + .alpha_exp = 27, + .beta_mant = 23, + .beta_exp = 51, + .perform_agc_softsplit = 0, +}; + +static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { + .internal = 60000, + .sampling = 15000, + .pll_prediv = 1, + .pll_ratio = 20, + .pll_range = 3, + .pll_reset = 1, + .pll_bypass = 0, + .enable_refdiv = 0, + .bypclk_div = 0, + .IO_CLK_en_core = 1, + .ADClkSrc = 1, + .modulo = 2, + /* refsel, sel, freq_15k */ + .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), + .ifreq = (0 << 25) | 0, + .timf = 20452225, + .xtal_hz = 12000000, +}; + +static struct dib7000p_config cxusb_dualdig4_rev2_config = { + .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, + .output_mpeg2_in_188_bytes = 1, + + .agc_config_count = 1, + .agc = &dib7070_agc_config, + .bw = &dib7070_bw_config_12_mhz, + .tuner_is_baseband = 1, + .spur_protect = 1, + + .gpio_dir = 0xfcef, + .gpio_val = 0x0110, + + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .hostbus_diversity = 1, +}; + +static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) +{ + if (usb_set_interface(adap->dev->udev, 0, 1) < 0) + err("set interface failed"); + + cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); + + cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); + + dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &cxusb_dualdig4_rev2_config); + + if ((adap->fe = dvb_attach(dib7000p_attach, + &adap->dev->i2c_adap, 0x80, + &cxusb_dualdig4_rev2_config)) == NULL) + return -EIO; + + return 0; +} + +static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) +{ + return dib7000p_set_gpio(fe, 8, 0, !onoff); +} + +static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) +{ + return 0; +} + +static struct dib0070_config dib7070p_dib0070_config = { + .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, + .reset = dib7070_tuner_reset, + .sleep = dib7070_tuner_sleep, + .clock_khz = 12000, +}; + +struct dib0700_adapter_state { + int (*set_param_save) (struct dvb_frontend *, + struct dvb_frontend_parameters *); +}; + +static int dib7070_set_param_override(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fep) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + + u16 offset; + u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); + switch (band) { + case BAND_VHF: offset = 950; break; + case BAND_UHF: + default: offset = 550; break; + } + + dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); + + return state->set_param_save(fe, fep); +} + +static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + + if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, + &dib7070p_dib0070_config) == NULL) + return -ENODEV; + + st->set_param_save = adap->fe->ops.tuner_ops.set_params; + adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override; + return 0; +} + static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) { if (usb_set_interface(adap->dev->udev, 0, 1) < 0) @@ -826,6 +979,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties; static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; +static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; static struct dvb_usb_device_properties cxusb_aver_a868r_properties; @@ -852,6 +1006,9 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, + &cxusb_bluebird_dualdig4_rev2_properties, + THIS_MODULE, NULL, adapter_nr) || 0) return 0; @@ -876,6 +1033,7 @@ static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, + { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -1321,6 +1479,54 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { } }; +static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .size_of_priv = sizeof(struct cxusb_state), + + .num_adapters = 1, + .adapter = { + { + .streaming_ctrl = cxusb_streaming_ctrl, + .frontend_attach = cxusb_dualdig4_rev2_frontend_attach, + .tuner_attach = cxusb_dualdig4_rev2_tuner_attach, + .size_of_priv = sizeof(struct dib0700_adapter_state), + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + }, + }, + + .power_ctrl = cxusb_bluebird_power_ctrl, + + .i2c_algo = &cxusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + + .rc_interval = 100, + .rc_key_map = dvico_mce_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), + .rc_query = cxusb_rc_query, + + .num_device_descs = 1, + .devices = { + { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)", + { NULL }, + { &cxusb_table[17], NULL }, + }, + } +}; + static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 029b437ca..9b12261e0 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -170,6 +170,7 @@ #define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58 #define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59 #define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78 +#define USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2 0xdb98 #define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70 #define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71 #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54 diff --git a/linux/drivers/media/dvb/frontends/dib7000p.c b/linux/drivers/media/dvb/frontends/dib7000p.c index c74d373b6..ebb7594e3 100644 --- a/linux/drivers/media/dvb/frontends/dib7000p.c +++ b/linux/drivers/media/dvb/frontends/dib7000p.c @@ -1359,7 +1359,8 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, /* Ensure the output mode remains at the previous default if it's * not specifically set by the caller. */ - if (st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) + if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && + (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) st->cfg.output_mode = OUTMODE_MPEG2_FIFO; demod = &st->demod; -- cgit v1.2.3 From 13b2927b565ccf92dbe49b663b758d2bfc866536 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 9 Aug 2008 12:06:26 -0400 Subject: cxusb: fix checkpatch warnings & errors From: Michael Krufky Fix the following checkpatch.pl errors and warnings: ERROR: do not use assignment in if condition 117: FILE: linux/drivers/media/dvb/dvb-usb/cxusb.c:819: + if ((adap->fe = dvb_attach(dib7000p_attach, ERROR: switch and case should be at the same indent 155: FILE: linux/drivers/media/dvb/dvb-usb/cxusb.c:857: + switch (band) { + case BAND_VHF: offset = 950; break; + case BAND_UHF: + default: offset = 550; break; WARNING: line over 80 characters 169: FILE: linux/drivers/media/dvb/dvb-usb/cxusb.c:871: + struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); WARNING: line over 80 characters 213: FILE: linux/drivers/media/dvb/dvb-usb/cxusb.c:1342: +static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { WARNING: line over 80 characters 226: FILE: linux/drivers/media/dvb/dvb-usb/cxusb.c:1355: + .size_of_priv = sizeof(struct dib0700_adapter_state), total: 2 errors, 3 warnings, 266 lines checked Priority: normal Signed-off-by: Michael Krufky Cc: Anton Blanchard --- linux/drivers/media/dvb/dvb-usb/cxusb.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/dvb-usb/cxusb.c b/linux/drivers/media/dvb/dvb-usb/cxusb.c index 67a3bd350..ae560b8c7 100644 --- a/linux/drivers/media/dvb/dvb-usb/cxusb.c +++ b/linux/drivers/media/dvb/dvb-usb/cxusb.c @@ -816,9 +816,9 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &cxusb_dualdig4_rev2_config); - if ((adap->fe = dvb_attach(dib7000p_attach, - &adap->dev->i2c_adap, 0x80, - &cxusb_dualdig4_rev2_config)) == NULL) + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + &cxusb_dualdig4_rev2_config); + if (adap->fe == NULL) return -EIO; return 0; @@ -855,9 +855,9 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, u16 offset; u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); switch (band) { - case BAND_VHF: offset = 950; break; - case BAND_UHF: - default: offset = 550; break; + case BAND_VHF: offset = 950; break; + default: + case BAND_UHF: offset = 550; break; } dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); @@ -868,7 +868,9 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct i2c_adapter *tun_i2c = + dib7000p_get_i2c_master(adap->fe, + DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config) == NULL) @@ -1479,7 +1481,8 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { } }; -static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { +static +struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = CYPRESS_FX2, @@ -1489,10 +1492,10 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties .num_adapters = 1, .adapter = { { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_dualdig4_rev2_frontend_attach, - .tuner_attach = cxusb_dualdig4_rev2_tuner_attach, - .size_of_priv = sizeof(struct dib0700_adapter_state), + .streaming_ctrl = cxusb_streaming_ctrl, + .frontend_attach = cxusb_dualdig4_rev2_frontend_attach, + .tuner_attach = cxusb_dualdig4_rev2_tuner_attach, + .size_of_priv = sizeof(struct dib0700_adapter_state), /* parameter for the MPEG2-data transfer */ .stream = { .type = USB_BULK, -- cgit v1.2.3 From aa2741ad0e0d705cb706d4476091e047818f7020 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 9 Aug 2008 13:21:58 -0400 Subject: fix DVB_FE_CUSTOMISE for DVB_DIB7000P and DVB_TUNER_DIB0070 with dvb-usb-cxusb From: Michael Krufky Allow dvb-usb-cxusb to be built without dib7000p or dib0070 selected Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 4 +-- linux/drivers/media/dvb/frontends/dib0070.h | 8 +++++- linux/drivers/media/dvb/frontends/dib7000p.h | 41 ++++++++++++++++++++++++---- 3 files changed, 45 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index df9932368..8a54cb483 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -108,8 +108,8 @@ config DVB_USB_CXUSB select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE - select DVB_DIB7000P - select DVB_TUNER_DIB0070 + select DVB_DIB7000P if !DVB_FE_CUSTOMISE + select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode diff --git a/linux/drivers/media/dvb/frontends/dib0070.h b/linux/drivers/media/dvb/frontends/dib0070.h index 3eedfdf50..21f2c5161 100644 --- a/linux/drivers/media/dvb/frontends/dib0070.h +++ b/linux/drivers/media/dvb/frontends/dib0070.h @@ -41,6 +41,7 @@ struct dib0070_config { extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); +extern u16 dib0070_wbd_offset(struct dvb_frontend *); #else static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, @@ -49,9 +50,14 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } + +static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); -extern u16 dib0070_wbd_offset(struct dvb_frontend *); #endif diff --git a/linux/drivers/media/dvb/frontends/dib7000p.h b/linux/drivers/media/dvb/frontends/dib7000p.h index 07c4d12ed..3e8126857 100644 --- a/linux/drivers/media/dvb/frontends/dib7000p.h +++ b/linux/drivers/media/dvb/frontends/dib7000p.h @@ -41,6 +41,14 @@ struct dib7000p_config { extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); +extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, + enum dibx000_i2c_interface, + int); +extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, + int no_of_demods, u8 default_addr, + struct dib7000p_config cfg[]); +extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); +extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); #else static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, @@ -49,13 +57,36 @@ static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -#endif -extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]); +static inline +struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, + enum dibx000_i2c_interface i, int x) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, + int no_of_demods, u8 default_addr, + struct dib7000p_config cfg[]) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +extern int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +extern int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} +#endif -extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); -extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); -extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); #endif -- cgit v1.2.3 From a09ed3d987422da2f6d14fc6e7efa295c1312629 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 9 Aug 2008 12:36:51 -0400 Subject: cxusb: add lgs8gl5 and support for Magic-Pro DMB-TH usb stick From: Timothy Lee Add support for Magic-Pro DMB-TH usb stick. DMB-TH is the HDTV broadcast standard used in Hong Kong and China. [...] I've also attached a second patch against the dvb-apps repository which adds a DMB-TH scan file for Hong Kong. Since the ProHDTV stick contains a DMB-TH decoder (lgs8gl5) onboard, it outputs MPEG-TS to the PC. Priority: normal Signed-off-by: Timothy Lee Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/cxusb.c | 286 +++++++++++++++ linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 + linux/drivers/media/dvb/frontends/Kconfig | 7 + linux/drivers/media/dvb/frontends/Makefile | 1 + linux/drivers/media/dvb/frontends/lgs8gl5.c | 480 ++++++++++++++++++++++++++ linux/drivers/media/dvb/frontends/lgs8gl5.h | 45 +++ 6 files changed, 821 insertions(+) create mode 100644 linux/drivers/media/dvb/frontends/lgs8gl5.c create mode 100644 linux/drivers/media/dvb/frontends/lgs8gl5.h (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/dvb-usb/cxusb.c b/linux/drivers/media/dvb/dvb-usb/cxusb.c index ae560b8c7..49985f992 100644 --- a/linux/drivers/media/dvb/dvb-usb/cxusb.c +++ b/linux/drivers/media/dvb/dvb-usb/cxusb.c @@ -38,6 +38,7 @@ #include "mxl5005s.h" #include "dib7000p.h" #include "dib0070.h" +#include "lgs8gl5.h" /* debug */ static int dvb_usb_cxusb_debug; @@ -111,6 +112,25 @@ static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff) cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40); } +static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d, + u8 addr, int onoff) +{ + u8 o[2] = {addr, onoff}; + u8 i; + int rc; + + rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); + + if (rc < 0) + return rc; + if (i == 0x01) + return 0; + else { + deb_info("gpio_write failed.\n"); + return -EIO; + } +} + /* I2C */ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) @@ -264,6 +284,20 @@ static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff) return rc; } +static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + int ret; + u8 b; + ret = cxusb_power_ctrl(d, onoff); + if (!onoff) + return ret; + + msleep(128); + cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1); + msleep(100); + return ret; +} + static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { u8 buf[2] = { 0x03, 0x00 }; @@ -285,6 +319,67 @@ static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return 0; } +static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) +{ + int ep = d->props.generic_bulk_ctrl_endpoint; + const int timeout = 100; + const int junk_len = 32; + u8 *junk; + int rd_count; + + /* Discard remaining data in video pipe */ + junk = kmalloc(junk_len, GFP_KERNEL); + if (!junk) + return; + while (1) { + if (usb_bulk_msg(d->udev, + usb_rcvbulkpipe(d->udev, ep), + junk, junk_len, &rd_count, timeout) < 0) + break; + if (!rd_count) + break; + } + kfree(junk); +} + +static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d) +{ + struct usb_data_stream_properties *p = &d->props.adapter[0].stream; + const int timeout = 100; + const int junk_len = p->u.bulk.buffersize; + u8 *junk; + int rd_count; + + /* Discard remaining data in video pipe */ + junk = kmalloc(junk_len, GFP_KERNEL); + if (!junk) + return; + while (1) { + if (usb_bulk_msg(d->udev, + usb_rcvbulkpipe(d->udev, p->endpoint), + junk, junk_len, &rd_count, timeout) < 0) + break; + if (!rd_count) + break; + } + kfree(junk); +} + +static int cxusb_d680_dmb_streaming_ctrl( + struct dvb_usb_adapter *adap, int onoff) +{ + if (onoff) { + u8 buf[2] = { 0x03, 0x00 }; + cxusb_d680_dmb_drain_video(adap->dev); + return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, + buf, sizeof(buf), NULL, 0); + } else { + int ret = cxusb_ctrl_msg(adap->dev, + CMD_STREAMING_OFF, NULL, 0, NULL, 0); + return ret; + } +} + static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { struct dvb_usb_rc_key *keymap = d->props.rc_key_map; @@ -337,6 +432,32 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event, return 0; } +static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, + int *state) +{ + struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + u8 ircode[2]; + int i; + + *event = 0; + *state = REMOTE_NO_KEY_PRESSED; + + if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0) + return 0; + + for (i = 0; i < d->props.rc_key_map_size; i++) { + if (keymap[i].custom == ircode[0] && + keymap[i].data == ircode[1]) { + *event = keymap[i].event; + *state = REMOTE_KEY_PRESSED; + + return 0; + } + } + + return 0; +} + static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { { 0xfe, 0x02, KEY_TV }, { 0xfe, 0x0e, KEY_MP3 }, @@ -424,6 +545,44 @@ static struct dvb_usb_rc_key dvico_portable_rc_keys[] = { { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */ }; +static struct dvb_usb_rc_key d680_dmb_rc_keys[] = { + { 0x00, 0x38, KEY_UNKNOWN }, /* TV/AV */ + { 0x08, 0x0c, KEY_ZOOM }, + { 0x08, 0x00, KEY_0 }, + { 0x00, 0x01, KEY_1 }, + { 0x08, 0x02, KEY_2 }, + { 0x00, 0x03, KEY_3 }, + { 0x08, 0x04, KEY_4 }, + { 0x00, 0x05, KEY_5 }, + { 0x08, 0x06, KEY_6 }, + { 0x00, 0x07, KEY_7 }, + { 0x08, 0x08, KEY_8 }, + { 0x00, 0x09, KEY_9 }, + { 0x00, 0x0a, KEY_MUTE }, + { 0x08, 0x29, KEY_BACK }, + { 0x00, 0x12, KEY_CHANNELUP }, + { 0x08, 0x13, KEY_CHANNELDOWN }, + { 0x00, 0x2b, KEY_VOLUMEUP }, + { 0x08, 0x2c, KEY_VOLUMEDOWN }, + { 0x00, 0x20, KEY_UP }, + { 0x08, 0x21, KEY_DOWN }, + { 0x00, 0x11, KEY_LEFT }, + { 0x08, 0x10, KEY_RIGHT }, + { 0x00, 0x0d, KEY_OK }, + { 0x08, 0x1f, KEY_RECORD }, + { 0x00, 0x17, KEY_PLAYPAUSE }, + { 0x08, 0x16, KEY_PLAYPAUSE }, + { 0x00, 0x0b, KEY_STOP }, + { 0x08, 0x27, KEY_FASTFORWARD }, + { 0x00, 0x26, KEY_REWIND }, + { 0x08, 0x1e, KEY_UNKNOWN }, /* Time Shift */ + { 0x00, 0x0e, KEY_UNKNOWN }, /* Snapshot */ + { 0x08, 0x2d, KEY_UNKNOWN }, /* Mouse Cursor */ + { 0x00, 0x0f, KEY_UNKNOWN }, /* Minimize/Maximize */ + { 0x08, 0x14, KEY_UNKNOWN }, /* Shuffle */ + { 0x00, 0x25, KEY_POWER }, +}; + static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) { static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; @@ -529,6 +688,24 @@ static struct mxl5005s_config aver_a868r_tuner = { .AgcMasterByte = 0x00, }; +/* FIXME: needs tweaking */ +static struct mxl5005s_config d680_dmb_tuner = { + .i2c_address = 0x63, + .if_freq = 36125000UL, + .xtal_freq = CRYSTAL_FREQ_16000000HZ, + .agc_mode = MXL_SINGLE_AGC, + .tracking_filter = MXL_TF_C, + .rssi_enable = MXL_RSSI_ENABLE, + .cap_select = MXL_CAP_SEL_ENABLE, + .div_out = MXL_DIV_OUT_4, + .clock_out = MXL_CLOCK_OUT_DISABLE, + .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, + .top = MXL5005S_TOP_25P2, + .mod_mode = MXL_DIGITAL_MODE, + .if_mode = MXL_ZERO_IF, + .AgcMasterByte = 0x00, +}; + /* Callbacks for DVB USB */ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) { @@ -617,6 +794,14 @@ static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) return 0; } +static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dvb_frontend *fe; + fe = dvb_attach(mxl5005s_attach, adap->fe, + &adap->dev->i2c_adap, &d680_dmb_tuner); + return (fe == NULL) ? -EIO : 0; +} + static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) { u8 b; @@ -906,6 +1091,54 @@ static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) return -EIO; } +static struct lgs8gl5_config lgs8gl5_cfg = { + .demod_address = 0x19, +}; + +static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dvb_usb_device *d = adap->dev; + int n; + + /* Select required USB configuration */ + if (usb_set_interface(d->udev, 0, 0) < 0) + err("set interface failed"); + + /* Unblock all USB pipes */ + usb_clear_halt(d->udev, + usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, + usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, + usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint)); + + /* Drain USB pipes to avoid hang after reboot */ + for (n = 0; n < 5; n++) { + cxusb_d680_dmb_drain_message(d); + cxusb_d680_dmb_drain_video(d); + msleep(200); + } + + /* Reset the tuner */ + if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { + err("clear tuner gpio failed"); + return -EIO; + } + msleep(100); + if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { + err("set tuner gpio failed"); + return -EIO; + } + msleep(100); + + /* Attach frontend */ + adap->fe = dvb_attach(lgs8gl5_attach, &lgs8gl5_cfg, &d->i2c_adap); + if (adap->fe == NULL) + return -EIO; + + return 0; +} + /* * DViCO has shipped two devices with the same USB ID, but only one of them * needs a firmware download. Check the device class details to see if they @@ -985,6 +1218,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; static struct dvb_usb_device_properties cxusb_aver_a868r_properties; +static struct dvb_usb_device_properties cxusb_d680_dmb_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -1011,6 +1245,8 @@ static int cxusb_probe(struct usb_interface *intf, 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_rev2_properties, THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, + THIS_MODULE, NULL, adapter_nr) || 0) return 0; @@ -1036,6 +1272,7 @@ static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, + { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -1530,6 +1767,55 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { } }; +static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .size_of_priv = sizeof(struct cxusb_state), + + .num_adapters = 1, + .adapter = { + { + .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, + .frontend_attach = cxusb_d680_dmb_frontend_attach, + .tuner_attach = cxusb_d680_dmb_tuner_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_BULK, + .count = 5, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 8192, + } + } + }, + }, + }, + + .power_ctrl = cxusb_d680_dmb_power_ctrl, + + .i2c_algo = &cxusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + + .rc_interval = 100, + .rc_key_map = d680_dmb_rc_keys, + .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys), + .rc_query = cxusb_d680_dmb_rc_query, + + .num_device_descs = 1, + .devices = { + { + "Conexant DMB-TH Stick", + { NULL }, + { &cxusb_table[18], NULL }, + }, + } +}; + static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 9b12261e0..851070b86 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -22,6 +22,7 @@ #define USB_VID_AVERMEDIA 0x07ca #define USB_VID_COMPRO 0x185b #define USB_VID_COMPRO_UNK 0x145f +#define USB_VID_CONEXANT 0x0572 #define USB_VID_CYPRESS 0x04b4 #define USB_VID_DIBCOM 0x10b8 #define USB_VID_DPOSH 0x1498 @@ -69,6 +70,7 @@ #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d #define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 #define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 +#define USB_PID_CONEXANT_D680_DMB 0x86d6 #define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 #define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 7dbb4a223..774f5c2a7 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -385,4 +385,11 @@ config DVB_ISL6421 help An SEC control chip. +config DVB_LGS8GL5 + tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DMB-TH tuner module. Say Y when you want to support this frontend. + endmenu diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 028da5561..262eaa429 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -48,3 +48,4 @@ obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o obj-$(CONFIG_DVB_AU8522) += au8522.o obj-$(CONFIG_DVB_TDA10048) += tda10048.o obj-$(CONFIG_DVB_S5H1411) += s5h1411.o +obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o diff --git a/linux/drivers/media/dvb/frontends/lgs8gl5.c b/linux/drivers/media/dvb/frontends/lgs8gl5.c new file mode 100644 index 000000000..c0a223d28 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgs8gl5.c @@ -0,0 +1,480 @@ +/* + Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver + + Copyright (C) 2008 Sirius International (Hong Kong) Limited + Timothy Lee + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include +#include "dvb_frontend.h" +#include "lgs8gl5.h" + + +#define REG_RESET 0x02 +#define REG_RESET_OFF 0x01 +#define REG_03 0x03 +#define REG_04 0x04 +#define REG_07 0x07 +#define REG_09 0x09 +#define REG_0A 0x0a +#define REG_0B 0x0b +#define REG_0C 0x0c +#define REG_37 0x37 +#define REG_STRENGTH 0x4b +#define REG_STRENGTH_MASK 0x7f +#define REG_STRENGTH_CARRIER 0x80 +#define REG_INVERSION 0x7c +#define REG_INVERSION_ON 0x80 +#define REG_7D 0x7d +#define REG_7E 0x7e +#define REG_A2 0xa2 +#define REG_STATUS 0xa4 +#define REG_STATUS_SYNC 0x04 +#define REG_STATUS_LOCK 0x01 + + +struct lgs8gl5_state { + struct i2c_adapter *i2c; + const struct lgs8gl5_config *config; + struct dvb_frontend frontend; +}; + + +static int debug; +#define dprintk(args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG "lgs8gl5: " args); \ + } while (0) + + +/* Writes into demod's register */ +static int +lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data) +{ + int ret; + u8 buf[] = {reg, data}; + struct i2c_msg msg = { + .addr = state->config->demod_address, + .flags = 0, + .buf = buf, + .len = 2 + }; + + ret = i2c_transfer(state->i2c, &msg, 1); + if (ret != 1) + dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n", + __func__, reg, data, ret); + return (ret != 1) ? -1 : 0; +} + + +/* Reads from demod's register */ +static int +lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg) +{ + int ret, j; + u8 b0[] = {reg}; + u8 b1[] = {0}; + struct i2c_msg msg[2] = { + { + .addr = state->config->demod_address, + .flags = 0, + .buf = b0, + .len = 1 + }, + { + .addr = state->config->demod_address, + .flags = I2C_M_RD, + .buf = b1, + .len = 1 + } + }; + + ret = i2c_transfer(state->i2c, msg, 2); + if (ret != 2) + return -EIO; + + return b1[0]; +} + + +static int +lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data) +{ + lgs8gl5_read_reg(state, reg); + lgs8gl5_write_reg(state, reg, data); + return 0; +} + + +/* Writes into alternate device's register */ +/* TODO: Find out what that device is for! */ +static int +lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data) +{ + int ret, j; + u8 b0[] = {reg}; + u8 b1[] = {0}; + u8 b2[] = {reg, data}; + struct i2c_msg msg[3] = { + { + .addr = state->config->demod_address + 2, + .flags = 0, + .buf = b0, + .len = 1 + }, + { + .addr = state->config->demod_address + 2, + .flags = I2C_M_RD, + .buf = b1, + .len = 1 + }, + { + .addr = state->config->demod_address + 2, + .flags = 0, + .buf = b2, + .len = 2 + }, + }; + + ret = i2c_transfer(state->i2c, msg, 3); + return (ret != 3) ? -1 : 0; +} + + +static void +lgs8gl5_soft_reset(struct lgs8gl5_state *state) +{ + u8 val; + + dprintk("%s\n", __func__); + + val = lgs8gl5_read_reg(state, REG_RESET); + lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF); + lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF); + msleep(5); +} + + +static int +lgs8gl5_set_inversion(struct lgs8gl5_state *state, int inversion) +{ + u8 val; + + dprintk("%s\n", __func__); + + switch (inversion) { + case INVERSION_AUTO: + return -EOPNOTSUPP; + case INVERSION_ON: + val = lgs8gl5_read_reg(state, REG_INVERSION); + return lgs8gl5_write_reg(state, REG_INVERSION, + val | REG_INVERSION_ON); + case INVERSION_OFF: + val = lgs8gl5_read_reg(state, REG_INVERSION); + return lgs8gl5_write_reg(state, REG_INVERSION, + val & ~REG_INVERSION_ON); + default: + return -EINVAL; + } +} + + +/* Starts demodulation */ +static void +lgs8gl5_start_demod(struct lgs8gl5_state *state) +{ + u8 val; + int n; + + dprintk("%s\n", __func__); + + lgs8gl5_update_alt_reg(state, 0xc2, 0x28); + lgs8gl5_soft_reset(state); + lgs8gl5_update_reg(state, REG_07, 0x10); + lgs8gl5_update_reg(state, REG_07, 0x10); + lgs8gl5_write_reg(state, REG_09, 0x0e); + lgs8gl5_write_reg(state, REG_0A, 0xe5); + lgs8gl5_write_reg(state, REG_0B, 0x35); + lgs8gl5_write_reg(state, REG_0C, 0x30); + + lgs8gl5_update_reg(state, REG_03, 0x00); + lgs8gl5_update_reg(state, REG_7E, 0x01); + lgs8gl5_update_alt_reg(state, 0xc5, 0x00); + lgs8gl5_update_reg(state, REG_04, 0x02); + lgs8gl5_update_reg(state, REG_37, 0x01); + lgs8gl5_soft_reset(state); + + /* Wait for carrier */ + for (n = 0; n < 10; n++) { + val = lgs8gl5_read_reg(state, REG_STRENGTH); + dprintk("Wait for carrier[%d] 0x%02X\n", n, val); + if (val & REG_STRENGTH_CARRIER) + break; + msleep(4); + } + if (!(val & REG_STRENGTH_CARRIER)) + return; + + /* Wait for lock */ + for (n = 0; n < 20; n++) { + val = lgs8gl5_read_reg(state, REG_STATUS); + dprintk("Wait for lock[%d] 0x%02X\n", n, val); + if (val & REG_STATUS_LOCK) + break; + msleep(12); + } + if (!(val & REG_STATUS_LOCK)) + return; + + lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2)); + lgs8gl5_soft_reset(state); +} + + +static int +lgs8gl5_init(struct dvb_frontend *fe) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + + dprintk("%s\n", __func__); + + lgs8gl5_update_alt_reg(state, 0xc2, 0x28); + lgs8gl5_soft_reset(state); + lgs8gl5_update_reg(state, REG_07, 0x10); + lgs8gl5_update_reg(state, REG_07, 0x10); + lgs8gl5_write_reg(state, REG_09, 0x0e); + lgs8gl5_write_reg(state, REG_0A, 0xe5); + lgs8gl5_write_reg(state, REG_0B, 0x35); + lgs8gl5_write_reg(state, REG_0C, 0x30); + + return 0; +} + + +static int +lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); + u8 flags = lgs8gl5_read_reg(state, REG_STATUS); + + *status = 0; + + if ((level & REG_STRENGTH_MASK) > 0) + *status |= FE_HAS_SIGNAL; + if (level & REG_STRENGTH_CARRIER) + *status |= FE_HAS_CARRIER; + if (flags & REG_STATUS_SYNC) + *status |= FE_HAS_SYNC; + if (flags & REG_STATUS_LOCK) + *status |= FE_HAS_LOCK; + + return 0; +} + + +static int +lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + *ber = 0; + + return 0; +} + + +static int +lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); + *signal_strength = (level & REG_STRENGTH_MASK) << 8; + + return 0; +} + + +static int +lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); + *snr = (level & REG_STRENGTH_MASK) << 8; + + return 0; +} + + +static int +lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + *ucblocks = 0; + + return 0; +} + + +static int +lgs8gl5_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + + dprintk("%s\n", __func__); + + if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ) + return -EINVAL; + + if (fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, p); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + /* lgs8gl5_set_inversion(state, p->inversion); */ + + lgs8gl5_start_demod(state); + + return 0; +} + + +static int +lgs8gl5_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + u8 inv = lgs8gl5_read_reg(state, REG_INVERSION); + struct dvb_ofdm_parameters *o = &p->u.ofdm; + + p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF; + + o->code_rate_HP = FEC_1_2; + o->code_rate_LP = FEC_7_8; + o->guard_interval = GUARD_INTERVAL_1_32; + o->transmission_mode = TRANSMISSION_MODE_2K; + o->constellation = QAM_64; + o->hierarchy_information = HIERARCHY_NONE; + o->bandwidth = BANDWIDTH_8_MHZ; + + return 0; +} + + +static int +lgs8gl5_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *fesettings) +{ + fesettings->min_delay_ms = 240; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; +} + + +static void +lgs8gl5_release(struct dvb_frontend *fe) +{ + struct lgs8gl5_state *state = fe->demodulator_priv; + kfree(state); +} + + +static struct dvb_frontend_ops lgs8gl5_ops; + + +struct dvb_frontend* +lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c) +{ + struct lgs8gl5_state *state = NULL; + + dprintk("%s\n", __func__); + + /* Allocate memory for the internal state */ + state = kmalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* Setup the state */ + state->config = config; + state->i2c = i2c; + + /* Check if the demod is there */ + if (lgs8gl5_read_reg(state, REG_RESET) < 0) + goto error; + + /* Create dvb_frontend */ + memcpy(&state->frontend.ops, &lgs8gl5_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(lgs8gl5_attach); + + +static struct dvb_frontend_ops lgs8gl5_ops = { + .info = { + .name = "Legend Silicon LGS-8GL5 DMB-TH", + .type = FE_OFDM, + .frequency_min = 474000000, + .frequency_max = 858000000, + .frequency_stepsize = 10000, + .frequency_tolerance = 0, + .caps = FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | + FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_BANDWIDTH_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER + }, + + .release = lgs8gl5_release, + + .init = lgs8gl5_init, + + .set_frontend = lgs8gl5_set_frontend, + .get_frontend = lgs8gl5_get_frontend, + .get_tune_settings = lgs8gl5_get_tune_settings, + + .read_status = lgs8gl5_read_status, + .read_ber = lgs8gl5_read_ber, + .read_signal_strength = lgs8gl5_read_signal_strength, + .read_snr = lgs8gl5_read_snr, + .read_ucblocks = lgs8gl5_read_ucblocks, +}; + + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + +MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver"); +MODULE_AUTHOR("Timothy Lee"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/lgs8gl5.h b/linux/drivers/media/dvb/frontends/lgs8gl5.h new file mode 100644 index 000000000..d14176787 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgs8gl5.h @@ -0,0 +1,45 @@ +/* + Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver + + Copyright (C) 2008 Sirius International (Hong Kong) Limited + Timothy Lee + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef LGS8GL5_H +#define LGS8GL5_H + +#include + +struct lgs8gl5_config { + /* the demodulator's i2c address */ + u8 demod_address; +}; + +#if defined(CONFIG_DVB_LGS8GL5) || \ + (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE)) +extern struct dvb_frontend *lgs8gl5_attach( + const struct lgs8gl5_config *config, struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *lgs8gl5_attach( + const struct lgs8gl5_config *config, struct i2c_adapter *i2c) { + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_LGS8GL5 */ + +#endif /* LGS8GL5_H */ -- cgit v1.2.3 From 7fd7d21d543d90ecf1086f9c5909bd4c01cf69ae Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 9 Aug 2008 14:29:46 -0400 Subject: lgs8gl5: fix build warnings From: Michael Krufky Fix the following build warnings: lgs8gl5.c: In function 'lgs8gl5_read_reg': lgs8gl5.c:95: warning: unused variable 'j' lgs8gl5.c: In function 'lgs8gl5_update_alt_reg': lgs8gl5.c:135: warning: unused variable 'j' lgs8gl5.c: In function 'lgs8gl5_read_ber': lgs8gl5.c:300: warning: unused variable 'state' lgs8gl5.c: In function 'lgs8gl5_read_ucblocks': lgs8gl5.c:332: warning: unused variable 'state' lgs8gl5.c: At top level: lgs8gl5.c:181: warning: 'lgs8gl5_set_inversion' defined but not used Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/lgs8gl5.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/dvb/frontends/lgs8gl5.c b/linux/drivers/media/dvb/frontends/lgs8gl5.c index c0a223d28..380ae1868 100644 --- a/linux/drivers/media/dvb/frontends/lgs8gl5.c +++ b/linux/drivers/media/dvb/frontends/lgs8gl5.c @@ -92,7 +92,7 @@ lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data) static int lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg) { - int ret, j; + int ret; u8 b0[] = {reg}; u8 b1[] = {0}; struct i2c_msg msg[2] = { @@ -132,7 +132,7 @@ lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data) static int lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data) { - int ret, j; + int ret; u8 b0[] = {reg}; u8 b1[] = {0}; u8 b2[] = {reg, data}; @@ -175,7 +175,7 @@ lgs8gl5_soft_reset(struct lgs8gl5_state *state) msleep(5); } - +#if 0 static int lgs8gl5_set_inversion(struct lgs8gl5_state *state, int inversion) { @@ -198,7 +198,7 @@ lgs8gl5_set_inversion(struct lgs8gl5_state *state, int inversion) return -EINVAL; } } - +#endif /* Starts demodulation */ static void @@ -297,7 +297,6 @@ lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status) static int lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber) { - struct lgs8gl5_state *state = fe->demodulator_priv; *ber = 0; return 0; @@ -329,7 +328,6 @@ lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr) static int lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { - struct lgs8gl5_state *state = fe->demodulator_priv; *ucblocks = 0; return 0; -- cgit v1.2.3 From 820cd3d979980715c200c58479a5160fb7ca73f5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 11 Aug 2008 10:26:51 +0200 Subject: gspca: Remove the unused field 'dev_name' of the device structure. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.h | 1 - linux/drivers/media/video/gspca/pac207.c | 1 - linux/drivers/media/video/gspca/spca561.c | 1 - 3 files changed, 3 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/gspca.h b/linux/drivers/media/video/gspca/gspca.h index 67e448940..5cb584546 100644 --- a/linux/drivers/media/video/gspca/gspca.h +++ b/linux/drivers/media/video/gspca/gspca.h @@ -56,7 +56,6 @@ extern int gspca_debug; /* device information - set at probe time */ struct cam { - char *dev_name; struct v4l2_pix_format *cam_mode; /* size nmodes */ char nmodes; __u8 epaddr; diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c index 7ef18d578..cee45b048 100644 --- a/linux/drivers/media/video/gspca/pac207.c +++ b/linux/drivers/media/video/gspca/pac207.c @@ -271,7 +271,6 @@ static int sd_config(struct gspca_dev *gspca_dev, " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x05; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 02e274452..a9f7c99e6 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -602,7 +602,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ cam->cam_mode = sif_mode; -- cgit v1.2.3 From 77258a45e913a4808c3b25bd893a60d96a0e3778 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 11 Aug 2008 11:13:12 +0200 Subject: gspca: Big rewrite of spca561. From: Jean-Francois Moine Bug register/value inversions in USB exchanges. Exposure and gain controls added for rev 12a. Separate the functions and controls of the revisions 12a and 72a. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 595 ++++++++++++++++++------------ 1 file changed, 351 insertions(+), 244 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index a9f7c99e6..075699433 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -32,85 +32,44 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - unsigned short contrast; - __u8 brightness; - __u8 white; + __u16 contrast; /* rev72a only */ +#define CONTRAST_MIN 0x0000 +#define CONTRAST_DEF 0x2000 +#define CONTRAST_MAX 0x3fff + + __u16 exposure; /* rev12a only */ +#define EXPOSURE_MIN 0x0120 +#define EXPOSURE_DEF 0x20ae +#define EXPOSURE_MAX 0x5720 + + __u8 brightness; /* rev72a only */ +#define BRIGHTNESS_MIN 0 +#define BRIGHTNESS_DEF 32 +#define BRIGHTNESS_MAX 63 + + __u8 white; /* rev12a only */ +#define WHITE_MIN 0 +#define WHITE_DEF 0x40 +#define WHITE_MAX 0x7f + __u8 autogain; +#define AUTOGAIN_MIN 0 +#define AUTOGAIN_DEF 1 +#define AUTOGAIN_MAX 1 + + __u8 gain; /* rev12a only */ +#define GAIN_MIN 0x0 +#define GAIN_DEF 0x24 +#define GAIN_MAX 0x24 __u8 chip_revision; +#define Rev012A 0 +#define Rev072A 1 + signed char ag_cnt; #define AG_CNT_START 13 }; -/* V4L2 controls supported by the driver */ -static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); - -static struct ctrl sd_ctrls[] = { - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 63, - .step = 1, -#define BRIGHTNESS_DEF 32 - .default_value = BRIGHTNESS_DEF, - }, - .set = sd_setbrightness, - .get = sd_getbrightness, - }, - { - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 0x3fff, - .step = 1, -#define CONTRAST_DEF 0x2000 - .default_value = CONTRAST_DEF, - }, - .set = sd_setcontrast, - .get = sd_getcontrast, - }, - { - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "While Balance", - .minimum = 0, - .maximum = 0x7f, - .step = 1, -#define WHITE_DEF 40 - .default_value = WHITE_DEF, - }, - .set = sd_setwhite, - .get = sd_getwhite, - }, - { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Gain", - .minimum = 0, - .maximum = 1, - .step = 1, -#define AUTOGAIN_DEF 1 - .default_value = AUTOGAIN_DEF, - }, - .set = sd_setautogain, - .get = sd_getautogain, - }, -}; - static struct v4l2_pix_format sif_mode[] = { {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, .bytesperline = 160, @@ -160,12 +119,8 @@ static struct v4l2_pix_format sif_mode[] = { #define SPCA561_INDEX_I2C_BASE 0x8800 #define SPCA561_SNAPBIT 0x20 #define SPCA561_SNAPCTRL 0x40 -enum { - Rev072A = 0, - Rev012A, -}; -static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value) +static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) { int ret; @@ -215,12 +170,6 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, index, gspca_dev->usb_buf, len, 500); } -static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode) -{ - reg_w_val(gspca_dev->dev, 0x92, 0x8804); - reg_w_val(gspca_dev->dev, mode, 0x8802); -} - static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) { int retry = 60; @@ -229,9 +178,9 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) DataLow = valeur; DataHight = valeur >> 8; - reg_w_val(gspca_dev->dev, reg, 0x8801); - reg_w_val(gspca_dev->dev, DataLow, 0x8805); - reg_w_val(gspca_dev->dev, DataHight, 0x8800); + reg_w_val(gspca_dev->dev, 0x8801, reg); + reg_w_val(gspca_dev->dev, 0x8805, DataLow); + reg_w_val(gspca_dev->dev, 0x8800, DataHight); while (retry--) { reg_r(gspca_dev, 0x8803, 1); if (!gspca_dev->usb_buf[0]) @@ -245,9 +194,9 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) __u8 value; __u8 vallsb; - reg_w_val(gspca_dev->dev, 0x92, 0x8804); - reg_w_val(gspca_dev->dev, reg, 0x8801); - reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); + reg_w_val(gspca_dev->dev, 0x8804, 0x92); + reg_w_val(gspca_dev->dev, 0x8801, reg); + reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01)); while (retry--) { reg_r(gspca_dev, 0x8803, 1); if (!gspca_dev->usb_buf) @@ -459,6 +408,7 @@ static const __u16 spca561_init_data[][2] = { {} }; +#if 0 static void sensor_reset(struct gspca_dev *gspca_dev) { reg_w_val(gspca_dev->dev, 0x8631, 0xc8); @@ -466,10 +416,12 @@ static void sensor_reset(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev->dev, 0x8112, 0x00); reg_w_val(gspca_dev->dev, 0x8114, 0x00); reg_w_val(gspca_dev->dev, 0x8118, 0x21); - i2c_init(gspca_dev, 0x14); - i2c_write(gspca_dev, 1, 0x0d); - i2c_write(gspca_dev, 0, 0x0d); + reg_w_val(gspca_dev->dev, 0x8804, 0x92); /* i2c init */ + reg_w_val(gspca_dev->dev, 0x8802, 0x14); + i2c_write(gspca_dev, 0x0001, 0x0d); + i2c_write(gspca_dev, 0x0000, 0x0d); } +#endif /******************** QC Express etch2 stuff ********************/ static const __u16 Pb100_1map8300[][2] = { @@ -479,9 +431,9 @@ static const __u16 Pb100_1map8300[][2] = { {0x8303, 0x0125}, /* image area */ {0x8304, 0x0169}, {0x8328, 0x000b}, - {0x833c, 0x0001}, + {0x833c, 0x0001}, /*fixme: win:07*/ - {0x832f, 0x0419}, + {0x832f, 0x1904}, /*fixme: was 0419*/ {0x8307, 0x00aa}, {0x8301, 0x0003}, {0x8302, 0x000e}, @@ -547,7 +499,7 @@ static const __u16 spca561_161rev12A_data2[][2] = { {0xdf, 0x863c}, /* df */ {0xf0, 0x8505}, {0x32, 0x850a}, - {0x99, 0x8700}, /* - white balance - new */ +/* {0x99, 0x8700}, * - white balance - new (removed) */ {} }; @@ -566,9 +518,10 @@ static void sensor_mapwrite(struct gspca_dev *gspca_dev, } static void init_161rev12A(struct gspca_dev *gspca_dev) { - sensor_reset(gspca_dev); +/* sensor_reset(gspca_dev); (not in win) */ write_vector(gspca_dev, spca561_161rev12A_data1); sensor_mapwrite(gspca_dev, Pb100_1map8300); +/*fixme: should be in sd_start*/ write_vector(gspca_dev, spca561_161rev12A_data2); sensor_mapwrite(gspca_dev, Pb100_2map8300); } @@ -605,32 +558,29 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->epaddr = 0x01; gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ cam->cam_mode = sif_mode; - cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + cam->nmodes = ARRAY_SIZE(sif_mode); sd->chip_revision = id->driver_info; sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; - sd->autogain = AUTOGAIN_DEF; sd->white = WHITE_DEF; + sd->exposure = EXPOSURE_DEF; + sd->autogain = AUTOGAIN_DEF; + sd->gain = GAIN_DEF; return 0; } /* this function is called at open time */ -static int sd_open(struct gspca_dev *gspca_dev) +static int sd_open_12a(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->chip_revision) { - case Rev072A: - PDEBUG(D_STREAM, "Chip revision id: 072a"); - write_vector(gspca_dev, spca561_init_data); - break; - default: -/* case Rev012A: */ - PDEBUG(D_STREAM, "Chip revision id: 012a"); - init_161rev12A(gspca_dev); - break; - } + PDEBUG(D_STREAM, "Chip revision: 012a"); + init_161rev12A(gspca_dev); + return 0; +} +static int sd_open_72a(struct gspca_dev *gspca_dev) +{ + PDEBUG(D_STREAM, "Chip revision: 072a"); + write_vector(gspca_dev, spca561_init_data); return 0; } @@ -639,61 +589,82 @@ static void setcontrast(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; __u8 lowb; - int expotimes; switch (sd->chip_revision) { case Rev072A: lowb = sd->contrast >> 8; - reg_w_val(dev, lowb, 0x8651); - reg_w_val(dev, lowb, 0x8652); - reg_w_val(dev, lowb, 0x8653); - reg_w_val(dev, lowb, 0x8654); + reg_w_val(dev, 0x8651, lowb); + reg_w_val(dev, 0x8652, lowb); + reg_w_val(dev, 0x8653, lowb); + reg_w_val(dev, 0x8654, lowb); break; default: { /* case Rev012A: { */ +#if 1 + static const __u8 Reg8391[] = + { 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 }; + + reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); + reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); +#else + int expotimes; __u8 Reg8391[] = { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; +/*fixme: does not work..*/ /* Write camera sensor settings */ - expotimes = (sd->contrast >> 5) & 0x07ff; + expotimes = sd->contrast >> 5; /* exposure is in 8309 2b, range 0120 - 5720 */ - Reg8391[0] = expotimes & 0xff; /* exposure */ + Reg8391[0] = expotimes; /* exposure */ Reg8391[1] = 0x18 | (expotimes >> 8); Reg8391[2] = sd->brightness; /* gain */ /* gain in 8335, 2b range 0000 - 2400 */ reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); +#endif break; } } } +/* rev12a only */ static void setwhite(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u16 white; __u8 reg8614, reg8616; - switch (sd->chip_revision) { - case Rev072A: - /* no such hardware */ - break; - default: -/* case Rev012A: */ - white = sd->white; - if (sd->white == 0) { - PDEBUG(D_CONF, "Discarding null whiteness"); - break; - } - /* try to emulate MS-win as possible */ - if (white < 0x45) - reg8616 = white; - else - reg8616 = 0x93 + (white >> 2); - reg8614 = 0x28 + (white >> 4); - reg_w_val(gspca_dev->dev, reg8616, 0x8616); - reg_w_val(gspca_dev->dev, reg8614, 0x8614); + white = sd->white; + if (sd->white == 0) { + PDEBUG(D_CONF, "Discarding null whiteness"); + return; } + /* try to emulate MS-win as possible */ + if (white < 0x45) + reg8616 = white; + else + reg8616 = 0x93 + (white >> 2); + reg8614 = 0x28 + (white >> 4); + reg_w_val(gspca_dev->dev, 0x8616, reg8616); + reg_w_val(gspca_dev->dev, 0x8614, reg8614); +} + +/* rev 12a only */ +static void setexposure(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + reg_w_val(dev, 0x8309, sd->gain); +} + +/* rev 12a only */ +static void setgain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + reg_w_val(dev, 0x8335, sd->gain); } static void setautogain(struct gspca_dev *gspca_dev) @@ -708,67 +679,67 @@ static void setautogain(struct gspca_dev *gspca_dev) } } -static void sd_start(struct gspca_dev *gspca_dev) +static void sd_start_12a(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; int Clck; __u8 Reg8307[] = { 0xaa, 0x00 }; int mode; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - switch (sd->chip_revision) { - case Rev072A: - switch (mode) { - default: -/* case 0: - case 1: */ - Clck = 0x25; - break; - case 2: - Clck = 0x22; - break; - case 3: - Clck = 0x21; - break; - } - reg_w_val(dev, 0x8500, mode); /* mode */ - reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ - reg_w_val(dev, 0x8112, 0x10 | 0x20); - setautogain(gspca_dev); + switch (mode) { + case 0: + case 1: + Clck = 0x8a; + break; + case 2: + Clck = 0x85; break; default: -/* case Rev012A: */ - switch (mode) { - case 0: - case 1: - Clck = 0x8a; - break; - case 2: - Clck = 0x85; - break; - default: - Clck = 0x83; - break; - } - if (mode <= 1) { - /* Use compression on 320x240 and above */ - reg_w_val(dev, 0x8500, 0x10 | mode); - } else { - /* I couldn't get the compression to work below 320x240 - * Fortunately at these resolutions the bandwidth - * is sufficient to push raw frames at ~20fps */ - reg_w_val(dev, 0x8500, mode); - } /* -- qq@kuku.eu.org */ - reg_w_buf(gspca_dev, 0x8307, Reg8307, 2); - reg_w_val(gspca_dev->dev, 0x8700, Clck); - /* 0x8f 0x85 0x27 clock */ - reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); - reg_w_val(gspca_dev->dev, 0x850b, 0x03); - setcontrast(gspca_dev); - setwhite(gspca_dev); + Clck = 0x83; + break; + } + if (mode <= 1) { + /* Use compression on 320x240 and above */ + reg_w_val(dev, 0x8500, 0x10 | mode); + } else { + /* I couldn't get the compression to work below 320x240 + * Fortunately at these resolutions the bandwidth + * is sufficient to push raw frames at ~20fps */ + reg_w_val(dev, 0x8500, mode); + } /* -- qq@kuku.eu.org */ + reg_w_buf(gspca_dev, 0x8307, Reg8307, 2); + reg_w_val(gspca_dev->dev, 0x8700, Clck); + /* 0x8f 0x85 0x27 clock */ + reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); + reg_w_val(gspca_dev->dev, 0x850b, 0x03); + setcontrast(gspca_dev); + setwhite(gspca_dev); +} +static void sd_start_72a(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int Clck; + int mode; + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; + switch (mode) { + default: +/* case 0: + case 1: */ + Clck = 0x25; + break; + case 2: + Clck = 0x22; + break; + case 3: + Clck = 0x21; break; } + reg_w_val(dev, 0x8500, mode); /* mode */ + reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ + reg_w_val(dev, 0x8112, 0x10 | 0x20); + setautogain(gspca_dev); } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -787,6 +758,7 @@ static void sd_close(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev->dev, 0x8114, 0); } +/* rev72a only */ static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -895,24 +867,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } +/* rev 72a only */ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u8 value; - switch (sd->chip_revision) { - case Rev072A: - value = sd->brightness; - reg_w_val(gspca_dev->dev, value, 0x8611); - reg_w_val(gspca_dev->dev, value, 0x8612); - reg_w_val(gspca_dev->dev, value, 0x8613); - reg_w_val(gspca_dev->dev, value, 0x8614); - break; - default: -/* case Rev012A: */ - setcontrast(gspca_dev); - break; - } + value = sd->brightness; + reg_w_val(gspca_dev->dev, 0x8611, value); + reg_w_val(gspca_dev->dev, 0x8612, value); + reg_w_val(gspca_dev->dev, 0x8613, value); + reg_w_val(gspca_dev->dev, 0x8614, value); } static void getbrightness(struct gspca_dev *gspca_dev) @@ -920,52 +885,38 @@ static void getbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; __u16 tot; - switch (sd->chip_revision) { - case Rev072A: - tot = 0; - reg_r(gspca_dev, 0x8611, 1); - tot += gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8612, 1); - tot += gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8613, 1); - tot += gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8614, 1); - tot += gspca_dev->usb_buf[0]; - sd->brightness = tot >> 2; - break; - default: -/* case Rev012A: */ - /* no way to read sensor settings */ - break; - } + tot = 0; + reg_r(gspca_dev, 0x8611, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8612, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8613, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8614, 1); + tot += gspca_dev->usb_buf[0]; + sd->brightness = tot >> 2; } +/* rev72a only */ static void getcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u16 tot; - switch (sd->chip_revision) { - case Rev072A: - tot = 0; - reg_r(gspca_dev, 0x8651, 1); - tot += gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8652, 1); - tot += gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8653, 1); - tot += gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8654, 1); - tot += gspca_dev->usb_buf[0]; - sd->contrast = tot << 6; - break; - default: -/* case Rev012A: */ - /* no way to read sensor settings */ - break; - } + tot = 0; + reg_r(gspca_dev, 0x8651, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8652, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8653, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8654, 1); + tot += gspca_dev->usb_buf[0]; + sd->contrast = tot << 6; PDEBUG(D_CONF, "get contrast %d", sd->contrast); } +/* rev 72a only */ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -985,6 +936,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +/* rev 72a only */ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1022,7 +974,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -/* white balance - new */ +/* rev12a only */ static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1041,20 +993,173 @@ static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +/* rev12a only */ +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->exposure = val; + if (gspca_dev->streaming) + setexposure(gspca_dev); + return 0; +} + +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->exposure; + return 0; +} + +/* rev12a only */ +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->gain = val; + if (gspca_dev->streaming) + setgain(gspca_dev); + return 0; +} + +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->gain; + return 0; +} + +/* control tables */ +static struct ctrl sd_ctrls_12a[] = { + { + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "While Balance", + .minimum = WHITE_MIN, + .maximum = WHITE_MAX, + .step = 1, + .default_value = WHITE_DEF, + }, + .set = sd_setwhite, + .get = sd_getwhite, + }, + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = EXPOSURE_MIN, + .maximum = EXPOSURE_MAX, + .step = 1, + .default_value = EXPOSURE_DEF, + }, + .set = sd_setexposure, + .get = sd_getexposure, + }, + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = AUTOGAIN_MIN, + .maximum = AUTOGAIN_MAX, + .step = 1, + .default_value = AUTOGAIN_DEF, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, + { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = GAIN_MIN, + .maximum = GAIN_MAX, + .step = 1, + .default_value = GAIN_DEF, + }, + .set = sd_setgain, + .get = sd_getgain, + }, +}; + +static struct ctrl sd_ctrls_72a[] = { + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = BRIGHTNESS_MIN, + .maximum = BRIGHTNESS_MAX, + .step = 1, + .default_value = BRIGHTNESS_DEF, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = CONTRAST_MIN, + .maximum = CONTRAST_MAX, + .step = 1, + .default_value = CONTRAST_DEF, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = AUTOGAIN_MIN, + .maximum = AUTOGAIN_MAX, + .step = 1, + .default_value = AUTOGAIN_DEF, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +}; + /* sub-driver description */ -static const struct sd_desc sd_desc = { +static const struct sd_desc sd_desc_12a = { .name = MODULE_NAME, - .ctrls = sd_ctrls, - .nctrls = ARRAY_SIZE(sd_ctrls), + .ctrls = sd_ctrls_12a, + .nctrls = ARRAY_SIZE(sd_ctrls_12a), .config = sd_config, - .open = sd_open, - .start = sd_start, + .open = sd_open_12a, + .start = sd_start_12a, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +/* .dq_callback = do_autogain, * fixme */ +}; +static const struct sd_desc sd_desc_72a = { + .name = MODULE_NAME, + .ctrls = sd_ctrls_72a, + .nctrls = ARRAY_SIZE(sd_ctrls_72a), + .config = sd_config, + .open = sd_open_72a, + .start = sd_start_72a, .stopN = sd_stopN, .stop0 = sd_stop0, .close = sd_close, .pkt_scan = sd_pkt_scan, .dq_callback = do_autogain, }; +static const struct sd_desc *sd_desc[2] = { + &sd_desc_12a, + &sd_desc_72a +}; /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { @@ -1082,7 +1187,9 @@ MODULE_DEVICE_TABLE(usb, device_table); static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + return gspca_dev_probe(intf, id, + sd_desc[id->driver_info], + sizeof(struct sd), THIS_MODULE); } -- cgit v1.2.3 From 1ed2472d509f192f2420635f87057f0d53345ed6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 11 Aug 2008 17:06:20 +0200 Subject: gspca: Bad frame scanning again and bad init in pac7311. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 62 +++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 12 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 730b4a1ae..85d9ddbc5 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -220,6 +220,7 @@ static const __u8 probe_7302[] = { }; static const __u8 start_7302[] = { /* index, len, [value]* */ + 0xff, 1, 0x00, /* page 0 */ 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00, @@ -249,7 +250,7 @@ static const __u8 start_7302[] = { 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9, 0xc1, 0xd7, 0xec, 0xdc, 1, 0x01, - 0xff, 1, 0x01, + 0xff, 1, 0x01, /* page 1 */ 0x12, 3, 0x02, 0x00, 0x01, 0x3e, 2, 0x00, 0x00, 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2, @@ -257,26 +258,26 @@ static const __u8 start_7302[] = { 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20, 0x02, 0x00, 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04, - 0xc8, 17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x01, 0x07, 0x04, 0x01, - 0x01, + 0xd8, 1, 0x01, 0xdb, 2, 0x00, 0x01, - 0xde, 8, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, + 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, 0xe6, 4, 0x00, 0x00, 0x00, 0x01, 0xeb, 1, 0x00, - 0xff, 1, 0x02, + 0xff, 1, 0x02, /* page 2 */ 0x22, 1, 0x00, - 0xff, 1, 0x03, + 0xff, 1, 0x03, /* page 3 */ 0x00, 255, /* load the page 3 */ 0x11, 1, 0x01, - 0xff, 1, 0x02, + 0xff, 1, 0x02, /* page 2 */ 0x13, 1, 0x00, 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96, 0x27, 2, 0x14, 0x0c, 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22, 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44, 0x6e, 1, 0x08, - 0xff, 1, 0x03, + 0xff, 1, 0x03, /* page 1 */ 0x78, 1, 0x00, 0, 0 /* end of sequence */ }; @@ -321,14 +322,14 @@ static const __u8 probe_7311[] = { static const __u8 start_7311[] = { /* index, len, [value]* */ - 0xff, 1, 0x01, - 0x02, 53, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00, + 0xff, 1, 0x01, /* page 1 */ + 0x02, 43, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00, 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c, 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3e, 52, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e, + 0x3e, 42, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e, 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48, 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78, @@ -342,7 +343,7 @@ static const __u8 start_7311[] = { 0xa0, 4, 0x44, 0x44, 0x44, 0x04, 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00, 0x3f, 0x00, 0x0a, 0x01, 0x00, - 0xff, 1, 0x04, + 0xff, 1, 0x04, /* page 4 */ 0x00, 254, /* load the page 4 */ 0x11, 1, 0x01, 0, 0 /* end of sequence */ @@ -738,6 +739,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, #define INTER_FRAME 0x53 /* eof + inter frame + sof */ #define LUM_OFFSET 0x1e /* reverse offset / start of frame */ +/*fixme:test+*/ +/* dump the packet */ + if (gspca_debug & 0x200) { + static char tmp[50]; + + PDEBUG(0x200, "pkt_scan"); + tmp[0] = 0; + for (i = 0; i < len; i++) { + if (i % 16 == 0 && i != 0) { + PDEBUG(0x200, "%s", tmp); + tmp[0] = 0; + } + sprintf(&tmp[(i % 16) * 3], "%02x ", data[i]); + } + if (tmp[0] != 0) + PDEBUG(0x200, "%s", tmp); + } +/*fixme:test-*/ /* * inside a frame, there may be: * escaped ff ('ff 00') @@ -819,6 +838,25 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, put_jpeg_head(gspca_dev, frame); break; case 0xff: /* 'ff ff ff xx' */ +/*fixme:test+*/ +/* is there a start of frame ? */ + if (data[i + 2] == 0x00) { + static __u8 ffd9[2] = {0xff, 0xd9}; + + gspca_frame_add(gspca_dev, + INTER_PACKET, + frame, data, + i + 7 - INTER_FRAME); + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, ffd9, 2); + data += i + 7; + len -= i + 7; + i = 0; + put_jpeg_head(gspca_dev, frame); + break; + } +/*fixme:test-*/ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, i); data += i + 4; -- cgit v1.2.3 From d2e97898c7f8009430bfe79e0024051b1b6b6030 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 11 Aug 2008 20:14:52 +0200 Subject: gspca: Webcam 0c45:612e added in sonixj. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 118 +++++++++++++++++++++++++++---- 1 file changed, 106 insertions(+), 12 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 7b5b92094..2c76f02ce 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -55,8 +55,9 @@ struct sd { #define SENSOR_MI0360 1 #define SENSOR_MO4000 2 #define SENSOR_OM6802 3 -#define SENSOR_OV7648 4 -#define SENSOR_OV7660 5 +#define SENSOR_OV7630 4 +#define SENSOR_OV7648 5 +#define SENSOR_OV7660 6 unsigned char i2c_base; }; @@ -195,6 +196,17 @@ static const __u8 sn_om6802[] = { 0xf7 }; +static const __u8 sn_ov7630[] = { +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ + 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20, +/* reg8 reg9 rega regb regc regd rege regf */ + 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10, +/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ + 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2, +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + static const __u8 sn_ov7648[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, @@ -235,6 +247,7 @@ static const __u8 *sn_tb[] = { sn_mi0360, sn_mo4000, sn_om6802, + sn_ov7630, sn_ov7648, sn_ov7660 }; @@ -402,6 +415,56 @@ static __u8 om6802_sensor_init[][8] = { /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */ {} }; +static const __u8 ov7630_sensor_init[][8] = { + {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, +/* win: delay 20ms */ + {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, +/* win: delay 20ms */ + {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, +/* win: loop on 2 wwrite, 1 read */ + {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, + {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10}, + {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10}, + {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10}, + {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10}, + {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10}, + {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10}, + {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10}, + {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10}, + {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10}, + {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10}, + {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10}, + {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10}, + {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10}, + {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10}, + {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10}, + {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10}, + {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10}, + {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10}, + {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, +/* */ + {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, +/*fixme: + 0x12, 0x04*/ + {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, + {} +}; static const __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ /* (delay 20ms) */ @@ -754,6 +817,14 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w1(gspca_dev, 0x17, 0x64); reg_w1(gspca_dev, 0x01, 0x42); break; +#if 0 +/*jfm: from win trace */ + case SENSOR_OV7630: + reg_w1(gspca_dev, 0x01, 0x61); + reg_w1(gspca_dev, 0x17, 0xe2); + reg_w1(gspca_dev, 0x01, 0x60); + break; +#endif case SENSOR_OV7648: reg_w1(gspca_dev, 0x01, 0x43); reg_w1(gspca_dev, 0x17, 0xae); @@ -823,6 +894,19 @@ static void om6802_InitSensor(struct gspca_dev *gspca_dev) } } +static void ov7630_InitSensor(struct gspca_dev *gspca_dev) +{ + int i = 0; + + i2c_w8(gspca_dev, ov7630_sensor_init[i]); + i++; + msleep(20); + while (ov7630_sensor_init[i][0]) { + i2c_w8(gspca_dev, ov7630_sensor_init[i]); + i++; + } +} + static void ov7648_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; @@ -1085,8 +1169,8 @@ static void sd_start(struct gspca_dev *gspca_dev) static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ - static const __u8 CE_sn9c325[] = - { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ + static const __u8 CE_ov76xx[] = + { 0x32, 0xdd, 0x32, 0xdd }; /* OV7630/48 */ sn9c1xx = sn_tb[(int) sd->sensor]; configure_gpio(gspca_dev, sn9c1xx); @@ -1104,13 +1188,16 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0xc8, 0x50); reg_w1(gspca_dev, 0xc9, 0x3c); reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); - switch (sd->bridge) { - case BRIDGE_SN9C325: + switch (sd->sensor) { + case SENSOR_OV7630: + reg17 = 0xe2; + break; + case SENSOR_OV7648: reg17 = 0xae; break; -#if 0 +#if 1 /*jfm: from win trace */ - case BRIDGE_SN9C120: + case SENSOR_OV7660: reg17 = 0xa0; break; #endif @@ -1169,6 +1256,11 @@ static void sd_start(struct gspca_dev *gspca_dev) om6802_InitSensor(gspca_dev); reg17 = 0x64; /* 640 MCKSIZE */ break; + case SENSOR_OV7630: + ov7630_InitSensor(gspca_dev); + reg17 = 0xe2; + reg1 = 0x40; + break; case SENSOR_OV7648: ov7648_InitSensor(gspca_dev); reg17 = 0xa2; @@ -1199,9 +1291,10 @@ static void sd_start(struct gspca_dev *gspca_dev) } reg_w(gspca_dev, 0xc0, C0, 6); reg_w(gspca_dev, 0xca, CA, 4); - switch (sd->bridge) { - case BRIDGE_SN9C325: - reg_w(gspca_dev, 0xce, CE_sn9c325, 4); + switch (sd->sensor) { + case SENSOR_OV7630: + case SENSOR_OV7648: + reg_w(gspca_dev, 0xce, CE_ov76xx, 4); break; default: reg_w(gspca_dev, 0xce, CE, 4); @@ -1245,6 +1338,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) i2c_w8(gspca_dev, stopmi0360); data = 0x29; break; + case SENSOR_OV7630: case SENSOR_OV7648: data = 0x29; break; @@ -1540,7 +1634,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /*bw600.inf:*/ {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/ {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, -/* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)}, /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ #ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, -- cgit v1.2.3 From acca17a2d0197a622e05ca0f16d07700d5d83b6d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 12 Aug 2008 19:06:12 +0200 Subject: v4l2: fix for kernels <= 2.6.17 From: Hans Verkuil class and devt should also be set for kernels 2.6.16 and 2.6.17. This was the case originally, but unfortunately an earlier patch of mine inadvertently left in an incorrect #if/#endif pair. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-dev.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index 398376a40..d97320091 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -356,10 +356,8 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, /* sysfs class */ memset(&vfd->dev, 0x00, sizeof(vfd->dev)); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) vfd->dev.class = &video_class; vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); -#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) if (vfd->parent) vfd->dev.dev = vfd->parent; -- cgit v1.2.3 From bf23e05b3f443503624b55cb16f32afdcb74289c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 14 Aug 2008 10:50:14 +0200 Subject: gspca: Pixmap PJPG (Pixart 73xx JPEG) added, generated by pac7311. From: Jean-Francois Moine The JPEG frames generated by the Pixart 73xx have: - special markers 'ff ff ff xx' every 1024/512 bytes, - unused 8 bits at end of JPEG blocks, and then ask for a new pixel format. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 173 +++--------------------------- 1 file changed, 15 insertions(+), 158 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 85d9ddbc5..c148d1003 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -22,6 +22,7 @@ #define MODULE_NAME "pac7311" #include "gspca.h" +#include "jpeg.h" MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); MODULE_DESCRIPTION("Pixart PAC7311"); @@ -40,7 +41,6 @@ struct sd { unsigned char colors; unsigned char autogain; - char ffnb; /* number of 'ff' in the previous frame */ char tosof; /* number of bytes before next start of frame */ signed char ag_cnt; #define AG_CNT_START 13 @@ -121,95 +121,23 @@ static struct ctrl sd_ctrls[] = { }; static struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, .bytesperline = 160, .sizeimage = 160 * 120 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 2}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, .bytesperline = 640, .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, }; -#define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */ - -static const __u8 pac7311_jpeg_header[] = { - 0xff, 0xd8, - 0xff, 0xe0, 0x00, 0x03, 0x20, - 0xff, 0xc0, 0x00, 0x11, 0x08, - 0x01, 0xe0, /* 12: height */ - 0x02, 0x80, /* 14: width */ - 0x03, /* 16 */ - 0x01, 0x21, 0x00, - 0x02, 0x11, 0x01, - 0x03, 0x11, 0x01, - 0xff, 0xdb, 0x00, 0x84, - 0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, - 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, - 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, - 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, - 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 0x5f, - 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64, - 0x78, 0x5c, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 0x12, 0x18, - 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, - 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, - 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, - 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, - 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, - 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - 0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, - 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, - 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, - 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, - 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, - 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, - 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, - 0x11, 0x00, 0x3f, 0x00 -}; - /* pac 7302 */ static const __u8 probe_7302[] = { /* index,value */ @@ -566,7 +494,6 @@ static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - sd->ffnb = 0; sd->tosof = 0; if (sd->sensor == SENSOR_PAC7302) @@ -699,34 +626,6 @@ static void do_autogain(struct gspca_dev *gspca_dev) } } -/* output the jpeg header */ -static void put_jpeg_head(struct gspca_dev *gspca_dev, - struct gspca_frame *frame) -{ - struct sd *sd = (struct sd *) gspca_dev; - unsigned char tmpbuf[4]; - - if (sd->ag_cnt >= 0) { - if (--sd->ag_cnt < 0) { - sd->ag_cnt = AG_CNT_START; - atomic_set(&sd->avg_lum, sd->lum_sum / AG_CNT_START); - atomic_set(&sd->do_gain, 1); - } - } - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - (__u8 *) pac7311_jpeg_header, - 12); - tmpbuf[0] = gspca_dev->height >> 8; - tmpbuf[1] = gspca_dev->height & 0xff; - tmpbuf[2] = gspca_dev->width >> 8; - tmpbuf[3] = gspca_dev->width & 0xff; - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - tmpbuf, 4); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - (__u8 *) &pac7311_jpeg_header[16], - PAC7311_JPEG_HEADER_SIZE - 16); -} - /* this function is run at interrupt level */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ @@ -739,7 +638,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, #define INTER_FRAME 0x53 /* eof + inter frame + sof */ #define LUM_OFFSET 0x1e /* reverse offset / start of frame */ -/*fixme:test+*/ +#if 0 /*fixme:test+*/ /* dump the packet */ if (gspca_debug & 0x200) { static char tmp[50]; @@ -756,7 +655,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (tmp[0] != 0) PDEBUG(0x200, "%s", tmp); } -/*fixme:test-*/ +#endif /*fixme:test-*/ /* * inside a frame, there may be: * escaped ff ('ff 00') @@ -767,47 +666,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, * 0x33 bytes * one byte luminosity * 0x16 bytes - * ff ff 00 ff 96 62 44 start of frame header + * ff ff 00 ff 96 62 44 start of frame */ - if (sd->tosof == 0) { /* if inside a frame */ - - /* check for 'ff ff ff xx' at start and at end of packet */ - /* (len is always >= 3 and xx never ff) */ - switch (sd->ffnb) { - case 1: - if (data[0] != 0xff) { /* can be '00' only */ - __u8 ff; - - sd->ffnb = 0; - ff = 0xff; - gspca_frame_add(gspca_dev, INTER_PACKET, - frame, &ff, 1); - break; /* keep 'ff 00' */ - } - /* fall thru */ - case 2: - case 3: - data += 4 - sd->ffnb; - len -= 4 - sd->ffnb; - sd->ffnb = 0; - break; - } - if (data[len - 1] == 0xff) { - if (data[len - 2] == 0xff) { - if (data[len - 3] == 0xff) { - sd->ffnb = 3; - len -= 3; - } else { - sd->ffnb = 2; - len -= 2; - } - } else { - sd->ffnb = 1; - len--; - } - } - } else { /* outside a frame */ + if (sd->tosof != 0) { /* if outside a frame */ /* get the luminosity and go to the start of frame */ data += sd->tosof; @@ -815,14 +677,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (sd->tosof > LUM_OFFSET) sd->lum_sum += data[-LUM_OFFSET]; sd->tosof = 0; - put_jpeg_head(gspca_dev, frame); + jpeg_put_header(gspca_dev, frame, 1, 0x21); } for (i = 0; i < len; i++) { if (data[i] != 0xff) continue; switch (data[i + 1]) { - case 0xd9: /* end of frame */ + case 0xd9: /* 'ff d9' end of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, i + 2); @@ -835,11 +697,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, sd->tosof = -len; break; } - put_jpeg_head(gspca_dev, frame); + jpeg_put_header(gspca_dev, frame, 1, 0x21); break; - case 0xff: /* 'ff ff ff xx' */ -/*fixme:test+*/ +#if 0 /*fixme:test+*/ /* is there a start of frame ? */ + case 0xff: /* 'ff ff' */ if (data[i + 2] == 0x00) { static __u8 ffd9[2] = {0xff, 0xd9}; @@ -853,16 +715,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data += i + 7; len -= i + 7; i = 0; - put_jpeg_head(gspca_dev, frame); + jpeg_put_header(gspca_dev, frame, 1, 0x21); break; } -/*fixme:test-*/ - gspca_frame_add(gspca_dev, INTER_PACKET, - frame, data, i); - data += i + 4; - len -= i + 4; - i = 0; break; +#endif /*fixme:test-*/ } } gspca_frame_add(gspca_dev, INTER_PACKET, -- cgit v1.2.3 From 9ef1bd852be3b4191f3db5d56e022cf6eb59512a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 14 Aug 2008 13:37:28 +0200 Subject: gspca: Do controls work for spca561 revision 12a. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 73 +++++++++++++++++++------------ 1 file changed, 46 insertions(+), 27 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 075699433..c1fb1d60b 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -38,9 +38,9 @@ struct sd { #define CONTRAST_MAX 0x3fff __u16 exposure; /* rev12a only */ -#define EXPOSURE_MIN 0x0120 +#define EXPOSURE_MIN 0x2001 #define EXPOSURE_DEF 0x20ae -#define EXPOSURE_MAX 0x5720 +#define EXPOSURE_MAX 0x421d __u8 brightness; /* rev72a only */ #define BRIGHTNESS_MIN 0 @@ -62,6 +62,9 @@ struct sd { #define GAIN_DEF 0x24 #define GAIN_MAX 0x24 +#define EXPO12A_DEF 3 + __u8 expo12a; /* expo/gain? for rev 12a */ + __u8 chip_revision; #define Rev012A 0 #define Rev072A 1 @@ -567,6 +570,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->exposure = EXPOSURE_DEF; sd->autogain = AUTOGAIN_DEF; sd->gain = GAIN_DEF; + sd->expo12a = EXPO12A_DEF; return 0; } @@ -640,12 +644,9 @@ static void setwhite(struct gspca_dev *gspca_dev) return; } /* try to emulate MS-win as possible */ - if (white < 0x45) - reg8616 = white; - else - reg8616 = 0x93 + (white >> 2); - reg8614 = 0x28 + (white >> 4); + reg8616 = 0x90 - white * 5 / 8; reg_w_val(gspca_dev->dev, 0x8616, reg8616); + reg8614 = 0x20 + white * 3 / 8; reg_w_val(gspca_dev->dev, 0x8614, reg8614); } @@ -653,30 +654,32 @@ static void setwhite(struct gspca_dev *gspca_dev) static void setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; + __u8 data[2]; - reg_w_val(dev, 0x8309, sd->gain); + data[0] = sd->exposure; + data[1] = sd->exposure >> 8; + reg_w_buf(gspca_dev, 0x8309, data, 2); } /* rev 12a only */ static void setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; + __u8 data[2]; - reg_w_val(dev, 0x8335, sd->gain); + data[0] = sd->gain; + data[1] = 0; + reg_w_buf(gspca_dev, 0x8335, data, 2); } static void setautogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (sd->chip_revision == Rev072A) { - if (sd->autogain) - sd->ag_cnt = AG_CNT_START; - else - sd->ag_cnt = -1; - } + if (sd->autogain) + sd->ag_cnt = AG_CNT_START; + else + sd->ag_cnt = -1; } static void sd_start_12a(struct gspca_dev *gspca_dev) @@ -715,6 +718,7 @@ static void sd_start_12a(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev->dev, 0x850b, 0x03); setcontrast(gspca_dev); setwhite(gspca_dev); + setautogain(gspca_dev); } static void sd_start_72a(struct gspca_dev *gspca_dev) { @@ -744,12 +748,24 @@ static void sd_start_72a(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - reg_w_val(gspca_dev->dev, 0x8112, 0x20); - reg_w_val(gspca_dev->dev, 0x8102, 0x00); /* white balance - new */ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->chip_revision == Rev012A) { + reg_w_val(gspca_dev->dev, 0x8112, 0x0e); + } else { + reg_w_val(gspca_dev->dev, 0x8112, 0x20); +/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */ + } } static void sd_stop0(struct gspca_dev *gspca_dev) { + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->chip_revision == Rev012A) { + reg_w_val(gspca_dev->dev, 0x8118, 0x29); + reg_w_val(gspca_dev->dev, 0x8114, 0x08); + } } /* this function is called at close time */ @@ -758,7 +774,6 @@ static void sd_close(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev->dev, 0x8114, 0); } -/* rev72a only */ static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -770,6 +785,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) __u8 luma_mean = 110; __u8 luma_delta = 20; __u8 spring = 4; + __u8 reg8339[2]; if (sd->ag_cnt < 0) return; @@ -824,13 +840,16 @@ static void do_autogain(struct gspca_dev *gspca_dev) } break; case Rev012A: - /* sensor registers is access and memory mapped to 0x8300 */ - /* readind all 0x83xx block the sensor */ - /* - * The data from the header seem wrong where is the luma - * and chroma mean value - * at the moment set exposure in contrast set - */ + reg_r(gspca_dev, 0x8330, 2); + if (gspca_dev->usb_buf[1] > 0x08) { + reg8339[0] = ++sd->expo12a; + reg8339[1] = 0; + reg_w_buf(gspca_dev, 0x8339, reg8339, 2); + } else if (gspca_dev->usb_buf[1] < 0x02) { + reg8339[0] = --sd->expo12a; + reg8339[1] = 0; + reg_w_buf(gspca_dev, 0x8339, reg8339, 2); + } break; } } -- cgit v1.2.3 From abbb53148b769e275aba74bdf00b7dc50b937628 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 14 Aug 2008 17:02:51 +0200 Subject: Add support for Micron MT9M111 camera. Adds support for Micron MT9M111 camera chip, with basic features : - view rectangle configurable - some output formats (bayer8, bayer10, rgb565, rgb555, ycbycr) - autoexposure - only highpower mode context used (ie. context B) Signed-off-by: Robert Jarzmik Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/Kconfig | 6 + drivers/media/video/Makefile | 1 + drivers/media/video/mt9m111.c | 960 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 967 insertions(+), 0 deletions(-) create mode 100644 drivers/media/video/mt9m111.c --- linux/drivers/media/video/Kconfig | 6 + linux/drivers/media/video/Makefile | 1 + linux/drivers/media/video/mt9m111.c | 960 ++++++++++++++++++++++++++++++++++++ 3 files changed, 967 insertions(+) create mode 100644 linux/drivers/media/video/mt9m111.c (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 4c96b690a..c6516d42c 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -809,6 +809,12 @@ config MT9M001_PCA9536_SWITCH Select this if your MT9M001 camera uses a PCA9536 I2C GPIO extender to switch between 8 and 10 bit datawidth modes +config SOC_CAMERA_MT9M111 + tristate "mt9m001 support" + depends on SOC_CAMERA && I2C + help + This driver supports MT9M111 cameras from Micron + config SOC_CAMERA_MT9V022 tristate "mt9v022 support" depends on SOC_CAMERA && I2C diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index bf429b023..44e6ab891 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -138,6 +138,7 @@ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o +obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c new file mode 100644 index 000000000..0c88e5d6d --- /dev/null +++ b/linux/drivers/media/video/mt9m111.c @@ -0,0 +1,960 @@ +/* + * Driver for MT9M111 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Robert Jarzmik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * mt9m111 i2c address is 0x5d or 0x48 (depending on SAddr pin) + * The platform has to define i2c_board_info and call i2c_register_board_info() + */ + +/* mt9m111: Sensor register addresses */ +#define MT9M111_CHIP_VERSION 0x000 +#define MT9M111_ROW_START 0x001 +#define MT9M111_COLUMN_START 0x002 +#define MT9M111_WINDOW_HEIGHT 0x003 +#define MT9M111_WINDOW_WIDTH 0x004 +#define MT9M111_HORIZONTAL_BLANKING_B 0x005 +#define MT9M111_VERTICAL_BLANKING_B 0x006 +#define MT9M111_HORIZONTAL_BLANKING_A 0x007 +#define MT9M111_VERTICAL_BLANKING_A 0x008 +#define MT9M111_SHUTTER_WIDTH 0x009 +#define MT9M111_ROW_SPEED 0x00a +#define MT9M111_EXTRA_DELAY 0x00b +#define MT9M111_SHUTTER_DELAY 0x00c +#define MT9M111_RESET 0x00d +#define MT9M111_READ_MODE_B 0x020 +#define MT9M111_READ_MODE_A 0x021 +#define MT9M111_FLASH_CONTROL 0x023 +#define MT9M111_GREEN1_GAIN 0x02b +#define MT9M111_BLUE_GAIN 0x02c +#define MT9M111_RED_GAIN 0x02d +#define MT9M111_GREEN2_GAIN 0x02e +#define MT9M111_GLOBAL_GAIN 0x02f +#define MT9M111_CONTEXT_CONTROL 0x0c8 +#define MT9M111_PAGE_MAP 0x0f0 +#define MT9M111_BYTE_WISE_ADDR 0x0f1 + +#define MT9M111_RESET_SYNC_CHANGES (1 << 15) +#define MT9M111_RESET_RESTART_BAD_FRAME (1 << 9) +#define MT9M111_RESET_SHOW_BAD_FRAMES (1 << 8) +#define MT9M111_RESET_RESET_SOC (1 << 5) +#define MT9M111_RESET_OUTPUT_DISABLE (1 << 4) +#define MT9M111_RESET_CHIP_ENABLE (1 << 3) +#define MT9M111_RESET_ANALOG_STANDBY (1 << 2) +#define MT9M111_RESET_RESTART_FRAME (1 << 1) +#define MT9M111_RESET_RESET_MODE (1 << 0) + +#define MT9M111_RMB_MIRROR_COLS (1 << 1) +#define MT9M111_RMB_MIRROR_ROWS (1 << 0) +#define MT9M111_CTXT_CTRL_RESTART (1 << 15) +#define MT9M111_CTXT_CTRL_DEFECTCOR_B (1 << 12) +#define MT9M111_CTXT_CTRL_RESIZE_B (1 << 10) +#define MT9M111_CTXT_CTRL_CTRL2_B (1 << 9) +#define MT9M111_CTXT_CTRL_GAMMA_B (1 << 8) +#define MT9M111_CTXT_CTRL_XENON_EN (1 << 7) +#define MT9M111_CTXT_CTRL_READ_MODE_B (1 << 3) +#define MT9M111_CTXT_CTRL_LED_FLASH_EN (1 << 2) +#define MT9M111_CTXT_CTRL_VBLANK_SEL_B (1 << 1) +#define MT9M111_CTXT_CTRL_HBLANK_SEL_B (1 << 0) +/* + * mt9m111: Colorpipe register addresses (0x100..0x1ff) + */ +#define MT9M111_OPER_MODE_CTRL 0x106 +#define MT9M111_OUTPUT_FORMAT_CTRL 0x108 +#define MT9M111_REDUCER_XZOOM_B 0x1a0 +#define MT9M111_REDUCER_XSIZE_B 0x1a1 +#define MT9M111_REDUCER_YZOOM_B 0x1a3 +#define MT9M111_REDUCER_YSIZE_B 0x1a4 +#define MT9M111_REDUCER_XZOOM_A 0x1a6 +#define MT9M111_REDUCER_XSIZE_A 0x1a7 +#define MT9M111_REDUCER_YZOOM_A 0x1a9 +#define MT9M111_REDUCER_YSIZE_A 0x1aa + +#define MT9M111_OUTPUT_FORMAT_CTRL2_A 0x13a +#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b + +#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14) + + +#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14) +#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10) +#define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9) +#define MT9M111_OUTFMT_RGB (1 << 8) +#define MT9M111_OUTFMT_RGB565 (0x0 << 6) +#define MT9M111_OUTFMT_RGB555 (0x1 << 6) +#define MT9M111_OUTFMT_RGB444x (0x2 << 6) +#define MT9M111_OUTFMT_RGBx444 (0x3 << 6) +#define MT9M111_OUTFMT_TST_RAMP_OFF (0x0 << 4) +#define MT9M111_OUTFMT_TST_RAMP_COL (0x1 << 4) +#define MT9M111_OUTFMT_TST_RAMP_ROW (0x2 << 4) +#define MT9M111_OUTFMT_TST_RAMP_FRAME (0x3 << 4) +#define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3) +#define MT9M111_OUTFMT_AVG_CHROMA (1 << 2) +#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 << 1) +#define MT9M111_OUTFMT_SWAP_RGB_EVEN (1 << 1) +#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr (1 << 0) +/* + * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) + */ + +#define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg) +#define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val)) +#define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val)) +#define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val)) + +#define MT9M111_MIN_DARK_ROWS 8 +#define MT9M111_MIN_DARK_COLS 24 +#define MT9M111_MAX_HEIGHT 1024 +#define MT9M111_MAX_WIDTH 1280 + +#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ + { .name = _name, .depth = _depth, .fourcc = _fourcc, \ + .colorspace = _colorspace } +#define RGB_FMT(_name, _depth, _fourcc) \ + COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB) + +static const struct soc_camera_data_format mt9m111_colour_formats[] = { + COL_FMT("YCrYCb 8 bit", 8, V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_JPEG), + RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565), + RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555), + RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16), + RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8), +}; + +enum mt9m111_context { + HIGHPOWER = 0, + LOWPOWER, +}; + +struct mt9m111 { + struct i2c_client *client; + struct soc_camera_device icd; + int model; /* V4L2_IDENT_MT9M111* codes from v4l2-chip-ident.h */ + enum mt9m111_context context; + unsigned int left, top, width, height; + u32 pixfmt; + unsigned char autoexposure; + unsigned char datawidth; + unsigned int powered:1; + unsigned int hflip:1; + unsigned int vflip:1; + unsigned int swap_rgb_even_odd:1; + unsigned int swap_rgb_red_blue:1; + unsigned int swap_yuv_y_chromas:1; + unsigned int swap_yuv_cb_cr:1; +}; + +static int reg_page_map_set(struct i2c_client *client, const u16 reg) +{ + int ret; + u16 page; + static int lastpage = -1; /* PageMap cache value */ + + page = (reg >> 8); + if (page == lastpage) + return 0; + if (page > 2) + return -EINVAL; + + ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); + if (ret >= 0) + lastpage = page; + return ret; +} + +static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct i2c_client *client = mt9m111->client; + int ret; + + ret = reg_page_map_set(client, reg); + if (!ret) + ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); + + dev_dbg(&icd->dev, "read reg.%03x -> %04x\n", reg, ret); + return ret; +} + +static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct i2c_client *client = mt9m111->client; + int ret; + + ret = reg_page_map_set(client, reg); + if (ret >= 0) + ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), + swab16(data)); + dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); + return ret; +} + +static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + int ret; + + ret = mt9m111_reg_read(icd, reg); + if (ret >= 0) + ret = mt9m111_reg_write(icd, reg, ret | data); + return ret; +} + +static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + int ret; + + ret = mt9m111_reg_read(icd, reg); + return mt9m111_reg_write(icd, reg, ret & ~data); +} + +static int mt9m111_set_context(struct soc_camera_device *icd, + enum mt9m111_context ctxt) +{ + int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B + | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B + | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B + | MT9M111_CTXT_CTRL_VBLANK_SEL_B + | MT9M111_CTXT_CTRL_HBLANK_SEL_B; + int valA = MT9M111_CTXT_CTRL_RESTART; + + if (ctxt == HIGHPOWER) + return reg_write(CONTEXT_CONTROL, valB); + else + return reg_write(CONTEXT_CONTROL, valA); +} + +static int mt9m111_setup_rect(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0, is_raw_format; + int width = mt9m111->width; + int height = mt9m111->height; + + if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) + || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) + is_raw_format = 1; + else + is_raw_format = 0; + + if (ret >= 0) + ret = reg_write(COLUMN_START, mt9m111->left); + if (ret >= 0) + ret = reg_write(ROW_START, mt9m111->top); + + if (is_raw_format) { + if (ret >= 0) + ret = reg_write(WINDOW_WIDTH, width); + if (ret >= 0) + ret = reg_write(WINDOW_HEIGHT, height); + } else { + if (ret >= 0) + ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); + if (ret >= 0) + ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT); + if (ret >= 0) + ret = reg_write(REDUCER_XSIZE_B, width); + if (ret >= 0) + ret = reg_write(REDUCER_YSIZE_B, height); + if (ret >= 0) + ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH); + if (ret >= 0) + ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT); + if (ret >= 0) + ret = reg_write(REDUCER_XSIZE_A, width); + if (ret >= 0) + ret = reg_write(REDUCER_YSIZE_A, height); + } + + return ret; +} + +static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) +{ + int ret; + + ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); + if (ret >= 0) + ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); + return ret; +} + +static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) +{ + return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); +} + +static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) +{ + + return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); +} + +static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_rgb_red_blue) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_rgb_even_odd) + val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; + val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_rgb_red_blue) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_rgb_even_odd) + val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; + val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_yuv_cb_cr) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_yuv_y_chromas) + val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_enable(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); + if (ret >= 0) + mt9m111->powered = 1; + return ret; +} + +static int mt9m111_disable(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); + if (ret >= 0) + mt9m111->powered = 0; + return ret; +} + +static int mt9m111_reset(struct soc_camera_device *icd) +{ + int ret; + + ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); + if (ret >= 0) + ret = reg_set(RESET, MT9M111_RESET_RESET_SOC); + if (ret >= 0) + ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE + | MT9M111_RESET_RESET_SOC); + return ret; +} + +static int mt9m111_start_capture(struct soc_camera_device *icd) +{ + return 0; +} + +static int mt9m111_stop_capture(struct soc_camera_device *icd) +{ + return 0; +} + +static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) +{ + return SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | + SOCAM_DATAWIDTH_8; +} + +static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) +{ + return 0; +} + +static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + switch (pixfmt) { + case V4L2_PIX_FMT_SBGGR8: + ret = mt9m111_setfmt_bayer8(icd); + break; + case V4L2_PIX_FMT_SBGGR16: + ret = mt9m111_setfmt_bayer10(icd); + break; + case V4L2_PIX_FMT_RGB555: + ret = mt9m111_setfmt_rgb555(icd); + break; + case V4L2_PIX_FMT_RGB565: + ret = mt9m111_setfmt_rgb565(icd); + break; + case V4L2_PIX_FMT_YUYV: + ret = mt9m111_setfmt_yuv(icd); + break; + default: + dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); + ret = -EINVAL; + } + + if (ret >= 0) + mt9m111->pixfmt = pixfmt; + + return ret; +} + +static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + mt9m111->left = rect->left; + mt9m111->top = rect->top; + mt9m111->width = rect->width; + mt9m111->height = rect->height; + + dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", + __func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width, + mt9m111->height); + + ret = mt9m111_setup_rect(icd); + if (ret >= 0) + ret = mt9m111_set_pixfmt(icd, pixfmt); + return ret < 0 ? ret : 0; +} + +static int mt9m111_try_fmt_cap(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + if (f->fmt.pix.height > MT9M111_MAX_HEIGHT) + f->fmt.pix.height = MT9M111_MAX_HEIGHT; + if (f->fmt.pix.width > MT9M111_MAX_WIDTH) + f->fmt.pix.width = MT9M111_MAX_WIDTH; + + return 0; +} + +static int mt9m111_get_chip_id(struct soc_camera_device *icd, + struct v4l2_chip_ident *id) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match_chip != mt9m111->client->addr) + return -ENODEV; + + id->ident = mt9m111->model; + id->revision = 0; + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int mt9m111_get_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + int val; + + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + return -EINVAL; + if (reg->match_chip != mt9m111->client->addr) + return -ENODEV; + + val = mt9m111_reg_read(icd, reg->reg); + reg->val = (u64)val; + + if (reg->val > 0xffff) + return -EIO; + + return 0; +} + +static int mt9m111_set_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + return -EINVAL; + + if (reg->match_chip != mt9m111->client->addr) + return -ENODEV; + + if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) + return -EIO; + + return 0; +} +#endif + +static const struct v4l2_queryctrl mt9m111_controls[] = { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Verticaly", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Horizontaly", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { /* gain = 1/32*val (=>gain=1 if val==32) */ + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 63 * 2 * 2, + .step = 1, + .default_value = 32, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_EXPOSURE_AUTO, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Exposure", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + } +}; + +static int mt9m111_video_probe(struct soc_camera_device *); +static void mt9m111_video_remove(struct soc_camera_device *); +static int mt9m111_get_control(struct soc_camera_device *, + struct v4l2_control *); +static int mt9m111_set_control(struct soc_camera_device *, + struct v4l2_control *); +static int mt9m111_resume(struct soc_camera_device *icd); +static int mt9m111_init(struct soc_camera_device *icd); +static int mt9m111_release(struct soc_camera_device *icd); + +static struct soc_camera_ops mt9m111_ops = { + .owner = THIS_MODULE, + .probe = mt9m111_video_probe, + .remove = mt9m111_video_remove, + .init = mt9m111_init, + .resume = mt9m111_resume, + .release = mt9m111_release, + .start_capture = mt9m111_start_capture, + .stop_capture = mt9m111_stop_capture, + .set_fmt_cap = mt9m111_set_fmt_cap, + .try_fmt_cap = mt9m111_try_fmt_cap, + .query_bus_param = mt9m111_query_bus_param, + .set_bus_param = mt9m111_set_bus_param, + .controls = mt9m111_controls, + .num_controls = ARRAY_SIZE(mt9m111_controls), + .get_control = mt9m111_get_control, + .set_control = mt9m111_set_control, + .get_chip_id = mt9m111_get_chip_id, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .get_register = mt9m111_get_register, + .set_register = mt9m111_set_register, +#endif +}; + +static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + if (mt9m111->context == HIGHPOWER) { + if (flip) + ret = reg_set(READ_MODE_B, mask); + else + ret = reg_clear(READ_MODE_B, mask); + } else { + if (flip) + ret = reg_set(READ_MODE_A, mask); + else + ret = reg_clear(READ_MODE_A, mask); + } + + return ret; +} + +static int mt9m111_get_global_gain(struct soc_camera_device *icd) +{ + unsigned int data, gain; + + data = reg_read(GLOBAL_GAIN); + if (data >= 0) + gain = ((data & (1 << 10)) * 2) + | ((data & (1 << 9)) * 2) + | (data & 0x2f); + else + gain = data; + + return gain; +} +static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) +{ + u16 val; + + if (gain > 63 * 2 * 2) + return -EINVAL; + + icd->gain = gain; + if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) + val = (1 << 10) | (1 << 9) | (gain / 4); + else if ((gain >= 64) && (gain < 64 * 2)) + val = (1<<9) | (gain / 2); + else + val = gain; + + return reg_write(GLOBAL_GAIN, val); +} + +static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + if (on) + ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); + else + ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); + + if (ret >= 0) + mt9m111->autoexposure = on; + + return ret; +} +static int mt9m111_get_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int data; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + if (mt9m111->context == HIGHPOWER) + data = reg_read(READ_MODE_B); + else + data = reg_read(READ_MODE_A); + + if (data < 0) + return -EIO; + ctrl->value = !!(data & MT9M111_RMB_MIRROR_ROWS); + break; + case V4L2_CID_HFLIP: + if (mt9m111->context == HIGHPOWER) + data = reg_read(READ_MODE_B); + else + data = reg_read(READ_MODE_A); + + if (data < 0) + return -EIO; + ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); + break; + case V4L2_CID_GAIN: + data = mt9m111_get_global_gain(icd); + if (data < 0) + return data; + ctrl->value = data; + break; + case V4L2_CID_EXPOSURE_AUTO: + ctrl->value = mt9m111->autoexposure; + break; + } + return 0; +} + +static int mt9m111_set_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + const struct v4l2_queryctrl *qctrl; + int ret = 0; + + qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); + + if (!qctrl) + return -EINVAL; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + mt9m111->vflip = ctrl->value; + ret = mt9m111_set_flip(icd, ctrl->value, + MT9M111_RMB_MIRROR_ROWS); + break; + case V4L2_CID_HFLIP: + mt9m111->hflip = ctrl->value; + ret = mt9m111_set_flip(icd, ctrl->value, + MT9M111_RMB_MIRROR_COLS); + break; + case V4L2_CID_GAIN: + ret = mt9m111_set_global_gain(icd, ctrl->value); + break; + case V4L2_CID_EXPOSURE_AUTO: + ret = mt9m111_set_autoexposure(icd, ctrl->value); + break; + default: + ret = -EINVAL; + } + + return ret < 0 ? -EIO : 0; +} + +int mt9m111_restore_state(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + mt9m111_set_context(icd, mt9m111->context); + mt9m111_set_pixfmt(icd, mt9m111->pixfmt); + mt9m111_setup_rect(icd); + mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); + mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); + mt9m111_set_global_gain(icd, icd->gain); + mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + return 0; +} + +static int mt9m111_resume(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + if (mt9m111->powered) { + ret = mt9m111_enable(icd); + if (ret >= 0) + mt9m111_reset(icd); + if (ret >= 0) + mt9m111_restore_state(icd); + } + return ret; +} + +static int mt9m111_init(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + mt9m111->context = HIGHPOWER; + ret = mt9m111_enable(icd); + if (ret >= 0) + mt9m111_reset(icd); + if (ret >= 0) + mt9m111_set_context(icd, mt9m111->context); + if (ret >= 0) + mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + if (ret < 0) + dev_err(&icd->dev, "mt9m111 init failed: %d\n", ret); + return ret ? -EIO : 0; +} + +static int mt9m111_release(struct soc_camera_device *icd) +{ + int ret; + + ret = mt9m111_disable(icd); + if (ret < 0) + dev_err(&icd->dev, "mt9m111 release failed: %d\n", ret); + + return ret ? -EIO : 0; +} + +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ +static int mt9m111_video_probe(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + s32 data; + int ret; + + /* + * We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. + */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + ret = mt9m111_enable(icd); + if (ret) + goto ei2c; + ret = mt9m111_reset(icd); + if (ret) + goto ei2c; + + data = reg_read(CHIP_VERSION); + + switch (data) { + case 0x143a: + mt9m111->model = V4L2_IDENT_MT9M111; + icd->formats = mt9m111_colour_formats; + icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); + break; + default: + ret = -ENODEV; + dev_err(&icd->dev, + "No MT9M111 chip detected, register read %x\n", data); + goto ei2c; + } + + dev_info(&icd->dev, "Detected a MT9M111 chip ID 0x143a\n"); + + ret = soc_camera_video_start(icd); + if (ret) + goto eisis; + + mt9m111->autoexposure = 1; + + mt9m111->swap_rgb_even_odd = 1; + mt9m111->swap_rgb_red_blue = 1; + + return 0; +eisis: +ei2c: + return ret; +} + +static void mt9m111_video_remove(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m111->client->addr, + mt9m111->icd.dev.parent, mt9m111->icd.vdev); + soc_camera_video_stop(&mt9m111->icd); +} + +static int mt9m111_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct mt9m111 *mt9m111; + struct soc_camera_device *icd; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl = client->dev.platform_data; + int ret; + + if (!icl) { + dev_err(&client->dev, "MT9M111 driver needs platform data\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); + return -EIO; + } + + mt9m111 = kzalloc(sizeof(struct mt9m111), GFP_KERNEL); + if (!mt9m111) + return -ENOMEM; + + mt9m111->client = client; + i2c_set_clientdata(client, mt9m111); + + /* Second stage probe - when a capture adapter is there */ + icd = &mt9m111->icd; + icd->ops = &mt9m111_ops; + icd->control = &client->dev; + icd->x_min = MT9M111_MIN_DARK_COLS; + icd->y_min = MT9M111_MIN_DARK_ROWS; + icd->x_current = icd->x_min; + icd->y_current = icd->y_min; + icd->width_min = MT9M111_MIN_DARK_ROWS; + icd->width_max = MT9M111_MAX_WIDTH; + icd->height_min = MT9M111_MIN_DARK_COLS; + icd->height_max = MT9M111_MAX_HEIGHT; + icd->y_skip_top = 0; + icd->iface = icl->bus_id; + + ret = soc_camera_device_register(icd); + if (ret) + goto eisdr; + return 0; + +eisdr: + kfree(mt9m111); + return ret; +} + +static int mt9m111_remove(struct i2c_client *client) +{ + struct mt9m111 *mt9m111 = i2c_get_clientdata(client); + soc_camera_device_unregister(&mt9m111->icd); + kfree(mt9m111); + + return 0; +} + +static const struct i2c_device_id mt9m111_id[] = { + { "mt9m111", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mt9m111_id); + +static struct i2c_driver mt9m111_i2c_driver = { + .driver = { + .name = "mt9m111", + }, + .probe = mt9m111_probe, + .remove = mt9m111_remove, + .id_table = mt9m111_id, +}; + +static int __init mt9m111_mod_init(void) +{ + return i2c_add_driver(&mt9m111_i2c_driver); +} + +static void __exit mt9m111_mod_exit(void) +{ + i2c_del_driver(&mt9m111_i2c_driver); +} + +module_init(mt9m111_mod_init); +module_exit(mt9m111_mod_exit); + +MODULE_DESCRIPTION("Micron MT9M111 Camera driver"); +MODULE_AUTHOR("Robert Jarzmik"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 2068653681ec2030c378a0d1e25d1d451f7cd929 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 14 Aug 2008 17:03:18 +0200 Subject: mt9m001, mt9v022: Simplify return code checking i2c_smbus_write_word_data() returns 0 or a negative error, hence no need to check for "> 0". Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/mt9m001.c | 24 ++++++++++++------------ drivers/media/video/mt9v022.c | 28 ++++++++++++++-------------- 2 files changed, 26 insertions(+), 26 deletions(-) --- linux/drivers/media/video/mt9m001.c | 24 ++++++++++++------------ linux/drivers/media/video/mt9v022.c | 28 ++++++++++++++-------------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index f4742936c..2c2d0903e 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -119,16 +119,16 @@ static int mt9m001_init(struct soc_camera_device *icd) { int ret; - /* Disable chip, synchronous option update */ dev_dbg(icd->vdev->parent, "%s\n", __func__); ret = reg_write(icd, MT9M001_RESET, 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_RESET, 0); - if (ret >= 0) + /* Disable chip, synchronous option update */ + if (!ret) ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); - return ret >= 0 ? 0 : -EIO; + return ret; } static int mt9m001_release(struct soc_camera_device *icd) @@ -267,24 +267,24 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, /* Blanking and start values - default... */ ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); /* The caller provides a supported format, as verified per * call to icd->try_fmt_cap() */ - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_ROW_START, rect->top); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, rect->height + icd->y_skip_top - 1); - if (ret >= 0 && mt9m001->autoexposure) { + if (!ret && mt9m001->autoexposure) { ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, rect->height + icd->y_skip_top + vblank); - if (ret >= 0) { + if (!ret) { const struct v4l2_queryctrl *qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); @@ -295,7 +295,7 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, } } - return ret < 0 ? ret : 0; + return ret; } static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index 1ff36edd7..d9b229579 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -141,22 +141,22 @@ static int mt9v022_init(struct soc_camera_device *icd) * plus snapshot mode to disable scan for now */ mt9v022->chip_control |= 0x10; ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); - if (ret >= 0) - reg_write(icd, MT9V022_READ_MODE, 0x300); + if (!ret) + ret = reg_write(icd, MT9V022_READ_MODE, 0x300); /* All defaults */ - if (ret >= 0) + if (!ret) /* AEC, AGC on */ ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); - if (ret >= 0) + if (!ret) /* default - auto */ ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); - return ret >= 0 ? 0 : -EIO; + return ret; } static int mt9v022_release(struct soc_camera_device *icd) @@ -352,21 +352,21 @@ static int mt9v022_set_fmt_cap(struct soc_camera_device *icd, rect->height + icd->y_skip_top + 43); } /* Setup frame format: defaults apart from width and height */ - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_ROW_START, rect->top); - if (ret >= 0) + if (!ret) /* Default 94, Phytec driver says: * "width + horizontal blank >= 660" */ ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, rect->width > 660 - 43 ? 43 : 660 - rect->width); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, rect->height + icd->y_skip_top); @@ -717,7 +717,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) icd->num_formats = 1; } - if (ret >= 0) + if (!ret) ret = soc_camera_video_start(icd); if (ret < 0) goto eisis; -- cgit v1.2.3 From 4da232f764389ccafbe28832bf57aeae316d465f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 14 Aug 2008 17:03:49 +0200 Subject: mt9m111: style cleanup Fix a typo in Kconfig, simplify error checking, further minor cleanup. Signed-off-by: Guennadi Liakhovetski Tested-by: Robert Jarzmik --- drivers/media/video/Kconfig | 2 +- drivers/media/video/mt9m111.c | 86 ++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 45 deletions(-) --- linux/drivers/media/video/Kconfig | 2 +- linux/drivers/media/video/mt9m111.c | 86 ++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 45 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index c6516d42c..f8f7b3b44 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -810,7 +810,7 @@ config MT9M001_PCA9536_SWITCH extender to switch between 8 and 10 bit datawidth modes config SOC_CAMERA_MT9M111 - tristate "mt9m001 support" + tristate "mt9m111 support" depends on SOC_CAMERA && I2C help This driver supports MT9M111 cameras from Micron diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c index 0c88e5d6d..d99932631 100644 --- a/linux/drivers/media/video/mt9m111.c +++ b/linux/drivers/media/video/mt9m111.c @@ -173,7 +173,7 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg) return -EINVAL; ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); - if (ret >= 0) + if (!ret) lastpage = page; return ret; } @@ -200,7 +200,7 @@ static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, int ret; ret = reg_page_map_set(client, reg); - if (ret >= 0) + if (!ret) ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), swab16(data)); dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); @@ -246,7 +246,7 @@ static int mt9m111_set_context(struct soc_camera_device *icd, static int mt9m111_setup_rect(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0, is_raw_format; + int ret, is_raw_format; int width = mt9m111->width; int height = mt9m111->height; @@ -256,32 +256,31 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd) else is_raw_format = 0; - if (ret >= 0) - ret = reg_write(COLUMN_START, mt9m111->left); - if (ret >= 0) + ret = reg_write(COLUMN_START, mt9m111->left); + if (!ret) ret = reg_write(ROW_START, mt9m111->top); if (is_raw_format) { - if (ret >= 0) + if (!ret) ret = reg_write(WINDOW_WIDTH, width); - if (ret >= 0) + if (!ret) ret = reg_write(WINDOW_HEIGHT, height); } else { - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XSIZE_B, width); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YSIZE_B, height); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XSIZE_A, width); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YSIZE_A, height); } @@ -293,7 +292,7 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) int ret; ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); - if (ret >= 0) + if (!ret) ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); return ret; } @@ -305,7 +304,6 @@ static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) { - return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); } @@ -356,7 +354,7 @@ static int mt9m111_enable(struct soc_camera_device *icd) int ret; ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); - if (ret >= 0) + if (!ret) mt9m111->powered = 1; return ret; } @@ -367,7 +365,7 @@ static int mt9m111_disable(struct soc_camera_device *icd) int ret; ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); - if (ret >= 0) + if (!ret) mt9m111->powered = 0; return ret; } @@ -377,9 +375,9 @@ static int mt9m111_reset(struct soc_camera_device *icd) int ret; ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); - if (ret >= 0) + if (!ret) ret = reg_set(RESET, MT9M111_RESET_RESET_SOC); - if (ret >= 0) + if (!ret) ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE | MT9M111_RESET_RESET_SOC); return ret; @@ -410,7 +408,7 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0; + int ret; switch (pixfmt) { case V4L2_PIX_FMT_SBGGR8: @@ -433,7 +431,7 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) ret = -EINVAL; } - if (ret >= 0) + if (!ret) mt9m111->pixfmt = pixfmt; return ret; @@ -443,7 +441,7 @@ static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, __u32 pixfmt, struct v4l2_rect *rect) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0; + int ret; mt9m111->left = rect->left; mt9m111->top = rect->top; @@ -455,9 +453,9 @@ static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, mt9m111->height); ret = mt9m111_setup_rect(icd); - if (ret >= 0) + if (!ret) ret = mt9m111_set_pixfmt(icd, pixfmt); - return ret < 0 ? ret : 0; + return ret; } static int mt9m111_try_fmt_cap(struct soc_camera_device *icd, @@ -644,7 +642,7 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) val = (1 << 10) | (1 << 9) | (gain / 4); else if ((gain >= 64) && (gain < 64 * 2)) - val = (1<<9) | (gain / 2); + val = (1 << 9) | (gain / 2); else val = gain; @@ -661,7 +659,7 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) else ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); - if (ret >= 0) + if (!ret) mt9m111->autoexposure = on; return ret; @@ -711,7 +709,7 @@ static int mt9m111_set_control(struct soc_camera_device *icd, { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); const struct v4l2_queryctrl *qctrl; - int ret = 0; + int ret; qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); @@ -739,7 +737,7 @@ static int mt9m111_set_control(struct soc_camera_device *icd, ret = -EINVAL; } - return ret < 0 ? -EIO : 0; + return ret; } int mt9m111_restore_state(struct soc_camera_device *icd) @@ -763,10 +761,10 @@ static int mt9m111_resume(struct soc_camera_device *icd) if (mt9m111->powered) { ret = mt9m111_enable(icd); - if (ret >= 0) - mt9m111_reset(icd); - if (ret >= 0) - mt9m111_restore_state(icd); + if (!ret) + ret = mt9m111_reset(icd); + if (!ret) + ret = mt9m111_restore_state(icd); } return ret; } @@ -778,15 +776,15 @@ static int mt9m111_init(struct soc_camera_device *icd) mt9m111->context = HIGHPOWER; ret = mt9m111_enable(icd); - if (ret >= 0) - mt9m111_reset(icd); - if (ret >= 0) - mt9m111_set_context(icd, mt9m111->context); - if (ret >= 0) - mt9m111_set_autoexposure(icd, mt9m111->autoexposure); - if (ret < 0) + if (!ret) + ret = mt9m111_reset(icd); + if (!ret) + ret = mt9m111_set_context(icd, mt9m111->context); + if (!ret) + ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + if (ret) dev_err(&icd->dev, "mt9m111 init failed: %d\n", ret); - return ret ? -EIO : 0; + return ret; } static int mt9m111_release(struct soc_camera_device *icd) @@ -797,7 +795,7 @@ static int mt9m111_release(struct soc_camera_device *icd) if (ret < 0) dev_err(&icd->dev, "mt9m111 release failed: %d\n", ret); - return ret ? -EIO : 0; + return ret; } /* -- cgit v1.2.3 From 6413c9eb617e2eebe283211c0422e46bbd7289bb Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Thu, 14 Aug 2008 17:04:11 +0200 Subject: soc-camera: Move .power and .reset from soc_camera host to sensor driver Make .power and .reset callbacks per camera instead of per host, also move their invocation to camera drivers. Signed-off-by: Stefan Herbrechtsmeier Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/mt9m001.c | 33 +++++++++++++++++++++++++-- drivers/media/video/mt9m111.c | 15 ++++++++++++ drivers/media/video/mt9v022.c | 24 +++++++++++++++++++- drivers/media/video/pxa_camera.c | 24 -------------------- drivers/media/video/sh_mobile_ceu_camera.c | 5 ---- include/asm-arm/arch-pxa/camera.h | 2 - include/media/sh_mobile_ceu.h | 2 - include/media/soc_camera.h | 3 ++ 8 files changed, 71 insertions(+), 37 deletions(-) --- linux/drivers/media/video/mt9m001.c | 33 +++++++++++++++++++++--- linux/drivers/media/video/mt9m111.c | 15 +++++++++++ linux/drivers/media/video/mt9v022.c | 24 ++++++++++++++++- linux/drivers/media/video/pxa_camera.c | 24 ----------------- linux/drivers/media/video/sh_mobile_ceu_camera.c | 5 ---- 5 files changed, 68 insertions(+), 33 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index 2c2d0903e..228183c54 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -117,13 +117,33 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg, static int mt9m001_init(struct soc_camera_device *icd) { + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + struct soc_camera_link *icl = mt9m001->client->dev.platform_data; int ret; dev_dbg(icd->vdev->parent, "%s\n", __func__); - ret = reg_write(icd, MT9M001_RESET, 1); - if (!ret) - ret = reg_write(icd, MT9M001_RESET, 0); + if (icl->power) { + ret = icl->power(&mt9m001->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + + /* The camera could have been already on, we reset it additionally */ + if (icl->reset) + ret = icl->reset(&mt9m001->client->dev); + else + ret = -ENODEV; + + if (ret < 0) { + /* Either no platform reset, or platform reset failed */ + ret = reg_write(icd, MT9M001_RESET, 1); + if (!ret) + ret = reg_write(icd, MT9M001_RESET, 0); + } /* Disable chip, synchronous option update */ if (!ret) ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); @@ -133,8 +153,15 @@ static int mt9m001_init(struct soc_camera_device *icd) static int mt9m001_release(struct soc_camera_device *icd) { + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + struct soc_camera_link *icl = mt9m001->client->dev.platform_data; + /* Disable the chip */ reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); + + if (icl->power) + icl->power(&mt9m001->client->dev, 0); + return 0; } diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c index d99932631..4844486d7 100644 --- a/linux/drivers/media/video/mt9m111.c +++ b/linux/drivers/media/video/mt9m111.c @@ -351,8 +351,18 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) static int mt9m111_enable(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct soc_camera_link *icl = mt9m111->client->dev.platform_data; int ret; + if (icl->power) { + ret = icl->power(&mt9m111->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); if (!ret) mt9m111->powered = 1; @@ -362,11 +372,16 @@ static int mt9m111_enable(struct soc_camera_device *icd) static int mt9m111_disable(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct soc_camera_link *icl = mt9m111->client->dev.platform_data; int ret; ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); if (!ret) mt9m111->powered = 0; + + if (icl->power) + icl->power(&mt9m111->client->dev, 0); + return ret; } diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index d9b229579..0320d006f 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -134,8 +134,25 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg, static int mt9v022_init(struct soc_camera_device *icd) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + struct soc_camera_link *icl = mt9v022->client->dev.platform_data; int ret; + if (icl->power) { + ret = icl->power(&mt9v022->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + + /* + * The camera could have been already on, we hard-reset it additionally, + * if available. Soft reset is done in video_probe(). + */ + if (icl->reset) + icl->reset(&mt9v022->client->dev); + /* Almost the default mode: master, parallel, simultaneous, and an * undocumented bit 0x200, which is present in table 7, but not in 8, * plus snapshot mode to disable scan for now */ @@ -161,7 +178,12 @@ static int mt9v022_init(struct soc_camera_device *icd) static int mt9v022_release(struct soc_camera_device *icd) { - /* Nothing? */ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + struct soc_camera_link *icl = mt9v022->client->dev.platform_data; + + if (icl->power) + icl->power(&mt9v022->client->dev, 0); + return 0; } diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index ead87ddaf..6c869fb23 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -629,17 +629,6 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) pdata->init(pcdev->dev); } - if (pdata && pdata->power) { - dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__); - pdata->power(pcdev->dev, 1); - } - - if (pdata && pdata->reset) { - dev_dbg(pcdev->dev, "%s: Releasing camera reset\n", - __func__); - pdata->reset(pcdev->dev, 1); - } - CICR0 = 0x3FF; /* disable all interrupts */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) @@ -660,20 +649,7 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) { - struct pxacamera_platform_data *board = pcdev->pdata; - clk_disable(pcdev->clk); - - if (board && board->reset) { - dev_dbg(pcdev->dev, "%s: Asserting camera reset\n", - __func__); - board->reset(pcdev->dev, 0); - } - - if (board && board->power) { - dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__); - board->power(pcdev->dev, 0); - } } static irqreturn_t pxa_camera_irq(int irq, void *data) diff --git a/linux/drivers/media/video/sh_mobile_ceu_camera.c b/linux/drivers/media/video/sh_mobile_ceu_camera.c index 318754e73..76838091d 100644 --- a/linux/drivers/media/video/sh_mobile_ceu_camera.c +++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c @@ -304,9 +304,6 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) "SuperH Mobile CEU driver attached to camera %d\n", icd->devnum); - if (pcdev->pdata->enable_camera) - pcdev->pdata->enable_camera(); - ret = icd->ops->init(icd); if (ret) goto err; @@ -333,8 +330,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) ceu_write(pcdev, CEIER, 0); ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ icd->ops->release(icd); - if (pcdev->pdata->disable_camera) - pcdev->pdata->disable_camera(); dev_info(&icd->dev, "SuperH Mobile CEU driver detached from camera %d\n", -- cgit v1.2.3 From cad1a4391a036c6ae2a7b43fcd990560d0729ac8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 14 Aug 2008 19:53:33 +0200 Subject: gspca: Adjust some control limits in spca561. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/spca561.c | 35 +++++++------------------------ 1 file changed, 8 insertions(+), 27 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index c1fb1d60b..86fc55bf9 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -38,9 +38,9 @@ struct sd { #define CONTRAST_MAX 0x3fff __u16 exposure; /* rev12a only */ -#define EXPOSURE_MIN 0x2001 -#define EXPOSURE_DEF 0x20ae -#define EXPOSURE_MAX 0x421d +#define EXPOSURE_MIN 0 +#define EXPOSURE_DEF 200 +#define EXPOSURE_MAX 762 __u8 brightness; /* rev72a only */ #define BRIGHTNESS_MIN 0 @@ -48,7 +48,7 @@ struct sd { #define BRIGHTNESS_MAX 63 __u8 white; /* rev12a only */ -#define WHITE_MIN 0 +#define WHITE_MIN 1 #define WHITE_DEF 0x40 #define WHITE_MAX 0x7f @@ -604,28 +604,11 @@ static void setcontrast(struct gspca_dev *gspca_dev) break; default: { /* case Rev012A: { */ -#if 1 static const __u8 Reg8391[] = { 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 }; reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); -#else - int expotimes; - __u8 Reg8391[] = - { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; - -/*fixme: does not work..*/ - /* Write camera sensor settings */ - expotimes = sd->contrast >> 5; - /* exposure is in 8309 2b, range 0120 - 5720 */ - Reg8391[0] = expotimes; /* exposure */ - Reg8391[1] = 0x18 | (expotimes >> 8); - Reg8391[2] = sd->brightness; /* gain */ - /* gain in 8335, 2b range 0000 - 2400 */ - reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); - reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); -#endif break; } } @@ -639,10 +622,6 @@ static void setwhite(struct gspca_dev *gspca_dev) __u8 reg8614, reg8616; white = sd->white; - if (sd->white == 0) { - PDEBUG(D_CONF, "Discarding null whiteness"); - return; - } /* try to emulate MS-win as possible */ reg8616 = 0x90 - white * 5 / 8; reg_w_val(gspca_dev->dev, 0x8616, reg8616); @@ -654,10 +633,12 @@ static void setwhite(struct gspca_dev *gspca_dev) static void setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int expo; __u8 data[2]; - data[0] = sd->exposure; - data[1] = sd->exposure >> 8; + expo = sd->exposure + 0x20a8; /* from test */ + data[0] = expo; + data[1] = expo >> 8; reg_w_buf(gspca_dev, 0x8309, data, 2); } -- cgit v1.2.3 From a67e3dfddda677ede70a8570073f732719a88ab8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 15 Aug 2008 11:54:57 +0200 Subject: Make contrast and brightness work for pac7302. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 43 ++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index c148d1003..e5ecf5f1f 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -82,9 +82,10 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, - .maximum = 255, +#define CONTRAST_MAX 255 + .maximum = CONTRAST_MAX, .step = 1, -#define CONTRAST_DEF 127 +#define CONTRAST_DEF 60 .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, @@ -94,7 +95,7 @@ static struct ctrl sd_ctrls[] = { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Color", + .name = "Saturation", .minimum = 0, .maximum = 255, .step = 1, @@ -429,13 +430,42 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } +/* rev 12a only */ +static void setbrightcont(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i, v; + static const __u8 max[10] = + {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, + 0xd4, 0xec}; + static const __u8 delta[10] = + {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, + 0x11, 0x0b}; + + reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + for (i = 0; i < 10; i++) { + v = max[i]; + v += (sd->brightness - BRIGHTNESS_MAX) + * 150 / BRIGHTNESS_MAX; /* 200 ? */ + v -= delta[i] * sd->contrast / CONTRAST_MAX; + if (v < 0) + v = 0; + else if (v > 0xff) + v = 0xff; + reg_w(gspca_dev, 0xa2 + i, v); + } + reg_w(gspca_dev, 0xdc, 0x01); +} + static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int brightness; - if (sd->sensor == SENSOR_PAC7302) + if (sd->sensor == SENSOR_PAC7302) { + setbrightcont(gspca_dev); return; + } /*jfm: inverted?*/ brightness = BRIGHTNESS_MAX - sd->brightness; reg_w(gspca_dev, 0xff, 0x04); @@ -449,13 +479,14 @@ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (sd->sensor == SENSOR_PAC7302) + if (sd->sensor == SENSOR_PAC7302) { + setbrightcont(gspca_dev); return; + } reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x80, sd->contrast); /* load registers to sensor (Bit 0, auto clear) */ reg_w(gspca_dev, 0x11, 0x01); - PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast); } static void setcolors(struct gspca_dev *gspca_dev) -- cgit v1.2.3 From 0a22c4409f5febcafbb8f52523c82bfe626da34b Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 15 Aug 2008 19:10:10 +0200 Subject: gspca: Colors, hflip and vflip controls added for pac7302. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 107 +++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index e5ecf5f1f..795c536e4 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -40,6 +40,8 @@ struct sd { unsigned char contrast; unsigned char colors; unsigned char autogain; + __u8 hflip; + __u8 vflip; char tosof; /* number of bytes before next start of frame */ signed char ag_cnt; @@ -59,6 +61,10 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { { @@ -97,7 +103,8 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Saturation", .minimum = 0, - .maximum = 255, +#define COLOR_MAX 255 + .maximum = COLOR_MAX, .step = 1, #define COLOR_DEF 127 .default_value = COLOR_DEF, @@ -119,6 +126,35 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, +/* next controls work with pac7302 only */ + { + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror", + .minimum = 0, + .maximum = 1, + .step = 1, +#define HFLIP_DEF 0 + .default_value = HFLIP_DEF, + }, + .set = sd_sethflip, + .get = sd_gethflip, + }, + { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Vflip", + .minimum = 0, + .maximum = 1, + .step = 1, +#define VFLIP_DEF 0 + .default_value = VFLIP_DEF, + }, + .set = sd_setvflip, + .get = sd_getvflip, + }, }; static struct v4l2_pix_format vga_mode[] = { @@ -493,8 +529,25 @@ static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (sd->sensor == SENSOR_PAC7302) + if (sd->sensor == SENSOR_PAC7302) { + int i, v; + static const int a[9] = + {217, -212, 0, -101, 170, -67, -38, -315, 355}; + static const int b[9] = + {19, 106, 0, 19, 106, 1, 19, 106, 1}; + + reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + reg_w(gspca_dev, 0x11, 0x01); + reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ + for (i = 0; i < 9; i++) { + v = a[i] * sd->colors / COLOR_MAX + b[i]; + reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); + reg_w(gspca_dev, 0x0f + 2 * i + 1, v); + } + reg_w(gspca_dev, 0xdc, 0x01); return; + } reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x10, sd->colors); /* load registers to sensor (Bit 0, auto clear) */ @@ -514,6 +567,19 @@ static void setautogain(struct gspca_dev *gspca_dev) } } +/* this function is used by pac7302 only */ +static void sethvflip(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 data; + + reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ + data = (sd->hflip ? 0x00 : 0x08) + | (sd->vflip ? 0x04 : 0x00); + reg_w(gspca_dev, 0x21, data); + reg_w(gspca_dev, 0x11, 0x01); +} + /* this function is called at open time */ static int sd_open(struct gspca_dev *gspca_dev) { @@ -574,6 +640,7 @@ static void sd_start(struct gspca_dev *gspca_dev) /* start stream */ reg_w(gspca_dev, 0xff, 0x01); if (sd->sensor == SENSOR_PAC7302) { + sethvflip(gspca_dev); reg_w(gspca_dev, 0x78, 0x01); reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x78, 0x01); @@ -829,6 +896,42 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hflip = val; + if (gspca_dev->streaming) + sethvflip(gspca_dev); + return 0; +} + +static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->hflip; + return 0; +} + +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->vflip = val; + if (gspca_dev->streaming) + sethvflip(gspca_dev); + return 0; +} + +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->vflip; + return 0; +} + /* sub-driver description */ static struct sd_desc sd_desc = { .name = MODULE_NAME, -- cgit v1.2.3 From 9c75e8157d1db6438ae8f801ceebb25e78a48812 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 12:50:23 +0200 Subject: dpc7146: remove dpc7146 demonstration board driver From: Hans Verkuil Old driver for the dpc7146 demonstration board that is no longer relevant. The last time this was tested on actual hardware was probably around 2002. Since this is a driver for a demonstration board the decision was made (after discussing this with the original author, Michael Hunold) to remove it rather than spending a lot of effort continually updating this driver to stay in sync with the latest internal V4L2 or I2C API. Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Michael Hunold --- linux/drivers/media/video/Kconfig | 15 -- linux/drivers/media/video/Makefile | 1 - linux/drivers/media/video/dpc7146.c | 409 ------------------------------------ 3 files changed, 425 deletions(-) delete mode 100644 linux/drivers/media/video/dpc7146.c (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 4c96b690a..61735004e 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -709,21 +709,6 @@ config VIDEO_MXB To compile this driver as a module, choose M here: the module will be called mxb. -config VIDEO_DPC - tristate "Philips-Semiconductors 'dpc7146 demonstration board'" - depends on PCI && VIDEO_V4L1 && I2C - select VIDEO_SAA7146_VV - select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO - ---help--- - This is a video4linux driver for the 'dpc7146 demonstration - board' by Philips-Semiconductors. It's the reference design - for SAA7146 bases boards, so if you have some unsupported - saa7146 based, analog video card, chances are good that it - will work with this skeleton driver. - - To compile this driver as a module, choose M here: the - module will be called dpc7146. - config VIDEO_HEXIUM_ORION tristate "Hexium HV-PCI6 and Orion frame grabber" depends on PCI && VIDEO_V4L2 && I2C diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index bf429b023..3512b715a 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -83,7 +83,6 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ obj-$(CONFIG_VIDEO_MXB) += mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o -obj-$(CONFIG_VIDEO_DPC) += dpc7146.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o diff --git a/linux/drivers/media/video/dpc7146.c b/linux/drivers/media/video/dpc7146.c deleted file mode 100644 index 4bfb3076b..000000000 --- a/linux/drivers/media/video/dpc7146.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - dpc7146.c - v4l2 driver for the dpc7146 demonstration board - - Copyright (C) 2000-2003 Michael Hunold - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#define DEBUG_VARIABLE debug - -#include -#include /* for saa7111a */ -#include "compat.h" - -#define I2C_SAA7111A 0x24 - -/* All unused bytes are reserverd. */ -#define SAA711X_CHIP_VERSION 0x00 -#define SAA711X_ANALOG_INPUT_CONTROL_1 0x02 -#define SAA711X_ANALOG_INPUT_CONTROL_2 0x03 -#define SAA711X_ANALOG_INPUT_CONTROL_3 0x04 -#define SAA711X_ANALOG_INPUT_CONTROL_4 0x05 -#define SAA711X_HORIZONTAL_SYNC_START 0x06 -#define SAA711X_HORIZONTAL_SYNC_STOP 0x07 -#define SAA711X_SYNC_CONTROL 0x08 -#define SAA711X_LUMINANCE_CONTROL 0x09 -#define SAA711X_LUMINANCE_BRIGHTNESS 0x0A -#define SAA711X_LUMINANCE_CONTRAST 0x0B -#define SAA711X_CHROMA_SATURATION 0x0C -#define SAA711X_CHROMA_HUE_CONTROL 0x0D -#define SAA711X_CHROMA_CONTROL 0x0E -#define SAA711X_FORMAT_DELAY_CONTROL 0x10 -#define SAA711X_OUTPUT_CONTROL_1 0x11 -#define SAA711X_OUTPUT_CONTROL_2 0x12 -#define SAA711X_OUTPUT_CONTROL_3 0x13 -#define SAA711X_V_GATE_1_START 0x15 -#define SAA711X_V_GATE_1_STOP 0x16 -#define SAA711X_V_GATE_1_MSB 0x17 -#define SAA711X_TEXT_SLICER_STATUS 0x1A -#define SAA711X_DECODED_BYTES_OF_TS_1 0x1B -#define SAA711X_DECODED_BYTES_OF_TS_2 0x1C -#define SAA711X_STATUS_BYTE 0x1F - -#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "debug verbosity"); - -static int dpc_num; - -#define DPC_INPUTS 2 -static struct v4l2_input dpc_inputs[DPC_INPUTS] = { - { 0, "Port A", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, - { 1, "Port B", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, -}; - -#define DPC_AUDIOS 0 - -static struct saa7146_extension_ioctls ioctls[] = { - { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_S_STD, SAA7146_AFTER }, - { 0, 0 } -}; - -struct dpc -{ - struct video_device *video_dev; - struct video_device *vbi_dev; - - struct i2c_adapter i2c_adapter; - struct i2c_client *saa7111a; - - int cur_input; /* current input */ -}; - -static int dpc_check_clients(struct device *dev, void *data) -{ - struct dpc* dpc = data; - struct i2c_client *client = i2c_verify_client(dev); - - if( !client ) - return 0; - - if( I2C_SAA7111A == client->addr ) - dpc->saa7111a = client; - - return 0; -} - -/* fixme: add vbi stuff here */ -static int dpc_probe(struct saa7146_dev* dev) -{ - struct dpc* dpc = NULL; - - dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL); - if( NULL == dpc ) { - printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n"); - return -ENOMEM; - } - - /* FIXME: enable i2c-port pins, video-port-pins - video port pins should be enabled here ?! */ - saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); - - dpc->i2c_adapter = (struct i2c_adapter) { - .class = I2C_CLASS_TV_ANALOG, - .name = "dpc7146", - }; - saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); - if(i2c_add_adapter(&dpc->i2c_adapter) < 0) { - DEB_S(("cannot register i2c-device. skipping.\n")); - kfree(dpc); - return -EFAULT; - } - - /* loop through all i2c-devices on the bus and look who is there */ - device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients); - - /* check if all devices are present */ - if (!dpc->saa7111a) { - DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); - i2c_del_adapter(&dpc->i2c_adapter); - kfree(dpc); - return -ENODEV; - } - - /* all devices are present, probe was successful */ - DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); - - /* we store the pointer in our private data field */ - dev->ext_priv = dpc; - - return 0; -} - -/* bring hardware to a sane state. this has to be done, just in case someone - wants to capture from this device before it has been properly initialized. - the capture engine would badly fail, because no valid signal arrives on the - saa7146, thus leading to timeouts and stuff. */ -static int dpc_init_done(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_D(("dpc_v4l2.o: dpc_init_done called.\n")); - - /* initialize the helper ics to useful values */ - i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81); - - return 0; -} - -static struct saa7146_ext_vv vv_data; - -/* this function only gets called when the probing was successful */ -static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_D(("dpc_v4l2.o: dpc_attach called.\n")); - - /* checking for i2c-devices can be omitted here, because we - already did this in "dpc_vl42_probe" */ - - saa7146_vv_init(dev,&vv_data); - if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) { - ERR(("cannot register capture v4l2 device. skipping.\n")); - return -1; - } - - /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ - if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { - if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) { - ERR(("cannot register vbi v4l2 device. skipping.\n")); - } - } - - i2c_use_client(dpc->saa7111a); - - printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num); - dpc_num++; - - /* the rest */ - dpc->cur_input = 0; - dpc_init_done(dev); - - return 0; -} - -static int dpc_detach(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_EE(("dev:%p\n",dev)); - - i2c_release_client(dpc->saa7111a); - - saa7146_unregister_device(&dpc->video_dev,dev); - if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { - saa7146_unregister_device(&dpc->vbi_dev,dev); - } - saa7146_vv_release(dev); - - dpc_num--; - - i2c_del_adapter(&dpc->i2c_adapter); - kfree(dpc); - return 0; -} - -#ifdef axa -int dpc_vbi_bypass(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - int i = 1; - - /* switch bypass in saa7111a */ - if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) { - printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n"); - return -1; - } - - return 0; -} -#endif - -static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) -{ - struct saa7146_dev *dev = fh->dev; - struct dpc* dpc = (struct dpc*)dev->ext_priv; -/* - struct saa7146_vv *vv = dev->vv_data; -*/ - switch(cmd) - { - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); - - if( i->index < 0 || i->index >= DPC_INPUTS) { - return -EINVAL; - } - - memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input)); - - DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index)); - return 0; - } - case VIDIOC_G_INPUT: - { - int *input = (int *)arg; - *input = dpc->cur_input; - - DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input)); - return 0; - } - case VIDIOC_S_INPUT: - { - int input = *(int *)arg; - - if (input < 0 || input >= DPC_INPUTS) { - return -EINVAL; - } - - dpc->cur_input = input; - - /* fixme: switch input here, switch audio, too! */ -// saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); - printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n"); - - return 0; - } - default: -/* - DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n")); -*/ - return -ENOIOCTLCMD; - } - return 0; -} - -static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) -{ - return 0; -} - -static struct saa7146_standard standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL, - .v_offset = 0x17, .v_field = 288, - .h_offset = 0x14, .h_pixels = 680, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x16, .v_field = 240, - .h_offset = 0x06, .h_pixels = 708, - .v_max_out = 480, .h_max_out = 640, - }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 0x14, .v_field = 288, - .h_offset = 0x14, .h_pixels = 720, - .v_max_out = 576, .h_max_out = 768, - } -}; - -static struct saa7146_extension extension; - -static struct saa7146_pci_extension_data dpc = { - .ext_priv = "Multimedia eXtension Board", - .ext = &extension, -}; - -static struct pci_device_id pci_tbl[] = { - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x0000, - .subdevice = 0x0000, - .driver_data = (unsigned long)&dpc, - }, { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_ext_vv vv_data = { - .inputs = DPC_INPUTS, - .capabilities = V4L2_CAP_VBI_CAPTURE, - .stds = &standard[0], - .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), - .std_callback = &std_callback, - .ioctls = &ioctls[0], - .ioctl = dpc_ioctl, -}; - -static struct saa7146_extension extension = { - .name = "dpc7146 demonstration board", - .flags = SAA7146_USE_I2C_IRQ, - - .pci_tbl = &pci_tbl[0], - .module = THIS_MODULE, - - .probe = dpc_probe, - .attach = dpc_attach, - .detach = dpc_detach, - - .irq_mask = 0, - .irq_func = NULL, -}; - -static int __init dpc_init_module(void) -{ - if( 0 != saa7146_register_extension(&extension)) { - DEB_S(("failed to register extension.\n")); - return -ENODEV; - } - - return 0; -} - -static void __exit dpc_cleanup_module(void) -{ - saa7146_unregister_extension(&extension); -} - -module_init(dpc_init_module); -module_exit(dpc_cleanup_module); - -MODULE_DESCRIPTION("video4linux-2 driver for the 'dpc7146 demonstration board'"); -MODULE_AUTHOR("Michael Hunold "); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 59bb2ab87f97424a41cf69511ff79ae8a5ea08b9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 12:56:12 +0200 Subject: tuner-3036: remove driver From: Hans Verkuil This driver is for VERY old i2c-over-parallel port teletext receiver boxes. Rather then spending effort on converting this driver to V4L2, and since it is extremely unlikely that anyone still uses one of these devices, it was decided to drop it (after discussing this as well with the original author, Phil Blundell). Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Phil Blundell --- linux/drivers/media/video/Kconfig | 7 -- linux/drivers/media/video/Makefile | 1 - linux/drivers/media/video/tuner-3036.c | 215 --------------------------------- 3 files changed, 223 deletions(-) delete mode 100644 linux/drivers/media/video/tuner-3036.c (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 61735004e..c315885a6 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -579,13 +579,6 @@ config VIDEO_SAA5249 To compile this driver as a module, choose M here: the module will be called saa5249. -config TUNER_3036 - tristate "SAB3036 tuner" - depends on I2C && VIDEO_V4L1 - help - Say Y here to include support for Philips SAB3036 compatible tuners. - If in doubt, say N. - config VIDEO_VINO tristate "SGI Vino Video For Linux (EXPERIMENTAL)" depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 3512b715a..22d98ee61 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -83,7 +83,6 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ obj-$(CONFIG_VIDEO_MXB) += mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o -obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o diff --git a/linux/drivers/media/video/tuner-3036.c b/linux/drivers/media/video/tuner-3036.c deleted file mode 100644 index 8b87d75f4..000000000 --- a/linux/drivers/media/video/tuner-3036.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Driver for Philips SAB3036 "CITAC" tuner control chip. - * - * Author: Phil Blundell - * - * The SAB3036 is just about different enough from the chips that - * tuner.c copes with to make it not worth the effort to crowbar - * the support into that file. So instead we have a separate driver. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "compat.h" -#include -#include - -#include - -static int debug; /* insmod parameter */ -static int this_adap; - -static struct i2c_client client_template; - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x60, 0x61, I2C_CLIENT_END }; -static unsigned short ignore = I2C_CLIENT_END; - -static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_i2c, - .probe = &ignore, - .ignore = &ignore, -}; - -/* ---------------------------------------------------------------------- */ - -static unsigned char -tuner_getstatus (struct i2c_client *c) -{ - unsigned char byte; - if (i2c_master_recv(c, &byte, 1) != 1) - printk(KERN_ERR "tuner-3036: I/O error.\n"); - return byte; -} - -#define TUNER_FL 0x80 - -static int -tuner_islocked (struct i2c_client *c) -{ - return (tuner_getstatus(c) & TUNER_FL); -} - -/* ---------------------------------------------------------------------- */ - -static void -set_tv_freq(struct i2c_client *c, int freq) -{ - u16 div = ((freq * 20) / 16); - unsigned long give_up = jiffies + HZ; - unsigned char buffer[2]; - - if (debug) - printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div); - - /* Select high tuning current */ - buffer[0] = 0x29; - buffer[1] = 0x3e; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 1\n"); - - buffer[0] = 0x80 | ((div>>8) & 0x7f); - buffer[1] = div & 0xff; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 2\n"); - - while (!tuner_islocked(c) && time_before(jiffies, give_up)) - schedule(); - - if (!tuner_islocked(c)) - printk(KERN_WARNING "tuner: failed to achieve PLL lock\n"); - - /* Select low tuning current and engage AFC */ - buffer[0] = 0x29; - buffer[1] = 0xb2; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 3\n"); - - if (debug) - printk(KERN_DEBUG "tuner: status %02x\n", tuner_getstatus(c)); -} - -/* ---------------------------------------------------------------------- */ - -static int -tuner_attach(struct i2c_adapter *adap, int addr, int kind) -{ - static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 }; - - struct i2c_client *client; - - if (this_adap > 0) - return -1; - this_adap++; - - client_template.adapter = adap; - client_template.addr = addr; - - client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memcpy(client, &client_template, sizeof(struct i2c_client)); - - printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client)); - - i2c_attach_client(client); - - if (i2c_master_send(client, buffer, 2) != 2) - printk("tuner: i2c i/o error 1\n"); - if (i2c_master_send(client, buffer+2, 2) != 2) - printk("tuner: i2c i/o error 2\n"); - if (i2c_master_send(client, buffer+4, 2) != 2) - printk("tuner: i2c i/o error 3\n"); - return 0; -} - -static int -tuner_detach(struct i2c_client *c) -{ - return 0; -} - -static int -tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - int *iarg = (int*)arg; - - switch (cmd) - { - case VIDIOCSFREQ: - set_tv_freq(client, *iarg); - break; - - default: - return -EINVAL; - } - return 0; -} - -static int -tuner_probe(struct i2c_adapter *adap) -{ - this_adap = 0; - if (adap->id == I2C_HW_B_LP) - return i2c_probe(adap, &addr_data, tuner_attach); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static struct i2c_driver -i2c_driver_tuner = -{ - .driver = { - .name = "sab3036", - }, - .id = I2C_DRIVERID_SAB3036, - .attach_adapter = tuner_probe, - .detach_client = tuner_detach, - .command = tuner_command -}; - -static struct i2c_client client_template = -{ - .driver = &i2c_driver_tuner, - .name = "SAB3036", -}; - -static int __init -tuner3036_init(void) -{ - return i2c_add_driver(&i2c_driver_tuner); -} - -static void __exit -tuner3036_exit(void) -{ - i2c_del_driver(&i2c_driver_tuner); -} - -MODULE_DESCRIPTION("SAB3036 tuner driver"); -MODULE_AUTHOR("Philip Blundell "); -MODULE_LICENSE("GPL"); - -module_param(debug, int, 0); -MODULE_PARM_DESC(debug,"Enable debugging output"); - -module_init(tuner3036_init); -module_exit(tuner3036_exit); -- cgit v1.2.3 From 58df9dfb0cd0e6afde3ae7a49f84d4f216bc3cbf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 15:55:33 +0200 Subject: aci: remove obsolete sources From: Hans Verkuil The aci.c and aci.h files were copied from the kernel for a Miro radio card. That driver has been removed, so these supported sources can also be removed. In addition some remaining traces of the Miro driver were also deleted. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/radio/Kconfig | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig index 01ee71e82..1b41b3f77 100644 --- a/linux/drivers/media/radio/Kconfig +++ b/linux/drivers/media/radio/Kconfig @@ -195,38 +195,6 @@ config RADIO_MAESTRO To compile this driver as a module, choose M here: the module will be called radio-maestro. -config RADIO_MIROPCM20 - tristate "miroSOUND PCM20 radio" - depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER - ---help--- - Choose Y here if you have this FM radio card. You also need to say Y - to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound") - for this to work. - - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - . - - To compile this driver as a module, choose M here: the - module will be called miropcm20. - -config RADIO_MIROPCM20_RDS - tristate "miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)" - depends on RADIO_MIROPCM20 && EXPERIMENTAL - ---help--- - Choose Y here if you want to see RDS/RBDS information like - RadioText, Programme Service name, Clock Time and date, Programme - Type and Traffic Announcement/Programme identification. - - It's not possible to read the raw RDS packets from the device, so - the driver cant provide an V4L interface for this. But the - availability of RDS is reported over V4L by the basic driver - already. Here RDS can be read from files in /dev/v4l/rds. - - To compile this driver as a module, choose M here: the - module will be called miropcm20-rds. - config RADIO_SF16FMI tristate "SF16FMI Radio" depends on ISA && VIDEO_V4L2 -- cgit v1.2.3 From 995c07b049f1633deb6e269cc0e7978b8c0dff4e Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 17 Aug 2008 22:13:31 -0400 Subject: cx18: Add missing lock for when the irq handler manipulates the queues From: Andy Walls cx18: Add missing lock for when the irq handler manipulates the queues. This was a potential source of stream queue corruption. Also changed the name of cx18_queue_find_buf() to cx18_queue_get_buf_irq(). Priority: high Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-irq.c | 2 +- linux/drivers/media/video/cx18/cx18-queue.c | 23 +++++++++++++---------- linux/drivers/media/video/cx18/cx18-queue.h | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/cx18/cx18-irq.c b/linux/drivers/media/video/cx18/cx18-irq.c index 654664783..b9cf609ee 100644 --- a/linux/drivers/media/video/cx18/cx18-irq.c +++ b/linux/drivers/media/video/cx18/cx18-irq.c @@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) CX18_WARN("Ack struct = %d for %s\n", mb->args[2], s->name); id = read_enc(off); - buf = cx18_queue_find_buf(s, id, read_enc(off + 4)); + buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4)); CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); if (buf) { cx18_buf_sync_for_cpu(s, buf); diff --git a/linux/drivers/media/video/cx18/cx18-queue.c b/linux/drivers/media/video/cx18/cx18-queue.c index 6990b77c6..8a4dd821f 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.c +++ b/linux/drivers/media/video/cx18/cx18-queue.c @@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) return buf; } -struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, +struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, u32 bytesused) { struct cx18 *cx = s->cx; struct list_head *p; + spin_lock(&s->qlock); list_for_each(p, &s->q_free.list) { struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); @@ -92,17 +93,19 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, continue; buf->bytesused = bytesused; /* the transport buffers are handled differently, - so there is no need to move them to the full queue */ - if (s->type == CX18_ENC_STREAM_TYPE_TS) - return buf; - s->q_free.buffers--; - s->q_free.length -= s->buf_size; - s->q_full.buffers++; - s->q_full.length += s->buf_size; - s->q_full.bytesused += buf->bytesused; - list_move_tail(&buf->list, &s->q_full.list); + they are not moved to the full queue */ + if (s->type != CX18_ENC_STREAM_TYPE_TS) { + s->q_free.buffers--; + s->q_free.length -= s->buf_size; + s->q_full.buffers++; + s->q_full.length += s->buf_size; + s->q_full.bytesused += buf->bytesused; + list_move_tail(&buf->list, &s->q_full.list); + } + spin_unlock(&s->qlock); return buf; } + spin_unlock(&s->qlock); CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); return NULL; } diff --git a/linux/drivers/media/video/cx18/cx18-queue.h b/linux/drivers/media/video/cx18/cx18-queue.h index 91423b986..7f93bb13c 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.h +++ b/linux/drivers/media/video/cx18/cx18-queue.h @@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q); void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, struct cx18_queue *q); struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); -struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, +struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, u32 bytesused); void cx18_flush_queues(struct cx18_stream *s); -- cgit v1.2.3 From 2315f8eef1304343666da0b452b8ec290aa32132 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Aug 2008 09:46:12 +0200 Subject: pxa: fix build error for 2.6.27. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/pxa_camera.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index ead87ddaf..4ddd26d6c 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -36,8 +36,13 @@ #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) +#include +#include +#else #include #include +#endif #define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) #define PXA_CAM_DRV_NAME "pxa27x-camera" -- cgit v1.2.3 From 4589075f331c3f32641ecd0313fe4728a9f75940 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Aug 2008 09:48:42 +0200 Subject: usbvideo: add proper error check and add release function From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/usbvideo/usbvideo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/usbvideo/usbvideo.c b/linux/drivers/media/video/usbvideo/usbvideo.c index 5bda83f7d..4b28a6dfb 100644 --- a/linux/drivers/media/video/usbvideo/usbvideo.c +++ b/linux/drivers/media/video/usbvideo/usbvideo.c @@ -1006,6 +1006,10 @@ allocate_done: EXPORT_SYMBOL(usbvideo_AllocateDevice); +static void usbvideo_dummy_release(struct video_device *vfd) +{ +} + int usbvideo_RegisterVideoDevice(struct uvd *uvd) { char tmp1[20], tmp2[20]; /* Buffers for printing */ @@ -1039,7 +1043,8 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) return -EINVAL; } uvd->vdev.parent = &uvd->dev->dev; - if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { + uvd->vdev.release = usbvideo_dummy_release; + if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { err("%s: video_register_device failed", __func__); return -EPIPE; } -- cgit v1.2.3 From 6bcdd562d2f7ec79396f4717d2a108b6dcafe597 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 18 Aug 2008 11:12:43 +0200 Subject: gspca: Fix initialization and controls of sn9x110 - ov7630. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 197 ++++++++++++++++--------------- 1 file changed, 103 insertions(+), 94 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 2c76f02ce..8cf5d60d3 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -59,6 +59,7 @@ struct sd { #define SENSOR_OV7648 5 #define SENSOR_OV7660 6 unsigned char i2c_base; + __u8 regf1; }; /* V4L2 controls supported by the driver */ @@ -78,7 +79,8 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, - .maximum = 0xffff, +#define BRIGHTNESS_MAX 0xffff + .maximum = BRIGHTNESS_MAX, .step = 1, #define BRIGHTNESS_DEF 0x7fff .default_value = BRIGHTNESS_DEF, @@ -92,7 +94,8 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, - .maximum = 127, +#define CONTRAST_MAX 127 + .maximum = CONTRAST_MAX, .step = 1, #define CONTRAST_DEF 63 .default_value = CONTRAST_DEF, @@ -252,27 +255,20 @@ static const __u8 *sn_tb[] = { sn_ov7660 }; -static const __u8 regsn20[] = { +static const __u8 gamma_def[] = { 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; -static const __u8 regsn20_sn9c325[] = { - 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, - 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 -}; static const __u8 reg84[] = { 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, -/* 0x00, 0x00, 0x00, 0x00, 0x00 */ +#if 1 + 0xf7, 0x0f, 0x00, 0x00, 0x00 +#else 0xf7, 0x0f, 0x0a, 0x00, 0x00 +#endif }; -static const __u8 reg84_sn9c325[] = { - 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, - 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, - 0xf8, 0x0f, 0x00, 0x00, 0x00 -}; - static const __u8 hv7131r_sensor_init[][8] = { {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, @@ -423,7 +419,7 @@ static const __u8 ov7630_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, /* win: delay 20ms */ {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, -/* win: loop on 2 wwrite, 1 read */ +/* win: i2c_r from 00 to 80 */ {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10}, {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10}, @@ -458,9 +454,11 @@ static const __u8 ov7630_sensor_init[][8] = { {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, +/* */ {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, +/* */ {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, {} @@ -790,7 +788,11 @@ static int configure_gpio(struct gspca_dev *gspca_dev, static const __u8 regd4[] = {0x60, 0x00, 0x00}; reg_w1(gspca_dev, 0xf1, 0x00); - reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ +#if 1 + reg_w1(gspca_dev, 0x01, sn9c1xx[1]); +#else + reg_w1(gspca_dev, 0x01, 0x00); /*jfm: in some win traces*/ +#endif /* configure gpio */ reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); @@ -817,12 +819,13 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w1(gspca_dev, 0x17, 0x64); reg_w1(gspca_dev, 0x01, 0x42); break; -#if 0 +#if 1 /*jfm: from win trace */ case SENSOR_OV7630: reg_w1(gspca_dev, 0x01, 0x61); reg_w1(gspca_dev, 0x17, 0xe2); reg_w1(gspca_dev, 0x01, 0x60); + reg_w1(gspca_dev, 0x01, 0x40); break; #endif case SENSOR_OV7648: @@ -898,9 +901,20 @@ static void ov7630_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; - i2c_w8(gspca_dev, ov7630_sensor_init[i]); + i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */ + i++; + i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */ + i++; + msleep(20); + i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */ + i++; + i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */ i++; msleep(20); + i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */ + i++; +/*jfm:win i2c_r from 00 to 80*/ + while (ov7630_sensor_init[i][0]) { i2c_w8(gspca_dev, ov7630_sensor_init[i]); i++; @@ -945,6 +959,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->bridge = id->driver_info >> 16; sd->sensor = id->driver_info >> 8; sd->i2c_base = id->driver_info; + sd->regf1 = 0; /*jfm: was 1 in v1*/ sd->qindex = 4; /* set the quantization table */ sd->brightness = BRIGHTNESS_DEF; @@ -997,7 +1012,7 @@ static int sd_open(struct gspca_dev *gspca_dev) break; } - reg_w1(gspca_dev, 0xf1, 0x01); + reg_w1(gspca_dev, 0xf1, sd->regf1); #if 1 /*jfm: from win trace*/ return 0; @@ -1084,6 +1099,28 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, return expo; } +/* this function is used for sensors o76xx only */ +static void setbrightcont(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + unsigned val; + __u8 reg84_full[13]; + + memset(reg84_full, 0, sizeof reg84_full); + val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */ + reg84_full[2] = val; + reg84_full[0] = (val + 1) / 2; + reg84_full[4] = (val + 1) / 5; + if (val > BRIGHTNESS_DEF) + val = (sd->brightness - BRIGHTNESS_DEF) * 0x20 + / BRIGHTNESS_MAX; + else + val = 0; + reg84_full[10] = val; /* 00..1f */ + reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full); +} + +/* sensor != ov76xx */ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1115,6 +1152,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x96, k2); } +/* sensor != ov76xx */ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1210,24 +1248,23 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x07, sn9c1xx[7]); reg_w1(gspca_dev, 0x06, sn9c1xx[6]); reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); + reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def); + for (i = 0; i < 8; i++) + reg_w(gspca_dev, 0x84, reg84, sizeof reg84); +#if 0 switch (sd->bridge) { case BRIDGE_SN9C325: - reg_w(gspca_dev, 0x20, regsn20_sn9c325, - sizeof regsn20_sn9c325); - for (i = 0; i < 8; i++) - reg_w(gspca_dev, 0x84, reg84_sn9c325, - sizeof reg84_sn9c325); reg_w1(gspca_dev, 0x9a, 0x0a); reg_w1(gspca_dev, 0x99, 0x60); break; default: - reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); - for (i = 0; i < 8; i++) - reg_w(gspca_dev, 0x84, reg84, sizeof reg84); +#endif reg_w1(gspca_dev, 0x9a, 0x08); reg_w1(gspca_dev, 0x99, 0x59); +#if 0 break; } +#endif mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; if (mode) @@ -1313,8 +1350,18 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x17, reg17); reg_w1(gspca_dev, 0x01, reg1); - setbrightness(gspca_dev); - setcontrast(gspca_dev); + switch (sd->sensor) { + case SENSOR_HV7131R: + case SENSOR_MI0360: + case SENSOR_MO4000: + case SENSOR_OM6802: + setbrightness(gspca_dev); + setcontrast(gspca_dev); + break; + default: /* OV76xx */ + setbrightcont(gspca_dev); + break; + } setautogain(gspca_dev); } @@ -1352,7 +1399,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); reg_w1(gspca_dev, 0x01, sn9c1xx[1]); reg_w1(gspca_dev, 0x01, data); - reg_w1(gspca_dev, 0xf1, 0x01); + reg_w1(gspca_dev, 0xf1, sd->regf1); } static void sd_stop0(struct gspca_dev *gspca_dev) @@ -1450,72 +1497,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } -static unsigned int getexposure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 hexpo, mexpo, lexpo; - - switch (sd->sensor) { - case SENSOR_HV7131R: - /* read sensor exposure */ - i2c_r5(gspca_dev, 0x25); - return (gspca_dev->usb_buf[0] << 16) - | (gspca_dev->usb_buf[1] << 8) - | gspca_dev->usb_buf[2]; - case SENSOR_MI0360: - /* read sensor exposure */ - i2c_r5(gspca_dev, 0x09); - return (gspca_dev->usb_buf[0] << 8) - | gspca_dev->usb_buf[1]; - default: -/* case SENSOR_MO4000: */ - i2c_r5(gspca_dev, 0x0e); - hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */ - mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */ - lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4; - PDEBUG(D_CONF, "exposure %d", - (hexpo << 10) | (mexpo << 2) | lexpo); - return (hexpo << 10) | (mexpo << 2) | lexpo; -#if 0 /* keep */ -/*jfm: not called*/ -/* case SENSOR_OV7648: * jfm: is it ok for 7648? */ -/* case SENSOR_OV7660: */ - /* read sensor exposure */ - i2c_r5(gspca_dev, 0x04); - hexpo = gspca_dev->usb_buf[3] & 0x2f; - lexpo = gspca_dev->usb_buf[0] & 0x02; - i2c_r5(gspca_dev, 0x08); - mexpo = gspca_dev->usb_buf[2]; - return (hexpo << 10) | (mexpo << 2) | lexpo; -#endif - } - /* not reached */ -} - -static void getbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* hardcoded registers seem not readable */ - switch (sd->sensor) { - case SENSOR_HV7131R: - sd->brightness = getexposure(gspca_dev) >> 4; - break; - case SENSOR_MI0360: - case SENSOR_MO4000: - case SENSOR_OM6802: - sd->brightness = getexposure(gspca_dev) << 4; - break; - } -} - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; sd->brightness = val; - if (gspca_dev->streaming) - setbrightness(gspca_dev); + if (gspca_dev->streaming) { + switch (sd->sensor) { + case SENSOR_HV7131R: + case SENSOR_MI0360: + case SENSOR_MO4000: + case SENSOR_OM6802: + setbrightness(gspca_dev); + break; + default: /* OV76xx */ + setbrightcont(gspca_dev); + break; + } + } return 0; } @@ -1523,7 +1522,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -1533,8 +1531,19 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) struct sd *sd = (struct sd *) gspca_dev; sd->contrast = val; - if (gspca_dev->streaming) - setcontrast(gspca_dev); + if (gspca_dev->streaming) { + switch (sd->sensor) { + case SENSOR_HV7131R: + case SENSOR_MI0360: + case SENSOR_MO4000: + case SENSOR_OM6802: + setcontrast(gspca_dev); + break; + default: /* OV76xx */ + setbrightcont(gspca_dev); + break; + } + } return 0; } -- cgit v1.2.3 From 353199b76b1499244bd79cbfc66efed0bac94e95 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 18 Aug 2008 11:45:13 +0200 Subject: gspca: Bad color control in sonixj. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 8cf5d60d3..8a42d2a4f 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -814,7 +814,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev, switch (sd->sensor) { case SENSOR_OM6802: - reg_w1(gspca_dev, 0x02, 0x71); + reg_w1(gspca_dev, 0x02, 0x73); /* was 71 */ reg_w1(gspca_dev, 0x01, 0x42); reg_w1(gspca_dev, 0x17, 0x64); reg_w1(gspca_dev, 0x01, 0x42); @@ -1091,7 +1091,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, expo = 0x0001; gainOm[3] = expo >> 2; i2c_w8(gspca_dev, gainOm); - reg_w1(gspca_dev, 0x96, expo >> 5); + reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f); PDEBUG(D_CONF, "set exposure %d", gainOm[3]); break; } @@ -1173,11 +1173,13 @@ static void setcolors(struct gspca_dev *gspca_dev) int colour; colour = sd->colors - 128; - if (colour > 0) + if (colour > 0) { data = (colour + 32) & 0x7f; /* blue */ - else + reg_w1(gspca_dev, 0x06, data); + } else { data = (-colour + 32) & 0x7f; /* red */ - reg_w1(gspca_dev, 0x05, data); + reg_w1(gspca_dev, 0x05, data); + } } static void setautogain(struct gspca_dev *gspca_dev) -- cgit v1.2.3 From f9d5ea385bf4bef5716b10250160bd7cb408d990 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 18 Aug 2008 19:40:11 +0200 Subject: gspca: Bad controls and quantization table of pac7311. From: Jean-Francois Moine Patch adapted from a gspca v1 patch by Thomas Kaiser. Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/pac7311.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 795c536e4..3a22f2162 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -42,6 +42,7 @@ struct sd { unsigned char autogain; __u8 hflip; __u8 vflip; + __u8 qindex; char tosof; /* number of bytes before next start of frame */ signed char ag_cnt; @@ -462,6 +463,9 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; sd->autogain = AUTOGAIN_DEF; + sd->hflip = HFLIP_DEF; + sd->vflip = VFLIP_DEF; + sd->qindex = 3; sd->ag_cnt = -1; return 0; } @@ -505,6 +509,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) /*jfm: inverted?*/ brightness = BRIGHTNESS_MAX - sd->brightness; reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x0e, 0x00); reg_w(gspca_dev, 0x0f, brightness); /* load registers to sensor (Bit 0, auto clear) */ reg_w(gspca_dev, 0x11, 0x01); @@ -520,7 +525,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) return; } reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x80, sd->contrast); + reg_w(gspca_dev, 0x10, sd->contrast); /* load registers to sensor (Bit 0, auto clear) */ reg_w(gspca_dev, 0x11, 0x01); } @@ -549,7 +554,7 @@ static void setcolors(struct gspca_dev *gspca_dev) return; } reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x10, sd->colors); + reg_w(gspca_dev, 0x80, sd->colors); /* load registers to sensor (Bit 0, auto clear) */ reg_w(gspca_dev, 0x11, 0x01); PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); @@ -583,7 +588,7 @@ static void sethvflip(struct gspca_dev *gspca_dev) /* this function is called at open time */ static int sd_open(struct gspca_dev *gspca_dev) { - reg_w(gspca_dev, 0x78, 0x00); /* Turn on LED */ + reg_w(gspca_dev, 0x78, 0x44); /* Turn on LED */ return 0; } @@ -612,27 +617,24 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x08, 0x09); reg_w(gspca_dev, 0x17, 0x20); reg_w(gspca_dev, 0x1b, 0x00); -/* reg_w(gspca_dev, 0x80, 0x69); */ reg_w(gspca_dev, 0x87, 0x10); break; case 1: /* 320x240 pac7311 */ reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x02, 0x03); + reg_w(gspca_dev, 0x02, 0x07); reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x08, 0x09); reg_w(gspca_dev, 0x17, 0x30); -/* reg_w(gspca_dev, 0x80, 0x3f); */ reg_w(gspca_dev, 0x87, 0x11); break; case 0: /* 640x480 */ if (sd->sensor == SENSOR_PAC7302) break; reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x02, 0x03); + reg_w(gspca_dev, 0x02, 0x07); reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x08, 0x08); reg_w(gspca_dev, 0x17, 0x00); -/* reg_w(gspca_dev, 0x80, 0x1c); */ reg_w(gspca_dev, 0x87, 0x12); break; } @@ -645,8 +647,8 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x78, 0x01); } else { - reg_w(gspca_dev, 0x78, 0x04); - reg_w(gspca_dev, 0x78, 0x05); + reg_w(gspca_dev, 0x78, 0x44); + reg_w(gspca_dev, 0x78, 0x45); } } @@ -666,7 +668,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x2a, 0x0e); reg_w(gspca_dev, 0xff, 0x01); reg_w(gspca_dev, 0x3e, 0x20); - reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ } @@ -775,7 +777,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (sd->tosof > LUM_OFFSET) sd->lum_sum += data[-LUM_OFFSET]; sd->tosof = 0; - jpeg_put_header(gspca_dev, frame, 1, 0x21); + jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21); } for (i = 0; i < len; i++) { @@ -795,7 +797,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, sd->tosof = -len; break; } - jpeg_put_header(gspca_dev, frame, 1, 0x21); + jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21); break; #if 0 /*fixme:test+*/ /* is there a start of frame ? */ @@ -813,7 +815,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data += i + 7; len -= i + 7; i = 0; - jpeg_put_header(gspca_dev, frame, 1, 0x21); + jpeg_put_header(gspca_dev, frame, + sd->qindex, 0x21); break; } break; -- cgit v1.2.3 From dbcc686f4d8690159db7c5bb13fc08be07a4bf91 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 19 Aug 2008 11:31:08 +0200 Subject: gspca: Bad start of sonixj webcams since changeset a8779025e7e8. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 8a42d2a4f..137a609cb 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -59,7 +59,6 @@ struct sd { #define SENSOR_OV7648 5 #define SENSOR_OV7660 6 unsigned char i2c_base; - __u8 regf1; }; /* V4L2 controls supported by the driver */ @@ -959,7 +958,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->bridge = id->driver_info >> 16; sd->sensor = id->driver_info >> 8; sd->i2c_base = id->driver_info; - sd->regf1 = 0; /*jfm: was 1 in v1*/ sd->qindex = 4; /* set the quantization table */ sd->brightness = BRIGHTNESS_DEF; @@ -1012,7 +1010,7 @@ static int sd_open(struct gspca_dev *gspca_dev) break; } - reg_w1(gspca_dev, 0xf1, sd->regf1); + reg_w1(gspca_dev, 0xf1, 0x01); #if 1 /*jfm: from win trace*/ return 0; @@ -1401,7 +1399,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); reg_w1(gspca_dev, 0x01, sn9c1xx[1]); reg_w1(gspca_dev, 0x01, data); - reg_w1(gspca_dev, 0xf1, sd->regf1); + reg_w1(gspca_dev, 0xf1, 0x00); } static void sd_stop0(struct gspca_dev *gspca_dev) -- cgit v1.2.3 From 5e7d387f09334ce7b85f97fc8317e8e0a135865c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 19 Aug 2008 12:25:03 +0200 Subject: gspca: Bad color control again in sonixj. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 137a609cb..6c7ea00e4 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -108,9 +108,9 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Color", .minimum = 0, - .maximum = 255, + .maximum = 64, .step = 1, -#define COLOR_DEF 127 +#define COLOR_DEF 32 .default_value = COLOR_DEF, }, .set = sd_setcolors, @@ -1167,17 +1167,18 @@ static void setcontrast(struct gspca_dev *gspca_dev) static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 data; - int colour; + __u8 blue, red; - colour = sd->colors - 128; - if (colour > 0) { - data = (colour + 32) & 0x7f; /* blue */ - reg_w1(gspca_dev, 0x06, data); + if (sd->colors >= 32) { + red = 32 + (sd->colors - 32) / 2; + blue = 64 - sd->colors; } else { - data = (-colour + 32) & 0x7f; /* red */ - reg_w1(gspca_dev, 0x05, data); + red = sd->colors; + blue = 32 + (32 - sd->colors) / 2; } + reg_w1(gspca_dev, 0x05, red); +/* reg_w1(gspca_dev, 0x07, 32); */ + reg_w1(gspca_dev, 0x06, blue); } static void setautogain(struct gspca_dev *gspca_dev) -- cgit v1.2.3 From afe4decd7e483e9b2e59145ab17b2d7c12ceed9a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 19 Aug 2008 18:17:37 +0200 Subject: gspca: Bad start of sn9c110 and sensor om6802. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 6c7ea00e4..785ab2fc3 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -813,7 +813,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev, switch (sd->sensor) { case SENSOR_OM6802: - reg_w1(gspca_dev, 0x02, 0x73); /* was 71 */ + reg_w1(gspca_dev, 0x02, 0x71); reg_w1(gspca_dev, 0x01, 0x42); reg_w1(gspca_dev, 0x17, 0x64); reg_w1(gspca_dev, 0x01, 0x42); -- cgit v1.2.3 From bca290bed996cc2b74f31adba84b1f09f395cc40 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 21 Aug 2008 09:00:48 +0200 Subject: gspca: Bad start of sn9c110 and sensor ov7630. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 785ab2fc3..7b24a8915 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1297,7 +1297,7 @@ static void sd_start(struct gspca_dev *gspca_dev) case SENSOR_OV7630: ov7630_InitSensor(gspca_dev); reg17 = 0xe2; - reg1 = 0x40; + reg1 = 0x44; break; case SENSOR_OV7648: ov7648_InitSensor(gspca_dev); -- cgit v1.2.3 From fe4bc624af9585529df5e185c813d5804eec23c6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 21 Aug 2008 09:16:41 +0200 Subject: gspca: Frame buffer too small for small resolutions (sonixj and t613). From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 2 +- linux/drivers/media/video/gspca/t613.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 7b24a8915..9ab29155b 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -135,7 +135,7 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format vga_mode[] = { {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 8 + 590, + .sizeimage = 160 * 120 * 4 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 2}, {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 56b1dfa72..f3ddb5cc5 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -233,7 +233,7 @@ static char *effects_control[] = { static struct v4l2_pix_format vga_mode_t16[] = { {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 8 + 590, + .sizeimage = 160 * 120 * 4 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 4}, {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, -- cgit v1.2.3 From b9ae7f8e368d1e376130025e9d903db00e39a414 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 21 Aug 2008 16:25:31 +0200 Subject: gspca: suspend/resume added. From: Jean-Francois Moine Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/conex.c | 4 ++++ linux/drivers/media/video/gspca/etoms.c | 4 ++++ linux/drivers/media/video/gspca/gspca.c | 30 +++++++++++++++++++++++++++++- linux/drivers/media/video/gspca/gspca.h | 7 +++++++ linux/drivers/media/video/gspca/mars.c | 4 ++++ linux/drivers/media/video/gspca/ov519.c | 4 ++++ linux/drivers/media/video/gspca/pac207.c | 4 ++++ linux/drivers/media/video/gspca/pac7311.c | 4 ++++ linux/drivers/media/video/gspca/sonixb.c | 4 ++++ linux/drivers/media/video/gspca/sonixj.c | 4 ++++ linux/drivers/media/video/gspca/spca500.c | 4 ++++ linux/drivers/media/video/gspca/spca501.c | 4 ++++ linux/drivers/media/video/gspca/spca505.c | 4 ++++ linux/drivers/media/video/gspca/spca506.c | 4 ++++ linux/drivers/media/video/gspca/spca508.c | 4 ++++ linux/drivers/media/video/gspca/spca561.c | 4 ++++ linux/drivers/media/video/gspca/stk014.c | 4 ++++ linux/drivers/media/video/gspca/sunplus.c | 4 ++++ linux/drivers/media/video/gspca/t613.c | 4 ++++ linux/drivers/media/video/gspca/tv8532.c | 4 ++++ linux/drivers/media/video/gspca/vc032x.c | 4 ++++ linux/drivers/media/video/gspca/zc3xx.c | 4 ++++ 22 files changed, 116 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/conex.c b/linux/drivers/media/video/gspca/conex.c index cd3a3f582..739ef557c 100644 --- a/linux/drivers/media/video/gspca/conex.c +++ b/linux/drivers/media/video/gspca/conex.c @@ -1026,6 +1026,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/etoms.c b/linux/drivers/media/video/gspca/etoms.c index a9d043606..626d03e17 100644 --- a/linux/drivers/media/video/gspca/etoms.c +++ b/linux/drivers/media/video/gspca/etoms.c @@ -932,6 +932,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 61071a4f4..fd008b956 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -118,7 +118,8 @@ static void fill_frame(struct gspca_dev *gspca_dev, cam_pkt_op pkt_scan; if (urb->status != 0) { - PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); + if (!gspca_dev->frozen) + PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); return; /* disconnection ? */ } pkt_scan = gspca_dev->sd_desc->pkt_scan; @@ -1815,6 +1816,33 @@ void gspca_disconnect(struct usb_interface *intf) } EXPORT_SYMBOL(gspca_disconnect); +#ifdef CONFIG_PM +int gspca_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + + if (!gspca_dev->streaming) + return 0; + gspca_dev->frozen = 1; /* avoid urb error messages */ + gspca_dev->sd_desc->stopN(gspca_dev); + destroy_urbs(gspca_dev); + gspca_set_alt0(gspca_dev); + gspca_dev->sd_desc->stop0(gspca_dev); + return 0; +} +EXPORT_SYMBOL(gspca_suspend); + +int gspca_resume(struct usb_interface *intf) +{ + struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + + gspca_dev->frozen = 0; + if (!gspca_dev->streaming) + return 0; + return gspca_init_transfer(gspca_dev); +} +EXPORT_SYMBOL(gspca_resume); +#endif /* -- cam driver utility functions -- */ /* auto gain and exposure algorithm based on the knee algorithm described here: diff --git a/linux/drivers/media/video/gspca/gspca.h b/linux/drivers/media/video/gspca/gspca.h index 5cb584546..2596568e8 100644 --- a/linux/drivers/media/video/gspca/gspca.h +++ b/linux/drivers/media/video/gspca/gspca.h @@ -154,6 +154,9 @@ struct gspca_dev { struct mutex queue_lock; /* ISOC queue protection */ __u32 sequence; /* frame sequence number */ char streaming; +#ifdef CONFIG_PM + char frozen; /* suspend - resume */ +#endif char users; /* number of opens */ char present; /* device connected */ char nbufread; /* number of buffers for read() */ @@ -173,6 +176,10 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, struct gspca_frame *frame, const __u8 *data, int len); +#ifdef CONFIG_PM +int gspca_suspend(struct usb_interface *intf, pm_message_t message); +int gspca_resume(struct usb_interface *intf); +#endif int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); #endif /* GSPCAV2_H */ diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c index 21c4ee56a..d7e209578 100644 --- a/linux/drivers/media/video/gspca/mars.c +++ b/linux/drivers/media/video/gspca/mars.c @@ -439,6 +439,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/ov519.c b/linux/drivers/media/video/gspca/ov519.c index 2379433f0..e1c665b4d 100644 --- a/linux/drivers/media/video/gspca/ov519.c +++ b/linux/drivers/media/video/gspca/ov519.c @@ -2157,6 +2157,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c index cee45b048..d9668f4cb 100644 --- a/linux/drivers/media/video/gspca/pac207.c +++ b/linux/drivers/media/video/gspca/pac207.c @@ -596,6 +596,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/pac7311.c b/linux/drivers/media/video/gspca/pac7311.c index 3a22f2162..94f0cd1b8 100644 --- a/linux/drivers/media/video/gspca/pac7311.c +++ b/linux/drivers/media/video/gspca/pac7311.c @@ -976,6 +976,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/sonixb.c b/linux/drivers/media/video/gspca/sonixb.c index 4d979fa39..afbb969ba 100644 --- a/linux/drivers/media/video/gspca/sonixb.c +++ b/linux/drivers/media/video/gspca/sonixb.c @@ -1264,6 +1264,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 9ab29155b..217a31a0e 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1672,6 +1672,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/spca500.c b/linux/drivers/media/video/gspca/spca500.c index be88d30a3..2aff5af9a 100644 --- a/linux/drivers/media/video/gspca/spca500.c +++ b/linux/drivers/media/video/gspca/spca500.c @@ -1110,6 +1110,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/spca501.c b/linux/drivers/media/video/gspca/spca501.c index f8df18e85..df657cb9d 100644 --- a/linux/drivers/media/video/gspca/spca501.c +++ b/linux/drivers/media/video/gspca/spca501.c @@ -2165,6 +2165,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index 1cde4b34f..440e6853c 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -924,6 +924,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/spca506.c b/linux/drivers/media/video/gspca/spca506.c index f622fa757..ae772488c 100644 --- a/linux/drivers/media/video/gspca/spca506.c +++ b/linux/drivers/media/video/gspca/spca506.c @@ -772,6 +772,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/spca508.c b/linux/drivers/media/video/gspca/spca508.c index 52e2f7462..585468863 100644 --- a/linux/drivers/media/video/gspca/spca508.c +++ b/linux/drivers/media/video/gspca/spca508.c @@ -1705,6 +1705,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/spca561.c b/linux/drivers/media/video/gspca/spca561.c index 86fc55bf9..d686b6bd7 100644 --- a/linux/drivers/media/video/gspca/spca561.c +++ b/linux/drivers/media/video/gspca/spca561.c @@ -1198,6 +1198,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/stk014.c b/linux/drivers/media/video/gspca/stk014.c index 16219cf6a..387a8cf2b 100644 --- a/linux/drivers/media/video/gspca/stk014.c +++ b/linux/drivers/media/video/gspca/stk014.c @@ -564,6 +564,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/sunplus.c b/linux/drivers/media/video/gspca/sunplus.c index 8701b07c8..e1a7e53ba 100644 --- a/linux/drivers/media/video/gspca/sunplus.c +++ b/linux/drivers/media/video/gspca/sunplus.c @@ -1487,6 +1487,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index f3ddb5cc5..c90925362 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -1037,6 +1037,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/tv8532.c b/linux/drivers/media/video/gspca/tv8532.c index fcac077bb..c55dbe8ac 100644 --- a/linux/drivers/media/video/gspca/tv8532.c +++ b/linux/drivers/media/video/gspca/tv8532.c @@ -653,6 +653,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 0e23edb16..f37c63d6d 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -1971,6 +1971,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; /* -- module insert / remove -- */ diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 468b01b8f..d6aa970cf 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -7596,6 +7596,10 @@ static struct usb_driver sd_driver = { .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif }; static int __init sd_mod_init(void) -- cgit v1.2.3 From ff9634945387dde6b9a361d902bbe73d0c1a236e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 21 Aug 2008 19:11:16 +0200 Subject: gspca: Have VIDIOC_QUERYCTRL more compliant to the spec. From: Jean-Francois Moine - return -EINVAL when control not supported. - start the private controls at V4L2_CID_PRIVATE_BASE. Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 5 ----- linux/drivers/media/video/gspca/t613.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index fd008b956..731957af3 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -891,11 +891,6 @@ static int vidioc_queryctrl(struct file *file, void *priv, return 0; } } - if (id >= V4L2_CID_BASE - && id <= V4L2_CID_LASTP1) { - q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; - return 0; - } return -EINVAL; } diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index c90925362..27bff51a0 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -30,7 +30,7 @@ #define MAX_GAMMA 0x10 /* 0 to 15 */ -#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0) MODULE_AUTHOR("Leandro Costantino "); MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); -- cgit v1.2.3 From 14eb37189ae76c7f329e1eb00c023198f6b3a33d Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 22 Aug 2008 09:13:34 +0200 Subject: gspca: V4L2_CAP_SENSOR_UPSIDE_DOWN added as a cap for some webcams. From: Hans de Goede This patch adds a V4L2_CAP_SENSOR_UPSIDE_DOWN flag to the capabilities flags, and sets this flag for the Philips SPC200NC cam (which has its sensor installed upside down). The same flag is also needed and added for the Philips SPC300NC. Together with a patch to libv4l which adds flipping the image in software this fixes the upside down display with the SPC200NC cam. Signed-of-by: Hans de Goede Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 2 ++ linux/drivers/media/video/gspca/gspca.h | 4 ++++ linux/drivers/media/video/gspca/zc3xx.c | 31 +++++++++++++++++++------------ 3 files changed, 25 insertions(+), 12 deletions(-) (limited to 'linux/drivers/media') diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 731957af3..df7c5cb0a 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -858,6 +858,8 @@ static int vidioc_querycap(struct file *file, void *priv, cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; + if (gspca_dev->flags & GSPCA_SENSOR_UPSIDE_DOWN_FLAG) + cap->capabilities |= V4L2_CAP_SENSOR_UPSIDE_DOWN; return 0; } diff --git a/linux/drivers/media/video/gspca/gspca.h b/linux/drivers/media/video/gspca/gspca.h index 2596568e8..1920c99d6 100644 --- a/linux/drivers/media/video/gspca/gspca.h +++ b/linux/drivers/media/video/gspca/gspca.h @@ -118,6 +118,9 @@ struct gspca_frame { struct v4l2_buffer v4l2_buf; }; +/* defines for the flags member */ +#define GSPCA_SENSOR_UPSIDE_DOWN_FLAG 0x01 + struct gspca_dev { struct video_device vdev; /* !! must be the first item */ struct file_operations fops; @@ -163,6 +166,7 @@ struct gspca_dev { char nurbs; /* number of allocated URBs */ char memory; /* memory type (V4L2_MEMORY_xxx) */ __u8 nbalt; /* number of USB alternate settings */ + __u8 flags; /* see GSPCA_XXX_FLAG defines */ }; int gspca_dev_probe(struct usb_interface *intf, diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index d6aa970cf..a3f109ac4 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -70,6 +70,10 @@ struct sd { unsigned short chip_revision; }; +#define DRIVER_INFO(sensor, flags) .driver_info = ((sensor) << 8) | (flags) +#define DRIVER_INFO_GET_SENSOR(driver_info) ((driver_info) >> 8) +#define DRIVER_INFO_GET_FLAGS(driver_info) ((driver_info) & 0xff) + /* V4L2 controls supported by the driver */ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); @@ -7020,7 +7024,8 @@ static int sd_config(struct gspca_dev *gspca_dev, /* define some sensors from the vendor/product */ sd->sharpness = 2; - sd->sensor = id->driver_info; + sd->sensor = DRIVER_INFO_GET_SENSOR(id->driver_info); + gspca_dev->flags = DRIVER_INFO_GET_FLAGS(id->driver_info); sensor = zcxx_probeSensor(gspca_dev); if (sensor >= 0) PDEBUG(D_PROBE, "probe sensor -> %02x", sensor); @@ -7517,19 +7522,19 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x041e)}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x041e, 0x4017)}, - {USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106}, + {USB_DEVICE(0x041e, 0x401c), DRIVER_INFO(SENSOR_PAS106, 0)}, {USB_DEVICE(0x041e, 0x401e)}, {USB_DEVICE(0x041e, 0x401f)}, #endif {USB_DEVICE(0x041e, 0x4029)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x041e, 0x4034), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106}, + {USB_DEVICE(0x041e, 0x4034), DRIVER_INFO(SENSOR_PAS106, 0)}, + {USB_DEVICE(0x041e, 0x4035), DRIVER_INFO(SENSOR_PAS106, 0)}, {USB_DEVICE(0x041e, 0x4036)}, {USB_DEVICE(0x041e, 0x403a)}, #endif - {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250}, - {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x041e, 0x4051), DRIVER_INFO(SENSOR_TAS5130C_VF0250, 0)}, + {USB_DEVICE(0x041e, 0x4053), DRIVER_INFO(SENSOR_TAS5130C_VF0250, 0)}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0458, 0x7007)}, {USB_DEVICE(0x0458, 0x700c)}, @@ -7555,11 +7560,13 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x08d9)}, {USB_DEVICE(0x046d, 0x08d8)}, {USB_DEVICE(0x046d, 0x08da)}, - {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, - {USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0471, 0x0326), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0471, 0x032d), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0471, 0x032e), .driver_info = SENSOR_PAS106}, + {USB_DEVICE(0x046d, 0x08dd), DRIVER_INFO(SENSOR_MC501CB, 0)}, + {USB_DEVICE(0x0471, 0x0325), DRIVER_INFO(SENSOR_PAS106, + GSPCA_SENSOR_UPSIDE_DOWN_FLAG)}, + {USB_DEVICE(0x0471, 0x0326), DRIVER_INFO(SENSOR_PAS106, + GSPCA_SENSOR_UPSIDE_DOWN_FLAG)}, + {USB_DEVICE(0x0471, 0x032d), DRIVER_INFO(SENSOR_PAS106, 0)}, + {USB_DEVICE(0x0471, 0x032e), DRIVER_INFO(SENSOR_PAS106, 0)}, {USB_DEVICE(0x055f, 0xc005)}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x055f, 0xd003)}, @@ -7571,7 +7578,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0ac8, 0x301b)}, {USB_DEVICE(0x0ac8, 0x303b)}, #endif - {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x0ac8, 0x305b), DRIVER_INFO(SENSOR_TAS5130C_VF0250, 0)}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0ac8, 0x307b)}, {USB_DEVICE(0x10fd, 0x0128)}, -- cgit v1.2.3