From 7f1711234e6a21c153e892758d9d82c333ab37ac Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 18 Oct 2007 19:56:47 -0300 Subject: V4L/DVB (6384): Replace TDA9887_SET_CONFIG by TUNER_SET_CONFIG Currently, the only tuner-specific device that allows special configurations is tda9887. However, tea5767 also may require some special configurations (for example, to specify a different Xtal freq). This patch replaces TDA9887_SET_CONFIG by a more generic internal ioctl (TUNER_SET_CONFIG). The newer one allows specifying what tuner is appliable to a configuration set, and allows an arbitrary configuration struct. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 181a40c46a52..c019c1e99895 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -116,6 +116,11 @@ struct v4l2_decode_vbi_line { u32 type; /* VBI service type (V4L2_SLICED_*). 0 if no service found */ }; +struct v4l2_priv_tun_config { + int tuner; + void *priv; +}; + /* audio ioctls */ /* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */ @@ -131,7 +136,7 @@ struct v4l2_decode_vbi_line { #define TUNER_SET_STANDBY _IOW('d', 91, int) /* Sets tda9887 specific stuff, like port1, port2 and qss */ -#define TDA9887_SET_CONFIG _IOW('d', 92, int) +#define TUNER_SET_CONFIG _IOW('d', 92, struct v4l2_priv_tun_config) /* Switch the tuner to a specific tuner mode. Replacement of AUDC_SET_RADIO */ #define VIDIOC_INT_S_TUNER_MODE _IOW('d', 93, enum v4l2_tuner_type) -- cgit v1.2.3 From 12466577853b0d057f4416f4c7020e544f3a4209 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 24 Oct 2007 11:08:20 -0300 Subject: V4L/DVB (6422): Add the pending entries for xc2028/3028 based boards Also replaces all occurrences of TUNER_XCEIVE_XC3028 to TUNER_XC2028. Some work is still may be required to make sure that non-tm6000 drivers will be capable of using tuner-xc2028. Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.tuner | 2 +- drivers/media/video/em28xx/em28xx-cards.c | 71 +++++++++++++++++++++++++++++++ drivers/media/video/ivtv/ivtv-cards.c | 6 +-- drivers/media/video/ivtv/ivtv-driver.c | 2 +- drivers/media/video/tuner-types.c | 6 +-- include/media/tuner.h | 2 +- 6 files changed, 80 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index a88c02d23805..84c3ac7c33d9 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -69,7 +69,7 @@ tuner=67 - Philips TD1316 Hybrid Tuner tuner=68 - Philips TUV1236D ATSC/NTSC dual in tuner=69 - Tena TNF 5335 and similar models tuner=70 - Samsung TCPN 2121P30A -tuner=71 - Xceive xc3028 +tuner=71 - Xceive xc2028/xc3028 tuner tuner=72 - Thomson FE6600 tuner=73 - Samsung TCPG 6121P30A tuner=75 - Philips TEA5761 FM Radio diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 418ea8b7f85a..2d72de0e7564 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -156,6 +156,74 @@ struct em28xx_board em28xx_boards[] = { MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), }}, }, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { + .name = "Hauppauge WinTV HVR 900", + .vchannels = 3, + .norm = VIDEO_MODE_PAL, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .has_tuner = 1, + .decoder = EM28XX_TVP5150, + .input = {{ + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + },{ + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + },{ + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + }}, + }, + [EM2880_BOARD_TERRATEC_HYBRID_XS] = { + .name = "Terratec Hybrid XS", + .vchannels = 3, + .norm = VIDEO_MODE_PAL, + .tda9887_conf = TDA9887_PRESENT, + .has_tuner = 1, + .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, + }}, + }, + /* 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, + .norm = VIDEO_MODE_PAL, + .tda9887_conf = TDA9887_PRESENT, + .has_tuner = 1, + .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, @@ -274,6 +342,9 @@ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x2040, 0x6500), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, + { USB_DEVICE(0x0ccd, 0x0042), .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x0047), .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, { }, }; diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index b6a8be622d3c..aaa114b5c268 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c @@ -848,7 +848,7 @@ static const struct ivtv_card ivtv_card_pg600v2 = { { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, }, .tuners = { - { .std = V4L2_STD_ALL, .tuner = TUNER_XCEIVE_XC3028 }, + { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, }, .pci_list = ivtv_pci_pg600v2, }; @@ -879,7 +879,7 @@ static const struct ivtv_card ivtv_card_club3d = { { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, }, .tuners = { - { .std = V4L2_STD_ALL, .tuner = TUNER_XCEIVE_XC3028 }, + { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, }, .pci_list = ivtv_pci_club3d, }; @@ -910,7 +910,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = { }, .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, /* enable line-in */ .tuners = { - { .std = V4L2_STD_ALL, .tuner = TUNER_XCEIVE_XC3028 }, + { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, }, .pci_list = ivtv_pci_avertv_mce116, }; diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 6d2dd8764f81..ec40453e46e4 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -829,7 +829,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) /* load modules */ #ifndef CONFIG_VIDEO_TUNER if (hw & IVTV_HW_TUNER) { - if (itv->options.tuner == TUNER_XCEIVE_XC3028) { + if (itv->options.tuner == TUNER_XC2028) { IVTV_INFO("Xceive tuner not yet supported, only composite and S-Video inputs will be available\n"); itv->tunerid = 1; } diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index c6a7934bd5a6..ac363f019227 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c @@ -1452,9 +1452,9 @@ struct tunertype tuners[] = { .params = tuner_samsung_tcpn_2121p30a_params, .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params), }, - [TUNER_XCEIVE_XC3028] = { /* Xceive 3028 */ - .name = "Xceive xc3028", - /* see xc3028.c for details */ + [TUNER_XC2028] = { /* Xceive 2028 */ + .name = "Xceive xc2028/xc3028 tuner", + /* see tuner-xc2028.c for details */ }, [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */ .name = "Thomson FE6600", diff --git a/include/media/tuner.h b/include/media/tuner.h index c03dceb92605..d49392d90e56 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -117,7 +117,7 @@ extern int tuner_debug; #define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */ #define TUNER_TNF_5335MF 69 /* Sabrent Bt848 */ #define TUNER_SAMSUNG_TCPN_2121P30A 70 /* Hauppauge PVR-500MCE NTSC */ -#define TUNER_XCEIVE_XC3028 71 +#define TUNER_XC2028 71 #define TUNER_THOMSON_FE6600 72 /* DViCO FusionHDTV DVB-T Hybrid */ #define TUNER_SAMSUNG_TCPG_6121P30A 73 /* Hauppauge PVR-500 PAL */ -- cgit v1.2.3 From 5bea1cd3871351d70cc7624af138f8aa68b7be77 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 22 Oct 2007 09:56:38 -0300 Subject: V4L/DVB (6435): tda8290: add support for NXP TDA18271 tuner and TDA8295 analog demod Add basic support for NXP TDA8295 analog demod and TDA18271 tuner silicon. TDA8295 + TDA8275a not yet tested. TDA8290 + TDA18271 not yet supported. Digital mode of TDA18271 not yet tested & needs more work. Signed-off-by: Michael Krufky Reviewed-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.tuner | 1 + drivers/media/Kconfig | 3 +- drivers/media/dvb/frontends/Kconfig | 7 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/tda18271.c | 1054 ++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/tda18271.h | 40 ++ drivers/media/video/tda8290.c | 319 ++++++++- drivers/media/video/tda8290.h | 8 + drivers/media/video/tuner-core.c | 5 + drivers/media/video/tuner-types.c | 3 + drivers/media/video/tveeprom.c | 2 +- include/media/tuner.h | 2 + 12 files changed, 1437 insertions(+), 8 deletions(-) create mode 100644 drivers/media/dvb/frontends/tda18271.c create mode 100644 drivers/media/dvb/frontends/tda18271.h (limited to 'include') diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index 84c3ac7c33d9..ac47b48715dd 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -73,3 +73,4 @@ tuner=71 - Xceive xc2028/xc3028 tuner tuner=72 - Thomson FE6600 tuner=73 - Samsung TCPG 6121P30A tuner=75 - Philips TEA5761 FM Radio +tuner=76 - tda8295+18271 diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index d363d0cae38b..e52229380984 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -105,9 +105,10 @@ config TUNER_MT20XX Say Y here to include support for the MT2032 / MT2050 tuner. config TUNER_TDA8290 - tristate "TDA 8290+8275(a) tuner combo" + tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo" depends on I2C select DVB_TDA827X + select DVB_TDA18271 default m if VIDEO_TUNER_CUSTOMIZE help Say Y here to include support for Philips TDA8290+8275(a) tuner. diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 59b9ed1f1aec..57178d6e1cf8 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -316,6 +316,13 @@ config DVB_TDA827X help A DVB-T silicon tuner module. Say Y when you want to support this tuner. +config DVB_TDA18271 + tristate "NXP TDA18271 silicon tuner" + depends on I2C + default m if DVB_FE_CUSTOMISE + help + A silicon tuner module. Say Y when you want to support this tuner. + config DVB_TUNER_QT1010 tristate "Quantek QT1010 silicon tuner" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 4b8ad1f132aa..457effcda5da 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_DVB_ISL6421) += isl6421.o obj-$(CONFIG_DVB_TDA10086) += tda10086.o obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TDA827X) += tda827x.o +obj-$(CONFIG_DVB_TDA18271) += tda18271.o obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o diff --git a/drivers/media/dvb/frontends/tda18271.c b/drivers/media/dvb/frontends/tda18271.c new file mode 100644 index 000000000000..3395f2bda498 --- /dev/null +++ b/drivers/media/dvb/frontends/tda18271.c @@ -0,0 +1,1054 @@ +/* + tda18271.c - driver for the Philips / NXP TDA18271 silicon tuner + + Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org) + + 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 "tda18271.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + +#define tuner_dbg(fmt, arg...) do {\ + if (debug > 0) \ + printk(KERN_DEBUG fmt, ##arg); } while (0) + +#define tuner_extra_dbg(fmt, arg...) do {\ + if (debug > 1) \ + printk(KERN_DEBUG fmt, ##arg); } while (0) + +#define R_ID 0x00 /* ID byte */ +#define R_TM 0x01 /* Thermo byte */ +#define R_PL 0x02 /* Power level byte */ +#define R_EP1 0x03 /* Easy Prog byte 1 */ +#define R_EP2 0x04 /* Easy Prog byte 2 */ +#define R_EP3 0x05 /* Easy Prog byte 3 */ +#define R_EP4 0x06 /* Easy Prog byte 4 */ +#define R_EP5 0x07 /* Easy Prog byte 5 */ +#define R_CPD 0x08 /* Cal Post-Divider byte */ +#define R_CD1 0x09 /* Cal Divider byte 1 */ +#define R_CD2 0x0a /* Cal Divider byte 2 */ +#define R_CD3 0x0b /* Cal Divider byte 3 */ +#define R_MPD 0x0c /* Main Post-Divider byte */ +#define R_MD1 0x0d /* Main Divider byte 1 */ +#define R_MD2 0x0e /* Main Divider byte 2 */ +#define R_MD3 0x0f /* Main Divider byte 3 */ +#define R_EB1 0x10 /* Extended byte 1 */ +#define R_EB2 0x11 /* Extended byte 2 */ +#define R_EB3 0x12 /* Extended byte 3 */ +#define R_EB4 0x13 /* Extended byte 4 */ +#define R_EB5 0x14 /* Extended byte 5 */ +#define R_EB6 0x15 /* Extended byte 6 */ +#define R_EB7 0x16 /* Extended byte 7 */ +#define R_EB8 0x17 /* Extended byte 8 */ +#define R_EB9 0x18 /* Extended byte 9 */ +#define R_EB10 0x19 /* Extended byte 10 */ +#define R_EB11 0x1a /* Extended byte 11 */ +#define R_EB12 0x1b /* Extended byte 12 */ +#define R_EB13 0x1c /* Extended byte 13 */ +#define R_EB14 0x1d /* Extended byte 14 */ +#define R_EB15 0x1e /* Extended byte 15 */ +#define R_EB16 0x1f /* Extended byte 16 */ +#define R_EB17 0x20 /* Extended byte 17 */ +#define R_EB18 0x21 /* Extended byte 18 */ +#define R_EB19 0x22 /* Extended byte 19 */ +#define R_EB20 0x23 /* Extended byte 20 */ +#define R_EB21 0x24 /* Extended byte 21 */ +#define R_EB22 0x25 /* Extended byte 22 */ +#define R_EB23 0x26 /* Extended byte 23 */ + +struct tda18271_pll_map { + u32 lomax; + u8 pd; /* post div */ + u8 d; /* div */ +}; + +static struct tda18271_pll_map tda18271_main_pll[] = { + { .lomax = 32000, .pd = 0x5f, .d = 0xf0 }, + { .lomax = 35000, .pd = 0x5e, .d = 0xe0 }, + { .lomax = 37000, .pd = 0x5d, .d = 0xd0 }, + { .lomax = 41000, .pd = 0x5c, .d = 0xc0 }, + { .lomax = 44000, .pd = 0x5b, .d = 0xb0 }, + { .lomax = 49000, .pd = 0x5a, .d = 0xa0 }, + { .lomax = 54000, .pd = 0x59, .d = 0x90 }, + { .lomax = 61000, .pd = 0x58, .d = 0x80 }, + { .lomax = 65000, .pd = 0x4f, .d = 0x78 }, + { .lomax = 70000, .pd = 0x4e, .d = 0x70 }, + { .lomax = 75000, .pd = 0x4d, .d = 0x68 }, + { .lomax = 82000, .pd = 0x4c, .d = 0x60 }, + { .lomax = 89000, .pd = 0x4b, .d = 0x58 }, + { .lomax = 98000, .pd = 0x4a, .d = 0x50 }, + { .lomax = 109000, .pd = 0x49, .d = 0x48 }, + { .lomax = 123000, .pd = 0x48, .d = 0x40 }, + { .lomax = 131000, .pd = 0x3f, .d = 0x3c }, + { .lomax = 141000, .pd = 0x3e, .d = 0x38 }, + { .lomax = 151000, .pd = 0x3d, .d = 0x34 }, + { .lomax = 164000, .pd = 0x3c, .d = 0x30 }, + { .lomax = 179000, .pd = 0x3b, .d = 0x2c }, + { .lomax = 197000, .pd = 0x3a, .d = 0x28 }, + { .lomax = 219000, .pd = 0x39, .d = 0x24 }, + { .lomax = 246000, .pd = 0x38, .d = 0x20 }, + { .lomax = 263000, .pd = 0x2f, .d = 0x1e }, + { .lomax = 282000, .pd = 0x2e, .d = 0x1c }, + { .lomax = 303000, .pd = 0x2d, .d = 0x1a }, + { .lomax = 329000, .pd = 0x2c, .d = 0x18 }, + { .lomax = 359000, .pd = 0x2b, .d = 0x16 }, + { .lomax = 395000, .pd = 0x2a, .d = 0x14 }, + { .lomax = 438000, .pd = 0x29, .d = 0x12 }, + { .lomax = 493000, .pd = 0x28, .d = 0x10 }, + { .lomax = 526000, .pd = 0x1f, .d = 0x0f }, + { .lomax = 564000, .pd = 0x1e, .d = 0x0e }, + { .lomax = 607000, .pd = 0x1d, .d = 0x0d }, + { .lomax = 658000, .pd = 0x1c, .d = 0x0c }, + { .lomax = 718000, .pd = 0x1b, .d = 0x0b }, + { .lomax = 790000, .pd = 0x1a, .d = 0x0a }, + { .lomax = 877000, .pd = 0x19, .d = 0x09 }, + { .lomax = 987000, .pd = 0x18, .d = 0x08 }, + { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */ +}; + +static struct tda18271_pll_map tda18271_cal_pll[] = { + { .lomax = 33000, .pd = 0xdd, .d = 0xd0 }, + { .lomax = 36000, .pd = 0xdc, .d = 0xc0 }, + { .lomax = 40000, .pd = 0xdb, .d = 0xb0 }, + { .lomax = 44000, .pd = 0xda, .d = 0xa0 }, + { .lomax = 49000, .pd = 0xd9, .d = 0x90 }, + { .lomax = 55000, .pd = 0xd8, .d = 0x80 }, + { .lomax = 63000, .pd = 0xd3, .d = 0x70 }, + { .lomax = 67000, .pd = 0xcd, .d = 0x68 }, + { .lomax = 73000, .pd = 0xcc, .d = 0x60 }, + { .lomax = 80000, .pd = 0xcb, .d = 0x58 }, + { .lomax = 88000, .pd = 0xca, .d = 0x50 }, + { .lomax = 98000, .pd = 0xc9, .d = 0x48 }, + { .lomax = 110000, .pd = 0xc8, .d = 0x40 }, + { .lomax = 126000, .pd = 0xc3, .d = 0x38 }, + { .lomax = 135000, .pd = 0xbd, .d = 0x34 }, + { .lomax = 147000, .pd = 0xbc, .d = 0x30 }, + { .lomax = 160000, .pd = 0xbb, .d = 0x2c }, + { .lomax = 176000, .pd = 0xba, .d = 0x28 }, + { .lomax = 196000, .pd = 0xb9, .d = 0x24 }, + { .lomax = 220000, .pd = 0xb8, .d = 0x20 }, + { .lomax = 252000, .pd = 0xb3, .d = 0x1c }, + { .lomax = 271000, .pd = 0xad, .d = 0x1a }, + { .lomax = 294000, .pd = 0xac, .d = 0x18 }, + { .lomax = 321000, .pd = 0xab, .d = 0x16 }, + { .lomax = 353000, .pd = 0xaa, .d = 0x14 }, + { .lomax = 392000, .pd = 0xa9, .d = 0x12 }, + { .lomax = 441000, .pd = 0xa8, .d = 0x10 }, + { .lomax = 505000, .pd = 0xa3, .d = 0x0e }, + { .lomax = 543000, .pd = 0x9d, .d = 0x0d }, + { .lomax = 589000, .pd = 0x9c, .d = 0x0c }, + { .lomax = 642000, .pd = 0x9b, .d = 0x0b }, + { .lomax = 707000, .pd = 0x9a, .d = 0x0a }, + { .lomax = 785000, .pd = 0x99, .d = 0x09 }, + { .lomax = 883000, .pd = 0x98, .d = 0x08 }, + { .lomax = 1010000, .pd = 0x93, .d = 0x07 }, + { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */ +}; + +struct tda18271_map { + u32 rfmax; + u8 val; +}; + +static struct tda18271_map tda18271_bp_filter[] = { + { .rfmax = 62000, .val = 0x00 }, + { .rfmax = 84000, .val = 0x01 }, + { .rfmax = 100000, .val = 0x02 }, + { .rfmax = 140000, .val = 0x03 }, + { .rfmax = 170000, .val = 0x04 }, + { .rfmax = 180000, .val = 0x05 }, + { .rfmax = 865000, .val = 0x06 }, + { .rfmax = 0, .val = 0x00 }, /* end */ +}; + +static struct tda18271_map tda18271_km[] = { + { .rfmax = 61100, .val = 0x74 }, + { .rfmax = 350000, .val = 0x40 }, + { .rfmax = 720000, .val = 0x30 }, + { .rfmax = 865000, .val = 0x40 }, + { .rfmax = 0, .val = 0x00 }, /* end */ +}; + +static struct tda18271_map tda18271_rf_band[] = { + { .rfmax = 47900, .val = 0x00 }, + { .rfmax = 61100, .val = 0x01 }, +/* { .rfmax = 152600, .val = 0x02 }, */ + { .rfmax = 121200, .val = 0x02 }, + { .rfmax = 164700, .val = 0x03 }, + { .rfmax = 203500, .val = 0x04 }, + { .rfmax = 457800, .val = 0x05 }, + { .rfmax = 865000, .val = 0x06 }, + { .rfmax = 0, .val = 0x00 }, /* end */ +}; + +static struct tda18271_map tda18271_gain_taper[] = { + { .rfmax = 45400, .val = 0x1f }, + { .rfmax = 45800, .val = 0x1e }, + { .rfmax = 46200, .val = 0x1d }, + { .rfmax = 46700, .val = 0x1c }, + { .rfmax = 47100, .val = 0x1b }, + { .rfmax = 47500, .val = 0x1a }, + { .rfmax = 47900, .val = 0x19 }, + { .rfmax = 49600, .val = 0x17 }, + { .rfmax = 51200, .val = 0x16 }, + { .rfmax = 52900, .val = 0x15 }, + { .rfmax = 54500, .val = 0x14 }, + { .rfmax = 56200, .val = 0x13 }, + { .rfmax = 57800, .val = 0x12 }, + { .rfmax = 59500, .val = 0x11 }, + { .rfmax = 61100, .val = 0x10 }, + { .rfmax = 67600, .val = 0x0d }, + { .rfmax = 74200, .val = 0x0c }, + { .rfmax = 80700, .val = 0x0b }, + { .rfmax = 87200, .val = 0x0a }, + { .rfmax = 93800, .val = 0x09 }, + { .rfmax = 100300, .val = 0x08 }, + { .rfmax = 106900, .val = 0x07 }, + { .rfmax = 113400, .val = 0x06 }, + { .rfmax = 119900, .val = 0x05 }, + { .rfmax = 126500, .val = 0x04 }, + { .rfmax = 133000, .val = 0x03 }, + { .rfmax = 139500, .val = 0x02 }, + { .rfmax = 146100, .val = 0x01 }, + { .rfmax = 152600, .val = 0x00 }, + { .rfmax = 154300, .val = 0x1f }, + { .rfmax = 156100, .val = 0x1e }, + { .rfmax = 157800, .val = 0x1d }, + { .rfmax = 159500, .val = 0x1c }, + { .rfmax = 161200, .val = 0x1b }, + { .rfmax = 163000, .val = 0x1a }, + { .rfmax = 164700, .val = 0x19 }, + { .rfmax = 170200, .val = 0x17 }, + { .rfmax = 175800, .val = 0x16 }, + { .rfmax = 181300, .val = 0x15 }, + { .rfmax = 186900, .val = 0x14 }, + { .rfmax = 192400, .val = 0x13 }, + { .rfmax = 198000, .val = 0x12 }, + { .rfmax = 203500, .val = 0x11 }, + { .rfmax = 216200, .val = 0x14 }, + { .rfmax = 228900, .val = 0x13 }, + { .rfmax = 241600, .val = 0x12 }, + { .rfmax = 254400, .val = 0x11 }, + { .rfmax = 267100, .val = 0x10 }, + { .rfmax = 279800, .val = 0x0f }, + { .rfmax = 292500, .val = 0x0e }, + { .rfmax = 305200, .val = 0x0d }, + { .rfmax = 317900, .val = 0x0c }, + { .rfmax = 330700, .val = 0x0b }, + { .rfmax = 343400, .val = 0x0a }, + { .rfmax = 356100, .val = 0x09 }, + { .rfmax = 368800, .val = 0x08 }, + { .rfmax = 381500, .val = 0x07 }, + { .rfmax = 394200, .val = 0x06 }, + { .rfmax = 406900, .val = 0x05 }, + { .rfmax = 419700, .val = 0x04 }, + { .rfmax = 432400, .val = 0x03 }, + { .rfmax = 445100, .val = 0x02 }, + { .rfmax = 457800, .val = 0x01 }, + { .rfmax = 476300, .val = 0x19 }, + { .rfmax = 494800, .val = 0x18 }, + { .rfmax = 513300, .val = 0x17 }, + { .rfmax = 531800, .val = 0x16 }, + { .rfmax = 550300, .val = 0x15 }, + { .rfmax = 568900, .val = 0x14 }, + { .rfmax = 587400, .val = 0x13 }, + { .rfmax = 605900, .val = 0x12 }, + { .rfmax = 624400, .val = 0x11 }, + { .rfmax = 642900, .val = 0x10 }, + { .rfmax = 661400, .val = 0x0f }, + { .rfmax = 679900, .val = 0x0e }, + { .rfmax = 698400, .val = 0x0d }, + { .rfmax = 716900, .val = 0x0c }, + { .rfmax = 735400, .val = 0x0b }, + { .rfmax = 753900, .val = 0x0a }, + { .rfmax = 772500, .val = 0x09 }, + { .rfmax = 791000, .val = 0x08 }, + { .rfmax = 809500, .val = 0x07 }, + { .rfmax = 828000, .val = 0x06 }, + { .rfmax = 846500, .val = 0x05 }, + { .rfmax = 865000, .val = 0x04 }, + { .rfmax = 0, .val = 0x00 }, /* end */ +}; + +static struct tda18271_map tda18271_rf_cal[] = { + { .rfmax = 41000, .val = 0x1e }, + { .rfmax = 43000, .val = 0x30 }, + { .rfmax = 45000, .val = 0x43 }, + { .rfmax = 46000, .val = 0x4d }, + { .rfmax = 47000, .val = 0x54 }, + { .rfmax = 47900, .val = 0x64 }, + { .rfmax = 49100, .val = 0x20 }, + { .rfmax = 50000, .val = 0x22 }, + { .rfmax = 51000, .val = 0x2a }, + { .rfmax = 53000, .val = 0x32 }, + { .rfmax = 55000, .val = 0x35 }, + { .rfmax = 56000, .val = 0x3c }, + { .rfmax = 57000, .val = 0x3f }, + { .rfmax = 58000, .val = 0x48 }, + { .rfmax = 59000, .val = 0x4d }, + { .rfmax = 60000, .val = 0x58 }, + { .rfmax = 61100, .val = 0x5f }, + { .rfmax = 0, .val = 0x00 }, /* end */ +}; + +/*---------------------------------------------------------------------*/ + +#define TDA18271_NUM_REGS 39 + +#define TDA18271_ANALOG 0 +#define TDA18271_DIGITAL 1 + +struct tda18271_priv { + u8 i2c_addr; + struct i2c_adapter *i2c_adap; + unsigned char tda18271_regs[TDA18271_NUM_REGS]; + int mode; + + u32 frequency; + u32 bandwidth; +}; + +/*---------------------------------------------------------------------*/ + +static void tda18271_dump_regs(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + unsigned char *regs = priv->tda18271_regs; + + tuner_dbg("=== TDA18271 REG DUMP ===\n"); + tuner_dbg("ID_BYTE = 0x%x\n", 0xff & regs[R_ID]); + tuner_dbg("THERMO_BYTE = 0x%x\n", 0xff & regs[R_TM]); + tuner_dbg("POWER_LEVEL_BYTE = 0x%x\n", 0xff & regs[R_PL]); + tuner_dbg("EASY_PROG_BYTE_1 = 0x%x\n", 0xff & regs[R_EP1]); + tuner_dbg("EASY_PROG_BYTE_2 = 0x%x\n", 0xff & regs[R_EP2]); + tuner_dbg("EASY_PROG_BYTE_3 = 0x%x\n", 0xff & regs[R_EP3]); + tuner_dbg("EASY_PROG_BYTE_4 = 0x%x\n", 0xff & regs[R_EP4]); + tuner_dbg("EASY_PROG_BYTE_5 = 0x%x\n", 0xff & regs[R_EP5]); + tuner_dbg("CAL_POST_DIV_BYTE = 0x%x\n", 0xff & regs[R_CPD]); + tuner_dbg("CAL_DIV_BYTE_1 = 0x%x\n", 0xff & regs[R_CD1]); + tuner_dbg("CAL_DIV_BYTE_2 = 0x%x\n", 0xff & regs[R_CD2]); + tuner_dbg("CAL_DIV_BYTE_3 = 0x%x\n", 0xff & regs[R_CD3]); + tuner_dbg("MAIN_POST_DIV_BYTE = 0x%x\n", 0xff & regs[R_MPD]); + tuner_dbg("MAIN_DIV_BYTE_1 = 0x%x\n", 0xff & regs[R_MD1]); + tuner_dbg("MAIN_DIV_BYTE_2 = 0x%x\n", 0xff & regs[R_MD2]); + tuner_dbg("MAIN_DIV_BYTE_3 = 0x%x\n", 0xff & regs[R_MD3]); +} + +static void tda18271_read_regs(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + unsigned char *regs = priv->tda18271_regs; + unsigned char buf = 0x00; + int ret; + struct i2c_msg msg[] = { + { .addr = priv->i2c_addr, .flags = 0, + .buf = &buf, .len = 1 }, + { .addr = priv->i2c_addr, .flags = I2C_M_RD, + .buf = regs, .len = 16 } + }; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + /* read all registers */ + ret = i2c_transfer(priv->i2c_adap, msg, 2); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (ret != 2) + printk("ERROR: %s: i2c_transfer returned: %d\n", + __FUNCTION__, ret); + + if (debug > 1) + tda18271_dump_regs(fe); +} + +static void tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) +{ + struct tda18271_priv *priv = fe->tuner_priv; + unsigned char *regs = priv->tda18271_regs; + unsigned char buf[TDA18271_NUM_REGS+1]; + struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, + .buf = buf, .len = len+1 }; + int i, ret; + + BUG_ON((len == 0) || (idx+len > sizeof(buf))); + + buf[0] = idx; + for (i = 1; i <= len; i++) { + buf[i] = regs[idx-1+i]; + } + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + /* write registers */ + ret = i2c_transfer(priv->i2c_adap, &msg, 1); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (ret != 1) + printk(KERN_WARNING "ERROR: %s: i2c_transfer returned: %d\n", + __FUNCTION__, ret); +} + +/*---------------------------------------------------------------------*/ + +static void tda18271_init_regs(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + unsigned char *regs = priv->tda18271_regs; + + tda18271_read_regs(fe); + + /* test IR_CAL_OK to see if we need init */ + if ((regs[R_EP1] & 0x08) != 0) + return; + + printk(KERN_INFO "tda18271: initializing registers\n"); + + /* initialize registers */ + regs[R_ID] = 0x83; + regs[R_TM] = 0x08; + regs[R_PL] = 0x80; + regs[R_EP1] = 0xc6; + regs[R_EP2] = 0xdf; + regs[R_EP3] = 0x16; + regs[R_EP4] = 0x60; + regs[R_EP5] = 0x80; + regs[R_CPD] = 0x80; + regs[R_CD1] = 0x00; + regs[R_CD2] = 0x00; + regs[R_CD3] = 0x00; + regs[R_MPD] = 0x00; + regs[R_MD1] = 0x00; + regs[R_MD2] = 0x00; + regs[R_MD3] = 0x00; + regs[R_EB1] = 0xff; + regs[R_EB2] = 0x01; + regs[R_EB3] = 0x84; + regs[R_EB4] = 0x41; + regs[R_EB5] = 0x01; + regs[R_EB6] = 0x84; + regs[R_EB7] = 0x40; + regs[R_EB8] = 0x07; + regs[R_EB9] = 0x00; + regs[R_EB10] = 0x00; + regs[R_EB11] = 0x96; + regs[R_EB12] = 0x0f; + regs[R_EB13] = 0xc1; + regs[R_EB14] = 0x00; + regs[R_EB15] = 0x8f; + regs[R_EB16] = 0x00; + regs[R_EB17] = 0x00; + regs[R_EB18] = 0x00; + regs[R_EB19] = 0x00; + regs[R_EB20] = 0x20; + regs[R_EB21] = 0x33; + regs[R_EB22] = 0x48; + regs[R_EB23] = 0xb0; + + tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); + /* setup AGC1 & AGC2 */ + regs[R_EB17] = 0x00; + tda18271_write_regs(fe, R_EB17, 1); + regs[R_EB17] = 0x03; + tda18271_write_regs(fe, R_EB17, 1); + regs[R_EB17] = 0x43; + tda18271_write_regs(fe, R_EB17, 1); + regs[R_EB17] = 0x4c; + tda18271_write_regs(fe, R_EB17, 1); + + regs[R_EB20] = 0xa0; + tda18271_write_regs(fe, R_EB20, 1); + regs[R_EB20] = 0xa7; + tda18271_write_regs(fe, R_EB20, 1); + regs[R_EB20] = 0xe7; + tda18271_write_regs(fe, R_EB20, 1); + regs[R_EB20] = 0xec; + tda18271_write_regs(fe, R_EB20, 1); + + /* image rejection calibration */ + + /* low-band */ + regs[R_EP3] = 0x1f; + regs[R_EP4] = 0x66; + regs[R_EP5] = 0x81; + regs[R_CPD] = 0xcc; + regs[R_CD1] = 0x6c; + regs[R_CD2] = 0x00; + regs[R_CD3] = 0x00; + regs[R_MPD] = 0xcd; + regs[R_MD1] = 0x77; + regs[R_MD2] = 0x08; + regs[R_MD3] = 0x00; + + tda18271_write_regs(fe, R_EP3, 11); + msleep(5); /* pll locking */ + + regs[R_EP1] = 0xc6; + tda18271_write_regs(fe, R_EP1, 1); + msleep(5); /* wanted low measurement */ + + regs[R_EP3] = 0x1f; + regs[R_EP4] = 0x66; + regs[R_EP5] = 0x85; + regs[R_CPD] = 0xcb; + regs[R_CD1] = 0x66; + regs[R_CD2] = 0x70; + regs[R_CD3] = 0x00; + + tda18271_write_regs(fe, R_EP3, 7); + msleep(5); /* pll locking */ + + regs[R_EP2] = 0xdf; + tda18271_write_regs(fe, R_EP2, 1); + msleep(30); /* image low optimization completion */ + + /* mid-band */ + regs[R_EP3] = 0x1f; + regs[R_EP4] = 0x66; + regs[R_EP5] = 0x82; + regs[R_CPD] = 0xa8; + regs[R_CD1] = 0x66; + regs[R_CD2] = 0x00; + regs[R_CD3] = 0x00; + regs[R_MPD] = 0xa9; + regs[R_MD1] = 0x73; + regs[R_MD2] = 0x1a; + regs[R_MD3] = 0x00; + + tda18271_write_regs(fe, R_EP3, 11); + msleep(5); /* pll locking */ + + regs[R_EP1] = 0xc6; + tda18271_write_regs(fe, R_EP1, 1); + msleep(5); /* wanted mid measurement */ + + regs[R_EP3] = 0x1f; + regs[R_EP4] = 0x66; + regs[R_EP5] = 0x86; + regs[R_CPD] = 0xa8; + regs[R_CD1] = 0x66; + regs[R_CD2] = 0xa0; + regs[R_CD3] = 0x00; + + tda18271_write_regs(fe, R_EP3, 7); + msleep(5); /* pll locking */ + + regs[R_EP2] = 0xdf; + tda18271_write_regs(fe, R_EP2, 1); + msleep(30); /* image mid optimization completion */ + + /* high-band */ + regs[R_EP3] = 0x1f; + regs[R_EP4] = 0x66; + regs[R_EP5] = 0x83; + regs[R_CPD] = 0x98; + regs[R_CD1] = 0x65; + regs[R_CD2] = 0x00; + regs[R_CD3] = 0x00; + regs[R_MPD] = 0x99; + regs[R_MD1] = 0x71; + regs[R_MD2] = 0xcd; + regs[R_MD3] = 0x00; + + tda18271_write_regs(fe, R_EP3, 11); + msleep(5); /* pll locking */ + + regs[R_EP1] = 0xc6; + tda18271_write_regs(fe, R_EP1, 1); + msleep(5); /* wanted high measurement */ + + regs[R_EP3] = 0x1f; + regs[R_EP4] = 0x66; + regs[R_EP5] = 0x87; + regs[R_CPD] = 0x98; + regs[R_CD1] = 0x65; + regs[R_CD2] = 0x50; + regs[R_CD3] = 0x00; + + tda18271_write_regs(fe, R_EP3, 7); + msleep(5); /* pll locking */ + + regs[R_EP2] = 0xdf; + + tda18271_write_regs(fe, R_EP2, 1); + msleep(30); /* image high optimization completion */ + + regs[R_EP4] = 0x64; + tda18271_write_regs(fe, R_EP4, 1); + + regs[R_EP1] = 0xc6; + tda18271_write_regs(fe, R_EP1, 1); +} + +static int tda18271_tune(struct dvb_frontend *fe, + u32 ifc, u32 freq, u32 bw, u8 std) +{ + struct tda18271_priv *priv = fe->tuner_priv; + unsigned char *regs = priv->tda18271_regs; + u32 div, N = 0; + int i; + + + tuner_dbg("%s: freq = %d, ifc = %d\n", __FUNCTION__, freq, ifc); + + tda18271_init_regs(fe); + /* RF tracking filter calibration */ + + /* calculate BP_Filter */ + i = 0; + while ((tda18271_bp_filter[i].rfmax * 1000) < freq) { + if (tda18271_bp_filter[i + 1].rfmax == 0) + break; + i++; + } + tuner_extra_dbg("bp filter = 0x%x, i = %d\n", + tda18271_bp_filter[i].val, i); + + regs[R_EP1] &= ~0x07; /* clear bp filter bits */ + regs[R_EP1] |= tda18271_bp_filter[i].val; + tda18271_write_regs(fe, R_EP1, 1); + + regs[R_EB4] &= 0x07; + regs[R_EB4] |= 0x60; + tda18271_write_regs(fe, R_EB4, 1); + + regs[R_EB7] = 0x60; + tda18271_write_regs(fe, R_EB7, 1); + + regs[R_EB14] = 0x00; + tda18271_write_regs(fe, R_EB14, 1); + + regs[R_EB20] = 0xcc; + tda18271_write_regs(fe, R_EB20, 1); + + /* set CAL mode to RF tracking filter calibration */ + regs[R_EB4] |= 0x03; + + /* calculate CAL PLL */ + + switch (priv->mode) { + case TDA18271_ANALOG: + N = freq - 1250000; + break; + case TDA18271_DIGITAL: + N = freq + bw / 2; + break; + } + + i = 0; + while ((tda18271_cal_pll[i].lomax * 1000) < N) { + if (tda18271_cal_pll[i + 1].lomax == 0) + break; + i++; + } + tuner_extra_dbg("cal pll, pd = 0x%x, d = 0x%x, i = %d\n", + tda18271_cal_pll[i].pd, tda18271_cal_pll[i].d, i); + + regs[R_CPD] = tda18271_cal_pll[i].pd; + + div = ((tda18271_cal_pll[i].d * (N / 1000)) << 7) / 125; + regs[R_CD1] = 0xff & (div >> 16); + regs[R_CD2] = 0xff & (div >> 8); + regs[R_CD3] = 0xff & div; + + /* calculate MAIN PLL */ + + switch (priv->mode) { + case TDA18271_ANALOG: + N = freq - 250000; + break; + case TDA18271_DIGITAL: + N = freq + bw / 2 + 1000000; + break; + } + + i = 0; + while ((tda18271_main_pll[i].lomax * 1000) < N) { + if (tda18271_main_pll[i + 1].lomax == 0) + break; + i++; + } + tuner_extra_dbg("main pll, pd = 0x%x, d = 0x%x, i = %d\n", + tda18271_main_pll[i].pd, tda18271_main_pll[i].d, i); + + regs[R_MPD] = (0x7f & tda18271_main_pll[i].pd); + + switch (priv->mode) { + case TDA18271_ANALOG: + regs[R_MPD] &= ~0x08; + break; + case TDA18271_DIGITAL: + regs[R_MPD] |= 0x08; + break; + } + + div = ((tda18271_main_pll[i].d * (N / 1000)) << 7) / 125; + regs[R_MD1] = 0xff & (div >> 16); + regs[R_MD2] = 0xff & (div >> 8); + regs[R_MD3] = 0xff & div; + + tda18271_write_regs(fe, R_EP3, 11); + msleep(5); /* RF tracking filter calibration initialization */ + + /* search for K,M,CO for RF Calibration */ + i = 0; + while ((tda18271_km[i].rfmax * 1000) < freq) { + if (tda18271_km[i + 1].rfmax == 0) + break; + i++; + } + tuner_extra_dbg("km = 0x%x, i = %d\n", tda18271_km[i].val, i); + + regs[R_EB13] &= 0x83; + regs[R_EB13] |= tda18271_km[i].val; + tda18271_write_regs(fe, R_EB13, 1); + + /* search for RF_BAND */ + i = 0; + while ((tda18271_rf_band[i].rfmax * 1000) < freq) { + if (tda18271_rf_band[i + 1].rfmax == 0) + break; + i++; + } + tuner_extra_dbg("rf band = 0x%x, i = %d\n", + tda18271_rf_band[i].val, i); + + regs[R_EP2] &= ~0xe0; /* clear rf band bits */ + regs[R_EP2] |= (tda18271_rf_band[i].val << 5); + + /* search for Gain_Taper */ + i = 0; + while ((tda18271_gain_taper[i].rfmax * 1000) < freq) { + if (tda18271_gain_taper[i + 1].rfmax == 0) + break; + i++; + } + tuner_extra_dbg("gain taper = 0x%x, i = %d\n", + tda18271_gain_taper[i].val, i); + + regs[R_EP2] &= ~0x1f; /* clear gain taper bits */ + regs[R_EP2] |= tda18271_gain_taper[i].val; + + tda18271_write_regs(fe, R_EP2, 1); + tda18271_write_regs(fe, R_EP1, 1); + tda18271_write_regs(fe, R_EP2, 1); + tda18271_write_regs(fe, R_EP1, 1); + + regs[R_EB4] &= 0x07; + regs[R_EB4] |= 0x40; + tda18271_write_regs(fe, R_EB4, 1); + + regs[R_EB7] = 0x40; + tda18271_write_regs(fe, R_EB7, 1); + msleep(10); + + regs[R_EB20] = 0xec; + tda18271_write_regs(fe, R_EB20, 1); + msleep(60); /* RF tracking filter calibration completion */ + + regs[R_EP4] &= ~0x03; /* set cal mode to normal */ + tda18271_write_regs(fe, R_EP4, 1); + + tda18271_write_regs(fe, R_EP1, 1); + + /* RF tracking filer correction for VHF_Low band */ + i = 0; + while ((tda18271_rf_cal[i].rfmax * 1000) < freq) { + if (tda18271_rf_cal[i].rfmax == 0) + break; + i++; + } + tuner_extra_dbg("rf cal = 0x%x, i = %d\n", tda18271_rf_cal[i].val, i); + + /* VHF_Low band only */ + if (tda18271_rf_cal[i].rfmax != 0) { + regs[R_EB14] = tda18271_rf_cal[i].val; + tda18271_write_regs(fe, R_EB14, 1); + } + + /* Channel Configuration */ + + switch (priv->mode) { + case TDA18271_ANALOG: + regs[R_EB22] = 0x2c; + break; + case TDA18271_DIGITAL: + regs[R_EB22] = 0x37; + break; + } + tda18271_write_regs(fe, R_EB22, 1); + + regs[R_EP1] |= 0x40; /* set dis power level on */ + + /* set standard */ + regs[R_EP3] &= ~0x1f; /* clear std bits */ + + /* see table 22 */ + regs[R_EP3] |= std; + + /* TO DO: * + * ================ * + * FM radio, 0x18 * + * ATSC 6MHz, 0x1c * + * DVB-T 6MHz, 0x1c * + * DVB-T 7MHz, 0x1d * + * DVB-T 8MHz, 0x1e * + * QAM 6MHz, 0x1d * + * QAM 8MHz, 0x1f */ + + regs[R_EP4] &= ~0x03; /* set cal mode to normal */ + + regs[R_EP4] &= ~0x1c; /* clear if level bits */ + switch (priv->mode) { + case TDA18271_ANALOG: + regs[R_MPD] &= ~0x80; /* IF notch = 0 */ + break; + case TDA18271_DIGITAL: + regs[R_EP4] |= 0x04; + regs[R_MPD] |= 0x80; + break; + } + + regs[R_EP4] &= ~0x80; /* turn this bit on only for fm */ + + /* FIXME: image rejection validity EP5[2:0] */ + + /* calculate MAIN PLL */ + N = freq + ifc; + + i = 0; + while ((tda18271_main_pll[i].lomax * 1000) < N) { + if (tda18271_main_pll[i + 1].lomax == 0) + break; + i++; + } + tuner_extra_dbg("main pll, pd = 0x%x, d = 0x%x, i = %d\n", + tda18271_main_pll[i].pd, tda18271_main_pll[i].d, i); + + regs[R_MPD] = (0x7f & tda18271_main_pll[i].pd); + switch (priv->mode) { + case TDA18271_ANALOG: + regs[R_MPD] &= ~0x08; + break; + case TDA18271_DIGITAL: + regs[R_MPD] |= 0x08; + break; + } + + div = ((tda18271_main_pll[i].d * (N / 1000)) << 7) / 125; + regs[R_MD1] = 0xff & (div >> 16); + regs[R_MD2] = 0xff & (div >> 8); + regs[R_MD3] = 0xff & div; + + tda18271_write_regs(fe, R_TM, 15); + msleep(5); + return 0; +} + +/* ------------------------------------------------------------------ */ + +static int tda18271_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct tda18271_priv *priv = fe->tuner_priv; + u8 std; + u32 bw, sgIF = 0; + + u32 freq = params->frequency; + + priv->mode = TDA18271_DIGITAL; + + /* see table 22 */ + if (fe->ops.info.type == FE_ATSC) { + switch (params->u.vsb.modulation) { + case VSB_8: + case VSB_16: + std = 0x1b; /* device-specific (spec says 0x1c) */ + sgIF = 5380000; + break; + case QAM_64: + case QAM_256: + std = 0x18; /* device-specific (spec says 0x1d) */ + sgIF = 4000000; + break; + default: + printk(KERN_WARNING "%s: modulation not set!\n", + __FUNCTION__); + return -EINVAL; + } + freq += 1750000; /* Adjust to center (+1.75MHZ) */ + bw = 6000000; + } else if (fe->ops.info.type == FE_OFDM) { + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + std = 0x1c; + bw = 6000000; + break; + case BANDWIDTH_7_MHZ: + std = 0x1d; + bw = 7000000; + break; + case BANDWIDTH_8_MHZ: + std = 0x1e; + bw = 8000000; + break; + default: + printk(KERN_WARNING "%s: bandwidth not set!\n", + __FUNCTION__); + return -EINVAL; + } + } else { + printk(KERN_WARNING "%s: modulation type not supported!\n", + __FUNCTION__); + return -EINVAL; + } + + return tda18271_tune(fe, sgIF, freq, bw, std); +} + +static int tda18271_set_analog_params(struct dvb_frontend *fe, + struct analog_parameters *params) +{ + struct tda18271_priv *priv = fe->tuner_priv; + u8 std; + unsigned int sgIF; + char *mode; + + priv->mode = TDA18271_ANALOG; + + /* see table 22 */ + if (params->std & V4L2_STD_MN) { + std = 0x0d; + sgIF = 92; + mode = "MN"; + } else if (params->std & V4L2_STD_B) { + std = 0x0e; + sgIF = 108; + mode = "B"; + } else if (params->std & V4L2_STD_GH) { + std = 0x0f; + sgIF = 124; + mode = "GH"; + } else if (params->std & V4L2_STD_PAL_I) { + std = 0x0f; + sgIF = 124; + mode = "I"; + } else if (params->std & V4L2_STD_DK) { + std = 0x0f; + sgIF = 124; + mode = "DK"; + } else if (params->std & V4L2_STD_SECAM_L) { + std = 0x0f; + sgIF = 124; + mode = "L"; + } else if (params->std & V4L2_STD_SECAM_LC) { + std = 0x0f; + sgIF = 20; + mode = "LC"; + } else { + std = 0x0f; + sgIF = 124; + mode = "xx"; + } + + if (params->mode == V4L2_TUNER_RADIO) + sgIF = 88; /* if frequency is 5.5 MHz */ + + tuner_dbg("setting tda18271 to system %s\n", mode); + + return tda18271_tune(fe, sgIF * 62500, params->frequency * 62500, + 0, std); +} + +static int tda18271_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct tda18271_priv *priv = fe->tuner_priv; + *frequency = priv->frequency; + return 0; +} + +static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct tda18271_priv *priv = fe->tuner_priv; + *bandwidth = priv->bandwidth; + return 0; +} + +static struct dvb_tuner_ops tda18271_tuner_ops = { + .info = { + .name = "NXP TDA18271HD", + .frequency_min = 45000000, + .frequency_max = 864000000, + .frequency_step = 62500 + }, + .set_params = tda18271_set_params, + .set_analog_params = tda18271_set_analog_params, + .release = tda18271_release, + .get_frequency = tda18271_get_frequency, + .get_bandwidth = tda18271_get_bandwidth, +}; + +struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, + struct i2c_adapter *i2c) +{ + struct tda18271_priv *priv = NULL; + + tuner_dbg("%s:\n", __FUNCTION__); + priv = kzalloc(sizeof(struct tda18271_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + priv->i2c_addr = addr; + priv->i2c_adap = i2c; + + memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = priv; + + return fe; +} +EXPORT_SYMBOL_GPL(tda18271_attach); +MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver"); +MODULE_AUTHOR("Michael Krufky "); +MODULE_LICENSE("GPL"); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/drivers/media/dvb/frontends/tda18271.h b/drivers/media/dvb/frontends/tda18271.h new file mode 100644 index 000000000000..a8a19a7197f0 --- /dev/null +++ b/drivers/media/dvb/frontends/tda18271.h @@ -0,0 +1,40 @@ +/* + tda18271.h - header for the Philips / NXP TDA18271 silicon tuner + + Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org) + + 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 __TDA18271_H__ +#define __TDA18271_H__ + +#include +#include "dvb_frontend.h" + +#if defined(CONFIG_DVB_TDA18271) || (defined(CONFIG_DVB_TDA18271_MODULE) && defined(MODULE)) +extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, + u8 addr, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + return NULL; +} +#endif + +#endif /* __TDA18271_H__ */ diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 5d30cbcd7361..a38ed9db6403 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c @@ -25,8 +25,9 @@ #include #include "tda8290.h" #include "tda827x.h" +#include "tda18271.h" -static int tuner_debug = 0; +static int tuner_debug; module_param_named(debug, tuner_debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); @@ -65,6 +66,34 @@ static void tda8290_i2c_bridge(struct tuner *t, int close) } } +static void tda8295_i2c_bridge(struct tuner *t, int close) +{ + struct tda8290_priv *priv = t->priv; + + unsigned char enable[2] = { 0x45, 0xc1 }; + unsigned char disable[2] = { 0x46, 0x00 }; + unsigned char buf[3] = { 0x45, 0x01, 0x00 }; + unsigned char *msg; + if (close) { + msg = enable; + tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); + /* let the bridge stabilize */ + msleep(20); + } else { + msg = disable; + tuner_i2c_xfer_send(&priv->i2c_props, msg, 1); + tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1); + + buf[2] = msg[1]; + buf[2] &= ~0x04; + tuner_i2c_xfer_send(&priv->i2c_props, buf, 3); + msleep(5); + + msg[1] |= 0x04; + tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); + } +} + /*---------------------------------------------------------------------*/ static void set_audio(struct tuner *t) @@ -233,6 +262,153 @@ static void tda8290_set_freq(struct tuner *t, unsigned int freq) /*---------------------------------------------------------------------*/ +static void tda8295_power(struct tuner *t, int enable) +{ + struct tda8290_priv *priv = t->priv; + unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */ + + tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); + tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); + + if (enable) + buf[1] = 0x01; + else + buf[1] = 0x03; + + tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); +} + +static void tda8295_set_easy_mode(struct tuner *t, int enable) +{ + struct tda8290_priv *priv = t->priv; + unsigned char buf[] = { 0x01, 0x00 }; + + tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); + tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); + + if (enable) + buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */ + else + buf[1] = 0x00; /* reset active bit */ + + tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); +} + +static void tda8295_set_video_std(struct tuner *t) +{ + struct tda8290_priv *priv = t->priv; + unsigned char buf[] = { 0x00, priv->tda8290_easy_mode }; + + tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); + + tda8295_set_easy_mode(t, 1); + msleep(20); + tda8295_set_easy_mode(t, 0); +} + +/*---------------------------------------------------------------------*/ + +static void tda8295_agc1_out(struct tuner *t, int enable) +{ + struct tda8290_priv *priv = t->priv; + unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */ + + tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); + tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); + + if (enable) + buf[1] &= ~0x40; + else + buf[1] |= 0x40; + + tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); +} + +static void tda8295_agc2_out(struct tuner *t, int enable) +{ + struct tda8290_priv *priv = t->priv; + unsigned char set_gpio_cf[] = { 0x44, 0x00 }; + unsigned char set_gpio_val[] = { 0x46, 0x00 }; + + tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1); + tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1); + tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1); + tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1); + + set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */ + + if (enable) { + set_gpio_cf[1] |= 0x01; /* config GPIO_0 as Open Drain Out */ + set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */ + } + tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2); + tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2); +} + +static int tda8295_has_signal(struct tuner *t) +{ + struct tda8290_priv *priv = t->priv; + + unsigned char hvpll_stat = 0x26; + unsigned char ret; + + tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1); + tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1); + return (ret & 0x01) ? 65535 : 0; +} + +/*---------------------------------------------------------------------*/ + +static void tda8295_set_freq(struct tuner *t, unsigned int freq) +{ + struct tda8290_priv *priv = t->priv; + u16 ifc; + + unsigned char blanking_mode[] = { 0x1d, 0x00 }; + + struct analog_parameters params = { + .frequency = freq, + .mode = t->mode, + .audmode = t->audmode, + .std = t->std + }; + + set_audio(t); + + ifc = priv->cfg.sgIF; /* FIXME */ + + tuner_dbg("%s: ifc = %u, freq = %d\n", __FUNCTION__, ifc, freq); + + tda8295_power(t, 1); + tda8295_agc1_out(t, 1); + + tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1); + tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1); + + tda8295_set_video_std(t); + + blanking_mode[1] = 0x03; + tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2); + msleep(20); + + tda8295_i2c_bridge(t, 1); + + if (t->fe.ops.tuner_ops.set_analog_params) + t->fe.ops.tuner_ops.set_analog_params(&t->fe, ¶ms); + + if (priv->cfg.agcf) + priv->cfg.agcf(&t->fe); + + if (tda8295_has_signal(t)) + tuner_dbg("tda8295 is locked\n"); + else + tuner_dbg("tda8295 not locked, no signal?\n"); + + tda8295_i2c_bridge(t, 0); +} + +/*---------------------------------------------------------------------*/ + static int tda8290_has_signal(struct tuner *t) { struct tda8290_priv *priv = t->priv; @@ -264,6 +440,13 @@ static void tda8290_standby(struct tuner *t) tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2); } +static void tda8295_standby(struct tuner *t) +{ + tda8295_agc1_out(t, 0); /* Put AGC in tri-state */ + + tda8295_power(t, 0); +} + static void tda8290_init_if(struct tuner *t) { struct tda8290_priv *priv = t->priv; @@ -279,6 +462,35 @@ static void tda8290_init_if(struct tuner *t) tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2); } +static void tda8295_init_if(struct tuner *t) +{ + struct tda8290_priv *priv = t->priv; + + static unsigned char set_adc_ctl[] = { 0x33, 0x14 }; + static unsigned char set_adc_ctl2[] = { 0x34, 0x00 }; + static unsigned char set_pll_reg6[] = { 0x3e, 0x63 }; + static unsigned char set_pll_reg0[] = { 0x38, 0x23 }; + static unsigned char set_pll_reg7[] = { 0x3f, 0x01 }; + static unsigned char set_pll_reg10[] = { 0x42, 0x61 }; + static unsigned char set_gpio_reg0[] = { 0x44, 0x0b }; + + tda8295_power(t, 1); + + tda8295_set_easy_mode(t, 0); + tda8295_set_video_std(t); + + tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2); + tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2); + tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2); + tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2); + tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2); + tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2); + tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2); + + tda8295_agc1_out(t, 0); + tda8295_agc2_out(t, 0); +} + static void tda8290_init_tuner(struct tuner *t) { struct tda8290_priv *priv = t->priv; @@ -298,7 +510,7 @@ static void tda8290_init_tuner(struct tuner *t) /*---------------------------------------------------------------------*/ -static void tda8290_release(struct tuner *t) +static void tda829x_release(struct tuner *t) { if (t->fe.ops.tuner_ops.release) t->fe.ops.tuner_ops.release(&t->fe); @@ -312,7 +524,15 @@ static struct tuner_operations tda8290_tuner_ops = { .set_radio_freq = tda8290_set_freq, .has_signal = tda8290_has_signal, .standby = tda8290_standby, - .release = tda8290_release, + .release = tda829x_release, +}; + +static struct tuner_operations tda8295_tuner_ops = { + .set_tv_freq = tda8295_set_freq, + .set_radio_freq = tda8295_set_freq, + .has_signal = tda8295_has_signal, + .standby = tda8295_standby, + .release = tda829x_release, }; int tda8290_attach(struct tuner *t) @@ -403,6 +623,95 @@ int tda8290_attach(struct tuner *t) tda8290_init_if(t); return 0; } +EXPORT_SYMBOL_GPL(tda8290_attach); + +int tda8295_attach(struct tuner *t) +{ + struct tda8290_priv *priv = NULL; + u8 data; + int i, ret, tuners_found; + u32 tuner_addrs; + struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; + + priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); + if (priv == NULL) + return -ENOMEM; + t->priv = priv; + + priv->i2c_props.addr = t->i2c.addr; + priv->i2c_props.adap = t->i2c.adapter; + + tda8295_i2c_bridge(t, 1); + /* probe for tuner chip */ + tuners_found = 0; + tuner_addrs = 0; + for (i = 0x60; i <= 0x63; i++) { + msg.addr = i; + ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); + if (ret == 1) { + tuners_found++; + tuner_addrs = (tuner_addrs << 8) + i; + } + } + /* if there is more than one tuner, we expect the right one is + behind the bridge and we choose the highest address that doesn't + give a response now + */ + tda8295_i2c_bridge(t, 0); + if (tuners_found > 1) + for (i = 0; i < tuners_found; i++) { + msg.addr = tuner_addrs & 0xff; + ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); + if (ret == 1) + tuner_addrs = tuner_addrs >> 8; + else + break; + } + if (tuner_addrs == 0) { + tuner_addrs = 0x60; + tuner_info("could not clearly identify tuner address, " + "defaulting to %x\n", tuner_addrs); + } else { + tuner_addrs = tuner_addrs & 0xff; + tuner_info("setting tuner address to %x\n", tuner_addrs); + } + priv->tda827x_addr = tuner_addrs; + msg.addr = tuner_addrs; + + tda8295_i2c_bridge(t, 1); + ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); + tda8295_i2c_bridge(t, 0); + if (ret != 1) + tuner_warn("TDA827x access failed!\n"); + if ((data & 0x3c) == 0) { + strlcpy(t->i2c.name, "tda8295+18271", sizeof(t->i2c.name)); + tda18271_attach(&t->fe, priv->tda827x_addr, + priv->i2c_props.adap); + priv->tda827x_ver = 4; + } else { + strlcpy(t->i2c.name, "tda8295+75a", sizeof(t->i2c.name)); + tda827x_attach(&t->fe, priv->tda827x_addr, + priv->i2c_props.adap, &priv->cfg); + + /* FIXME: tda827x module doesn't probe the tuner until + * tda827x_initial_sleep is called + */ + if (t->fe.ops.tuner_ops.sleep) + t->fe.ops.tuner_ops.sleep(&t->fe); + priv->tda827x_ver = 2; + } + priv->tda827x_ver |= 1; /* signifies 8295 vs 8290 */ + tuner_info("type set to %s\n", t->i2c.name); + + memcpy(&t->ops, &tda8295_tuner_ops, sizeof(struct tuner_operations)); + + priv->cfg.tda827x_lpsel = 0; + t->mode = V4L2_TUNER_ANALOG_TV; + + tda8295_init_if(t); + return 0; +} +EXPORT_SYMBOL_GPL(tda8295_attach); int tda8290_probe(struct tuner *t) { @@ -434,12 +743,10 @@ int tda8290_probe(struct tuner *t) tuner_i2c_xfer_send(&i2c_props, restore_9886, 3); return -1; } - EXPORT_SYMBOL_GPL(tda8290_probe); -EXPORT_SYMBOL_GPL(tda8290_attach); MODULE_DESCRIPTION("Philips TDA8290 + TDA8275 / TDA8275a tuner driver"); -MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann"); +MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky"); MODULE_LICENSE("GPL"); /* diff --git a/drivers/media/video/tda8290.h b/drivers/media/video/tda8290.h index 9b63e62b3a0f..dbbcb0f001e0 100644 --- a/drivers/media/video/tda8290.h +++ b/drivers/media/video/tda8290.h @@ -24,6 +24,7 @@ extern int tda8290_probe(struct tuner *t); extern int tda8290_attach(struct tuner *t); +extern int tda8295_attach(struct tuner *t); #else static inline int tda8290_probe(struct tuner *t) { @@ -37,6 +38,13 @@ static inline int tda8290_attach(struct tuner *t) __FUNCTION__); return -EINVAL; } + +static inline int tda8295_attach(struct tuner *t) +{ + printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", + __FUNCTION__); + return -EINVAL; +} #endif #endif /* __TDA8290_H__ */ diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 99558c708ae7..6ae8cb205d8e 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -278,6 +278,11 @@ static void set_type(struct i2c_client *c, unsigned int type, tda8290_attach(t); break; } + case TUNER_PHILIPS_TDA8295: + { + tda8295_attach(t); + break; + } case TUNER_TEA5767: if (tea5767_attach(&t->fe, t->i2c.adapter, t->i2c.addr) == NULL) { t->type = TUNER_ABSENT; diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index ac363f019227..4a674c436cf4 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c @@ -1475,6 +1475,9 @@ struct tunertype tuners[] = { .name = "Philips TEA5761 FM Radio", /* see tea5767.c for details */ }, + [TUNER_PHILIPS_TDA8295] = { /* Philips PAL|NTSC */ + .name = "tda8295+18271", + /* see tda8290.c for details */ }, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 4b2c4034f5b3..27bfe6d3a33c 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -257,7 +257,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "LG TAPQ_H702F"}, { TUNER_ABSENT, "TCL M09WPP_4N_E"}, { TUNER_ABSENT, "MaxLinear MXL5005_v2"}, - { TUNER_ABSENT, "Philips 18271_8295"}, + { TUNER_PHILIPS_TDA8295, "Philips 18271_8295"}, }; static struct HAUPPAUGE_AUDIOIC diff --git a/include/media/tuner.h b/include/media/tuner.h index d49392d90e56..faacd2d50b72 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -124,6 +124,8 @@ extern int tuner_debug; #define TUNER_TDA9887 74 /* This tuner should be used only internally */ #define TUNER_TEA5761 75 /* Only FM Radio Tuner */ +#define TUNER_PHILIPS_TDA8295 76 + /* tv card specific */ #define TDA9887_PRESENT (1<<0) #define TDA9887_PORT1_INACTIVE (1<<1) -- cgit v1.2.3 From 8ffbc6559493c64d6194c92d856196fdaeb8a5fb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 12 Sep 2007 08:32:50 -0300 Subject: V4L/DVB (6451): v4l2: add support for bus-based I2C drivers Two new headers were added: one for I2C drivers that are only used by V4L2 drivers converted to the new bus-based I2C API, and one that can be used by both converted and unconverted drivers (at the expense of some additional overhead). To support the legacy I2C API a helper function was added to v4l2-common.c. These headers take care of all the 'boilerplate' code that all V4L2 I2C drivers have in common and will automatically support the bus-based I2C API introduced in kernel 2.6.22. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-common.c | 31 +++++++++ include/media/v4l2-common.h | 11 +++ include/media/v4l2-i2c-drv-legacy.h | 132 ++++++++++++++++++++++++++++++++++++ include/media/v4l2-i2c-drv.h | 61 +++++++++++++++++ 4 files changed, 235 insertions(+) create mode 100644 include/media/v4l2-i2c-drv-legacy.h create mode 100644 include/media/v4l2-i2c-drv.h (limited to 'include') diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index a4d68d3ba5e4..32607a612b18 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -1013,6 +1013,35 @@ int v4l2_chip_match_host(u32 match_type, u32 match_chip) /* ----------------------------------------------------------------- */ +/* Helper function for I2C legacy drivers */ + +int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver, + const char *name, int (*probe)(struct i2c_client *)) +{ + struct i2c_client *client; + int err; + + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == 0) + return -ENOMEM; + + client->addr = address; + client->adapter = adapter; + client->driver = driver; + snprintf(client->name, sizeof(client->name) - 1, name); + + err = probe(client); + if (err == 0) { + i2c_attach_client(client); + } + else { + kfree(client); + } + return err; +} + +/* ----------------------------------------------------------------- */ + EXPORT_SYMBOL(v4l2_norm_to_name); EXPORT_SYMBOL(v4l2_video_std_construct); @@ -1038,6 +1067,8 @@ EXPORT_SYMBOL(v4l2_chip_match_i2c_client); EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); EXPORT_SYMBOL(v4l2_chip_match_host); +EXPORT_SYMBOL(v4l2_i2c_attach); + /* * Local variables: * c-basic-offset: 8 diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index c019c1e99895..475d0d8275e0 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -104,6 +104,17 @@ int v4l2_chip_match_host(u32 id_type, u32 chip_id); /* ------------------------------------------------------------------------- */ +/* Helper function for I2C legacy drivers */ + +struct i2c_driver; +struct i2c_adapter; +struct i2c_client; + +int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver, + const char *name, int (*probe)(struct i2c_client *)); + +/* ------------------------------------------------------------------------- */ + /* Internal ioctls */ /* VIDIOC_INT_DECODE_VBI_LINE */ diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h new file mode 100644 index 000000000000..c059b32844c1 --- /dev/null +++ b/include/media/v4l2-i2c-drv-legacy.h @@ -0,0 +1,132 @@ +/* + * v4l2-i2c-drv-legacy.h - contains I2C handling code that's identical + * for all V4L2 I2C drivers. Use this header if the + * I2C driver is used by both legacy drivers and + * drivers converted to the bus-based I2C API. + * + * Copyright (C) 2007 Hans Verkuil + * + * 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. + */ + +struct v4l2_i2c_driver_data { + const char * const name; + int driverid; + int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); + int (*probe)(struct i2c_client *client); + int (*remove)(struct i2c_client *client); + int (*suspend)(struct i2c_client *client, pm_message_t state); + int (*resume)(struct i2c_client *client); + int legacy_class; +}; + +static struct v4l2_i2c_driver_data v4l2_i2c_data; +static struct i2c_client_address_data addr_data; +static struct i2c_driver v4l2_i2c_driver_legacy; +static char v4l2_i2c_drv_name_legacy[32]; + +static int v4l2_i2c_drv_attach_legacy(struct i2c_adapter *adapter, int address, int kind) +{ + return v4l2_i2c_attach(adapter, address, &v4l2_i2c_driver_legacy, + v4l2_i2c_drv_name_legacy, v4l2_i2c_data.probe); +} + +static int v4l2_i2c_drv_probe_legacy(struct i2c_adapter *adapter) +{ + if (adapter->class & v4l2_i2c_data.legacy_class) + return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); + return 0; +} + +static int v4l2_i2c_drv_detach_legacy(struct i2c_client *client) +{ + int err = i2c_detach_client(client); + + if (err) + return err; + if (v4l2_i2c_data.remove) + v4l2_i2c_data.remove(client); + kfree(client); + + return 0; +} + +static int v4l2_i2c_drv_suspend_helper(struct i2c_client *client, pm_message_t state) +{ + return v4l2_i2c_data.suspend ? v4l2_i2c_data.suspend(client, state) : 0; +} + +static int v4l2_i2c_drv_resume_helper(struct i2c_client *client) +{ + return v4l2_i2c_data.resume ? v4l2_i2c_data.resume(client) : 0; +} + +/* ----------------------------------------------------------------------- */ + +/* i2c implementation */ +static struct i2c_driver v4l2_i2c_driver_legacy = { + .driver = { + .owner = THIS_MODULE, + }, + .attach_adapter = v4l2_i2c_drv_probe_legacy, + .detach_client = v4l2_i2c_drv_detach_legacy, + .suspend = v4l2_i2c_drv_suspend_helper, + .resume = v4l2_i2c_drv_resume_helper, +}; + +/* ----------------------------------------------------------------------- */ + +/* i2c implementation */ +static struct i2c_driver v4l2_i2c_driver = { + .suspend = v4l2_i2c_drv_suspend_helper, + .resume = v4l2_i2c_drv_resume_helper, +}; + +static int __init v4l2_i2c_drv_init(void) +{ + int err; + + strlcpy(v4l2_i2c_drv_name_legacy, v4l2_i2c_data.name, sizeof(v4l2_i2c_drv_name_legacy)); + strlcat(v4l2_i2c_drv_name_legacy, "'", sizeof(v4l2_i2c_drv_name_legacy)); + + if (v4l2_i2c_data.legacy_class == 0) + v4l2_i2c_data.legacy_class = I2C_CLASS_TV_ANALOG; + + v4l2_i2c_driver_legacy.driver.name = v4l2_i2c_drv_name_legacy; + v4l2_i2c_driver_legacy.id = v4l2_i2c_data.driverid; + v4l2_i2c_driver_legacy.command = v4l2_i2c_data.command; + err = i2c_add_driver(&v4l2_i2c_driver_legacy); + + if (err) + return err; + v4l2_i2c_driver.driver.name = v4l2_i2c_data.name; + v4l2_i2c_driver.id = v4l2_i2c_data.driverid; + v4l2_i2c_driver.command = v4l2_i2c_data.command; + v4l2_i2c_driver.probe = v4l2_i2c_data.probe; + v4l2_i2c_driver.remove = v4l2_i2c_data.remove; + err = i2c_add_driver(&v4l2_i2c_driver); + if (err) + i2c_del_driver(&v4l2_i2c_driver_legacy); + return err; +} + +static void __exit v4l2_i2c_drv_cleanup(void) +{ + i2c_del_driver(&v4l2_i2c_driver_legacy); + i2c_del_driver(&v4l2_i2c_driver); +} + +module_init(v4l2_i2c_drv_init); +module_exit(v4l2_i2c_drv_cleanup); diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h new file mode 100644 index 000000000000..547db60d3640 --- /dev/null +++ b/include/media/v4l2-i2c-drv.h @@ -0,0 +1,61 @@ +/* + * v4l2-i2c-drv.h - contains I2C handling code that's identical for + * all V4L2 I2C drivers. Use this header if the + * I2C driver is only used by drivers converted + * to the bus-based I2C API. + * + * Copyright (C) 2007 Hans Verkuil + * + * 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. + */ + +struct v4l2_i2c_driver_data { + const char * const name; + int driverid; + int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); + int (*probe)(struct i2c_client *client); + int (*remove)(struct i2c_client *client); + int (*suspend)(struct i2c_client *client, pm_message_t state); + int (*resume)(struct i2c_client *client); + int legacy_class; +}; + +static struct v4l2_i2c_driver_data v4l2_i2c_data; +static struct i2c_client_address_data addr_data; +static struct i2c_driver v4l2_i2c_driver; + + +/* Bus-based I2C implementation for kernels >= 2.6.22 */ + +static int __init v4l2_i2c_drv_init(void) +{ + v4l2_i2c_driver.driver.name = v4l2_i2c_data.name; + v4l2_i2c_driver.id = v4l2_i2c_data.driverid; + v4l2_i2c_driver.command = v4l2_i2c_data.command; + v4l2_i2c_driver.probe = v4l2_i2c_data.probe; + v4l2_i2c_driver.remove = v4l2_i2c_data.remove; + v4l2_i2c_driver.suspend = v4l2_i2c_data.suspend; + v4l2_i2c_driver.resume = v4l2_i2c_data.resume; + return i2c_add_driver(&v4l2_i2c_driver); +} + + +static void __exit v4l2_i2c_drv_cleanup(void) +{ + i2c_del_driver(&v4l2_i2c_driver); +} + +module_init(v4l2_i2c_drv_init); +module_exit(v4l2_i2c_drv_cleanup); -- cgit v1.2.3 From 88307eb3c69c80a705072e68463d8f72005fc027 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 14 Sep 2007 04:49:16 -0300 Subject: V4L/DVB (6460): v4l2-i2c-drv: add legacy_probe function pointer Some devices do complicated tests whether the device can be probed or not. Add a legacy_probe function pointer to support that. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-i2c-drv-legacy.h | 6 ++++++ include/media/v4l2-i2c-drv.h | 1 + 2 files changed, 7 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h index c059b32844c1..433c984eefa5 100644 --- a/include/media/v4l2-i2c-drv-legacy.h +++ b/include/media/v4l2-i2c-drv-legacy.h @@ -29,6 +29,7 @@ struct v4l2_i2c_driver_data { int (*remove)(struct i2c_client *client); int (*suspend)(struct i2c_client *client, pm_message_t state); int (*resume)(struct i2c_client *client); + int (*legacy_probe)(struct i2c_adapter *adapter); int legacy_class; }; @@ -45,6 +46,11 @@ static int v4l2_i2c_drv_attach_legacy(struct i2c_adapter *adapter, int address, static int v4l2_i2c_drv_probe_legacy(struct i2c_adapter *adapter) { + if (v4l2_i2c_data.legacy_probe) { + if (v4l2_i2c_data.legacy_probe(adapter)) + return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); + return 0; + } if (adapter->class & v4l2_i2c_data.legacy_class) return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); return 0; diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h index 547db60d3640..bc61ab27779d 100644 --- a/include/media/v4l2-i2c-drv.h +++ b/include/media/v4l2-i2c-drv.h @@ -29,6 +29,7 @@ struct v4l2_i2c_driver_data { int (*remove)(struct i2c_client *client); int (*suspend)(struct i2c_client *client, pm_message_t state); int (*resume)(struct i2c_client *client); + int (*legacy_probe)(struct i2c_adapter *adapter); int legacy_class; }; -- cgit v1.2.3 From a2e521e85c04af3511af3ea8971efb4ef8bde533 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 17 Sep 2007 05:13:45 -0300 Subject: V4L/DVB (6466): v4l2-i2c-drv: first call remove, then detach client The remove driver function expects that the client is still attached to the driver, so do the detach after calling remove(). Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-i2c-drv-legacy.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h index 433c984eefa5..241854229d6f 100644 --- a/include/media/v4l2-i2c-drv-legacy.h +++ b/include/media/v4l2-i2c-drv-legacy.h @@ -58,12 +58,14 @@ static int v4l2_i2c_drv_probe_legacy(struct i2c_adapter *adapter) static int v4l2_i2c_drv_detach_legacy(struct i2c_client *client) { - int err = i2c_detach_client(client); + int err; - if (err) - return err; if (v4l2_i2c_data.remove) v4l2_i2c_data.remove(client); + + err = i2c_detach_client(client); + if (err) + return err; kfree(client); return 0; -- cgit v1.2.3 From 0b5f4a12e628893624b478523fb4e2708c605710 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 27 Oct 2007 13:09:16 -0300 Subject: V4L/DVB (6469): tuner: remove TUNER_PHILIPS_TDA8295 TUNER_PHILIPS_TDA8290 will autodetect a TDA8290 or a TDA8295, so we don't need this separate entry anymore. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.tuner | 3 +-- drivers/media/video/tuner-core.c | 1 - drivers/media/video/tuner-types.c | 5 +---- drivers/media/video/tveeprom.c | 2 +- include/media/tuner.h | 2 -- 5 files changed, 3 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index ac47b48715dd..2211c8eac643 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -52,7 +52,7 @@ tuner=50 - TCL 2002N tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3) tuner=52 - Thomson DTT 7610 (ATSC/NTSC) tuner=53 - Philips FQ1286 -tuner=54 - tda8290+75 +tuner=54 - Philips/NXP TDA 8290/8295 + 8275/8275A/18271 tuner=55 - TCL 2002MB tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4) tuner=57 - Philips FQ1236A MK4 @@ -73,4 +73,3 @@ tuner=71 - Xceive xc2028/xc3028 tuner tuner=72 - Thomson FE6600 tuner=73 - Samsung TCPG 6121P30A tuner=75 - Philips TEA5761 FM Radio -tuner=76 - tda8295+18271 diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 6ab57ec3f5a3..600174239d09 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -295,7 +295,6 @@ static void set_type(struct i2c_client *c, unsigned int type, microtune_attach(&t->fe, t->i2c.adapter, t->i2c.addr); break; case TUNER_PHILIPS_TDA8290: - case TUNER_PHILIPS_TDA8295: { tda829x_attach(t); break; diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index 4a674c436cf4..e2cd05a05802 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c @@ -1366,7 +1366,7 @@ struct tunertype tuners[] = { .count = ARRAY_SIZE(tuner_philips_fq1286_params), }, [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */ - .name = "tda8290+75", + .name = "Philips/NXP TDA 8290/8295 + 8275/8275A/18271", /* see tda8290.c for details */ }, [TUNER_TCL_2002MB] = { /* TCL PAL */ .name = "TCL 2002MB", @@ -1475,9 +1475,6 @@ struct tunertype tuners[] = { .name = "Philips TEA5761 FM Radio", /* see tea5767.c for details */ }, - [TUNER_PHILIPS_TDA8295] = { /* Philips PAL|NTSC */ - .name = "tda8295+18271", - /* see tda8290.c for details */ }, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 27bfe6d3a33c..0faa14992353 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -257,7 +257,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "LG TAPQ_H702F"}, { TUNER_ABSENT, "TCL M09WPP_4N_E"}, { TUNER_ABSENT, "MaxLinear MXL5005_v2"}, - { TUNER_PHILIPS_TDA8295, "Philips 18271_8295"}, + { TUNER_PHILIPS_TDA8290, "Philips 18271_8295"}, }; static struct HAUPPAUGE_AUDIOIC diff --git a/include/media/tuner.h b/include/media/tuner.h index faacd2d50b72..d49392d90e56 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -124,8 +124,6 @@ extern int tuner_debug; #define TUNER_TDA9887 74 /* This tuner should be used only internally */ #define TUNER_TEA5761 75 /* Only FM Radio Tuner */ -#define TUNER_PHILIPS_TDA8295 76 - /* tv card specific */ #define TDA9887_PRESENT (1<<0) #define TDA9887_PORT1_INACTIVE (1<<1) -- cgit v1.2.3 From 761dacd25d9e9be2358df21a0f086bbb4cf1c789 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 30 Oct 2007 05:41:25 -0300 Subject: V4L/DVB (6486): m52790: add new Mitsubishi A/V switch i2c driver This driver is used by the ASUS Falcon2 cx23416-based cards. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 9 +++ drivers/media/video/Makefile | 1 + drivers/media/video/m52790.c | 172 ++++++++++++++++++++++++++++++++++++++++ include/media/m52790.h | 93 ++++++++++++++++++++++ include/media/v4l2-chip-ident.h | 3 + 5 files changed, 278 insertions(+) create mode 100644 drivers/media/video/m52790.c create mode 100644 include/media/m52790.h (limited to 'include') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index ea5be3711a7d..320f9e06a933 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -119,6 +119,15 @@ config VIDEO_CS53L32A To compile this driver as a module, choose M here: the module will be called cs53l32a. +config VIDEO_M52790 + tristate "Mitsubishi M52790 A/V switch" + depends on VIDEO_V4L2 && I2C && EXPERIMENTAL + ---help--- + Support for the Mitsubishi M52790 A/V switch. + + To compile this driver as a module, choose M here: the + module will be called m52790. + config VIDEO_TLV320AIC23B tristate "Texas Instruments TLV320AIC23B audio codec" depends on VIDEO_V4L2 && I2C && EXPERIMENTAL diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 8a2781821232..d8910d87acaa 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o +obj-$(CONFIG_VIDEO_M52790) += m52790.o obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o obj-$(CONFIG_VIDEO_WM8775) += wm8775.o obj-$(CONFIG_VIDEO_WM8739) += wm8739.o diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c new file mode 100644 index 000000000000..51ecbfbc1ae7 --- /dev/null +++ b/drivers/media/video/m52790.c @@ -0,0 +1,172 @@ +/* + * m52790 i2c ivtv driver. + * Copyright (C) 2007 Hans Verkuil + * + * A/V source switching Mitsubishi M52790SP/FP + * + * 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 +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch"); +MODULE_AUTHOR("Hans Verkuil"); +MODULE_LICENSE("GPL"); + +static unsigned short normal_i2c[] = { 0x90 >> 1, I2C_CLIENT_END }; + + +I2C_CLIENT_INSMOD; + +struct m52790_state { + u16 input; + u16 output; +}; + +/* ----------------------------------------------------------------------- */ + +static int m52790_write(struct i2c_client *client) +{ + struct m52790_state *state = i2c_get_clientdata(client); + u8 sw1 = (state->input | state->output) & 0xff; + u8 sw2 = (state->input | state->output) >> 8; + + return i2c_smbus_write_byte_data(client, sw1, sw2); +} + +static int m52790_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + struct m52790_state *state = i2c_get_clientdata(client); + struct v4l2_routing *route = arg; + + /* Note: audio and video are linked and cannot be switched separately. + So audio and video routing commands are identical for this chip. + In theory the video amplifier and audio modes could be handled + separately for the output, but that seems to be overkill right now. + The same holds for implementing an audio mute control, this is now + part of the audio output routing. The normal case is that another + chip takes care of the actual muting so making it part of the + output routing seems to be the right thing to do for now. */ + switch (cmd) { + case VIDIOC_INT_G_AUDIO_ROUTING: + case VIDIOC_INT_G_VIDEO_ROUTING: + route->input = state->input; + route->output = state->output; + break; + + case VIDIOC_INT_S_AUDIO_ROUTING: + case VIDIOC_INT_S_VIDEO_ROUTING: + state->input = route->input; + state->output = route->output; + m52790_write(client); + break; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + case VIDIOC_DBG_G_REGISTER: + case VIDIOC_DBG_S_REGISTER: + { + struct v4l2_register *reg = arg; + + if (!v4l2_chip_match_i2c_client(client, + reg->match_type, reg->match_chip)) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (reg->reg != 0) + return -EINVAL; + if (cmd == VIDIOC_DBG_G_REGISTER) + reg->val = state->input | state->output; + else { + state->input = reg->val & 0x0303; + state->output = reg->val & ~0x0303; + m52790_write(client); + } + break; + } +#endif + + case VIDIOC_G_CHIP_IDENT: + return v4l2_chip_ident_i2c_client(client, arg, + V4L2_IDENT_M52790, 0); + + case VIDIOC_LOG_STATUS: + v4l_info(client, "Switch 1: %02x\n", + (state->input | state->output) & 0xff); + v4l_info(client, "Switch 2: %02x\n", + (state->input | state->output) >> 8); + break; + + default: + return -EINVAL; + } + return 0; +} + +/* ----------------------------------------------------------------------- */ + +/* i2c implementation */ + +static int m52790_probe(struct i2c_client *client) +{ + struct m52790_state *state; + + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; + + snprintf(client->name, sizeof(client->name) - 1, "m52790"); + + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + + state = kmalloc(sizeof(struct m52790_state), GFP_KERNEL); + if (state == NULL) + return -ENOMEM; + + state->input = M52790_IN_TUNER; + state->output = M52790_OUT_STEREO; + i2c_set_clientdata(client, state); + m52790_write(client); + return 0; +} + +static int m52790_remove(struct i2c_client *client) +{ + kfree(i2c_get_clientdata(client)); + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "m52790", + .driverid = I2C_DRIVERID_M52790, + .command = m52790_command, + .probe = m52790_probe, + .remove = m52790_remove, +}; + diff --git a/include/media/m52790.h b/include/media/m52790.h new file mode 100644 index 000000000000..7ddffae31a67 --- /dev/null +++ b/include/media/m52790.h @@ -0,0 +1,93 @@ +/* + m52790.h - definition for m52790 inputs and outputs + + Copyright (C) 2007 Hans Verkuil (hverkuil@xs4all.nl) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License 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 _M52790_H_ +#define _M52790_H_ + +/* Input routing switch 1 */ + +#define M52790_SW1_IN_MASK 0x0003 +#define M52790_SW1_IN_TUNER 0x0000 +#define M52790_SW1_IN_V2 0x0001 +#define M52790_SW1_IN_V3 0x0002 +#define M52790_SW1_IN_V4 0x0003 + +/* Selects component input instead of composite */ +#define M52790_SW1_YCMIX 0x0004 + + +/* Input routing switch 2 */ + +#define M52790_SW2_IN_MASK 0x0300 +#define M52790_SW2_IN_TUNER 0x0000 +#define M52790_SW2_IN_V2 0x0100 +#define M52790_SW2_IN_V3 0x0200 +#define M52790_SW2_IN_V4 0x0300 + +/* Selects component input instead of composite */ +#define M52790_SW2_YCMIX 0x0400 + + +/* Output routing switch 1 */ + +/* Enable 6dB amplifier for composite out */ +#define M52790_SW1_V_AMP 0x0008 + +/* Enable 6dB amplifier for component out */ +#define M52790_SW1_YC_AMP 0x0010 + +/* Audio output mode */ +#define M52790_SW1_AUDIO_MASK 0x00c0 +#define M52790_SW1_AUDIO_MUTE 0x0000 +#define M52790_SW1_AUDIO_R 0x0040 +#define M52790_SW1_AUDIO_L 0x0080 +#define M52790_SW1_AUDIO_STEREO 0x00c0 + + +/* Output routing switch 2 */ + +/* Enable 6dB amplifier for composite out */ +#define M52790_SW2_V_AMP 0x0800 + +/* Enable 6dB amplifier for component out */ +#define M52790_SW2_YC_AMP 0x1000 + +/* Audio output mode */ +#define M52790_SW2_AUDIO_MASK 0xc000 +#define M52790_SW2_AUDIO_MUTE 0x0000 +#define M52790_SW2_AUDIO_R 0x4000 +#define M52790_SW2_AUDIO_L 0x8000 +#define M52790_SW2_AUDIO_STEREO 0xc000 + + +/* Common values */ +#define M52790_IN_TUNER (M52790_SW1_IN_TUNER | M52790_SW2_IN_TUNER) +#define M52790_IN_V2 (M52790_SW1_IN_V2 | M52790_SW2_IN_V2) +#define M52790_IN_V3 (M52790_SW1_IN_V3 | M52790_SW2_IN_V3) +#define M52790_IN_V4 (M52790_SW1_IN_V4 | M52790_SW2_IN_V4) + +#define M52790_OUT_STEREO (M52790_SW1_AUDIO_STEREO | \ + M52790_SW2_AUDIO_STEREO) +#define M52790_OUT_AMP_STEREO (M52790_SW1_AUDIO_STEREO | \ + M52790_SW1_V_AMP | \ + M52790_SW2_AUDIO_STEREO | \ + M52790_SW2_V_AMP) + +#endif diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 8ae42c41dd08..2442c281e4fe 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -83,6 +83,9 @@ enum { /* module upd64083: just ident 64083 */ V4L2_IDENT_UPD64083 = 64083, + /* module m52790: just ident 52790 */ + V4L2_IDENT_M52790 = 52790, + /* module msp34xx: reserved range 34000-34999 */ V4L2_IDENT_MSP3400B = 34002, V4L2_IDENT_MSP3410B = 34102, -- cgit v1.2.3 From 05e997197e459a03df577ba49c34c1820957ee4a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 30 Oct 2007 05:41:54 -0300 Subject: V4L/DVB (6487): i2c-id: add M52790 driver ID Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/i2c-id.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index e18017d45758..adbdc6da39ca 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -125,6 +125,7 @@ #define I2C_DRIVERID_LM4857 92 /* LM4857 Audio Amplifier */ #define I2C_DRIVERID_VP27SMPX 93 /* Panasonic VP27s tuner internal MPX */ #define I2C_DRIVERID_CS4270 94 /* Cirrus Logic 4270 audio codec */ +#define I2C_DRIVERID_M52790 95 /* Mitsubishi M52790SP/FP AV switch */ #define I2C_DRIVERID_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ -- cgit v1.2.3 From c5d857d5d3a7cfe355d93916fc094035c85147f7 Mon Sep 17 00:00:00 2001 From: Marco Schluessler Date: Wed, 31 Oct 2007 00:44:22 -0300 Subject: V4L/DVB (6496): saa7146_vv.h: remove wrong include remove wrong include Signed-off-by: Marco Schluessler Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- include/media/saa7146_vv.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h index e49f7e156061..89c442eb8849 100644 --- a/include/media/saa7146_vv.h +++ b/include/media/saa7146_vv.h @@ -1,7 +1,6 @@ #ifndef __SAA7146_VV__ #define __SAA7146_VV__ -#include #include #include #include -- cgit v1.2.3 From 9695a49839353bdaff79fe27399be2eb72585223 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 5 Nov 2007 14:07:18 -0300 Subject: V4L/DVB (6574): common/ir-functions.c: make a function static ir_rc5_decode() can become static. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 3 +-- include/media/ir-common.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index e7c3ab951a44..bb2a027b9483 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -258,7 +258,7 @@ int ir_decode_biphase(u32 *samples, int count, int low, int high) * saa7134 */ /* decode raw bit pattern to RC5 code */ -u32 ir_rc5_decode(unsigned int code) +static u32 ir_rc5_decode(unsigned int code) { unsigned int org_code = code; unsigned int pair; @@ -371,7 +371,6 @@ EXPORT_SYMBOL_GPL(ir_dump_samples); EXPORT_SYMBOL_GPL(ir_decode_biphase); EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); -EXPORT_SYMBOL_GPL(ir_rc5_decode); EXPORT_SYMBOL_GPL(ir_rc5_timer_end); EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 7a785fa77212..b904d3257260 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -97,7 +97,6 @@ int ir_dump_samples(u32 *samples, int count); int ir_decode_biphase(u32 *samples, int count, int low, int high); int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); -u32 ir_rc5_decode(unsigned int code); void ir_rc5_timer_end(unsigned long data); void ir_rc5_timer_keyup(unsigned long data); -- cgit v1.2.3 From 2c94a674e059e89252d58da655efa4e798be4d48 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 30 Oct 2007 05:52:52 -0300 Subject: V4L/DVB (6580): Set slave's master before master's attach call. V4L: Int if: Set slave's master before attach, remove master argument The master also now gets its own pointer from slave's structure. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-int-device.c | 6 +++--- include/media/v4l2-int-device.h | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/video/v4l2-int-device.c index 8b4ef530a3a8..a545dcaf857f 100644 --- a/drivers/media/video/v4l2-int-device.c +++ b/drivers/media/video/v4l2-int-device.c @@ -57,12 +57,12 @@ static void v4l2_int_device_try_attach_all(void) if (!try_module_get(m->module)) continue; - if (m->u.master->attach(m, s)) { + s->u.slave->master = m; + if (m->u.master->attach(s)) { + s->u.slave->master = NULL; module_put(m->module); continue; } - - s->u.slave->master = m; } } } diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h index 066ebfc4f983..c8b80e0f0651 100644 --- a/include/media/v4l2-int-device.h +++ b/include/media/v4l2-int-device.h @@ -44,9 +44,8 @@ enum v4l2_int_type { struct v4l2_int_device; struct v4l2_int_master { - int (*attach)(struct v4l2_int_device *master, - struct v4l2_int_device *slave); - void (*detach)(struct v4l2_int_device *master); + int (*attach)(struct v4l2_int_device *slave); + void (*detach)(struct v4l2_int_device *slave); }; typedef int (v4l2_int_ioctl_func)(struct v4l2_int_device *); -- cgit v1.2.3 From 0fc0686e64d21a6abded96af2b1a895dfa8b2530 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 6 Nov 2007 20:02:36 -0300 Subject: V4L/DVB (6600): V4L: videobuf: don't chew up namespace STATE_.*, convert to VIDEOBUF_ s/STATE_NEEDS_INIT/VIDEOBUF_NEEDS_INIT/g s/STATE_PREPARED/VIDEOBUF_PREPARED/g s/STATE_QUEUED/VIDEOBUF_QUEUED/g s/STATE_ACTIVE/VIDEOBUF_ACTIVE/g s/STATE_DONE/VIDEOBUF_DONE/g s/STATE_ERROR/VIDEOBUF_ERROR/g s/STATE_IDLE/VIDEOBUF_IDLE/g Signed-off-by: Brandon Philips Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_fops.c | 8 ++--- drivers/media/common/saa7146_vbi.c | 10 +++--- drivers/media/common/saa7146_video.c | 8 ++--- drivers/media/video/bt8xx/bttv-driver.c | 26 +++++++-------- drivers/media/video/bt8xx/bttv-risc.c | 14 ++++---- drivers/media/video/bt8xx/bttv-vbi.c | 6 ++-- drivers/media/video/cx23885/cx23885-core.c | 18 +++++------ drivers/media/video/cx88/cx88-alsa.c | 2 +- drivers/media/video/cx88/cx88-core.c | 4 +-- drivers/media/video/cx88/cx88-mpeg.c | 14 ++++---- drivers/media/video/cx88/cx88-vbi.c | 10 +++--- drivers/media/video/cx88/cx88-video.c | 22 ++++++------- drivers/media/video/saa7134/saa7134-core.c | 8 ++--- drivers/media/video/saa7134/saa7134-ts.c | 8 ++--- drivers/media/video/saa7134/saa7134-vbi.c | 8 ++--- drivers/media/video/saa7134/saa7134-video.c | 12 +++---- drivers/media/video/videobuf-core.c | 50 ++++++++++++++--------------- drivers/media/video/videobuf-dvb.c | 2 +- drivers/media/video/vivi.c | 24 +++++++------- include/media/videobuf-core.h | 14 ++++---- 20 files changed, 134 insertions(+), 134 deletions(-) (limited to 'include') diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 67d1b1b1b254..b40bf2306fbc 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -61,7 +61,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q, videobuf_waiton(&buf->vb,0,0); videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } @@ -83,7 +83,7 @@ int saa7146_buffer_queue(struct saa7146_dev *dev, buf->activate(dev,buf,NULL); } else { list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; DEB_D(("adding buffer %p to queue. (active buffer present)\n", buf)); } return 0; @@ -174,7 +174,7 @@ void saa7146_buffer_timeout(unsigned long data) spin_lock_irqsave(&dev->slock,flags); if (q->curr) { DEB_D(("timeout on %p\n", q->curr)); - saa7146_buffer_finish(dev,q,STATE_ERROR); + saa7146_buffer_finish(dev,q,VIDEOBUF_ERROR); } /* we don't restart the transfer here like other drivers do. when @@ -366,7 +366,7 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) } poll_wait(file, &buf->done, wait); - if (buf->state == STATE_DONE || buf->state == STATE_ERROR) { + if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { DEB_D(("poll succeeded!\n")); return POLLIN|POLLRDNORM; } diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c index 6103484e4442..c32dda973e92 100644 --- a/drivers/media/common/saa7146_vbi.c +++ b/drivers/media/common/saa7146_vbi.c @@ -205,7 +205,7 @@ static int buffer_activate(struct saa7146_dev *dev, struct saa7146_buf *next) { struct saa7146_vv *vv = dev->vv_data; - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next)); saa7146_set_vbi_capture(dev,buf,next); @@ -238,7 +238,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e if (buf->vb.size != size) saa7146_dma_free(dev,q,buf); - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; @@ -257,7 +257,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e if (0 != err) return err; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; return 0; @@ -335,7 +335,7 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file) saa7146_write(dev, MC1, MASK_20); if (vv->vbi_q.curr) { - saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE); + saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE); } videobuf_queue_cancel(&fh->vbi_q); @@ -458,7 +458,7 @@ static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status) /* this must be += 2, one count for each field */ vv->vbi_fieldcount+=2; vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount; - saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE); + saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE); } else { DEB_VBI(("dev:%p\n",dev)); } diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index ae36d101006b..c31ab480d8e1 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -1235,7 +1235,7 @@ static int buffer_activate (struct saa7146_dev *dev, { struct saa7146_vv *vv = dev->vv_data; - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; saa7146_set_capture(dev,buf,next); mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT); @@ -1281,7 +1281,7 @@ static int buffer_prepare(struct videobuf_queue *q, saa7146_dma_free(dev,q,buf); } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct saa7146_format *sfmt; buf->vb.bytesperline = fh->video_fmt.bytesperline; @@ -1314,7 +1314,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (err) goto oops; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; return 0; @@ -1453,7 +1453,7 @@ static void video_irq_done(struct saa7146_dev *dev, unsigned long st) /* only finish the buffer if we have one... */ if( NULL != q->curr ) { - saa7146_buffer_finish(dev,q,STATE_DONE); + saa7146_buffer_finish(dev,q,VIDEOBUF_DONE); } saa7146_buffer_next(dev,q,0); diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index db0e4b78e7dd..eb2c12eb2fc8 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -1638,7 +1638,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, dprintk("switch_overlay: enter [new=%p]\n",new); if (new) - new->vb.state = STATE_DONE; + new->vb.state = VIDEOBUF_DONE; spin_lock_irqsave(&btv->s_lock,flags); old = btv->screen; btv->screen = new; @@ -1749,7 +1749,7 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, } /* alloc risc memory */ - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { redo_dma_risc = 1; if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf))) goto fail; @@ -1759,7 +1759,7 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, if (0 != (rc = bttv_buffer_risc(btv,buf))) goto fail; - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -1798,7 +1798,7 @@ buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) struct bttv_fh *fh = q->priv_data; struct bttv *btv = fh->btv; - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; list_add_tail(&buf->vb.queue,&btv->capture); if (!btv->curr.frame_irq) { btv->loop_irq |= 1; @@ -3102,8 +3102,8 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) } poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == STATE_DONE || - buf->vb.state == STATE_ERROR) + if (buf->vb.state == VIDEOBUF_DONE || + buf->vb.state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; } @@ -3699,20 +3699,20 @@ static void bttv_irq_timeout(unsigned long data) bttv_set_dma(btv, 0); /* wake up */ - bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR); - bttv_irq_wakeup_vbi(btv, ovbi, STATE_ERROR); + bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_ERROR); + bttv_irq_wakeup_vbi(btv, ovbi, VIDEOBUF_ERROR); /* cancel all outstanding capture / vbi requests */ while (!list_empty(&btv->capture)) { item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue); list_del(&item->vb.queue); - item->vb.state = STATE_ERROR; + item->vb.state = VIDEOBUF_ERROR; wake_up(&item->vb.done); } while (!list_empty(&btv->vcapture)) { item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue); list_del(&item->vb.queue); - item->vb.state = STATE_ERROR; + item->vb.state = VIDEOBUF_ERROR; wake_up(&item->vb.done); } @@ -3735,7 +3735,7 @@ bttv_irq_wakeup_top(struct bttv *btv) do_gettimeofday(&wakeup->vb.ts); wakeup->vb.field_count = btv->field_count; - wakeup->vb.state = STATE_DONE; + wakeup->vb.state = VIDEOBUF_DONE; wake_up(&wakeup->vb.done); spin_unlock(&btv->s_lock); } @@ -3784,7 +3784,7 @@ bttv_irq_switch_video(struct bttv *btv) } /* wake up finished buffers */ - bttv_irq_wakeup_video(btv, &old, &new, STATE_DONE); + bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_DONE); spin_unlock(&btv->s_lock); } @@ -3817,7 +3817,7 @@ bttv_irq_switch_vbi(struct bttv *btv) bttv_buffer_activate_vbi(btv, new); bttv_set_dma(btv, 0); - bttv_irq_wakeup_vbi(btv, old, STATE_DONE); + bttv_irq_wakeup_vbi(btv, old, VIDEOBUF_DONE); spin_unlock(&btv->s_lock); } diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c index 58986f1a5f1a..e5979f77504c 100644 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ b/drivers/media/video/bt8xx/bttv-risc.c @@ -582,7 +582,7 @@ bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf videobuf_dma_free(dma); btcx_riscmem_free(btv->c.pci,&buf->bottom); btcx_riscmem_free(btv->c.pci,&buf->top); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } int @@ -602,7 +602,7 @@ bttv_buffer_activate_vbi(struct bttv *btv, if (vbi) { unsigned int crop, vdelay; - vbi->vb.state = STATE_ACTIVE; + vbi->vb.state = VIDEOBUF_ACTIVE; list_del(&vbi->vb.queue); /* VDELAY is start of video, end of VBI capturing. */ @@ -644,12 +644,12 @@ bttv_buffer_activate_video(struct bttv *btv, /* video capture */ if (NULL != set->top && NULL != set->bottom) { if (set->top == set->bottom) { - set->top->vb.state = STATE_ACTIVE; + set->top->vb.state = VIDEOBUF_ACTIVE; if (set->top->vb.queue.next) list_del(&set->top->vb.queue); } else { - set->top->vb.state = STATE_ACTIVE; - set->bottom->vb.state = STATE_ACTIVE; + set->top->vb.state = VIDEOBUF_ACTIVE; + set->bottom->vb.state = VIDEOBUF_ACTIVE; if (set->top->vb.queue.next) list_del(&set->top->vb.queue); if (set->bottom->vb.queue.next) @@ -666,7 +666,7 @@ bttv_buffer_activate_video(struct bttv *btv, btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05), ~0x0f, BT848_COLOR_CTL); } else if (NULL != set->top) { - set->top->vb.state = STATE_ACTIVE; + set->top->vb.state = VIDEOBUF_ACTIVE; if (set->top->vb.queue.next) list_del(&set->top->vb.queue); bttv_apply_geo(btv, &set->top->geo,1); @@ -677,7 +677,7 @@ bttv_buffer_activate_video(struct bttv *btv, btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT); btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); } else if (NULL != set->bottom) { - set->bottom->vb.state = STATE_ACTIVE; + set->bottom->vb.state = VIDEOBUF_ACTIVE; if (set->bottom->vb.queue.next) list_del(&set->bottom->vb.queue); bttv_apply_geo(btv, &set->bottom->geo,1); diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index 346ce019bdcb..b924f05e3b74 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c @@ -142,7 +142,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q, redo_dma_risc = 1; } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { redo_dma_risc = 1; if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) goto fail; @@ -189,7 +189,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q, /* For bttv_buffer_activate_vbi(). */ buf->geo.vdelay = min_vdelay; - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->vb.field = field; dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", vb, &buf->top, &buf->bottom, @@ -209,7 +209,7 @@ vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); dprintk("queue %p\n",vb); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; list_add_tail(&buf->vb.queue,&btv->vcapture); if (NULL == btv->cvbi) { fh->btv->loop_irq |= 4; diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 0c9c9af0efb7..f205ad6354e7 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -378,7 +378,7 @@ static void cx23885_wakeup(struct cx23885_tsport *port, do_gettimeofday(&buf->vb.ts); dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, count, buf->count); - buf->vb.state = STATE_DONE; + buf->vb.state = VIDEOBUF_DONE; list_del(&buf->vb.queue); wake_up(&buf->vb.done); } @@ -972,7 +972,7 @@ void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } static int cx23885_start_dma(struct cx23885_tsport *port, @@ -1075,7 +1075,7 @@ static int cx23885_restart_queue(struct cx23885_tsport *port, list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue, &q->active); cx23885_start_dma(port, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(5, "[%p/%d] restart_queue - first active\n", @@ -1086,7 +1086,7 @@ static int cx23885_restart_queue(struct cx23885_tsport *port, prev->fmt == buf->fmt) { list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ @@ -1123,7 +1123,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { buf->vb.width = port->ts_packet_size; buf->vb.height = port->ts_packet_count; buf->vb.size = size; @@ -1135,7 +1135,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, videobuf_to_dma(&buf->vb)->sglist, buf->vb.width, buf->vb.height); } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -1158,7 +1158,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) dprintk( 1, "queue is empty - first active\n" ); list_add_tail(&buf->vb.queue, &cx88q->active); cx23885_start_dma(port, cx88q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = cx88q->count++; mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); dprintk(1, "[%p/%d] %s - first active\n", @@ -1168,7 +1168,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) prev = list_entry(cx88q->active.prev, struct cx23885_buffer, vb.queue); list_add_tail(&buf->vb.queue, &cx88q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = cx88q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ @@ -1192,7 +1192,7 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); dprintk(1, "[%p/%d] %s - dma=0x%08lx\n", buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 40ffd7a5579a..8735227f7e47 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c @@ -417,7 +417,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; chip->buf = buf; chip->dma_risc = dma; diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 62e8dd24c5f5..01e2ac98970b 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -220,7 +220,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } /* ------------------------------------------------------------------ */ @@ -538,7 +538,7 @@ void cx88_wakeup(struct cx88_core *core, do_gettimeofday(&buf->vb.ts); dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i, count, buf->count); - buf->vb.state = STATE_DONE; + buf->vb.state = VIDEOBUF_DONE; list_del(&buf->vb.queue); wake_up(&buf->vb.done); } diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 60ac4234d84c..339a88a64f54 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -195,7 +195,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue,&q->active); cx8802_start_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(1,"[%p/%d] restart_queue - first active\n", @@ -206,7 +206,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, prev->fmt == buf->fmt) { list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(1,"[%p/%d] restart_queue - move to active\n", @@ -242,7 +242,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { buf->vb.width = dev->ts_packet_size; buf->vb.height = dev->ts_packet_count; buf->vb.size = size; @@ -254,7 +254,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, dma->sglist, buf->vb.width, buf->vb.height, 0); } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -276,7 +276,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) dprintk( 1, "queue is empty - first active\n" ); list_add_tail(&buf->vb.queue,&cx88q->active); cx8802_start_dma(dev, cx88q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = cx88q->count++; mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(1,"[%p/%d] %s - first active\n", @@ -286,7 +286,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) dprintk( 1, "queue is not empty - append to active\n" ); prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue); list_add_tail(&buf->vb.queue,&cx88q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = cx88q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk( 1, "[%p/%d] %s - append to active\n", @@ -306,7 +306,7 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart) while (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); dprintk(1,"[%p/%d] %s - dma=0x%08lx\n", buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index babb08556406..d96ecfcf393a 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c @@ -130,7 +130,7 @@ void cx8800_vbi_timeout(unsigned long data) while (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->core->name, buf, buf->vb.i, (unsigned long)buf->risc.dma); @@ -168,7 +168,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = VBI_LINE_LENGTH; buf->vb.height = VBI_LINE_COUNT; @@ -183,7 +183,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, buf->vb.width, 0, buf->vb.height); } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -207,7 +207,7 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) if (list_empty(&q->active)) { list_add_tail(&buf->vb.queue,&q->active); cx8800_start_vbi_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] vbi_queue - first active\n", @@ -216,7 +216,7 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) } else { prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] buffer_queue - append to active\n", diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index c84dafbdb991..6d5ea8ce9830 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -486,7 +486,7 @@ static int restart_video_queue(struct cx8800_dev *dev, if (NULL == prev) { list_move_tail(&buf->vb.queue, &q->active); start_video_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] restart_queue - first active\n", @@ -496,7 +496,7 @@ static int restart_video_queue(struct cx8800_dev *dev, prev->vb.height == buf->vb.height && prev->fmt == buf->fmt) { list_move_tail(&buf->vb.queue, &q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] restart_queue - move to active\n", @@ -553,7 +553,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, init_buffer = 1; } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { init_buffer = 1; if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) goto fail; @@ -601,7 +601,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, fh->width, fh->height, fh->fmt->depth, fh->fmt->name, (unsigned long)buf->risc.dma); - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: @@ -625,14 +625,14 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) if (!list_empty(&q->queued)) { list_add_tail(&buf->vb.queue,&q->queued); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; dprintk(2,"[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i); } else if (list_empty(&q->active)) { list_add_tail(&buf->vb.queue,&q->active); start_video_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] buffer_queue - first active\n", @@ -644,7 +644,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) prev->vb.height == buf->vb.height && prev->fmt == buf->fmt) { list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] buffer_queue - append to active\n", @@ -652,7 +652,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) } else { list_add_tail(&buf->vb.queue,&q->queued); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; dprintk(2,"[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i); } @@ -822,8 +822,8 @@ video_poll(struct file *file, struct poll_table_struct *wait) return POLLERR; } poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == STATE_DONE || - buf->vb.state == STATE_ERROR) + if (buf->vb.state == VIDEOBUF_DONE || + buf->vb.state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; } @@ -1496,7 +1496,7 @@ static void cx8800_vid_timeout(unsigned long data) while (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", core->name, buf, buf->vb.i, (unsigned long)buf->risc.dma); diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index fc71843b9dc2..76410f5bdcdd 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -294,7 +294,7 @@ void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf) videobuf_waiton(&buf->vb,0,0); videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } /* ------------------------------------------------------------------ */ @@ -313,7 +313,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, buf->activate(dev,buf,NULL); } else if (list_empty(&q->queue)) { list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; } else { next = list_entry(q->queue.next,struct saa7134_buf, vb.queue); @@ -322,7 +322,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, } } else { list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; } return 0; } @@ -387,7 +387,7 @@ void saa7134_buffer_timeout(unsigned long data) try to start over with the next one. */ if (q->curr) { dprintk("timeout on %p\n",q->curr); - saa7134_buffer_finish(dev,q,STATE_ERROR); + saa7134_buffer_finish(dev,q,VIDEOBUF_ERROR); } saa7134_buffer_next(dev,q); spin_unlock_irqrestore(&dev->slock,flags); diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index 4b63ad3e8466..f1b8fcaeb43a 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c @@ -47,7 +47,7 @@ static int buffer_activate(struct saa7134_dev *dev, { dprintk("buffer_activate [%p]",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; if (NULL == next) @@ -91,7 +91,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, saa7134_dma_free(q,buf); } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; @@ -121,7 +121,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE); saa_writel(SAA7134_RS_CONTROL(5),control); - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; buf->vb.field = field; return 0; @@ -242,7 +242,7 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) if ((status & 0x100000) != 0x100000) goto done; } - saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->ts_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->ts_q); diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c index 81a2aedeff5c..f0d5ed9c2b06 100644 --- a/drivers/media/video/saa7134/saa7134-vbi.c +++ b/drivers/media/video/saa7134/saa7134-vbi.c @@ -85,7 +85,7 @@ static int buffer_activate(struct saa7134_dev *dev, unsigned long control,base; dprintk("buffer_activate [%p]\n",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; task_init(dev,buf,TASK_A); @@ -136,7 +136,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (buf->vb.size != size) saa7134_dma_free(q,buf); - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; @@ -154,7 +154,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (err) goto oops; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; buf->vb.field = field; return 0; @@ -240,7 +240,7 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status) goto done; dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount; - saa7134_buffer_finish(dev,&dev->vbi_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->vbi_q); diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 86fe452842b3..9c160b2bca3d 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -945,7 +945,7 @@ static int buffer_activate(struct saa7134_dev *dev, unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */ dprintk("buffer_activate buf=%p\n",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; set_size(dev,TASK_A,buf->vb.width,buf->vb.height, @@ -1054,7 +1054,7 @@ static int buffer_prepare(struct videobuf_queue *q, saa7134_dma_free(q,buf); } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = fh->width; @@ -1074,7 +1074,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (err) goto oops; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; return 0; @@ -1421,8 +1421,8 @@ video_poll(struct file *file, struct poll_table_struct *wait) return POLLERR; poll_wait(file, &buf->done, wait); - if (buf->state == STATE_DONE || - buf->state == STATE_ERROR) + if (buf->state == VIDEOBUF_DONE || + buf->state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; } @@ -2519,7 +2519,7 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status) goto done; } dev->video_q.curr->vb.field_count = dev->video_fieldcount; - saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->video_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->video_q); diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index c8a5cb57963b..26d1a5001738 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -68,14 +68,14 @@ int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr) MAGIC_CHECK(vb->magic,MAGIC_BUFFER); add_wait_queue(&vb->done, &wait); - while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) { + while (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) { if (non_blocking) { retval = -EAGAIN; break; } set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); - if (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) + if (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) schedule(); set_current_state(TASK_RUNNING); if (intr && signal_pending(current)) { @@ -167,11 +167,11 @@ int videobuf_queue_is_busy(struct videobuf_queue *q) dprintk(1,"busy: buffer #%d mapped\n",i); return 1; } - if (q->bufs[i]->state == STATE_QUEUED) { + if (q->bufs[i]->state == VIDEOBUF_QUEUED) { dprintk(1,"busy: buffer #%d queued\n",i); return 1; } - if (q->bufs[i]->state == STATE_ACTIVE) { + if (q->bufs[i]->state == VIDEOBUF_ACTIVE) { dprintk(1,"busy: buffer #%d avtive\n",i); return 1; } @@ -191,9 +191,9 @@ void videobuf_queue_cancel(struct videobuf_queue *q) for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; - if (q->bufs[i]->state == STATE_QUEUED) { + if (q->bufs[i]->state == VIDEOBUF_QUEUED) { list_del(&q->bufs[i]->queue); - q->bufs[i]->state = STATE_ERROR; + q->bufs[i]->state = VIDEOBUF_ERROR; } } if (q->irqlock) @@ -259,17 +259,17 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, b->flags |= V4L2_BUF_FLAG_MAPPED; switch (vb->state) { - case STATE_PREPARED: - case STATE_QUEUED: - case STATE_ACTIVE: + case VIDEOBUF_PREPARED: + case VIDEOBUF_QUEUED: + case VIDEOBUF_ACTIVE: b->flags |= V4L2_BUF_FLAG_QUEUED; break; - case STATE_DONE: - case STATE_ERROR: + case VIDEOBUF_DONE: + case VIDEOBUF_ERROR: b->flags |= V4L2_BUF_FLAG_DONE; break; - case STATE_NEEDS_INIT: - case STATE_IDLE: + case VIDEOBUF_NEEDS_INIT: + case VIDEOBUF_IDLE: /* nothing */ break; } @@ -498,7 +498,7 @@ int videobuf_qbuf(struct videobuf_queue *q, dprintk(1,"qbuf: memory type is wrong.\n"); goto done; } - if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) { + if (buf->state != VIDEOBUF_NEEDS_INIT && buf->state != VIDEOBUF_IDLE) { dprintk(1,"qbuf: buffer is already queued or active.\n"); goto done; } @@ -525,7 +525,7 @@ int videobuf_qbuf(struct videobuf_queue *q, dprintk(1,"qbuf: buffer length is not enough\n"); goto done; } - if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr) + if (VIDEOBUF_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr) q->ops->buf_release(q,buf); buf->baddr = b->m.userptr; break; @@ -595,16 +595,16 @@ int videobuf_dqbuf(struct videobuf_queue *q, goto done; } switch (buf->state) { - case STATE_ERROR: + case VIDEOBUF_ERROR: dprintk(1,"dqbuf: state is error\n"); retval = -EIO; CALL(q,sync,q, buf); - buf->state = STATE_IDLE; + buf->state = VIDEOBUF_IDLE; break; - case STATE_DONE: + case VIDEOBUF_DONE: dprintk(1,"dqbuf: state is done\n"); CALL(q,sync,q, buf); - buf->state = STATE_IDLE; + buf->state = VIDEOBUF_IDLE; break; default: dprintk(1,"dqbuf: state invalid\n"); @@ -637,7 +637,7 @@ int videobuf_streamon(struct videobuf_queue *q) if (q->irqlock) spin_lock_irqsave(q->irqlock,flags); list_for_each_entry(buf, &q->stream, stream) - if (buf->state == STATE_PREPARED) + if (buf->state == VIDEOBUF_PREPARED) q->ops->buf_queue(q,buf); if (q->irqlock) spin_unlock_irqrestore(q->irqlock,flags); @@ -704,7 +704,7 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, retval = videobuf_waiton(q->read_buf,0,0); if (0 == retval) { CALL(q,sync,q,q->read_buf); - if (STATE_ERROR == q->read_buf->state) + if (VIDEOBUF_ERROR == q->read_buf->state) retval = -EIO; else retval = q->read_buf->size; @@ -778,7 +778,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, CALL(q,sync,q,q->read_buf); - if (STATE_ERROR == q->read_buf->state) { + if (VIDEOBUF_ERROR == q->read_buf->state) { /* catch I/O errors */ q->ops->buf_release(q,q->read_buf); kfree(q->read_buf); @@ -931,7 +931,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, break; } - if (q->read_buf->state == STATE_DONE) { + if (q->read_buf->state == VIDEOBUF_DONE) { rc = CALL (q,copy_stream, q, data + retval, count, retval, vbihack, nonblocking); if (rc < 0) { @@ -999,8 +999,8 @@ unsigned int videobuf_poll_stream(struct file *file, if (0 == rc) { poll_wait(file, &buf->done, wait); - if (buf->state == STATE_DONE || - buf->state == STATE_ERROR) + if (buf->state == VIDEOBUF_DONE || + buf->state == VIDEOBUF_ERROR) rc = POLLIN|POLLRDNORM; } mutex_unlock(&q->lock); diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c index 880317e04a02..b73aba65d21d 100644 --- a/drivers/media/video/videobuf-dvb.c +++ b/drivers/media/video/videobuf-dvb.c @@ -67,7 +67,7 @@ static int videobuf_dvb_thread(void *data) /* feed buffer data to demux */ dma=videobuf_to_dma(buf); - if (buf->state == STATE_DONE) + if (buf->state == VIDEOBUF_DONE) dvb_dmx_swfilter(&dvb->demux, dma->vmalloc, buf->size); diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 9b54ff9d2e36..fe9784a0cc21 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -370,7 +370,7 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) (unsigned long)tmpbuf,pos); /* Advice that buffer was filled */ - buf->vb.state = STATE_DONE; + buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; do_gettimeofday(&ts); buf->vb.ts = ts; @@ -522,7 +522,7 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q) /* cancel all outstanding capture / vbi requests */ list_for_each_entry_safe(buf, prev, &dma_q->active, vb.queue) { list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); } mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); @@ -543,7 +543,7 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q) vivi_stop_thread(dma_q); vivi_start_thread(dma_q); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] restart_queue - first active\n", buf,buf->vb.i); @@ -553,7 +553,7 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q) prev->fmt == buf->fmt) { list_del(&buf->vb.queue); list_add_tail(&buf->vb.queue,&dma_q->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; dprintk(2,"[%p/%d] restart_queue - move to active\n", buf,buf->vb.i); } else { @@ -572,7 +572,7 @@ static void vivi_vid_timeout(unsigned long data) while (!list_empty(&vidq->active)) { buf = list_entry(vidq->active.next, struct vivi_buffer, vb.queue); list_del(&buf->vb.queue); - buf->vb.state = STATE_ERROR; + buf->vb.state = VIDEOBUF_ERROR; wake_up(&buf->vb.done); printk("vivi/0: [%p/%d] timeout\n", buf, buf->vb.i); } @@ -610,7 +610,7 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) videobuf_waiton(&buf->vb,0,0); videobuf_vmalloc_free(&buf->vb); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } #define norm_maxw() 1024 @@ -644,12 +644,12 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, init_buffer = 1; } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { if (0 != (rc = videobuf_iolock(vq,&buf->vb,NULL))) goto fail; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; return 0; @@ -670,13 +670,13 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) if (!list_empty(&vidq->queued)) { dprintk(1,"adding vb queue=0x%08lx\n",(unsigned long)&buf->vb.queue); list_add_tail(&buf->vb.queue,&vidq->queued); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; dprintk(2,"[%p/%d] buffer_queue - append to queued\n", buf, buf->vb.i); } else if (list_empty(&vidq->active)) { list_add_tail(&buf->vb.queue,&vidq->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] buffer_queue - first active\n", buf, buf->vb.i); @@ -688,13 +688,13 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) prev->vb.height == buf->vb.height && prev->fmt == buf->fmt) { list_add_tail(&buf->vb.queue,&vidq->active); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; dprintk(2,"[%p/%d] buffer_queue - append to active\n", buf, buf->vb.i); } else { list_add_tail(&buf->vb.queue,&vidq->queued); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; dprintk(2,"[%p/%d] buffer_queue - first queued\n", buf, buf->vb.i); } diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 4fd5d0eaa935..567dfe22c07f 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h @@ -56,13 +56,13 @@ struct videobuf_mapping { }; enum videobuf_state { - STATE_NEEDS_INIT = 0, - STATE_PREPARED = 1, - STATE_QUEUED = 2, - STATE_ACTIVE = 3, - STATE_DONE = 4, - STATE_ERROR = 5, - STATE_IDLE = 6, + VIDEOBUF_NEEDS_INIT = 0, + VIDEOBUF_PREPARED = 1, + VIDEOBUF_QUEUED = 2, + VIDEOBUF_ACTIVE = 3, + VIDEOBUF_DONE = 4, + VIDEOBUF_ERROR = 5, + VIDEOBUF_IDLE = 6, }; struct videobuf_buffer { -- cgit v1.2.3 From d6964aa8d4a418d69da1652121940fabc6b5d591 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 6 Nov 2007 20:23:08 -0300 Subject: V4L/DVB (6603): V4L: videobuf: convert streaming and reading to bitfields Signed-off-by: Brandon Philips Signed-off-by: Mauro Carvalho Chehab --- include/media/videobuf-core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 567dfe22c07f..7aa7a7b64c1b 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h @@ -162,12 +162,12 @@ struct videobuf_queue { struct videobuf_queue_ops *ops; struct videobuf_qtype_ops *int_ops; + unsigned int streaming:1; + unsigned int reading:1; /* capture via mmap() + ioctl(QBUF/DQBUF) */ - unsigned int streaming; struct list_head stream; /* capture via read() */ - unsigned int reading; unsigned int read_off; struct videobuf_buffer *read_buf; -- cgit v1.2.3 From 2a2bfbff3d867c62a49f43266ca993c9c2c2ff28 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 Dec 2007 07:43:14 -0300 Subject: V4L/DVB (6766): ivtv: remove i2c legacy support from drivers that no longer need it Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/m52790.c | 4 ---- drivers/media/video/saa7127.c | 4 ---- drivers/media/video/upd64031a.c | 4 ---- drivers/media/video/upd64083.c | 4 ---- drivers/media/video/vp27smpx.c | 4 ---- drivers/media/video/wm8739.c | 3 --- include/media/v4l2-i2c-drv.h | 1 - 7 files changed, 24 deletions(-) (limited to 'include') diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index 51ecbfbc1ae7..4d2a52204ad4 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c @@ -36,10 +36,6 @@ MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch"); MODULE_AUTHOR("Hans Verkuil"); MODULE_LICENSE("GPL"); -static unsigned short normal_i2c[] = { 0x90 >> 1, I2C_CLIENT_END }; - - -I2C_CLIENT_INSMOD; struct m52790_state { u16 input; diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index 0262acde0888..a5fbfe025333 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -69,10 +69,6 @@ module_param(test_image, int, 0644); MODULE_PARM_DESC(debug, "debug level (0-2)"); MODULE_PARM_DESC(test_image, "test_image (0-1)"); -static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; - - -I2C_CLIENT_INSMOD; /* * SAA7127 registers diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c index 0318432d85f8..1b162f2dca95 100644 --- a/drivers/media/video/upd64031a.c +++ b/drivers/media/video/upd64031a.c @@ -49,10 +49,6 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -static unsigned short normal_i2c[] = { 0x24 >> 1, 0x26 >> 1, I2C_CLIENT_END }; - - -I2C_CLIENT_INSMOD; enum { R00 = 0, R01, R02, R03, R04, diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c index 7e32c5b0c29d..0f9e86cfc628 100644 --- a/drivers/media/video/upd64083.c +++ b/drivers/media/video/upd64083.c @@ -39,10 +39,6 @@ module_param(debug, bool, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -static unsigned short normal_i2c[] = { 0xb8 >> 1, 0xba >> 1, I2C_CLIENT_END }; - - -I2C_CLIENT_INSMOD; enum { R00 = 0, R01, R02, R03, R04, diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index 97e24769e65b..cd98084ac090 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c @@ -36,10 +36,6 @@ MODULE_DESCRIPTION("vp27smpx driver"); MODULE_AUTHOR("Hans Verkuil"); MODULE_LICENSE("GPL"); -static unsigned short normal_i2c[] = { 0xb6 >> 1, I2C_CLIENT_END }; - - -I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c index ac4fee1d0251..1c30a5c8455c 100644 --- a/drivers/media/video/wm8739.c +++ b/drivers/media/video/wm8739.c @@ -37,15 +37,12 @@ MODULE_AUTHOR("T. Adachi, Hans Verkuil"); MODULE_LICENSE("GPL"); static int debug; -static unsigned short normal_i2c[] = { 0x34 >> 1, 0x36 >> 1, I2C_CLIENT_END }; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -I2C_CLIENT_INSMOD; - /* ------------------------------------------------------------------------ */ enum { diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h index bc61ab27779d..d758b765e0ff 100644 --- a/include/media/v4l2-i2c-drv.h +++ b/include/media/v4l2-i2c-drv.h @@ -34,7 +34,6 @@ struct v4l2_i2c_driver_data { }; static struct v4l2_i2c_driver_data v4l2_i2c_data; -static struct i2c_client_address_data addr_data; static struct i2c_driver v4l2_i2c_driver; -- cgit v1.2.3 From ab1660503ac3af7febfcf987648509b484d4feda Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 9 Dec 2007 02:26:48 -0300 Subject: V4L/DVB (6785): tda8290: remove dependency on struct tuner - remove dependency of tda8290 module on struct tuner - move tuner_foo printk macros from tuner-driver.h into tuner-core.c - clean up #includes of tuner-i2c.h / tuner-driver.h Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tda8290.c | 103 ++++++++++++++++++------------------- drivers/media/video/tda8290.h | 24 ++++++--- drivers/media/video/tda9887.c | 1 + drivers/media/video/tuner-core.c | 43 ++++++++++++++-- drivers/media/video/tuner-driver.h | 27 ---------- drivers/media/video/tuner-i2c.h | 2 - include/media/tuner.h | 2 - 7 files changed, 109 insertions(+), 93 deletions(-) (limited to 'include') diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index a39cb1f9e875..d0d13bc61250 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c @@ -23,12 +23,14 @@ #include #include #include +#include "tuner-driver.h" +#include "tuner-i2c.h" #include "tda8290.h" #include "tda827x.h" #include "tda18271.h" -static int tuner_debug; -module_param_named(debug, tuner_debug, int, 0644); +static int debug; +module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable verbose debug messages"); #define PREFIX "tda8290" @@ -50,8 +52,6 @@ struct tda8290_priv { #define TDA18271 16 struct tda827x_config cfg; - - struct tuner *t; }; /*---------------------------------------------------------------------*/ @@ -114,7 +114,6 @@ static void set_audio(struct dvb_frontend *fe, struct analog_parameters *params) { struct tda8290_priv *priv = fe->analog_demod_priv; - struct tuner *t = priv->t; char* mode; if (params->std & V4L2_STD_MN) { @@ -150,7 +149,6 @@ static void tda8290_set_params(struct dvb_frontend *fe, struct analog_parameters *params) { struct tda8290_priv *priv = fe->analog_demod_priv; - struct tuner *t = priv->t; unsigned char soft_reset[] = { 0x00, 0x00 }; unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode }; @@ -176,7 +174,8 @@ static void tda8290_set_params(struct dvb_frontend *fe, set_audio(fe, params); - tuner_dbg("tda827xa config is 0x%02x\n", t->config); + if (priv->cfg.config) + tuner_dbg("tda827xa config is 0x%02x\n", *priv->cfg.config); tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2); tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2); tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); @@ -362,7 +361,6 @@ static void tda8295_set_params(struct dvb_frontend *fe, struct analog_parameters *params) { struct tda8290_priv *priv = fe->analog_demod_priv; - struct tuner *t = priv->t; unsigned char blanking_mode[] = { 0x1d, 0x00 }; @@ -442,13 +440,13 @@ static void tda8295_standby(struct dvb_frontend *fe) static void tda8290_init_if(struct dvb_frontend *fe) { struct tda8290_priv *priv = fe->analog_demod_priv; - struct tuner *t = priv->t; unsigned char set_VS[] = { 0x30, 0x6F }; unsigned char set_GP00_CF[] = { 0x20, 0x01 }; unsigned char set_GP01_CF[] = { 0x20, 0x0B }; - if ((t->config == 1) || (t->config == 2)) + if ((priv->cfg.config) && + ((*priv->cfg.config == 1) || (*priv->cfg.config == 2))) tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2); else tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2); @@ -516,7 +514,6 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) { struct tda8290_priv *priv = fe->analog_demod_priv; struct analog_tuner_ops *ops = fe->ops.analog_demod_ops; - struct tuner *t = priv->t; int i, ret, tuners_found; u32 tuner_addrs; u8 data; @@ -595,29 +592,6 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) ops->i2c_gate_ctrl(fe, 0); - switch (priv->ver) { - case TDA8290 | TDA8275: - strlcpy(t->i2c->name, "tda8290+75", sizeof(t->i2c->name)); - break; - case TDA8295 | TDA8275: - strlcpy(t->i2c->name, "tda8295+75", sizeof(t->i2c->name)); - break; - case TDA8290 | TDA8275A: - strlcpy(t->i2c->name, "tda8290+75a", sizeof(t->i2c->name)); - break; - case TDA8295 | TDA8275A: - strlcpy(t->i2c->name, "tda8295+75a", sizeof(t->i2c->name)); - break; - case TDA8290 | TDA18271: - strlcpy(t->i2c->name, "tda8290+18271", sizeof(t->i2c->name)); - break; - case TDA8295 | TDA18271: - strlcpy(t->i2c->name, "tda8295+18271", sizeof(t->i2c->name)); - break; - default: - return -EINVAL; - } - return 0; } @@ -631,7 +605,7 @@ static int tda8290_probe(struct tuner_i2c_props *i2c_props) tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1); if (tda8290_id[1] == TDA8290_ID) { - if (tuner_debug) + if (debug) printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", __FUNCTION__, i2c_adapter_id(i2c_props->adap), i2c_props->addr); @@ -651,7 +625,7 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); if (tda8295_id[1] == TDA8295_ID) { - if (tuner_debug) + if (debug) printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", __FUNCTION__, i2c_adapter_id(i2c_props->adap), i2c_props->addr); @@ -677,21 +651,24 @@ static struct analog_tuner_ops tda8295_tuner_ops = { .i2c_gate_ctrl = tda8295_i2c_bridge, }; -int tda829x_attach(struct tuner *t) +struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c_adap, u8 i2c_addr, + struct tda829x_config *cfg) { - struct dvb_frontend *fe = &t->fe; struct tda8290_priv *priv = NULL; + char *name; priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); if (priv == NULL) - return -ENOMEM; + return NULL; fe->analog_demod_priv = priv; - priv->i2c_props.addr = t->i2c->addr; - priv->i2c_props.adap = t->i2c->adapter; - priv->cfg.config = &t->config; - priv->cfg.tuner_callback = t->tuner_callback; - priv->t = t; + priv->i2c_props.addr = i2c_addr; + priv->i2c_props.adap = i2c_adap; + if (cfg) { + priv->cfg.config = cfg->lna_cfg; + priv->cfg.tuner_callback = cfg->tuner_callback; + } if (tda8290_probe(&priv->i2c_props) == 0) { priv->ver = TDA8290; @@ -706,30 +683,50 @@ int tda829x_attach(struct tuner *t) if (tda829x_find_tuner(fe) < 0) goto fail; + switch (priv->ver) { + case TDA8290 | TDA8275: + name = "tda8290+75"; + break; + case TDA8295 | TDA8275: + name = "tda8295+75"; + break; + case TDA8290 | TDA8275A: + name = "tda8290+75a"; + break; + case TDA8295 | TDA8275A: + name = "tda8295+75a"; + break; + case TDA8290 | TDA18271: + name = "tda8290+18271"; + break; + case TDA8295 | TDA18271: + name = "tda8295+18271"; + break; + default: + goto fail; + } + tuner_info("type set to %s\n", name); + if (priv->ver & TDA8290) { tda8290_init_tuner(fe); tda8290_init_if(fe); } else if (priv->ver & TDA8295) tda8295_init_if(fe); - tuner_info("type set to %s\n", t->i2c->name); - - t->mode = V4L2_TUNER_ANALOG_TV; - - return 0; + return fe; fail: tda829x_release(fe); fe->ops.analog_demod_ops = NULL; - return -EINVAL; + return NULL; } EXPORT_SYMBOL_GPL(tda829x_attach); -int tda829x_probe(struct tuner *t) +int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) { struct tuner_i2c_props i2c_props = { - .adap = t->i2c->adapter, - .addr = t->i2c->addr + .adap = i2c_adap, + .addr = i2c_addr, }; unsigned char soft_reset[] = { 0x00, 0x00 }; diff --git a/drivers/media/video/tda8290.h b/drivers/media/video/tda8290.h index 3a1f04520615..4c547577e7ca 100644 --- a/drivers/media/video/tda8290.h +++ b/drivers/media/video/tda8290.h @@ -18,24 +18,36 @@ #define __TDA8290_H__ #include -#include "tuner-driver.h" +#include "dvb_frontend.h" + +struct tda829x_config +{ + unsigned int *lna_cfg; + int (*tuner_callback) (void *dev, int command, int arg); +}; #if defined(CONFIG_TUNER_TDA8290) || (defined(CONFIG_TUNER_TDA8290_MODULE) && defined(MODULE)) -extern int tda829x_probe(struct tuner *t); +extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr); -extern int tda829x_attach(struct tuner *t); +extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c_adap, + u8 i2c_addr, + struct tda829x_config *cfg); #else -static inline int tda829x_probe(struct tuner *t) +static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); return -EINVAL; } -static inline int tda829x_attach(struct tuner *t) +static inline struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c_adap, + u8 i2c_addr, + struct tda829x_config *cfg) { printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", __FUNCTION__); - return -EINVAL; + return NULL; } #endif diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index d506d4bf8253..98d45c4912bd 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -9,6 +9,7 @@ #include #include #include +#include "tuner-i2c.h" #include "tda9887.h" diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 5f8bffc8209b..0cc190761e24 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -52,7 +52,34 @@ static unsigned int no_autodetect = 0; static unsigned int show_i2c = 0; /* insmod options used at runtime => read/write */ -int tuner_debug = 0; +static int tuner_debug; + +#define tuner_warn(fmt, arg...) do { \ + printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \ + i2c_adapter_id(t->i2c->adapter), \ + t->i2c->addr, ##arg); \ + } while (0) + +#define tuner_info(fmt, arg...) do { \ + printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \ + i2c_adapter_id(t->i2c->adapter), \ + t->i2c->addr, ##arg); \ + } while (0) + +#define tuner_err(fmt, arg...) do { \ + printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \ + i2c_adapter_id(t->i2c->adapter), \ + t->i2c->addr, ##arg); \ + } while (0) + +#define tuner_dbg(fmt, arg...) do { \ + if (tuner_debug) \ + printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \ + i2c_adapter_id(t->i2c->adapter), \ + t->i2c->addr, ##arg); \ + } while (0) + +/* ------------------------------------------------------------------------ */ static unsigned int tv_range[2] = { 44, 958 }; static unsigned int radio_range[2] = { 65, 108 }; @@ -261,6 +288,15 @@ static void attach_simple_tuner(struct tuner *t) simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); } +static void attach_tda829x(struct tuner *t) +{ + struct tda829x_config cfg = { + .lna_cfg = &t->config, + .tuner_callback = t->tuner_callback, + }; + tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); +} + static void set_type(struct i2c_client *c, unsigned int type, unsigned int new_mode_mask, unsigned int new_config, int (*tuner_callback) (void *dev, int command,int arg)) @@ -303,7 +339,7 @@ static void set_type(struct i2c_client *c, unsigned int type, break; case TUNER_PHILIPS_TDA8290: { - tda829x_attach(t); + attach_tda829x(t); break; } case TUNER_TEA5767: @@ -1045,7 +1081,8 @@ static int tuner_probe(struct i2c_client *client) case 0x4b: /* If chip is not tda8290, don't register. since it can be tda9887*/ - if (tda829x_probe(t) == 0) { + if (tda829x_probe(t->i2c->adapter, + t->i2c->addr) == 0) { tuner_dbg("tda829x detected\n"); } else { /* Default is being tda9887 */ diff --git a/drivers/media/video/tuner-driver.h b/drivers/media/video/tuner-driver.h index 91913ee08a07..a215161d0241 100644 --- a/drivers/media/video/tuner-driver.h +++ b/drivers/media/video/tuner-driver.h @@ -24,13 +24,10 @@ #include #include -#include "tuner-i2c.h" #include "dvb_frontend.h" extern unsigned const int tuner_count; -struct tuner; - struct analog_tuner_ops { void (*set_params)(struct dvb_frontend *fe, struct analog_parameters *params); @@ -69,28 +66,4 @@ struct tuner { int (*tuner_callback) (void *dev, int command,int arg); }; -/* ------------------------------------------------------------------------ */ - -#define tuner_warn(fmt, arg...) do { \ - printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(t->i2c->adapter), t->i2c->addr, ##arg); \ - } while (0) - -#define tuner_info(fmt, arg...) do { \ - printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(t->i2c->adapter), t->i2c->addr , ##arg); \ - } while (0) - -#define tuner_err(fmt, arg...) do { \ - printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(t->i2c->adapter), t->i2c->addr , ##arg); \ - } while (0) - -#define tuner_dbg(fmt, arg...) do { \ - extern int tuner_debug; \ - if (tuner_debug) \ - printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \ - i2c_adapter_id(t->i2c->adapter), t->i2c->addr , ##arg); \ - } while (0) - #endif /* __TUNER_DRIVER_H__ */ diff --git a/drivers/media/video/tuner-i2c.h b/drivers/media/video/tuner-i2c.h index d7cf72c3fd71..de52e8ffd347 100644 --- a/drivers/media/video/tuner-i2c.h +++ b/drivers/media/video/tuner-i2c.h @@ -59,7 +59,6 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, return (ret == 2) ? ilen : ret; } -#ifndef __TUNER_DRIVER_H__ #define tuner_warn(fmt, arg...) do { \ printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \ i2c_adapter_id(priv->i2c_props.adap), \ @@ -84,6 +83,5 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, i2c_adapter_id(priv->i2c_props.adap), \ priv->i2c_props.addr , ##arg); \ } while (0) -#endif /* __TUNER_DRIVER_H__ */ #endif /* __TUNER_I2C_H__ */ diff --git a/include/media/tuner.h b/include/media/tuner.h index d49392d90e56..97be269afbee 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -24,8 +24,6 @@ #include -extern int tuner_debug; - #define ADDR_UNSET (255) #define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */ -- cgit v1.2.3 From ea48c13ad0e5626b827bd7076c22df1a352e3983 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 12 Dec 2007 07:04:58 -0300 Subject: V4L/DVB (6861): cx2341x: command argument should be u32 instead of int Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx2341x.c | 2 +- drivers/media/video/cx88/cx88-blackbird.c | 2 +- drivers/media/video/ivtv/ivtv-mailbox.c | 2 +- drivers/media/video/ivtv/ivtv-mailbox.h | 2 +- drivers/media/video/pvrusb2/pvrusb2-encoder.c | 2 +- include/media/cx2341x.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c index 890c8867af1c..c592899a2317 100644 --- a/drivers/media/video/cx2341x.c +++ b/drivers/media/video/cx2341x.c @@ -775,7 +775,7 @@ void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p) EXPORT_SYMBOL(cx2341x_fill_defaults); static int cx2341x_api(void *priv, cx2341x_mbox_func func, - int cmd, int args, ...) + u32 cmd, int args, ...) { u32 data[CX2341X_MBOX_MAX_DATA]; va_list vargs; diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 5f79442924fd..a99e9d5950aa 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -307,7 +307,7 @@ static int register_read(struct cx88_core *core, u32 address, u32 *value) /* ------------------------------------------------------------------ */ -static int blackbird_mbox_func(void *priv, int command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) +static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) { struct cx8802_dev *dev = priv; unsigned long timeout; diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c index b05436da7136..13a6c374d2db 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/drivers/media/video/ivtv/ivtv-mailbox.c @@ -333,7 +333,7 @@ int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]) return (res == -EBUSY) ? ivtv_api_call(itv, cmd, args, data) : res; } -int ivtv_api_func(void *priv, int cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) +int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) { return ivtv_api(priv, cmd, in, data); } diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h index 71a54eef8fc7..6ef12091e3f3 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.h +++ b/drivers/media/video/ivtv/ivtv-mailbox.h @@ -28,6 +28,6 @@ void ivtv_api_get_data(struct ivtv_mailbox_data *mbox, int mb, u32 data[]); int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]); int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); -int ivtv_api_func(void *priv, int cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]); +int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]); #endif diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 52b39954f990..64062879981e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -140,7 +140,7 @@ static int pvr2_encoder_read_words(struct pvr2_hdw *hdw, cx2341x.ko to write to our encoder (by handing it a pointer to this function). For earlier kernels this doesn't really matter. */ static int pvr2_encoder_cmd(void *ctxt, - int cmd, + u32 cmd, int arg_cnt_send, int arg_cnt_recv, u32 *argp) diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h index af8071d7620d..5f4608e88476 100644 --- a/include/media/cx2341x.h +++ b/include/media/cx2341x.h @@ -83,7 +83,7 @@ struct cx2341x_mpeg_params { #define CX2341X_MBOX_MAX_DATA 16 extern const u32 cx2341x_mpeg_ctrls[]; -typedef int (*cx2341x_mbox_func)(void *priv, int cmd, int in, int out, +typedef int (*cx2341x_mbox_func)(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]); int cx2341x_update(void *priv, cx2341x_mbox_func func, const struct cx2341x_mpeg_params *old, -- cgit v1.2.3 From 0b394def21e7d3bd02aeee5570473582ce7984ec Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Dec 2007 19:27:31 -0300 Subject: V4L/DVB (6868): i2c-id.h: add I2C_DRIVERID_CS5345 Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/i2c-id.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index adbdc6da39ca..c7a51a196f51 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -126,6 +126,7 @@ #define I2C_DRIVERID_VP27SMPX 93 /* Panasonic VP27s tuner internal MPX */ #define I2C_DRIVERID_CS4270 94 /* Cirrus Logic 4270 audio codec */ #define I2C_DRIVERID_M52790 95 /* Mitsubishi M52790SP/FP AV switch */ +#define I2C_DRIVERID_CS5345 96 /* cs5345 audio processor */ #define I2C_DRIVERID_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ -- cgit v1.2.3 From 6fb377f85cb8c2c1580ce8b134c887a7b53c7aa9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Dec 2007 19:40:44 -0300 Subject: V4L/DVB (6869): cs5345: new i2c driver Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 10 +++ drivers/media/video/Makefile | 1 + drivers/media/video/cs5345.c | 168 ++++++++++++++++++++++++++++++++++++++++ include/media/cs5345.h | 39 ++++++++++ include/media/v4l2-chip-ident.h | 3 + 5 files changed, 221 insertions(+) create mode 100644 drivers/media/video/cs5345.c create mode 100644 include/media/cs5345.h (limited to 'include') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 6c7835629bcd..7431f6da5cae 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -109,6 +109,16 @@ config VIDEO_MSP3400 To compile this driver as a module, choose M here: the module will be called msp3400. +config VIDEO_CS5345 + tristate "Cirrus Logic CS5345 audio ADC" + depends on VIDEO_V4L2 && I2C && EXPERIMENTAL + ---help--- + Support for the Cirrus Logic CS5345 24-bit, 192 kHz + stereo A/D converter. + + To compile this driver as a module, choose M here: the + module will be called cs5345. + config VIDEO_CS53L32A tristate "Cirrus Logic CS53L32A audio ADC" depends on VIDEO_V4L2 && I2C diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index a837e1ea518f..74a2a1c45fe3 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o +obj-$(CONFIG_VIDEO_CS5345) += cs5345.o obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o obj-$(CONFIG_VIDEO_M52790) += m52790.o obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c new file mode 100644 index 000000000000..fae469ce16f5 --- /dev/null +++ b/drivers/media/video/cs5345.c @@ -0,0 +1,168 @@ +/* + * cs5345 Cirrus Logic 24-bit, 192 kHz Stereo Audio ADC + * Copyright (C) 2007 Hans Verkuil + * + * 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 +#include +#include + +MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC"); +MODULE_AUTHOR("Hans Verkuil"); +MODULE_LICENSE("GPL"); + +static int debug; + +module_param(debug, bool, 0644); + +MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); + + +/* ----------------------------------------------------------------------- */ + +static inline int cs5345_write(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +static inline int cs5345_read(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + struct v4l2_routing *route = arg; + struct v4l2_control *ctrl = arg; + + switch (cmd) { + case VIDIOC_INT_G_AUDIO_ROUTING: + route->input = cs5345_read(client, 0x09) & 7; + route->input |= cs5345_read(client, 0x05) & 0x70; + route->output = 0; + break; + + case VIDIOC_INT_S_AUDIO_ROUTING: + if ((route->input & 0xf) > 6) { + v4l_err(client, "Invalid input %d.\n", route->input); + return -EINVAL; + } + cs5345_write(client, 0x09, route->input & 0xf); + cs5345_write(client, 0x05, route->input & 0xf0); + break; + + case VIDIOC_G_CTRL: + if (ctrl->id == V4L2_CID_AUDIO_MUTE) { + ctrl->value = (cs5345_read(client, 0x04) & 0x08) != 0; + break; + } + if (ctrl->id != V4L2_CID_AUDIO_VOLUME) + return -EINVAL; + ctrl->value = cs5345_read(client, 0x07) & 0x3f; + if (ctrl->value >= 32) + ctrl->value = ctrl->value - 64; + break; + + case VIDIOC_S_CTRL: + break; + if (ctrl->id == V4L2_CID_AUDIO_MUTE) { + cs5345_write(client, 0x04, ctrl->value ? 0x80 : 0); + break; + } + if (ctrl->id != V4L2_CID_AUDIO_VOLUME) + return -EINVAL; + if (ctrl->value > 24 || ctrl->value < -24) + return -EINVAL; + cs5345_write(client, 0x07, ((u8)ctrl->value) & 0x3f); + cs5345_write(client, 0x08, ((u8)ctrl->value) & 0x3f); + break; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + case VIDIOC_DBG_G_REGISTER: + case VIDIOC_DBG_S_REGISTER: + { + struct v4l2_register *reg = arg; + + if (!v4l2_chip_match_i2c_client(client, + reg->match_type, reg->match_chip)) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (cmd == VIDIOC_DBG_G_REGISTER) + reg->val = cs5345_read(client, reg->reg & 0x1f); + else + cs5345_write(client, reg->reg & 0x1f, reg->val & 0x1f); + break; + } +#endif + + case VIDIOC_G_CHIP_IDENT: + return v4l2_chip_ident_i2c_client(client, + arg, V4L2_IDENT_CS5345, 0); + + case VIDIOC_LOG_STATUS: + { + u8 v = cs5345_read(client, 0x09) & 7; + u8 m = cs5345_read(client, 0x04); + int vol = cs5345_read(client, 0x08) & 0x3f; + + v4l_info(client, "Input: %d%s\n", v, + (m & 0x80) ? " (muted)" : ""); + if (vol >= 32) + vol = vol - 64; + v4l_info(client, "Volume: %d dB\n", vol); + break; + } + + default: + return -EINVAL; + } + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static int cs5345_probe(struct i2c_client *client) +{ + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; + + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + + cs5345_write(client, 0x02, 0x00); + cs5345_write(client, 0x04, 0x01); + cs5345_write(client, 0x09, 0x01); + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "cs5345", + .driverid = I2C_DRIVERID_CS5345, + .command = cs5345_command, + .probe = cs5345_probe, +}; + diff --git a/include/media/cs5345.h b/include/media/cs5345.h new file mode 100644 index 000000000000..6ccae24e65ed --- /dev/null +++ b/include/media/cs5345.h @@ -0,0 +1,39 @@ +/* + cs5345.h - definition for cs5345 inputs and outputs + + Copyright (C) 2007 Hans Verkuil (hverkuil@xs4all.nl) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License 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 _CS5345_H_ +#define _CS5345_H_ + +/* CS5345 HW inputs */ +#define CS5345_IN_MIC 0 +#define CS5345_IN_1 1 +#define CS5345_IN_2 2 +#define CS5345_IN_3 3 +#define CS5345_IN_4 4 +#define CS5345_IN_5 5 +#define CS5345_IN_6 6 + +#define CS5345_MCLK_1 0x00 +#define CS5345_MCLK_1_5 0x10 +#define CS5345_MCLK_2 0x20 +#define CS5345_MCLK_3 0x30 +#define CS5345_MCLK_4 0x40 + +#endif diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 2442c281e4fe..032bb75f69c2 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -68,6 +68,9 @@ enum { /* module vp27smpx: just ident 2700 */ V4L2_IDENT_VP27SMPX = 2700, + /* module cs5345: just ident 5345 */ + V4L2_IDENT_CS5345 = 5345, + /* module wm8739: just ident 8739 */ V4L2_IDENT_WM8739 = 8739, -- cgit v1.2.3 From 8574ac690eab730a3ff735177af1d52e45e36c8b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 24 Dec 2007 15:49:33 -0300 Subject: V4L/DVB (6921): include/media/v4l2-i2c-drv.h must #include Fix the following compiler error: v4l2-i2c-drv.h:72: error: implicit declaration of function 'v4l2_i2c_attach' Also, prevent multiple inclusions of v4l2-i2c-drv.h Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-i2c-drv.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h index d758b765e0ff..9e4bab276915 100644 --- a/include/media/v4l2-i2c-drv.h +++ b/include/media/v4l2-i2c-drv.h @@ -21,6 +21,11 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef __V4L2_I2C_DRV_H__ +#define __V4L2_I2C_DRV_H__ + +#include + struct v4l2_i2c_driver_data { const char * const name; int driverid; @@ -59,3 +64,5 @@ static void __exit v4l2_i2c_drv_cleanup(void) module_init(v4l2_i2c_drv_init); module_exit(v4l2_i2c_drv_cleanup); + +#endif /* __V4L2_I2C_DRV_H__ */ -- cgit v1.2.3 From e8018c9e78b0ff4bb0290e46f4045fb4ea589ae8 Mon Sep 17 00:00:00 2001 From: "Andrey J. Melnikoff (TEMHOTA)" Date: Mon, 7 Jan 2008 05:17:39 -0300 Subject: V4L/DVB (6973): Add Beholder TV 401/405/407/409/505/507/609/M6 support This patch updates cardlist for Beholder TV tuners: old models (with GPIO ir) 401, 403, 405, 407, 409, 505, 507 and add support for 607, 609, M6 cards with new i2c-ir. Signed-off-by: Igor Kuznetsov Signed-off-by: Andrey J. Melnikov Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 13 + drivers/media/common/ir-keymaps.c | 104 ++++++ drivers/media/video/ir-kbd-i2c.c | 3 +- drivers/media/video/saa7134/saa7134-cards.c | 504 ++++++++++++++++++++++++++++ drivers/media/video/saa7134/saa7134-i2c.c | 2 + drivers/media/video/saa7134/saa7134-input.c | 60 ++++ drivers/media/video/saa7134/saa7134.h | 13 + include/media/ir-common.h | 1 + 8 files changed, 699 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 29ca16cdb713..387c35f2ecd7 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -116,3 +116,16 @@ 115 -> Sabrent PCMCIA TV-PCB05 [0919:2003] 116 -> 10MOONS TM300 TV Card [1131:2304] 117 -> Avermedia Super 007 [1461:f01d] +118 -> Beholder BeholdTV 401 [1131:0000,0000:4016] +119 -> Beholder BeholdTV 403 [0000:4036] +120 -> Beholder BeholdTV 403 FM [1131:0000,0000:4037] +121 -> Beholder BeholdTV 405 [0000:4050] +122 -> Beholder BeholdTV 405 FM [0000:4051] +123 -> [0000:4070] +124 -> Beholder BeholdTV 407 FM [0000:4071] +125 -> Beholder BeholdTV 409 [0000:4090] +126 -> Beholder BeholdTV 505 FM/RDS [0000:5051,0000:505B,5ace:5050] +127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090] +128 -> Beholder BeholdTV Columbus TVFM [0000:5201] +129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093] +130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193] diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index 42762dfb7387..ee2c69e3152a 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -1848,3 +1848,107 @@ IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce); + +/* + * Igor Kuznetsov + * Andrey J. Melnikov + * + * Keytable is used by BeholdTV 60x series, M6 series at + * least, and probably other cards too. + * The "ascii-art picture" below (in comments, first row + * is the keycode in hex, and subsequent row(s) shows + * the button labels (several variants when appropriate) + * helps to descide which keycodes to assign to the buttons. + */ +IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = { + + /* 0x1c 0x12 * + * TV/FM POWER * + * */ + [ 0x1c ] = KEY_TUNER, /*XXX KEY_TV KEY_RADIO */ + [ 0x12 ] = KEY_POWER, + + /* 0x01 0x02 0x03 * + * 1 2 3 * + * * + * 0x04 0x05 0x06 * + * 4 5 6 * + * * + * 0x07 0x08 0x09 * + * 7 8 9 * + * */ + [ 0x01 ] = KEY_1, + [ 0x02 ] = KEY_2, + [ 0x03 ] = KEY_3, + [ 0x04 ] = KEY_4, + [ 0x05 ] = KEY_5, + [ 0x06 ] = KEY_6, + [ 0x07 ] = KEY_7, + [ 0x08 ] = KEY_8, + [ 0x09 ] = KEY_9, + + /* 0x0a 0x00 0x17 * + * RECALL 0 MODE * + * */ + [ 0x0a ] = KEY_AGAIN, + [ 0x00 ] = KEY_0, + [ 0x17 ] = KEY_MODE, + + /* 0x14 0x10 * + * ASPECT FULLSCREEN * + * */ + [ 0x14 ] = KEY_SCREEN, + [ 0x10 ] = KEY_ZOOM, + + /* 0x0b * + * Up * + * * + * 0x18 0x16 0x0c * + * Left Ok Right * + * * + * 0x015 * + * Down * + * */ + [ 0x0b ] = KEY_CHANNELUP, /*XXX KEY_UP */ + [ 0x18 ] = KEY_VOLUMEDOWN, /*XXX KEY_LEFT */ + [ 0x16 ] = KEY_OK, /*XXX KEY_ENTER */ + [ 0x0c ] = KEY_VOLUMEUP, /*XXX KEY_RIGHT */ + [ 0x15 ] = KEY_CHANNELDOWN, /*XXX KEY_DOWN */ + + /* 0x11 0x0d * + * MUTE INFO * + * */ + [ 0x11 ] = KEY_MUTE, + [ 0x0d ] = KEY_INFO, + + /* 0x0f 0x1b 0x1a * + * RECORD PLAY/PAUSE STOP * + * * + * 0x0e 0x1f 0x1e * + *TELETEXT AUDIO SOURCE * + * RED YELLOW * + * */ + [ 0x0f ] = KEY_RECORD, + [ 0x1b ] = KEY_PLAYPAUSE, + [ 0x1a ] = KEY_STOP, + [ 0x0e ] = KEY_TEXT, + [ 0x1f ] = KEY_RED, /*XXX KEY_AUDIO */ + [ 0x1e ] = KEY_YELLOW, /*XXX KEY_SOURCE */ + + /* 0x1d 0x13 0x19 * + * SLEEP PREVIEW DVB * + * GREEN BLUE * + * */ + [ 0x1d ] = KEY_SLEEP, + [ 0x13 ] = KEY_GREEN, + [ 0x19 ] = KEY_BLUE, /*XXX KEY_SAT */ + + /* 0x58 0x5c * + * FREEZE SNAPSHOT * + * */ + [ 0x58 ] = KEY_SLOW, + [ 0x5c ] = KEY_SAVE, + +}; + +EXPORT_SYMBOL_GPL(ir_codes_behold); diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 29779d8bf7fb..9851987b95fb 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -398,6 +398,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, case 0x7a: case 0x47: case 0x71: + case 0x2d: if (adap->id == I2C_HW_B_CX2388x) { /* Handled by cx88-input */ name = "CX2388x remote"; @@ -504,7 +505,7 @@ static int ir_probe(struct i2c_adapter *adap) */ static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; - static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 }; + static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 }; static const int probe_em28XX[] = { 0x30, 0x47, -1 }; static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; static const int probe_cx23885[] = { 0x6b, -1 }; diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index b29427aaa88d..6a35d88fdbb2 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -3562,6 +3562,329 @@ struct saa7134_board saa7134_boards[] = { .tv = 1, }}, }, + [SAA7134_BOARD_BEHOLD_401] = { + .name = "Beholder BeholdTV 401", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FQ1216ME, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + .mute = { + .name = name_mute, + .amux = LINE1, + }, + }, + [SAA7134_BOARD_BEHOLD_403] = { + .name = "Beholder BeholdTV 403", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FQ1216ME, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + }, + [SAA7134_BOARD_BEHOLD_403FM] = { + .name = "Beholder BeholdTV 403 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FQ1216ME, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_405] = { + .name = "Beholder BeholdTV 405", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + }, + [SAA7134_BOARD_BEHOLD_405FM] = { + /* Sergey */ + .name = "Beholder BeholdTV 405 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_407FM] = { + .name = "Beholder BeholdTV 407 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .gpiomask = 0xc0c000, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + .gpio = 0xc0c000, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + .gpio = 0xc0c000, + },{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + .gpio = 0xc0c000, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + .gpio = 0xc0c000, + }, + }, + [SAA7134_BOARD_BEHOLD_409] = { + .name = "Beholder BeholdTV 409", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + }, + [SAA7134_BOARD_BEHOLD_505FM] = { + .name = "Beholder BeholdTV 505 FM/RDS", + .audio_clock = 0x00200000, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .mute = { + .name = name_mute, + .amux = LINE1, + }, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_507_9FM] = { + .name = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { + .name = "Beholder BeholdTV Columbus TVFM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_ALPS_TSBE5_PAL, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_607_9FM] = { + /* Andrey Melnikoff */ + .name = "Beholder BeholdTV 607 / BeholdTV 609", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_M6] = { + /* Igor Kuznetsov */ + /* Andrey Melnikoff */ + .name = "Beholder BeholdTV M6 / BeholdTV M6 Extra", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + .mpeg = SAA7134_MPEG_EMPRESS, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -4326,6 +4649,174 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1461, /* Avermedia Technologies Inc */ .subdevice = 0xf01d, /* AVerTV DVB-T Super 007 */ .driver_data = SAA7134_BOARD_AVERMEDIA_SUPER_007, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x1131, + .subdevice = 0x0000, + .driver_data = SAA7134_BOARD_BEHOLD_401, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x4016, + .driver_data = SAA7134_BOARD_BEHOLD_401, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x1131, + .subdevice = 0x0000, + .driver_data = SAA7134_BOARD_BEHOLD_403FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0000, + .subdevice = 0x4036, + .driver_data = SAA7134_BOARD_BEHOLD_403, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0000, + .subdevice = 0x4037, + .driver_data = SAA7134_BOARD_BEHOLD_403FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x4050, + .driver_data = SAA7134_BOARD_BEHOLD_405, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x4051, + .driver_data = SAA7134_BOARD_BEHOLD_405FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0000, + .subdevice = 0x4070, + .driver_data = SAA7134_BOARD_BEHOLD_407, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0000, + .subdevice = 0x4071, + .driver_data = SAA7134_BOARD_BEHOLD_407FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0000, + .subdevice = 0x4090, + .driver_data = SAA7134_BOARD_BEHOLD_409, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x5051, + .driver_data = SAA7134_BOARD_BEHOLD_505FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x505B, + .driver_data = SAA7134_BOARD_BEHOLD_505FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x5ace, + .subdevice = 0x5050, + .driver_data = SAA7134_BOARD_BEHOLD_505FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0000, + .subdevice = 0x5071, + .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0000, + .subdevice = 0x507B, + .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x5070, + .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x5090, + .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0000, + .subdevice = 0x5201, + .driver_data = SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x6070, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x6071, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x6072, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x6073, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6090, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6091, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6092, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6093, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6190, + .driver_data = SAA7134_BOARD_BEHOLD_M6, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6193, + .driver_data = SAA7134_BOARD_BEHOLD_M6, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -4473,6 +4964,16 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_ENCORE_ENLTV: case SAA7134_BOARD_ENCORE_ENLTV_FM: case SAA7134_BOARD_10MOONSTVMASTER3: + case SAA7134_BOARD_BEHOLD_401: + case SAA7134_BOARD_BEHOLD_403: + case SAA7134_BOARD_BEHOLD_403FM: + case SAA7134_BOARD_BEHOLD_405: + case SAA7134_BOARD_BEHOLD_405FM: + case SAA7134_BOARD_BEHOLD_407: + case SAA7134_BOARD_BEHOLD_407FM: + case SAA7134_BOARD_BEHOLD_409: + case SAA7134_BOARD_BEHOLD_505FM: + case SAA7134_BOARD_BEHOLD_507_9FM: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: @@ -4512,6 +5013,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS: + case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: /* power-up tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); @@ -4533,6 +5035,8 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_PINNACLE_PCTV_310i: case SAA7134_BOARD_UPMOST_PURPLE_TV: case SAA7134_BOARD_HAUPPAUGE_HVR1110: + case SAA7134_BOARD_BEHOLD_607_9FM: + case SAA7134_BOARD_BEHOLD_M6: dev->has_remote = SAA7134_REMOTE_I2C; break; case SAA7134_BOARD_AVERMEDIA_A169_B: diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 800b397f8f16..d3322c3018f2 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -334,6 +334,7 @@ static int attach_inform(struct i2c_client *client) case 0x7a: case 0x47: case 0x71: + case 0x2d: { struct IR_i2c *ir = i2c_get_clientdata(client); d1printk("%s i2c IR detected (%s).\n", @@ -439,6 +440,7 @@ static char *i2c_devs[128] = { [ 0xa0 >> 1 ] = "eeprom", [ 0xc0 >> 1 ] = "tuner (analog)", [ 0x86 >> 1 ] = "tda9887", + [ 0x5a >> 1 ] = "remote control", }; static void do_i2c_scan(char *name, struct i2c_client *c) diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 8cfeb2bde90f..7f4212928e9f 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -52,6 +52,11 @@ module_param(repeat_period, int, 0644); MODULE_PARM_DESC(repeat_period, "repeat period between " "keypresses when key is down"); +static unsigned int disable_other_ir; +module_param(disable_other_ir, int, 0644); +MODULE_PARM_DESC(disable_other_ir, "disable full codes of " + "alternative remotes from other manufacturers"); + #define dprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) #define i2cdprintk(fmt, arg...) if (ir_debug) \ @@ -154,6 +159,45 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } + +static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char data[12]; + u32 gpio; + + struct saa7134_dev *dev = ir->c.adapter->algo_data; + + /* rising SAA7134_GPIO_GPRESCAN reads the status */ + saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + + gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); + + if (0x400000 &~ gpio) + return 0; /* No button press */ + + ir->c.addr = 0x5a >> 1; + + if (12 != i2c_master_recv(&ir->c, data, 12)) { + i2cdprintk("read error\n"); + return -EIO; + } + /* IR of this card normally decode signals NEC-standard from + * - Sven IHOO MT 5.1R remote. xxyye718 + * - Sven DVD HD-10xx remote. xxyyf708 + * - BBK ... + * - mayby others + * So, skip not our, if disable full codes mode. + */ + if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir) + return 0; + + *ir_key = data[9]; + *ir_raw = data[9]; + + return 1; +} + void saa7134_input_irq(struct saa7134_dev *dev) { struct card_ir *ir = dev->remote; @@ -288,6 +332,16 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_MANLI_MTV001: case SAA7134_BOARD_MANLI_MTV002: case SAA7134_BOARD_BEHOLD_409FM: + case SAA7134_BOARD_BEHOLD_401: + case SAA7134_BOARD_BEHOLD_403: + case SAA7134_BOARD_BEHOLD_403FM: + case SAA7134_BOARD_BEHOLD_405: + case SAA7134_BOARD_BEHOLD_405FM: + case SAA7134_BOARD_BEHOLD_407: + case SAA7134_BOARD_BEHOLD_407FM: + case SAA7134_BOARD_BEHOLD_409: + case SAA7134_BOARD_BEHOLD_505FM: + case SAA7134_BOARD_BEHOLD_507_9FM: ir_codes = ir_codes_manli; mask_keycode = 0x001f00; mask_keyup = 0x004000; @@ -458,6 +512,12 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) ir->get_key = get_key_hvr1110; ir->ir_codes = ir_codes_hauppauge_new; break; + case SAA7134_BOARD_BEHOLD_607_9FM: + case SAA7134_BOARD_BEHOLD_M6: + snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); + ir->get_key = get_key_beholdm6xx; + ir->ir_codes = ir_codes_behold; + break; default: dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); break; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 3e77aeb7974f..ce450304fb53 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -240,6 +240,19 @@ struct saa7134_format { #define SAA7134_BOARD_SABRENT_TV_PCB05 115 #define SAA7134_BOARD_10MOONSTVMASTER3 116 #define SAA7134_BOARD_AVERMEDIA_SUPER_007 117 +#define SAA7134_BOARD_BEHOLD_401 118 +#define SAA7134_BOARD_BEHOLD_403 119 +#define SAA7134_BOARD_BEHOLD_403FM 120 +#define SAA7134_BOARD_BEHOLD_405 121 +#define SAA7134_BOARD_BEHOLD_405FM 122 +#define SAA7134_BOARD_BEHOLD_407 123 +#define SAA7134_BOARD_BEHOLD_407FM 124 +#define SAA7134_BOARD_BEHOLD_409 125 +#define SAA7134_BOARD_BEHOLD_505FM 126 +#define SAA7134_BOARD_BEHOLD_507_9FM 127 +#define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 +#define SAA7134_BOARD_BEHOLD_607_9FM 129 +#define SAA7134_BOARD_BEHOLD_M6 130 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 diff --git a/include/media/ir-common.h b/include/media/ir-common.h index b904d3257260..9c2fc09a7133 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -140,6 +140,7 @@ extern IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE]; #endif -- cgit v1.2.3 From d05051c82e0e8ff748e9c9a06a061bda3ad656e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Jan 2008 07:33:03 -0300 Subject: V4L/DVB (6997): Replace a very dirty hack on videobuf for a clean wait_event In order to videobuf_iolock to work, mmap_mapper should be called first. Otherwise, an OOPS is generated. On some cases, .mmap file handler used to took some time to be called. On those situations, mmap_mmapper() were called after iolock. This patch properly waits for mmap_mapper to be called, otherwise generating an error. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-core.c | 15 +++++++++++---- include/media/videobuf-core.h | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 43fe3f78c8df..c3adbd686ffe 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -98,13 +98,15 @@ int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, MAGIC_CHECK(vb->magic, MAGIC_BUFFER); MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - /* FIXME: This is required to avoid OOPS on some cases, + /* This is required to avoid OOPS on some cases, since mmap_mapper() method should be called before _iolock. On some cases, the mmap_mapper() is called only after scheduling. - - However, this way is just too dirty! Better to wait for some event. */ - schedule_timeout(HZ); + wait_event_timeout(vb->done, q->is_mmapped, msecs_to_jiffies(100)); + if (!q->is_mmapped) { + printk(KERN_ERR "Error: mmap_mapper() never called!\n"); + return -EINVAL; + } return CALL(q, iolock, q, vb, fbuf); } @@ -300,7 +302,11 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); + rc = CALL(q, mmap_free, q); + + q->is_mmapped = 0; + if (rc < 0) return rc; @@ -1022,6 +1028,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, mutex_lock(&q->lock); retval = CALL(q, mmap_mapper, q, vma); + q->is_mmapped = 1; mutex_unlock(&q->lock); return retval; diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 7aa7a7b64c1b..97f14d469595 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h @@ -164,6 +164,8 @@ struct videobuf_queue { unsigned int streaming:1; unsigned int reading:1; + unsigned int is_mmapped:1; + /* capture via mmap() + ioctl(QBUF/DQBUF) */ struct list_head stream; -- cgit v1.2.3 From f234081bc564c69eb0e2cd4e957ad1cbae4a6144 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 10 Jan 2008 01:22:39 -0300 Subject: V4L/DVB (7002): cx25840: Add basic CX23885 AVCore support The cx23885/7/8 PCIe bridge has an internal AVCore modelled on the cx2584x family. Many of the registers positions are identical but some moved. The register values are also different because the different bridges run at different clock rates. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-audio.c | 65 ++++++-- drivers/media/video/cx25840/cx25840-core.c | 219 ++++++++++++++++++++++--- drivers/media/video/cx25840/cx25840-core.h | 1 + drivers/media/video/cx25840/cx25840-firmware.c | 5 + include/media/cx25840.h | 19 +++ 5 files changed, 272 insertions(+), 37 deletions(-) (limited to 'include') diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 51fc0af01578..d6421e1e8f6a 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c @@ -32,11 +32,17 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* common for all inputs and rates */ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ - cx25840_write(client, 0x127, 0x50); + if (!state->is_cx23885) + cx25840_write(client, 0x127, 0x50); if (state->aud_input != CX25840_AUDIO_SERIAL) { switch (freq) { case 32000: + if (state->is_cx23885) { + /* We don't have register values + * so avoid destroying registers. */ + break; + } /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x1006040f); @@ -53,6 +59,11 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) break; case 44100: + if (state->is_cx23885) { + /* We don't have register values + * so avoid destroying registers. */ + break; + } /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x1009040f); @@ -69,6 +80,11 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) break; case 48000: + if (state->is_cx23885) { + /* We don't have register values + * so avoid destroying registers. */ + break; + } /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x100a040f); @@ -87,6 +103,11 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) } else { switch (freq) { case 32000: + if (state->is_cx23885) { + /* We don't have register values + * so avoid destroying registers. */ + break; + } /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x1e08040f); @@ -109,6 +130,12 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) break; case 44100: + if (state->is_cx23885) { + /* We don't have register values + * so avoid destroying registers. */ + break; + } + /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x1809040f); @@ -128,22 +155,33 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) break; case 48000: - /* VID_PLL and AUX_PLL */ - cx25840_write4(client, 0x108, 0x180a040f); + if (!state->is_cx23885) { + /* VID_PLL and AUX_PLL */ + cx25840_write4(client, 0x108, 0x180a040f); - /* AUX_PLL_FRAC */ - cx25840_write4(client, 0x110, 0x0098d6e5); + /* AUX_PLL_FRAC */ + cx25840_write4(client, 0x110, 0x0098d6e5); + } if (state->is_cx25836) break; - /* src1_ctl = 0x08010000 */ - cx25840_write4(client, 0x8f8, 0x08018000); + if (!state->is_cx23885) { + /* src1_ctl */ + cx25840_write4(client, 0x8f8, 0x08018000); - /* src3/4/6_ctl = 0x08020000 */ - cx25840_write4(client, 0x900, 0x08015555); - cx25840_write4(client, 0x904, 0x08015555); - cx25840_write4(client, 0x90c, 0x08015555); + /* src3/4/6_ctl */ + cx25840_write4(client, 0x900, 0x08015555); + cx25840_write4(client, 0x904, 0x08015555); + cx25840_write4(client, 0x90c, 0x08015555); + } else { + + cx25840_write4(client, 0x8f8, 0x0801867c); + + cx25840_write4(client, 0x900, 0x08014faa); + cx25840_write4(client, 0x904, 0x08014faa); + cx25840_write4(client, 0x90c, 0x08014faa); + } break; } } @@ -188,6 +226,11 @@ void cx25840_audio_set_path(struct i2c_client *client) /* deassert soft reset */ cx25840_and_or(client, 0x810, ~0x1, 0x00); + + if (state->is_cx23885) { + /* Ensure the controller is running when we exit */ + cx25840_and_or(client, 0x803, ~0x10, 0x10); + } } static int get_volume(struct i2c_client *client) diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 0d3d24aff504..756a1eeb274e 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -13,6 +13,8 @@ * NTSC sliced VBI support by Christopher Neufeld * with additional fixes by Hans Verkuil . * + * CX23885 support by Steven Toth . + * * 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 @@ -255,6 +257,96 @@ static void cx25840_initialize(struct i2c_client *client) cx25840_and_or(client, 0x803, ~0x10, 0x10); } +static void cx23885_initialize(struct i2c_client *client) +{ + DEFINE_WAIT(wait); + struct cx25840_state *state = i2c_get_clientdata(client); + struct workqueue_struct *q; + + /* Internal Reset */ + cx25840_and_or(client, 0x102, ~0x01, 0x01); + cx25840_and_or(client, 0x102, ~0x01, 0x00); + + /* Stop microcontroller */ + cx25840_and_or(client, 0x803, ~0x10, 0x00); + + /* DIF in reset? */ + cx25840_write(client, 0x398, 0); + + /* Trust the default xtal, no division */ + /* This changes for the cx23888 products */ + cx25840_write(client, 0x2, 0x76); + + /* Bring down the regulator for AUX clk */ + cx25840_write(client, 0x1, 0x40); + + /* Sys PLL frac */ + cx25840_write4(client, 0x11c, 0x01d1744c); + + /* Sys PLL int */ + cx25840_write4(client, 0x118, 0x00000416); + + /* Disable DIF bypass */ + cx25840_write4(client, 0x33c, 0x00000001); + + /* DIF Src phase inc */ + cx25840_write4(client, 0x340, 0x0df7df83); + + /* Vid PLL frac */ + cx25840_write4(client, 0x10c, 0x01b6db7b); + + /* Vid PLL int */ + cx25840_write4(client, 0x108, 0x00000512); + + /* Luma */ + cx25840_write4(client, 0x414, 0x00107d12); + + /* Chroma */ + cx25840_write4(client, 0x420, 0x3d008282); + + /* Aux PLL frac */ + cx25840_write4(client, 0x114, 0x017dbf48); + + /* Aux PLL int */ + cx25840_write4(client, 0x110, 0x000a030e); + + /* ADC2 input select */ + cx25840_write(client, 0x102, 0x10); + + /* VIN1 & VIN5 */ + cx25840_write(client, 0x103, 0x11); + + /* Enable format auto detect */ + cx25840_write(client, 0x400, 0); + /* Fast subchroma lock */ + /* White crush, Chroma AGC & Chroma Killer enabled */ + cx25840_write(client, 0x401, 0xe8); + + /* Select AFE clock pad output source */ + cx25840_write(client, 0x144, 0x05); + + /* Do the firmware load in a work handler to prevent. + Otherwise the kernel is blocked waiting for the + bit-banging i2c interface to finish uploading the + firmware. */ + INIT_WORK(&state->fw_work, cx25840_work_handler); + init_waitqueue_head(&state->fw_wait); + q = create_singlethread_workqueue("cx25840_fw"); + prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); + queue_work(q, &state->fw_work); + schedule(); + finish_wait(&state->fw_wait, &wait); + destroy_workqueue(q); + + cx25840_vbi_setup(client); + + /* (re)set input */ + set_input(client, state->vid_input, state->aud_input); + + /* start microcontroller */ + cx25840_and_or(client, 0x803, ~0x10, 0x10); +} + /* ----------------------------------------------------------------------- */ static void input_change(struct i2c_client *client) @@ -318,9 +410,22 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp vid_input <= CX25840_COMPOSITE8); u8 reg; - v4l_dbg(1, cx25840_debug, client, "decoder set video input %d, audio input %d\n", - vid_input, aud_input); + v4l_dbg(1, cx25840_debug, client, + "decoder set video input %d, audio input %d\n", + vid_input, aud_input); + if (vid_input >= CX25840_VIN1_CH1) { + v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n", + vid_input); + reg = vid_input & 0xff; + if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON) + is_composite = 0; + else + is_composite = 1; + + v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n", + reg, is_composite); + } else if (is_composite) { reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); } else { @@ -330,7 +435,8 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp if ((vid_input & ~0xff0) || luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 || chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { - v4l_err(client, "0x%04x is not a valid video input!\n", vid_input); + v4l_err(client, "0x%04x is not a valid video input!\n", + vid_input); return -EINVAL; } reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4); @@ -343,31 +449,49 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp } } - switch (aud_input) { - case CX25840_AUDIO_SERIAL: - /* do nothing, use serial audio input */ - break; - case CX25840_AUDIO4: reg &= ~0x30; break; - case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break; - case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break; - case CX25840_AUDIO7: reg &= ~0xc0; break; - case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; + /* The caller has previously prepared the correct routing + * configuration in reg (for the cx23885) so we have no + * need to attempt to flip bits for earlier av decoders. + */ + if (!state->is_cx23885) { + switch (aud_input) { + case CX25840_AUDIO_SERIAL: + /* do nothing, use serial audio input */ + break; + case CX25840_AUDIO4: reg &= ~0x30; break; + case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break; + case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break; + case CX25840_AUDIO7: reg &= ~0xc0; break; + case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; - default: - v4l_err(client, "0x%04x is not a valid audio input!\n", aud_input); - return -EINVAL; + default: + v4l_err(client, "0x%04x is not a valid audio input!\n", + aud_input); + return -EINVAL; + } } cx25840_write(client, 0x103, reg); + /* Set INPUT_MODE to Composite (0) or S-Video (1) */ cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); - /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ - cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); - /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ - if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) - cx25840_and_or(client, 0x102, ~0x4, 4); - else - cx25840_and_or(client, 0x102, ~0x4, 0); + + if (!state->is_cx23885) { + /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ + cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); + /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */ + if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) + cx25840_and_or(client, 0x102, ~0x4, 4); + else + cx25840_and_or(client, 0x102, ~0x4, 0); + } else { + if (is_composite) + /* ADC2 input select channel 2 */ + cx25840_and_or(client, 0x102, ~0x2, 0); + else + /* ADC2 input select channel 3 */ + cx25840_and_or(client, 0x102, ~0x2, 2); + } state->vid_input = vid_input; state->aud_input = aud_input; @@ -375,6 +499,25 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp cx25840_audio_set_path(client); input_change(client); } + + if (state->is_cx23885) { + /* Audio channel 1 src : Parallel 1 */ + cx25840_write(client, 0x124, 0x03); + + /* Select AFE clock pad output source */ + cx25840_write(client, 0x144, 0x05); + + /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */ + cx25840_write(client, 0x914, 0xa0); + + /* I2S_OUT_CTL: + * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 + * I2S_OUT_MASTER_MODE = Master + */ + cx25840_write(client, 0x918, 0xa0); + cx25840_write(client, 0x919, 0x01); + } + return 0; } @@ -853,6 +996,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, state->is_initialized = 1; if (state->is_cx25836) cx25836_initialize(client); + else if (state->is_cx23885) + cx23885_initialize(client); else cx25840_initialize(client); } @@ -870,6 +1015,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; + if (cmd == VIDIOC_DBG_G_REGISTER) reg->val = cx25840_read(client, reg->reg & 0x0fff); else @@ -886,14 +1032,26 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, case VIDIOC_STREAMON: v4l_dbg(1, cx25840_debug, client, "enable output\n"); - cx25840_write(client, 0x115, state->is_cx25836 ? 0x0c : 0x8c); - cx25840_write(client, 0x116, state->is_cx25836 ? 0x04 : 0x07); + if (state->is_cx23885) { + u8 v = (cx25840_read(client, 0x421) | 0x0b); + cx25840_write(client, 0x421, v); + } else { + cx25840_write(client, 0x115, + state->is_cx25836 ? 0x0c : 0x8c); + cx25840_write(client, 0x116, + state->is_cx25836 ? 0x04 : 0x07); + } break; case VIDIOC_STREAMOFF: v4l_dbg(1, cx25840_debug, client, "disable output\n"); - cx25840_write(client, 0x115, 0x00); - cx25840_write(client, 0x116, 0x00); + if (state->is_cx23885) { + u8 v = cx25840_read(client, 0x421) & ~(0x0b); + cx25840_write(client, 0x421, v); + } else { + cx25840_write(client, 0x115, 0x00); + cx25840_write(client, 0x116, 0x00); + } break; case VIDIOC_LOG_STATUS: @@ -1056,6 +1214,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, case VIDIOC_INT_RESET: if (state->is_cx25836) cx25836_initialize(client); + else if (state->is_cx23885) + cx23885_initialize(client); else cx25840_initialize(client); break; @@ -1086,6 +1246,7 @@ static int cx25840_probe(struct i2c_client *client) device_id = cx25840_read(client, 0x101) << 8; device_id |= cx25840_read(client, 0x100); + v4l_dbg(1, cx25840_debug, client, "device_id = 0x%04x\n", device_id); /* The high byte of the device ID should be * 0x83 for the cx2583x and 0x84 for the cx2584x */ @@ -1094,6 +1255,10 @@ static int cx25840_probe(struct i2c_client *client) } else if ((device_id & 0xff00) == 0x8400) { id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); + } else if (device_id == 0x0000) { + id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; + } else if (device_id == 0x1313) { + id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; } else { v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); @@ -1115,6 +1280,7 @@ static int cx25840_probe(struct i2c_client *client) i2c_set_clientdata(client, state); state->c = client; state->is_cx25836 = ((device_id & 0xff00) == 0x8300); + state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313); state->vid_input = CX25840_COMPOSITE7; state->aud_input = CX25840_AUDIO8; state->audclk_freq = 48000; @@ -1124,6 +1290,7 @@ static int cx25840_probe(struct i2c_client *client) state->vbi_line_offset = 8; state->id = id; state->rev = device_id; + return 0; } diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index ea669b1f084d..95093edc9186 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h @@ -47,6 +47,7 @@ struct cx25840_state { u32 id; u32 rev; int is_cx25836; + int is_cx23885; int is_initialized; wait_queue_head_t fw_wait; /* wake up when the fw load is finished */ struct work_struct fw_work; /* work entry for fw load */ diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index e852024a5ea3..1ddf724a2c74 100644 --- a/drivers/media/video/cx25840/cx25840-firmware.c +++ b/drivers/media/video/cx25840/cx25840-firmware.c @@ -24,6 +24,7 @@ #include "cx25840-core.h" #define FWFILE "v4l-cx25840.fw" +#define FWFILE_CX23885 "v4l-cx23885-avcore-01.fw" /* * Mike Isely - The FWSEND parameter controls the @@ -92,10 +93,14 @@ static int fw_write(struct i2c_client *client, u8 * data, int size) int cx25840_loadfw(struct i2c_client *client) { + struct cx25840_state *state = i2c_get_clientdata(client); const struct firmware *fw = NULL; u8 buffer[4], *ptr; int size, send, retval; + if (state->is_cx23885) + firmware = FWFILE_CX23885; + if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { v4l_err(client, "unable to open firmware %s\n", firmware); return -EINVAL; diff --git a/include/media/cx25840.h b/include/media/cx25840.h index 8e7e52d659a0..cd599ad29fb2 100644 --- a/include/media/cx25840.h +++ b/include/media/cx25840.h @@ -49,6 +49,25 @@ enum cx25840_video_input { CX25840_SVIDEO2 = 0x620, CX25840_SVIDEO3 = 0x730, CX25840_SVIDEO4 = 0x840, + + /* Allow frames to specify specific input configurations */ + CX25840_VIN1_CH1 = 0x80000000, + CX25840_VIN2_CH1 = 0x80000001, + CX25840_VIN3_CH1 = 0x80000002, + CX25840_VIN4_CH1 = 0x80000003, + CX25840_VIN5_CH1 = 0x80000004, + CX25840_VIN6_CH1 = 0x80000005, + CX25840_VIN7_CH1 = 0x80000006, + CX25840_VIN8_CH1 = 0x80000007, + CX25840_VIN4_CH2 = 0x80000000, + CX25840_VIN5_CH2 = 0x80000010, + CX25840_VIN6_CH2 = 0x80000020, + CX25840_NONE_CH2 = 0x80000030, + CX25840_VIN7_CH3 = 0x80000000, + CX25840_VIN8_CH3 = 0x80000040, + CX25840_NONE0_CH3 = 0x80000080, + CX25840_NONE1_CH3 = 0x800000c0, + CX25840_SVIDEO_ON = 0x80000100, }; enum cx25840_audio_input { -- cgit v1.2.3 From 27c685a4b09b5e391023d769cddb97e4fcb3b9e1 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 5 Jan 2008 16:50:14 -0300 Subject: V4L/DVB (7042): xc5000: Tuner analog support From Zhang: This an updated patch that adds analog support for the xc5000 tuner driver. it was tested on a Pinnacle PCTV HD 800i card (patches to follow). Patch commited as-is, cleanup to follow ... Steve. Signed-off-by: Chaogui Zhang Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.tuner | 1 + drivers/media/dvb/frontends/xc5000.c | 213 ++++++++++++++++++++++++++----- drivers/media/dvb/frontends/xc5000.h | 12 +- drivers/media/video/tuner-core.c | 20 +++ drivers/media/video/tuner-types.c | 4 + include/media/tuner.h | 1 + 6 files changed, 213 insertions(+), 38 deletions(-) (limited to 'include') diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index 2211c8eac643..0e2394695bb8 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -73,3 +73,4 @@ tuner=71 - Xceive xc2028/xc3028 tuner tuner=72 - Thomson FE6600 tuner=73 - Samsung TCPG 6121P30A tuner=75 - Philips TEA5761 FM Radio +tuner=76 - Xceive 5000 tuner diff --git a/drivers/media/dvb/frontends/xc5000.c b/drivers/media/dvb/frontends/xc5000.c index a036530ee4b4..28048d5307a2 100644 --- a/drivers/media/dvb/frontends/xc5000.c +++ b/drivers/media/dvb/frontends/xc5000.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -56,6 +57,10 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); #define XC_RESULT_I2C_READ_FAILURE 3 #define XC_RESULT_OUT_OF_RANGE 5 +/* Product id */ +#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000 +#define XC_PRODUCT_ID_FW_LOADED 0x1388 + /* Registers */ #define XREG_INIT 0x00 #define XREG_VIDEO_MODE 0x01 @@ -122,7 +127,29 @@ typedef struct { } XC_TV_STANDARD; /* Tuner standards */ -#define DTV6 17 +#define MN_NTSC_PAL_BTSC 0 +#define MN_NTSC_PAL_A2 1 +#define MN_NTSC_PAL_EIAJ 2 +#define MN_NTSC_PAL_Mono 3 +#define BG_PAL_A2 4 +#define BG_PAL_NICAM 5 +#define BG_PAL_MONO 6 +#define I_PAL_NICAM 7 +#define I_PAL_NICAM_MONO 8 +#define DK_PAL_A2 9 +#define DK_PAL_NICAM 10 +#define DK_PAL_MONO 11 +#define DK_SECAM_A2DK1 12 +#define DK_SECAM_A2LDK3 13 +#define DK_SECAM_A2MONO 14 +#define L_SECAM_NICAM 15 +#define LC_SECAM_NICAM 16 +#define DTV6 17 +#define DTV8 18 +#define DTV7_8 19 +#define DTV7 20 +#define FM_Radio_INPUT2 21 +#define FM_Radio_INPUT1 22 XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, @@ -184,12 +211,13 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) dprintk(1, "%s()\n", __FUNCTION__); - if (priv->cfg->tuner_reset) { - ret = priv->cfg->tuner_reset(fe); + if (priv->cfg->tuner_callback) { + ret = priv->cfg->tuner_callback(priv->cfg->video_dev, + XC5000_TUNER_RESET, 0); if (ret) printk(KERN_ERR "xc5000: reset failed\n"); } else - printk(KERN_ERR "xc5000: no tuner reset function, fatal\n"); + printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); } static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) @@ -259,7 +287,6 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, u8 i2c_sequence[]) index=0; while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) { - len = i2c_sequence[index]* 256 + i2c_sequence[index+1]; if (len == 0x0000) { /* RESET command */ @@ -311,7 +338,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, u16 VideoMode, u16 AudioMode) { int ret; - dprintk(1, "%s(%d,%d)\n", __FUNCTION__, VideoMode, AudioMode); + dprintk(1, "%s(0x%04x,0x%04x)\n", __FUNCTION__, VideoMode, AudioMode); dprintk(1, "%s() Standard = %s\n", __FUNCTION__, XC5000_Standard[priv->video_standard].Name); @@ -325,7 +352,11 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, static int xc_shutdown(struct xc5000_priv *priv) { - return xc_write_reg(priv, XREG_POWER_DOWN, 0); + return 0; + /* Fixme: cannot bring tuner back alive once shutdown + * without reloading the driver modules. + * return xc_write_reg(priv, XREG_POWER_DOWN, 0); + */ } static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) @@ -349,7 +380,7 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz) { u16 freq_code; - dprintk(1, "%s(%d)\n", __FUNCTION__, freq_hz); + dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz); if ((freq_hz > xc5000_tuner_ops.info.frequency_max) || (freq_hz < xc5000_tuner_ops.info.frequency_min)) @@ -457,7 +488,7 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) { int found = 0; - dprintk(1, "%s(%d)\n", __FUNCTION__, freq_hz); + dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz); if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) return 0; @@ -480,7 +511,7 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) }; if (i2c_transfer(priv->i2c, msg, 2) != 2) { - printk(KERN_WARNING "xc5000 I2C read failed\n"); + printk(KERN_WARNING "xc5000: I2C read failed\n"); return -EREMOTEIO; } @@ -494,7 +525,7 @@ static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) .flags = 0, .buf = buf, .len = len }; if (i2c_transfer(priv->i2c, &msg, 1) != 1) { - printk(KERN_ERR "xc5000 I2C write failed (len=%i)\n", + printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", (int)len); return -EREMOTEIO; } @@ -519,16 +550,11 @@ static int xc5000_fwupload(struct dvb_frontend* fe) const struct firmware *fw; int ret; - if (!priv->cfg->request_firmware) { - printk(KERN_ERR "xc5000: no firmware callback, fatal\n"); - return -EIO; - } - /* request the firmware, this will block and timeout */ printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", XC5000_DEFAULT_FIRMWARE); - ret = priv->cfg->request_firmware(fe, &fw, XC5000_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c->dev); if (ret) { printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); ret = XC_RESULT_RESET_FAILURE; @@ -601,7 +627,6 @@ static int xc5000_set_params(struct dvb_frontend *fe, dprintk(1, "%s() frequency=%d (Hz)\n", __FUNCTION__, params->frequency); - switch(params->u.vsb.modulation) { case VSB_8: case VSB_16: @@ -658,6 +683,93 @@ static int xc5000_set_params(struct dvb_frontend *fe, return 0; } +static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); + +static int xc5000_set_analog_params(struct dvb_frontend *fe, + struct analog_parameters *params) +{ + struct xc5000_priv *priv = fe->tuner_priv; + int ret; + + if(priv->fwloaded == 0) + xc_load_fw_and_init_tuner(fe); + + dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", + __FUNCTION__, params->frequency); + + priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */ + + /* params->frequency is in units of 62.5khz */ + priv->freq_hz = params->frequency * 62500; + + /* FIX ME: Some video standards may have several possible audio + standards. We simply default to one of them here. + */ + if(params->std & V4L2_STD_MN) { + /* default to BTSC audio standard */ + priv->video_standard = MN_NTSC_PAL_BTSC; + goto tune_channel; + } + + if(params->std & V4L2_STD_PAL_BG) { + /* default to NICAM audio standard */ + priv->video_standard = BG_PAL_NICAM; + goto tune_channel; + } + + if(params->std & V4L2_STD_PAL_I) { + /* default to NICAM audio standard */ + priv->video_standard = I_PAL_NICAM; + goto tune_channel; + } + + if(params->std & V4L2_STD_PAL_DK) { + /* default to NICAM audio standard */ + priv->video_standard = DK_PAL_NICAM; + goto tune_channel; + } + + if(params->std & V4L2_STD_SECAM_DK) { + /* default to A2 DK1 audio standard */ + priv->video_standard = DK_SECAM_A2DK1; + goto tune_channel; + } + + if(params->std & V4L2_STD_SECAM_L) { + priv->video_standard = L_SECAM_NICAM; + goto tune_channel; + } + + if(params->std & V4L2_STD_SECAM_LC) { + priv->video_standard = LC_SECAM_NICAM; + goto tune_channel; + } + +tune_channel: + ret = xc_SetSignalSource(priv, priv->rf_mode); + if (ret != XC_RESULT_SUCCESS) { + printk(KERN_ERR + "xc5000: xc_SetSignalSource(%d) failed\n", + priv->rf_mode); + return -EREMOTEIO; + } + + ret = xc_SetTVStandard(priv, + XC5000_Standard[priv->video_standard].VideoMode, + XC5000_Standard[priv->video_standard].AudioMode); + if (ret != XC_RESULT_SUCCESS) { + printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n"); + return -EREMOTEIO; + } + + xc_tune_channel(priv, priv->freq_hz); + + if (debug) + xc_debug_dump(priv); + + return 0; +} + static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) { struct xc5000_priv *priv = fe->tuner_priv; @@ -670,6 +782,7 @@ static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw) { struct xc5000_priv *priv = fe->tuner_priv; dprintk(1, "%s()\n", __FUNCTION__); + *bw = priv->bandwidth; return 0; } @@ -691,13 +804,12 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status) static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) { struct xc5000_priv *priv = fe->tuner_priv; - int ret; + int ret = 0; if (priv->fwloaded == 0) { ret = xc5000_fwupload(fe); if (ret != XC_RESULT_SUCCESS) return ret; - priv->fwloaded = 1; } @@ -720,9 +832,27 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) static int xc5000_sleep(struct dvb_frontend *fe) { struct xc5000_priv *priv = fe->tuner_priv; + int ret; + dprintk(1, "%s()\n", __FUNCTION__); - return xc_shutdown(priv); + /* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized + * once shutdown without reloading the driver. Maybe I am not + * doing something right. + * + */ + + ret = xc_shutdown(priv); + if(ret != XC_RESULT_SUCCESS) { + printk(KERN_ERR + "xc5000: %s() unable to shutdown tuner\n", + __FUNCTION__); + return -EREMOTEIO; + } + else { + /* priv->fwloaded = 0; */ + return XC_RESULT_SUCCESS; + } } static int xc5000_init(struct dvb_frontend *fe) @@ -757,14 +887,15 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { .frequency_step = 50000, }, - .release = xc5000_release, - .init = xc5000_init, - .sleep = xc5000_sleep, + .release = xc5000_release, + .init = xc5000_init, + .sleep = xc5000_sleep, - .set_params = xc5000_set_params, - .get_frequency = xc5000_get_frequency, - .get_bandwidth = xc5000_get_bandwidth, - .get_status = xc5000_get_status + .set_params = xc5000_set_params, + .set_analog_params = xc5000_set_analog_params, + .get_frequency = xc5000_get_frequency, + .get_bandwidth = xc5000_get_bandwidth, + .get_status = xc5000_get_status }; struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe, @@ -783,14 +914,33 @@ struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe, priv->cfg = cfg; priv->bandwidth = BANDWIDTH_6_MHZ; priv->i2c = i2c; - priv->fwloaded = 0; + /* Check if firmware has been loaded. It is possible that another + instance of the driver has loaded the firmware. + */ if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) { kfree(priv); return NULL; } - if ((id != 0x2000) && (id != 0x1388)) { + switch(id) { + case XC_PRODUCT_ID_FW_LOADED: + printk(KERN_INFO + "xc5000: Successfully identified at address 0x%02x\n", + cfg->i2c_address); + printk(KERN_INFO + "xc5000: Firmware has been loaded previously\n"); + priv->fwloaded = 1; + break; + case XC_PRODUCT_ID_FW_NOT_LOADED: + printk(KERN_INFO + "xc5000: Successfully identified at address 0x%02x\n", + cfg->i2c_address); + printk(KERN_INFO + "xc5000: Firmware has not been loaded previously\n"); + priv->fwloaded = 0; + break; + default: printk(KERN_ERR "xc5000: Device not found at addr 0x%02x (0x%x)\n", cfg->i2c_address, id); @@ -798,9 +948,6 @@ struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe, return NULL; } - printk(KERN_INFO "xc5000: successfully identified at address 0x%02x\n", - cfg->i2c_address); - memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops, sizeof(struct dvb_tuner_ops)); diff --git a/drivers/media/dvb/frontends/xc5000.h b/drivers/media/dvb/frontends/xc5000.h index 941b31948133..85b2d438fa41 100644 --- a/drivers/media/dvb/frontends/xc5000.h +++ b/drivers/media/dvb/frontends/xc5000.h @@ -28,13 +28,15 @@ struct dvb_frontend; struct i2c_adapter; struct xc5000_config { - u8 i2c_address; - u32 if_khz; - int (*request_firmware)(struct dvb_frontend *fe, - const struct firmware **fw, char *name); - int (*tuner_reset)(struct dvb_frontend* fe); + u8 i2c_address; + u32 if_khz; + void *video_dev; + int (*tuner_callback) (void *dev, int command, int arg); }; +/* xc5000 callback command */ +#define XC5000_TUNER_RESET 0 + #if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE) extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 35976e6cb1b8..16cdeeafeb6c 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -27,6 +27,7 @@ #include "tuner-xc2028.h" #include "tuner-simple.h" #include "tda9887.h" +#include "xc5000.h" #define UNSET (-1U) @@ -329,6 +330,8 @@ static void attach_tda829x(struct tuner *t) tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); } +static struct xc5000_config xc5000_cfg; + static void set_type(struct i2c_client *c, unsigned int type, unsigned int new_mode_mask, unsigned int new_config, int (*tuner_callback) (void *dev, int command,int arg)) @@ -428,6 +431,23 @@ static void set_type(struct i2c_client *c, unsigned int type, case TUNER_TDA9887: tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr); break; + case TUNER_XC5000: + xc5000_cfg.i2c_address = t->i2c->addr; + xc5000_cfg.if_khz = 5380; + xc5000_cfg.video_dev = c->adapter->algo_data; + xc5000_cfg.tuner_callback = t->tuner_callback; + if (!xc5000_attach(&t->fe, t->i2c->adapter, &xc5000_cfg)) { + t->type = TUNER_ABSENT; + t->mode_mask = T_UNINITIALIZED; + return; + } + { + struct dvb_tuner_ops *xc_tuner_ops; + xc_tuner_ops = &t->fe.ops.tuner_ops; + if(xc_tuner_ops->init != NULL) + xc_tuner_ops->init(&t->fe); + } + break; default: attach_simple_tuner(t); break; diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index e2cd05a05802..883047f9c28c 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c @@ -1475,6 +1475,10 @@ struct tunertype tuners[] = { .name = "Philips TEA5761 FM Radio", /* see tea5767.c for details */ }, + [TUNER_XC5000] = { /* Xceive 5000 */ + .name = "Xceive 5000 tuner", + /* see xc5000.c for details */ + }, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); diff --git a/include/media/tuner.h b/include/media/tuner.h index 97be269afbee..1bf24a6ed8f1 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -121,6 +121,7 @@ #define TUNER_SAMSUNG_TCPG_6121P30A 73 /* Hauppauge PVR-500 PAL */ #define TUNER_TDA9887 74 /* This tuner should be used only internally */ #define TUNER_TEA5761 75 /* Only FM Radio Tuner */ +#define TUNER_XC5000 76 /* Xceive Silicon Tuner */ /* tv card specific */ #define TDA9887_PRESENT (1<<0) -- cgit v1.2.3 From 9121106a7f149f9702ed7c2ac0d86e9feb54ede8 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 22 Jan 2008 01:00:33 -0300 Subject: V4L/DVB (7058): IR corrections for the Pinnacle 800i IR corrections for the Pinnacle 800i Signed-off-by: Steven Toth Signed-off-by: Chaogui Zhang Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-keymaps.c | 35 +++++++++++++++++++++++++++++++++++ drivers/media/video/cx88/cx88-input.c | 6 +++++- include/media/ir-common.h | 1 + 3 files changed, 41 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index ee2c69e3152a..a4a937c90534 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -1849,6 +1849,41 @@ IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = { EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce); +/* Pinnacle PCTV HD 800i mini remote */ +IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE] = { + + [0x0f] = KEY_1, + [0x15] = KEY_2, + [0x10] = KEY_3, + [0x18] = KEY_4, + [0x1b] = KEY_5, + [0x1e] = KEY_6, + [0x11] = KEY_7, + [0x21] = KEY_8, + [0x12] = KEY_9, + [0x27] = KEY_0, + + [0x24] = KEY_ZOOM, + [0x2a] = KEY_SUBTITLE, + + [0x00] = KEY_MUTE, + [0x01] = KEY_ENTER, /* Pinnacle Logo */ + [0x39] = KEY_POWER, + + [0x03] = KEY_VOLUMEUP, + [0x09] = KEY_VOLUMEDOWN, + [0x06] = KEY_CHANNELUP, + [0x0c] = KEY_CHANNELDOWN, + + [0x2d] = KEY_REWIND, + [0x30] = KEY_PLAYPAUSE, + [0x33] = KEY_FASTFORWARD, + [0x3c] = KEY_STOP, + [0x36] = KEY_RECORD, + [0x3f] = KEY_EPG, /* Labeled "?" */ +}; +EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd); + /* * Igor Kuznetsov * Andrey J. Melnikov diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index f79a1c77414c..bb0911b4d2f6 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -224,7 +224,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_PINNACLE_PCTV_HD_800i: ir_codes = ir_codes_hauppauge_new; ir_type = IR_TYPE_RC5; ir->sampling = 1; @@ -306,6 +305,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keycode = 0xfa; ir->polling = 50; /* ms */ break; + case CX88_BOARD_PINNACLE_PCTV_HD_800i: + ir_codes = ir_codes_pinnacle_pctv_hd; + ir_type = IR_TYPE_RC5; + ir->sampling = 1; + break; } if (NULL == ir_codes) { diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 9c2fc09a7133..831547d79683 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -141,6 +141,7 @@ extern IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE]; #endif -- cgit v1.2.3