From 63b79cfa05b35973713caa91e290311bd5ebbe1d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Apr 2008 08:25:18 -0300 Subject: V4L/DVB (7732): vivi: fix a warning some gcc versions complain that fh is used without being defined. The error report is bogus. However, fixing it is trivial. Better to make gcc happy. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index b1e9592acb90..845be1864f68 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -888,7 +888,7 @@ static int vivi_open(struct inode *inode, struct file *file) { int minor = iminor(inode); struct vivi_dev *dev; - struct vivi_fh *fh; + struct vivi_fh *fh = NULL; int i; int retval = 0; -- cgit v1.2.1 From 50fa46b25490039ef51ef0dc8afdded60c4d3b59 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Sat, 26 Apr 2008 11:25:18 -0300 Subject: V4L/DVB (7733): blackbird_find_mailbox negative return ignored in blackbird_initialize_codec() dev->mailbox is unsigned. so a negative return goes unnoticed Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-blackbird.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 61c4f72644b8..6c0c94c5ef91 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -546,10 +546,12 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) if (retval < 0) return retval; - dev->mailbox = blackbird_find_mailbox(dev); - if (dev->mailbox < 0) + retval = blackbird_find_mailbox(dev); + if (retval < 0) return -1; + dev->mailbox = retval; + retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ if (retval < 0) { dprintk(0, "ERROR: Firmware ping failed!\n"); -- cgit v1.2.1 From 094f9b4b317b235b8d7fa03b356b9a3f3633b55b Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 24 Apr 2008 20:19:22 -0300 Subject: V4L/DVB (7734): em28xx: copy and paste error in em28xx_init_isoc Fixes a copy and paste error in check of kzalloc return value. The check block was copied from the previous allocation but the variable wasn't exchanged. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index f8c41d8c74c4..5d837c16ee22 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -650,7 +650,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); - if (!dev->isoc_ctl.urb) { + if (!dev->isoc_ctl.transfer_buffer) { em28xx_errdev("cannot allocate memory for usbtransfer\n"); kfree(dev->isoc_ctl.urb); return -ENOMEM; -- cgit v1.2.1 From d0d14226b94546a0054ded495157aa1cb41a7259 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Thu, 24 Apr 2008 21:34:00 -0300 Subject: V4L/DVB (7735): Fix compilation for au0828 Encountered this error when testing. Kernel: arch/x86/boot/bzImage is ready (#76) MODPOST 813 modules ERROR: "dvb_dmx_init" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_unregister_adapter" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_register_frontend" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_unregister_frontend" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_net_release" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_frontend_detach" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_dmxdev_release" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_net_init" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_dmx_release" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_dmx_swfilter_packets" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_register_adapter" [drivers/media/video/au0828/au0828.ko] undefined! ERROR: "dvb_dmxdev_init" [drivers/media/video/au0828/au0828.ko] undefined! WARNING: modpost: Found 9 section mismatch(es). To see full details build your kernel with: 'make CONFIG_DEBUG_SECTION_MISMATCH=y' make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 Signed-off-by: Brandon Philips Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/au0828/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig index c97c4bd24841..41708267e7a4 100644 --- a/drivers/media/video/au0828/Kconfig +++ b/drivers/media/video/au0828/Kconfig @@ -1,7 +1,7 @@ config VIDEO_AU0828 tristate "Auvitek AU0828 support" - depends on VIDEO_DEV && I2C && INPUT + depends on VIDEO_DEV && I2C && INPUT && DVB_CORE select I2C_ALGOBIT select DVB_AU8522 if !DVB_FE_CUSTOMIZE select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE -- cgit v1.2.1 From a45e0b45e52adb10634112b338dfb3e66a83de31 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 25 Apr 2008 01:49:24 -0300 Subject: V4L/DVB (7739): mt312.h: dubious one-bit signed bitfield Make it unsigned (0/1) rather than signed (0/-1). Signed-off-by: Harvey Harrison Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/mt312.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h index 96338f0c4dd4..de796eab3911 100644 --- a/drivers/media/dvb/frontends/mt312.h +++ b/drivers/media/dvb/frontends/mt312.h @@ -33,7 +33,7 @@ struct mt312_config { u8 demod_address; /* inverted voltage setting */ - int voltage_inverted:1; + unsigned int voltage_inverted:1; }; #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) -- cgit v1.2.1 From 8367fe248d74d53a6ae10e373c73230ab1536599 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 25 Apr 2008 01:28:10 -0300 Subject: V4L/DVB (7740): tuner-xc2028.c dubious !x & y Signed-off-by: Harvey Harrison Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tuner-xc2028.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c index cc3db7d79a0d..9e9003cffc7f 100644 --- a/drivers/media/video/tuner-xc2028.c +++ b/drivers/media/video/tuner-xc2028.c @@ -432,7 +432,7 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, type &= type_mask; - if (!type & SCODE) + if (!(type & SCODE)) type_mask = ~0; /* Seek for exact match */ -- cgit v1.2.1 From 8b4f1d031627d6f36d6ada05ab7670c2317efdaa Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 25 Apr 2008 03:44:36 -0300 Subject: V4L/DVB (7741): s5h1411: Adding support for this ATSC/QAM demodulator This adds full support for this demodulator. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 8 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/s5h1411.c | 888 ++++++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/s5h1411.h | 90 ++++ 4 files changed, 987 insertions(+) create mode 100644 drivers/media/dvb/frontends/s5h1411.c create mode 100644 drivers/media/dvb/frontends/s5h1411.h diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 68fab616f55d..f5fceb3cdb3c 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -307,6 +307,14 @@ config DVB_AU8522 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. +config DVB_S5H1411 + tristate "Samsung S5H1411 based" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want + to support this frontend. + comment "Tuners/PLL support" depends on DVB_CORE diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 2f873fc0f649..9747c73dc826 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -55,3 +55,4 @@ obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o obj-$(CONFIG_DVB_AU8522) += au8522.o obj-$(CONFIG_DVB_TDA10048) += tda10048.o +obj-$(CONFIG_DVB_S5H1411) += s5h1411.o diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c new file mode 100644 index 000000000000..eb5bfc99d4e9 --- /dev/null +++ b/drivers/media/dvb/frontends/s5h1411.c @@ -0,0 +1,888 @@ +/* + Samsung S5H1411 VSB/QAM demodulator driver + + Copyright (C) 2008 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 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 "dvb_frontend.h" +#include "dvb-pll.h" +#include "s5h1411.h" + +struct s5h1411_state { + + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct s5h1411_config *config; + + struct dvb_frontend frontend; + + fe_modulation_t current_modulation; + + u32 current_frequency; + int if_freq; + + u8 inversion; +}; + +static int debug; + +#define dprintk(arg...) do { \ + if (debug) \ + printk(arg); \ + } while (0) + +/* Register values to initialise the demod, defaults to VSB */ +static struct init_tab { + u8 addr; + u8 reg; + u16 data; +} init_tab[] = { + { S5H1411_I2C_TOP_ADDR, 0x00, 0x0071, }, + { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, }, + { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, }, + { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, }, + { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342a, }, + { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, }, + { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, }, + { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, }, + { S5H1411_I2C_TOP_ADDR, 0x27, 0x0f04, }, + { S5H1411_I2C_TOP_ADDR, 0x28, 0x070f, }, + { S5H1411_I2C_TOP_ADDR, 0x29, 0x2820, }, + { S5H1411_I2C_TOP_ADDR, 0x2a, 0x102e, }, + { S5H1411_I2C_TOP_ADDR, 0x2b, 0x0220, }, + { S5H1411_I2C_TOP_ADDR, 0x2e, 0x0d0e, }, + { S5H1411_I2C_TOP_ADDR, 0x2f, 0x1013, }, + { S5H1411_I2C_TOP_ADDR, 0x31, 0x171b, }, + { S5H1411_I2C_TOP_ADDR, 0x32, 0x0e0f, }, + { S5H1411_I2C_TOP_ADDR, 0x33, 0x0f10, }, + { S5H1411_I2C_TOP_ADDR, 0x34, 0x170e, }, + { S5H1411_I2C_TOP_ADDR, 0x35, 0x4b10, }, + { S5H1411_I2C_TOP_ADDR, 0x36, 0x0f17, }, + { S5H1411_I2C_TOP_ADDR, 0x3c, 0x1577, }, + { S5H1411_I2C_TOP_ADDR, 0x3d, 0x081a, }, + { S5H1411_I2C_TOP_ADDR, 0x3e, 0x77ee, }, + { S5H1411_I2C_TOP_ADDR, 0x40, 0x1e09, }, + { S5H1411_I2C_TOP_ADDR, 0x41, 0x0f0c, }, + { S5H1411_I2C_TOP_ADDR, 0x42, 0x1f10, }, + { S5H1411_I2C_TOP_ADDR, 0x4d, 0x0509, }, + { S5H1411_I2C_TOP_ADDR, 0x4e, 0x0a00, }, + { S5H1411_I2C_TOP_ADDR, 0x50, 0x0000, }, + { S5H1411_I2C_TOP_ADDR, 0x5b, 0x0000, }, + { S5H1411_I2C_TOP_ADDR, 0x5c, 0x0008, }, + { S5H1411_I2C_TOP_ADDR, 0x57, 0x1101, }, + { S5H1411_I2C_TOP_ADDR, 0x65, 0x007c, }, + { S5H1411_I2C_TOP_ADDR, 0x68, 0x0512, }, + { S5H1411_I2C_TOP_ADDR, 0x69, 0x0258, }, + { S5H1411_I2C_TOP_ADDR, 0x70, 0x0004, }, + { S5H1411_I2C_TOP_ADDR, 0x71, 0x0007, }, + { S5H1411_I2C_TOP_ADDR, 0x76, 0x00a9, }, + { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, }, + { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, }, + { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, }, + { S5H1411_I2C_TOP_ADDR, 0xb5, 0xafbb, }, + { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, }, + { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, }, + { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, }, + { S5H1411_I2C_TOP_ADDR, 0xb8, 0x003f, }, + { S5H1411_I2C_TOP_ADDR, 0xb9, 0x2700, }, + { S5H1411_I2C_TOP_ADDR, 0xba, 0xfac8, }, + { S5H1411_I2C_TOP_ADDR, 0xbe, 0x1003, }, + { S5H1411_I2C_TOP_ADDR, 0xbf, 0x103f, }, + { S5H1411_I2C_TOP_ADDR, 0xce, 0x2000, }, + { S5H1411_I2C_TOP_ADDR, 0xcf, 0x0800, }, + { S5H1411_I2C_TOP_ADDR, 0xd0, 0x0800, }, + { S5H1411_I2C_TOP_ADDR, 0xd1, 0x0400, }, + { S5H1411_I2C_TOP_ADDR, 0xd2, 0x0800, }, + { S5H1411_I2C_TOP_ADDR, 0xd3, 0x2000, }, + { S5H1411_I2C_TOP_ADDR, 0xd4, 0x3000, }, + { S5H1411_I2C_TOP_ADDR, 0xdb, 0x4a9b, }, + { S5H1411_I2C_TOP_ADDR, 0xdc, 0x1000, }, + { S5H1411_I2C_TOP_ADDR, 0xde, 0x0001, }, + { S5H1411_I2C_TOP_ADDR, 0xdf, 0x0000, }, + { S5H1411_I2C_TOP_ADDR, 0xe3, 0x0301, }, + { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0000, }, + { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0001, }, + { S5H1411_I2C_QAM_ADDR, 0x08, 0x0600, }, + { S5H1411_I2C_QAM_ADDR, 0x18, 0x4201, }, + { S5H1411_I2C_QAM_ADDR, 0x1e, 0x6476, }, + { S5H1411_I2C_QAM_ADDR, 0x21, 0x0830, }, + { S5H1411_I2C_QAM_ADDR, 0x0c, 0x5679, }, + { S5H1411_I2C_QAM_ADDR, 0x0d, 0x579b, }, + { S5H1411_I2C_QAM_ADDR, 0x24, 0x0102, }, + { S5H1411_I2C_QAM_ADDR, 0x31, 0x7488, }, + { S5H1411_I2C_QAM_ADDR, 0x32, 0x0a08, }, + { S5H1411_I2C_QAM_ADDR, 0x3d, 0x8689, }, + { S5H1411_I2C_QAM_ADDR, 0x49, 0x0048, }, + { S5H1411_I2C_QAM_ADDR, 0x57, 0x2012, }, + { S5H1411_I2C_QAM_ADDR, 0x5d, 0x7676, }, + { S5H1411_I2C_QAM_ADDR, 0x04, 0x0400, }, + { S5H1411_I2C_QAM_ADDR, 0x58, 0x00c0, }, + { S5H1411_I2C_QAM_ADDR, 0x5b, 0x0100, }, +}; + +/* VSB SNR lookup table */ +static struct vsb_snr_tab { + u16 val; + u16 data; +} vsb_snr_tab[] = { + { 0x39f, 300, }, + { 0x39b, 295, }, + { 0x397, 290, }, + { 0x394, 285, }, + { 0x38f, 280, }, + { 0x38b, 275, }, + { 0x387, 270, }, + { 0x382, 265, }, + { 0x37d, 260, }, + { 0x377, 255, }, + { 0x370, 250, }, + { 0x36a, 245, }, + { 0x364, 240, }, + { 0x35b, 235, }, + { 0x353, 230, }, + { 0x349, 225, }, + { 0x340, 320, }, + { 0x337, 215, }, + { 0x327, 210, }, + { 0x31b, 205, }, + { 0x310, 200, }, + { 0x302, 195, }, + { 0x2f3, 190, }, + { 0x2e4, 185, }, + { 0x2d7, 180, }, + { 0x2cd, 175, }, + { 0x2bb, 170, }, + { 0x2a9, 165, }, + { 0x29e, 160, }, + { 0x284, 155, }, + { 0x27a, 150, }, + { 0x260, 145, }, + { 0x23a, 140, }, + { 0x224, 135, }, + { 0x213, 130, }, + { 0x204, 125, }, + { 0x1fe, 120, }, + { 0, 0, }, +}; + +/* QAM64 SNR lookup table */ +static struct qam64_snr_tab { + u16 val; + u16 data; +} qam64_snr_tab[] = { + { 0x0001, 0, }, + { 0x0af0, 300, }, + { 0x0d80, 290, }, + { 0x10a0, 280, }, + { 0x14b5, 270, }, + { 0x1590, 268, }, + { 0x1680, 266, }, + { 0x17b0, 264, }, + { 0x18c0, 262, }, + { 0x19b0, 260, }, + { 0x1ad0, 258, }, + { 0x1d00, 256, }, + { 0x1da0, 254, }, + { 0x1ef0, 252, }, + { 0x2050, 250, }, + { 0x20f0, 249, }, + { 0x21d0, 248, }, + { 0x22b0, 247, }, + { 0x23a0, 246, }, + { 0x2470, 245, }, + { 0x24f0, 244, }, + { 0x25a0, 243, }, + { 0x26c0, 242, }, + { 0x27b0, 241, }, + { 0x28d0, 240, }, + { 0x29b0, 239, }, + { 0x2ad0, 238, }, + { 0x2ba0, 237, }, + { 0x2c80, 236, }, + { 0x2d20, 235, }, + { 0x2e00, 234, }, + { 0x2f10, 233, }, + { 0x3050, 232, }, + { 0x3190, 231, }, + { 0x3300, 230, }, + { 0x3340, 229, }, + { 0x3200, 228, }, + { 0x3550, 227, }, + { 0x3610, 226, }, + { 0x3600, 225, }, + { 0x3700, 224, }, + { 0x3800, 223, }, + { 0x3920, 222, }, + { 0x3a20, 221, }, + { 0x3b30, 220, }, + { 0x3d00, 219, }, + { 0x3e00, 218, }, + { 0x4000, 217, }, + { 0x4100, 216, }, + { 0x4300, 215, }, + { 0x4400, 214, }, + { 0x4600, 213, }, + { 0x4700, 212, }, + { 0x4800, 211, }, + { 0x4a00, 210, }, + { 0x4b00, 209, }, + { 0x4d00, 208, }, + { 0x4f00, 207, }, + { 0x5050, 206, }, + { 0x5200, 205, }, + { 0x53c0, 204, }, + { 0x5450, 203, }, + { 0x5650, 202, }, + { 0x5820, 201, }, + { 0x6000, 200, }, + { 0xffff, 0, }, +}; + +/* QAM256 SNR lookup table */ +static struct qam256_snr_tab { + u16 val; + u16 data; +} qam256_snr_tab[] = { + { 0x0001, 0, }, + { 0x0970, 400, }, + { 0x0a90, 390, }, + { 0x0b90, 380, }, + { 0x0d90, 370, }, + { 0x0ff0, 360, }, + { 0x1240, 350, }, + { 0x1345, 348, }, + { 0x13c0, 346, }, + { 0x14c0, 344, }, + { 0x1500, 342, }, + { 0x1610, 340, }, + { 0x1700, 338, }, + { 0x1800, 336, }, + { 0x18b0, 334, }, + { 0x1900, 332, }, + { 0x1ab0, 330, }, + { 0x1bc0, 328, }, + { 0x1cb0, 326, }, + { 0x1db0, 324, }, + { 0x1eb0, 322, }, + { 0x2030, 320, }, + { 0x2200, 318, }, + { 0x2280, 316, }, + { 0x2410, 314, }, + { 0x25b0, 312, }, + { 0x27a0, 310, }, + { 0x2840, 308, }, + { 0x29d0, 306, }, + { 0x2b10, 304, }, + { 0x2d30, 302, }, + { 0x2f20, 300, }, + { 0x30c0, 298, }, + { 0x3260, 297, }, + { 0x32c0, 296, }, + { 0x3300, 295, }, + { 0x33b0, 294, }, + { 0x34b0, 293, }, + { 0x35a0, 292, }, + { 0x3650, 291, }, + { 0x3800, 290, }, + { 0x3900, 289, }, + { 0x3a50, 288, }, + { 0x3b30, 287, }, + { 0x3cb0, 286, }, + { 0x3e20, 285, }, + { 0x3fa0, 284, }, + { 0x40a0, 283, }, + { 0x41c0, 282, }, + { 0x42f0, 281, }, + { 0x44a0, 280, }, + { 0x4600, 279, }, + { 0x47b0, 278, }, + { 0x4900, 277, }, + { 0x4a00, 276, }, + { 0x4ba0, 275, }, + { 0x4d00, 274, }, + { 0x4f00, 273, }, + { 0x5000, 272, }, + { 0x51f0, 272, }, + { 0x53a0, 270, }, + { 0x5520, 269, }, + { 0x5700, 268, }, + { 0x5800, 267, }, + { 0x5a00, 266, }, + { 0x5c00, 265, }, + { 0x5d00, 264, }, + { 0x5f00, 263, }, + { 0x6000, 262, }, + { 0x6200, 261, }, + { 0x6400, 260, }, + { 0xffff, 0, }, +}; + +/* 8 bit registers, 16 bit values */ +static int s5h1411_writereg(struct s5h1411_state *state, + u8 addr, u8 reg, u16 data) +{ + int ret; + u8 buf [] = { reg, data >> 8, data & 0xff }; + + struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; + + ret = i2c_transfer(state->i2c, &msg, 1); + + if (ret != 1) + printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, " + "ret == %i)\n", __func__, addr, reg, data, ret); + + return (ret != 1) ? -1 : 0; +} + +static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg) +{ + int ret; + u8 b0 [] = { reg }; + u8 b1 [] = { 0, 0 }; + + struct i2c_msg msg [] = { + { .addr = addr, .flags = 0, .buf = b0, .len = 1 }, + { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; + + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) + printk(KERN_ERR "%s: readreg error (ret == %i)\n", + __func__, ret); + return (b1[0] << 8) | b1[1]; +} + +static int s5h1411_softreset(struct dvb_frontend *fe) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + dprintk("%s()\n", __func__); + + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 0); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 1); + return 0; +} + +static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + dprintk("%s(%d KHz)\n", __func__, KHz); + + switch (KHz) { + case 3250: + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d9); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342); + s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9); + break; + case 3500: + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1225); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x1e96); + s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1225); + break; + case 4000: + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x14bc); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0xb53e); + s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x14bd); + break; + default: + dprintk("%s(%d KHz) Invalid, defaulting to 5380\n", + __func__, KHz); + /* no break, need to continue */ + case 5380: + case 44000: + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x3655); + s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1be4); + break; + } + + state->if_freq = KHz; + + return 0; +} + +static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode) +{ + struct s5h1411_state *state = fe->demodulator_priv; + u16 val; + + dprintk("%s(%d)\n", __func__, mode); + + val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff; + switch (mode) { + case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK: + val |= 0x0000; + break; + case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: + dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); + val |= 0x1000; + break; + case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: + val |= 0x2000; + break; + case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK: + val |= 0x3000; + break; + default: + return -EINVAL; + } + + /* Configure MPEG Signal Timing charactistics */ + return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbe, val); +} + +static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion) +{ + struct s5h1411_state *state = fe->demodulator_priv; + u16 val; + + dprintk("%s(%d)\n", __func__, inversion); + val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x24) & ~0x1000; + + if (inversion == 1) + val |= 0x1000; /* Inverted */ + else + val |= 0x0000; + + state->inversion = inversion; + return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val); +} + +static int s5h1411_enable_modulation(struct dvb_frontend *fe, + fe_modulation_t m) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + dprintk("%s(0x%08x)\n", __func__, m); + + switch (m) { + case VSB_8: + dprintk("%s() VSB_8\n", __func__); + s5h1411_set_if_freq(fe, state->config->vsb_if); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x71); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x00); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0xf1); + break; + case QAM_64: + case QAM_256: + dprintk("%s() QAM_AUTO (64/256)\n", __func__); + s5h1411_set_if_freq(fe, state->config->qam_if); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x0001); + s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x16, 0x1101); + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0x00f0); + break; + default: + dprintk("%s() Invalid modulation\n", __func__); + return -EINVAL; + } + + state->current_modulation = m; + s5h1411_softreset(fe); + + return 0; +} + +static int s5h1411_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + dprintk("%s(%d)\n", __func__, enable); + + if (enable) + return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1); + else + return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 0); +} + +static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable) +{ + struct s5h1411_state *state = fe->demodulator_priv; + u16 val; + + dprintk("%s(%d)\n", __func__, enable); + + val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xe0) & ~0x02; + + if (enable) + return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, + val | 0x02); + else + return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val); +} + +static int s5h1411_sleep(struct dvb_frontend *fe, int enable) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + dprintk("%s(%d)\n", __func__, enable); + + if (enable) + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 1); + else { + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 0); + s5h1411_softreset(fe); + } + + return 0; +} + +static int s5h1411_register_reset(struct dvb_frontend *fe) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + dprintk("%s()\n", __func__); + + return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf3, 0); +} + +/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ +static int s5h1411_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + dprintk("%s(frequency=%d)\n", __func__, p->frequency); + + s5h1411_softreset(fe); + + state->current_frequency = p->frequency; + + s5h1411_enable_modulation(fe, p->u.vsb.modulation); + + /* Allow the demod to settle */ + msleep(100); + + if (fe->ops.tuner_ops.set_params) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + fe->ops.tuner_ops.set_params(fe, p); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + return 0; +} + +/* Reset the demod hardware and reset all of the configuration registers + to a default state. */ +static int s5h1411_init(struct dvb_frontend *fe) +{ + struct s5h1411_state *state = fe->demodulator_priv; + int i; + + dprintk("%s()\n", __func__); + + s5h1411_sleep(fe, 0); + s5h1411_register_reset(fe); + + for (i = 0; i < ARRAY_SIZE(init_tab); i++) + s5h1411_writereg(state, init_tab[i].addr, + init_tab[i].reg, + init_tab[i].data); + + /* The datasheet says that after initialisation, VSB is default */ + state->current_modulation = VSB_8; + + if (state->config->output_mode == S5H1411_SERIAL_OUTPUT) + /* Serial */ + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1101); + else + /* Parallel */ + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1001); + + s5h1411_set_spectralinversion(fe, state->config->inversion); + s5h1411_set_if_freq(fe, state->config->vsb_if); + s5h1411_set_gpio(fe, state->config->gpio); + s5h1411_set_mpeg_timing(fe, state->config->mpeg_timing); + s5h1411_softreset(fe); + + /* Note: Leaving the I2C gate closed. */ + s5h1411_i2c_gate_ctrl(fe, 0); + + return 0; +} + +static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct s5h1411_state *state = fe->demodulator_priv; + u16 reg; + u32 tuner_status = 0; + + *status = 0; + + /* Get the demodulator status */ + reg = (s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2) >> 15) + & 0x0001; + if (reg) + *status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_SIGNAL; + + switch (state->current_modulation) { + case QAM_64: + case QAM_256: + reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0); + if (reg & 0x100) + *status |= FE_HAS_VITERBI; + if (reg & 0x10) + *status |= FE_HAS_SYNC; + break; + case VSB_8: + reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x5e); + if (reg & 0x0001) + *status |= FE_HAS_SYNC; + reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2); + if (reg & 0x1000) + *status |= FE_HAS_VITERBI; + break; + default: + return -EINVAL; + } + + switch (state->config->status_mode) { + case S5H1411_DEMODLOCKING: + if (*status & FE_HAS_VITERBI) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + case S5H1411_TUNERLOCKING: + /* Get the tuner status */ + if (fe->ops.tuner_ops.get_status) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + fe->ops.tuner_ops.get_status(fe, &tuner_status); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + if (tuner_status) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + } + + dprintk("%s() status 0x%08x\n", __func__, *status); + + return 0; +} + +static int s5h1411_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) +{ + int i, ret = -EINVAL; + dprintk("%s()\n", __func__); + + for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) { + if (v < qam256_snr_tab[i].val) { + *snr = qam256_snr_tab[i].data; + ret = 0; + break; + } + } + return ret; +} + +static int s5h1411_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) +{ + int i, ret = -EINVAL; + dprintk("%s()\n", __func__); + + for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) { + if (v < qam64_snr_tab[i].val) { + *snr = qam64_snr_tab[i].data; + ret = 0; + break; + } + } + return ret; +} + +static int s5h1411_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) +{ + int i, ret = -EINVAL; + dprintk("%s()\n", __func__); + + for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) { + if (v > vsb_snr_tab[i].val) { + *snr = vsb_snr_tab[i].data; + ret = 0; + break; + } + } + dprintk("%s() snr=%d\n", __func__, *snr); + return ret; +} + +static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct s5h1411_state *state = fe->demodulator_priv; + u16 reg; + dprintk("%s()\n", __func__); + + switch (state->current_modulation) { + case QAM_64: + reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1); + return s5h1411_qam64_lookup_snr(fe, snr, reg); + case QAM_256: + reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1); + return s5h1411_qam256_lookup_snr(fe, snr, reg); + case VSB_8: + reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, + 0xf2) & 0x3ff; + return s5h1411_vsb_lookup_snr(fe, snr, reg); + default: + break; + } + + return -EINVAL; +} + +static int s5h1411_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + return s5h1411_read_snr(fe, signal_strength); +} + +static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + *ucblocks = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xc9); + + return 0; +} + +static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + return s5h1411_read_ucblocks(fe, ber); +} + +static int s5h1411_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct s5h1411_state *state = fe->demodulator_priv; + + p->frequency = state->current_frequency; + p->u.vsb.modulation = state->current_modulation; + + return 0; +} + +static int s5h1411_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 1000; + return 0; +} + +static void s5h1411_release(struct dvb_frontend *fe) +{ + struct s5h1411_state *state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops s5h1411_ops; + +struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, + struct i2c_adapter *i2c) +{ + struct s5h1411_state *state = NULL; + u16 reg; + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct s5h1411_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* setup the state */ + state->config = config; + state->i2c = i2c; + state->current_modulation = VSB_8; + state->inversion = state->config->inversion; + + /* check if the demod exists */ + reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x05); + if (reg != 0x0066) + goto error; + + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &s5h1411_ops, + sizeof(struct dvb_frontend_ops)); + + state->frontend.demodulator_priv = state; + + if (s5h1411_init(&state->frontend) != 0) { + printk(KERN_ERR "%s: Failed to initialize correctly\n", + __func__); + goto error; + } + + /* Note: Leaving the I2C gate open here. */ + s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1); + + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(s5h1411_attach); + +static struct dvb_frontend_ops s5h1411_ops = { + + .info = { + .name = "Samsung S5H1411 QAM/8VSB Frontend", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + + .init = s5h1411_init, + .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl, + .set_frontend = s5h1411_set_frontend, + .get_frontend = s5h1411_get_frontend, + .get_tune_settings = s5h1411_get_tune_settings, + .read_status = s5h1411_read_status, + .read_ber = s5h1411_read_ber, + .read_signal_strength = s5h1411_read_signal_strength, + .read_snr = s5h1411_read_snr, + .read_ucblocks = s5h1411_read_ucblocks, + .release = s5h1411_release, +}; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Enable verbose debug messages"); + +MODULE_DESCRIPTION("Samsung S5H1411 QAM-B/ATSC Demodulator driver"); +MODULE_AUTHOR("Steven Toth"); +MODULE_LICENSE("GPL"); + +/* + * Local variables: + * c-basic-offset: 8 + */ diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h new file mode 100644 index 000000000000..1855f64ed4d8 --- /dev/null +++ b/drivers/media/dvb/frontends/s5h1411.h @@ -0,0 +1,90 @@ +/* + Samsung S5H1411 VSB/QAM demodulator driver + + Copyright (C) 2008 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 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 __S5H1411_H__ +#define __S5H1411_H__ + +#include + +#define S5H1411_I2C_TOP_ADDR (0x32 >> 1) +#define S5H1411_I2C_QAM_ADDR (0x34 >> 1) + +struct s5h1411_config { + + /* serial/parallel output */ +#define S5H1411_PARALLEL_OUTPUT 0 +#define S5H1411_SERIAL_OUTPUT 1 + u8 output_mode; + + /* GPIO Setting */ +#define S5H1411_GPIO_OFF 0 +#define S5H1411_GPIO_ON 1 + u8 gpio; + + /* MPEG signal timing */ +#define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 +#define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 +#define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 +#define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 + u16 mpeg_timing; + + /* IF Freq for QAM and VSB in KHz */ +#define S5H1411_IF_2500 2500 +#define S5H1411_IF_3500 3500 +#define S5H1411_IF_4000 4000 +#define S5H1411_IF_5380 5380 +#define S5H1411_IF_44000 44000 +#define S5H1411_VSB_IF_DEFAULT S5H1411_IF_44000 +#define S5H1411_QAM_IF_DEFAULT S5H1411_IF_44000 + u16 qam_if; + u16 vsb_if; + + /* Spectral Inversion */ +#define S5H1411_INVERSION_OFF 0 +#define S5H1411_INVERSION_ON 1 + u8 inversion; + + /* Return lock status based on tuner lock, or demod lock */ +#define S5H1411_TUNERLOCKING 0 +#define S5H1411_DEMODLOCKING 1 + u8 status_mode; +}; + +#if defined(CONFIG_DVB_S5H1411) || \ + (defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE)) +extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *s5h1411_attach( + const struct s5h1411_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_S5H1411 */ + +#endif /* __S5H1411_H__ */ + +/* + * Local variables: + * c-basic-offset: 8 + */ -- cgit v1.2.1 From d893d5dc7fef94a072a74f3141f9d1f60fd0cc7e Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 25 Apr 2008 03:46:43 -0300 Subject: V4L/DVB (7742): cx88: Add support for the DViCO FusionHDTV_7_GOLD digital modes The S5H1411 demodulator is now enabled. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/Kconfig | 1 + drivers/media/video/cx88/cx88-cards.c | 1 + drivers/media/video/cx88/cx88-dvb.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index bcf6d9ba063d..27635cdcbaf2 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -58,6 +58,7 @@ config VIDEO_CX88_DVB select DVB_CX24123 if !DVB_FE_CUSTOMISE select DVB_ISL6421 if !DVB_FE_CUSTOMISE select TUNER_SIMPLE if !DVB_FE_CUSTOMISE + select DVB_S5H1411 if !DVB_FE_CUSTOMISE ---help--- This adds support for DVB/ATSC cards based on the Conexant 2388x chip. diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 620159d05506..2b6b283cda15 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -1591,6 +1591,7 @@ static const struct cx88_board cx88_boards[] = { .vmux = 2, .gpio0 = 0x16d9, }}, + .mpeg = CX88_MPEG_DVB, }, [CX88_BOARD_PROLINK_PV_8000GT] = { .name = "Prolink Pixelview MPEG 8000GT", diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index f1251b844e08..1c7fe6862a60 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -47,6 +47,7 @@ #include "isl6421.h" #include "tuner-simple.h" #include "tda9887.h" +#include "s5h1411.h" MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); MODULE_AUTHOR("Chris Pascoe "); @@ -463,6 +464,22 @@ static struct zl10353_config cx88_geniatech_x8000_mt = { .no_tuner = 1, }; +static struct s5h1411_config dvico_fusionhdtv7_config = { + .output_mode = S5H1411_SERIAL_OUTPUT, + .gpio = S5H1411_GPIO_ON, + .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, + .qam_if = S5H1411_IF_44000, + .vsb_if = S5H1411_IF_44000, + .inversion = S5H1411_INVERSION_OFF, + .status_mode = S5H1411_DEMODLOCKING +}; + +static struct xc5000_config dvico_fusionhdtv7_tuner_config = { + .i2c_address = 0xc2 >> 1, + .if_khz = 5380, + .tuner_callback = cx88_tuner_callback, +}; + static int attach_xc3028(u8 addr, struct cx8802_dev *dev) { struct dvb_frontend *fe; @@ -844,6 +861,21 @@ static int dvb_register(struct cx8802_dev *dev) if (attach_xc3028(0x61, dev) < 0) return -EINVAL; break; + case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: + dev->dvb.frontend = dvb_attach(s5h1411_attach, + &dvico_fusionhdtv7_config, + &dev->core->i2c_adap); + if (dev->dvb.frontend != NULL) { + /* tuner_config.video_dev must point to + * i2c_adap.algo_data + */ + dvico_fusionhdtv7_tuner_config.priv = + dev->core->i2c_adap.algo_data; + dvb_attach(xc5000_attach, dev->dvb.frontend, + &dev->core->i2c_adap, + &dvico_fusionhdtv7_tuner_config); + } + break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", dev->core->name); -- cgit v1.2.1 From 4aef8fddb6639056ea830509ce3015c79f158011 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 25 Apr 2008 04:19:02 -0300 Subject: V4L/DVB (7744): pvrusb2-dvb: add atsc/qam support for Hauppauge pvrusb2 model 751xx Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/Kconfig | 1 + drivers/media/video/pvrusb2/pvrusb2-devattr.c | 28 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig index a8da90f69dd9..158b3d0c6532 100644 --- a/drivers/media/video/pvrusb2/Kconfig +++ b/drivers/media/video/pvrusb2/Kconfig @@ -64,6 +64,7 @@ config VIDEO_PVRUSB2_DVB depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_S5H1409 if !DVB_FE_CUSTOMISE + select DVB_S5H1411 if !DVB_FE_CUSTOMISE select DVB_TDA10048 if !DVB_FE_CUSTOMIZE select DVB_TDA18271 if !DVB_FE_CUSTOMIZE select TUNER_SIMPLE if !DVB_FE_CUSTOMISE diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 2dd06a90adce..3a141d93e1a9 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -36,6 +36,7 @@ pvr2_device_desc structures. #include "pvrusb2-hdw-internal.h" #include "lgdt330x.h" #include "s5h1409.h" +#include "s5h1411.h" #include "tda10048.h" #include "tda18271.h" #include "tda8290.h" @@ -368,6 +369,15 @@ static struct s5h1409_config pvr2_s5h1409_config = { .status_mode = S5H1409_DEMODLOCKING, }; +static struct s5h1411_config pvr2_s5h1411_config = { + .output_mode = S5H1411_PARALLEL_OUTPUT, + .gpio = S5H1411_GPIO_OFF, + .vsb_if = S5H1411_IF_44000, + .qam_if = S5H1411_IF_4000, + .inversion = S5H1411_INVERSION_ON, + .status_mode = S5H1411_DEMODLOCKING, +}; + static struct tda18271_std_map hauppauge_tda18271_std_map = { .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, .if_lvl = 6, .rfagc_top = 0x37, }, @@ -390,6 +400,16 @@ static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap) return -EIO; } +static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap) +{ + adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config, + &adap->channel.hdw->i2c_adap); + if (adap->fe) + return 0; + + return -EIO; +} + static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) { dvb_attach(tda829x_attach, adap->fe, @@ -406,6 +426,11 @@ struct pvr2_dvb_props pvr2_750xx_dvb_props = { .frontend_attach = pvr2_s5h1409_attach, .tuner_attach = pvr2_tda18271_8295_attach, }; + +struct pvr2_dvb_props pvr2_751xx_dvb_props = { + .frontend_attach = pvr2_s5h1411_attach, + .tuner_attach = pvr2_tda18271_8295_attach, +}; #endif static const char *pvr2_client_75xxx[] = { @@ -454,6 +479,9 @@ static const struct pvr2_device_desc pvr2_device_751xx = { .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .default_std_mask = V4L2_STD_NTSC_M, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, +#ifdef CONFIG_VIDEO_PVRUSB2_DVB + .dvb_props = &pvr2_751xx_dvb_props, +#endif }; -- cgit v1.2.1 From 0e3cbe81d52d18d83d068935512bd623a8765c12 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 25 Apr 2008 02:19:44 -0300 Subject: V4L/DVB (7746): pvrusb2: make signed one-bit bitfields unsigned Single-bit signed bitfields can only take 0/-1 rather than 0/1 as the drivers seems to assume...add unsigned. Noticed by sparse: drivers/media/video/pvrusb2/pvrusb2-devattr.h:107:34: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:114:37: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:117:30: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:120:23: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:124:24: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:128:23: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:138:36: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:143:24: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:144:28: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:145:26: error: dubious one-bit signed bitfield drivers/media/video/pvrusb2/pvrusb2-devattr.h:146:23: error: dubious one-bit signed bitfield Signed-off-by: Harvey Harrison Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index c2e2b06fe2e0..d016f8b6c70b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h @@ -104,28 +104,28 @@ struct pvr2_device_desc { unsigned char digital_control_scheme; /* If set, we don't bother trying to load cx23416 firmware. */ - int flag_skip_cx23416_firmware:1; + unsigned int flag_skip_cx23416_firmware:1; /* If set, the encoder must be healthy in order for digital mode to work (otherwise we assume that digital streaming will work even if we fail to locate firmware for the encoder). If the device doesn't support digital streaming then this flag has no effect. */ - int flag_digital_requires_cx23416:1; + unsigned int flag_digital_requires_cx23416:1; /* Device has a hauppauge eeprom which we can interrogate. */ - int flag_has_hauppauge_rom:1; + unsigned int flag_has_hauppauge_rom:1; /* Device does not require a powerup command to be issued. */ - int flag_no_powerup:1; + unsigned int flag_no_powerup:1; /* Device has a cx25840 - this enables special additional logic to handle it. */ - int flag_has_cx25840:1; + unsigned int flag_has_cx25840:1; /* Device has a wm8775 - this enables special additional logic to ensure that it is found. */ - int flag_has_wm8775:1; + unsigned int flag_has_wm8775:1; /* Device has IR hardware that can be faked into looking like a normal Hauppauge i2c IR receiver. This is currently very @@ -135,15 +135,15 @@ struct pvr2_device_desc { to virtualize the presence of the non-existant IR receiver chip and implement the virtual receiver in terms of appropriate FX2 commands. */ - int flag_has_hauppauge_custom_ir:1; + unsigned int flag_has_hauppauge_custom_ir:1; /* These bits define which kinds of sources the device can handle. Note: Digital tuner presence is inferred by the digital_control_scheme enumeration. */ - int flag_has_fmradio:1; /* Has FM radio receiver */ - int flag_has_analogtuner:1; /* Has analog tuner */ - int flag_has_composite:1; /* Has composite input */ - int flag_has_svideo:1; /* Has s-video input */ + unsigned int flag_has_fmradio:1; /* Has FM radio receiver */ + unsigned int flag_has_analogtuner:1; /* Has analog tuner */ + unsigned int flag_has_composite:1; /* Has composite input */ + unsigned int flag_has_svideo:1; /* Has s-video input */ }; extern struct usb_device_id pvr2_device_table[]; -- cgit v1.2.1 From b9ef6bbbbeaf65c6a452fe3c75c196f86e0d984d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Apr 2008 11:29:34 -0300 Subject: V4L/DVB (7748): tuner-core: some adjustments at tuner logs, if debug enabled set_addr log were almost useless: discarded SET_TYPE_ADDR commands weren't reported. This patch changed set_addr printk to print a message only if set_addr is wrong. It also fix printk at set_type, since, if an attach were failing, nothing were reported. With the current code, working or not, a call to set_addr will produce a debug printk. also, set_type() were producing a false error message on tuner_xc2028, since it were requesting for setting a frequency on a place where firmware name weren't set yet. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tuner-core.c | 92 ++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 529e00952a8d..2b72e10e6b9f 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -369,19 +369,13 @@ static void set_type(struct i2c_client *c, unsigned int type, break; } case TUNER_TEA5767: - if (tea5767_attach(&t->fe, t->i2c->adapter, t->i2c->addr) == NULL) { - t->type = TUNER_ABSENT; - t->mode_mask = T_UNINITIALIZED; - return; - } + if (!tea5767_attach(&t->fe, t->i2c->adapter, t->i2c->addr)) + goto attach_failed; t->mode_mask = T_RADIO; break; case TUNER_TEA5761: - if (tea5761_attach(&t->fe, t->i2c->adapter, t->i2c->addr) == NULL) { - t->type = TUNER_ABSENT; - t->mode_mask = T_UNINITIALIZED; - return; - } + if (!tea5761_attach(&t->fe, t->i2c->adapter, t->i2c->addr)) + goto attach_failed; t->mode_mask = T_RADIO; break; case TUNER_PHILIPS_FMD1216ME_MK3: @@ -394,12 +388,9 @@ static void set_type(struct i2c_client *c, unsigned int type, buffer[2] = 0x86; buffer[3] = 0x54; i2c_master_send(c, buffer, 4); - if (simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, - t->type) == NULL) { - t->type = TUNER_ABSENT; - t->mode_mask = T_UNINITIALIZED; - return; - } + if (!simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, + t->type)) + goto attach_failed; break; case TUNER_PHILIPS_TD1316: buffer[0] = 0x0b; @@ -407,12 +398,9 @@ static void set_type(struct i2c_client *c, unsigned int type, buffer[2] = 0x86; buffer[3] = 0xa4; i2c_master_send(c,buffer,4); - if (simple_tuner_attach(&t->fe, t->i2c->adapter, - t->i2c->addr, t->type) == NULL) { - t->type = TUNER_ABSENT; - t->mode_mask = T_UNINITIALIZED; - return; - } + if (!simple_tuner_attach(&t->fe, t->i2c->adapter, + t->i2c->addr, t->type)) + goto attach_failed; break; case TUNER_XC2028: { @@ -421,40 +409,34 @@ static void set_type(struct i2c_client *c, unsigned int type, .i2c_addr = t->i2c->addr, .callback = t->tuner_callback, }; - if (!xc2028_attach(&t->fe, &cfg)) { - t->type = TUNER_ABSENT; - t->mode_mask = T_UNINITIALIZED; - return; - } + if (!xc2028_attach(&t->fe, &cfg)) + goto attach_failed; break; } case TUNER_TDA9887: tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr); break; case TUNER_XC5000: + { + struct dvb_tuner_ops *xc_tuner_ops; + xc5000_cfg.i2c_address = t->i2c->addr; xc5000_cfg.if_khz = 5380; xc5000_cfg.priv = 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; + if (!xc5000_attach(&t->fe, t->i2c->adapter, &xc5000_cfg)) + goto attach_failed; + xc_tuner_ops = &t->fe.ops.tuner_ops; - if(xc_tuner_ops->init != NULL) + if (xc_tuner_ops->init) xc_tuner_ops->init(&t->fe); - } break; + } default: - if (simple_tuner_attach(&t->fe, t->i2c->adapter, - t->i2c->addr, t->type) == NULL) { - t->type = TUNER_ABSENT; - t->mode_mask = T_UNINITIALIZED; - return; - } + if (!simple_tuner_attach(&t->fe, t->i2c->adapter, + t->i2c->addr, t->type)) + goto attach_failed; + break; } @@ -476,11 +458,27 @@ static void set_type(struct i2c_client *c, unsigned int type, if (t->mode_mask == T_UNINITIALIZED) t->mode_mask = new_mode_mask; - set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? t->radio_freq : t->tv_freq); + /* xc2028/3028 and xc5000 requires a firmware to be set-up later + trying to set a frequency here will just fail + FIXME: better to move set_freq to the tuner code. This is needed + on analog tuners for PLL to properly work + */ + if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000) + set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? + t->radio_freq : t->tv_freq); + tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", c->adapter->name, c->driver->driver.name, c->addr << 1, type, t->mode_mask); tuner_i2c_address_check(t); + return; + +attach_failed: + tuner_dbg("Tuner attach for type = %d failed.\n", t->type); + t->type = TUNER_ABSENT; + t->mode_mask = T_UNINITIALIZED; + + return; } /* @@ -495,14 +493,16 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) { struct tuner *t = i2c_get_clientdata(c); - tuner_dbg("set addr for type %i\n", t->type); - if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) && (t->mode_mask & tun_setup->mode_mask))) || (tun_setup->addr == c->addr)) { set_type(c, tun_setup->type, tun_setup->mode_mask, tun_setup->config, tun_setup->tuner_callback); - } + } else + tuner_dbg("set addr discarded for type %i, mask %x. " + "Asked to change tuner at addr 0x%02x, with mask %x\n", + t->type, t->mode_mask, + tun_setup->addr, tun_setup->mode_mask); } static inline int check_mode(struct tuner *t, char *cmd) -- cgit v1.2.1 From b33d24c4cc14ee40d83a7e1ea0bfb9567d6059aa Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Apr 2008 19:06:03 -0300 Subject: V4L/DVB (7750): au0828/ cleanups and fixes This patch contains the following cleanups and fixes: - "debug" is definitely not a good name for a global variable, renamed it to "au0828_debug" this fixes a compile error with some kernel configurations - since the module parameter is int the variable shouldn't be unsigned - remove the {usb,bridge,i2c}_debug module parameters since they are already covered by the "debug" module parameter - remove the unused au0828_bcount - make the needlessly global i2c_scan static - make the needlessly global dvb_register() static Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/au0828/au0828-cards.c | 1 - drivers/media/video/au0828/au0828-core.c | 26 ++++++-------------------- drivers/media/video/au0828/au0828-dvb.c | 2 +- drivers/media/video/au0828/au0828-i2c.c | 6 +----- drivers/media/video/au0828/au0828.h | 8 ++------ 5 files changed, 10 insertions(+), 33 deletions(-) diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 8ca91f814277..a2a6983444fa 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c @@ -36,7 +36,6 @@ struct au0828_board au0828_boards[] = { .name = "DViCO FusionHDTV USB", }, }; -const unsigned int au0828_bcount = ARRAY_SIZE(au0828_boards); /* Tuner callback function for au0828 boards. Currently only needed * for HVR1500Q, which has an xc5000 tuner. diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c index e65d5642cb1d..54bfc0f05295 100644 --- a/drivers/media/video/au0828/au0828-core.c +++ b/drivers/media/video/au0828/au0828-core.c @@ -32,18 +32,10 @@ * 4 = I2C related * 8 = Bridge related */ -unsigned int debug; -module_param(debug, int, 0644); +int au0828_debug; +module_param_named(debug, au0828_debug, int, 0644); MODULE_PARM_DESC(debug, "enable debug messages"); -unsigned int usb_debug; -module_param(usb_debug, int, 0644); -MODULE_PARM_DESC(usb_debug, "enable usb debug messages"); - -unsigned int bridge_debug; -module_param(bridge_debug, int, 0644); -MODULE_PARM_DESC(bridge_debug, "enable bridge debug messages"); - #define _AU0828_BULKPIPE 0x03 #define _BULKPIPESIZE 0xffff @@ -229,24 +221,18 @@ static int __init au0828_init(void) { int ret; - if (debug) + if (au0828_debug & 1) printk(KERN_INFO "%s() Debugging is enabled\n", __func__); - if (usb_debug) { + if (au0828_debug & 2) printk(KERN_INFO "%s() USB Debugging is enabled\n", __func__); - debug |= 2; - } - if (i2c_debug) { + if (au0828_debug & 4) printk(KERN_INFO "%s() I2C Debugging is enabled\n", __func__); - debug |= 4; - } - if (bridge_debug) { + if (au0828_debug & 8) printk(KERN_INFO "%s() Bridge Debugging is enabled\n", __func__); - debug |= 8; - } printk(KERN_INFO "au0828 driver loaded\n"); diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c index 85d0ae9a322f..5040d7fc4af5 100644 --- a/drivers/media/video/au0828/au0828-dvb.c +++ b/drivers/media/video/au0828/au0828-dvb.c @@ -204,7 +204,7 @@ static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed) return ret; } -int dvb_register(struct au0828_dev *dev) +static int dvb_register(struct au0828_dev *dev) { struct au0828_dvb *dvb = &dev->dvb; int result; diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c index 94c8b74a6651..741a4937b050 100644 --- a/drivers/media/video/au0828/au0828-i2c.c +++ b/drivers/media/video/au0828/au0828-i2c.c @@ -29,11 +29,7 @@ #include -unsigned int i2c_debug; -module_param(i2c_debug, int, 0444); -MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); - -unsigned int i2c_scan; +static int i2c_scan; module_param(i2c_scan, int, 0444); MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h index 0200b9fc5dc4..7beb571798e5 100644 --- a/drivers/media/video/au0828/au0828.h +++ b/drivers/media/video/au0828/au0828.h @@ -96,15 +96,12 @@ struct au0828_buff { /* au0828-core.c */ extern u32 au0828_read(struct au0828_dev *dev, u16 reg); extern u32 au0828_write(struct au0828_dev *dev, u16 reg, u32 val); -extern unsigned int debug; -extern unsigned int usb_debug; -extern unsigned int bridge_debug; +extern int au0828_debug; /* ----------------------------------------------------------- */ /* au0828-cards.c */ extern struct au0828_board au0828_boards[]; extern struct usb_device_id au0828_usb_id_table[]; -extern const unsigned int au0828_bcount; extern void au0828_gpio_setup(struct au0828_dev *dev); extern int au0828_tuner_callback(void *priv, int command, int arg); extern void au0828_card_setup(struct au0828_dev *dev); @@ -115,7 +112,6 @@ extern int au0828_i2c_register(struct au0828_dev *dev); extern int au0828_i2c_unregister(struct au0828_dev *dev); extern void au0828_call_i2c_clients(struct au0828_dev *dev, unsigned int cmd, void *arg); -extern unsigned int i2c_debug; /* ----------------------------------------------------------- */ /* au0828-dvb.c */ @@ -123,6 +119,6 @@ extern int au0828_dvb_register(struct au0828_dev *dev); extern void au0828_dvb_unregister(struct au0828_dev *dev); #define dprintk(level, fmt, arg...)\ - do { if (debug & level)\ + do { if (au0828_debug & level)\ printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\ } while (0) -- cgit v1.2.1 From 37c45df740f79c58bb0fc0de151fd2504234032b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 25 Apr 2008 20:42:45 -0300 Subject: V4L/DVB (7751): ir-kbd-i2c: Save a temporary memory allocation in ir_probe Using i2c_transfer instead of i2c_master_recv in ir_probe saves a temporary memory allocation. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ir-kbd-i2c.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 11c5fdedc23b..7b65f5e537f8 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -509,8 +509,11 @@ static int ir_probe(struct i2c_adapter *adap) static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; static const int probe_cx23885[] = { 0x6b, -1 }; const int *probe; - struct i2c_client *c; - unsigned char buf; + struct i2c_msg msg = { + .flags = I2C_M_RD, + .len = 0, + .buf = NULL, + }; int i, rc; switch (adap->id) { @@ -536,23 +539,17 @@ static int ir_probe(struct i2c_adapter *adap) return 0; } - c = kzalloc(sizeof(*c), GFP_KERNEL); - if (!c) - return -ENOMEM; - - c->adapter = adap; for (i = 0; -1 != probe[i]; i++) { - c->addr = probe[i]; - rc = i2c_master_recv(c, &buf, 0); + msg.addr = probe[i]; + rc = i2c_transfer(adap, &msg, 1); dprintk(1,"probe 0x%02x @ %s: %s\n", probe[i], adap->name, - (0 == rc) ? "yes" : "no"); - if (0 == rc) { + (1 == rc) ? "yes" : "no"); + if (1 == rc) { ir_attach(adap, probe[i], 0, 0); break; } } - kfree(c); return 0; } -- cgit v1.2.1