From e3ab2fdd3f5efe62d266877c53c578fe5b547b31 Mon Sep 17 00:00:00 2001 From: Mario Rossi Date: Wed, 20 Dec 2006 10:54:30 -0300 Subject: V4L/DVB (4998): [PATCH] DIB3000MC and NOVA T USB2 #2 Second part of the patch to make the autosearch work again with DiB3000P/MC. Signed-off-by: Mario Rossi Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib3000mc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 23aa75a..054d7e6 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c @@ -475,7 +475,7 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha; dib3000mc_write_word(state, 0, tmp); - dib3000mc_write_word(state, 5, seq); + dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4)); tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp); if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp)) -- cgit v1.1 From 017cf012570c955c3e1ff025802d7cb46fd1d37b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 23 Sep 2006 20:40:20 -0300 Subject: V4L/DVB (5129): M920x: break out qt1010 tuner code into a separate file qt1010 is a tuner used in some other devices, so this code should be put into a separate file so that it could be reused by other drivers. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/qt1010.h | 221 +++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 drivers/media/dvb/frontends/qt1010.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/qt1010.h b/drivers/media/dvb/frontends/qt1010.h new file mode 100644 index 0000000..e526e3c --- /dev/null +++ b/drivers/media/dvb/frontends/qt1010.h @@ -0,0 +1,221 @@ +/* + * qt1010.h - DVB-T Tuner support + * + * 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 _QT1010_H_ +#define _QT1010_H_ + +#define QT1010_W 0 +#define QT1010_R 1 +/* Not actual hw limits. */ +#define QT1010_MIN_STEP 2000000 +#define QT1010_MIN_FREQ 48000000 + +static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) +{ + int i; + int div, mod; + struct { + u8 read, reg, value; + } rd[46] = { { QT1010_W, 0x01, 0x80 }, + { QT1010_W, 0x02, 0x3f }, + { QT1010_W, 0x05, 0xff }, /* c */ + { QT1010_W, 0x06, 0x44 }, + { QT1010_W, 0x07, 0xff }, /* c */ + { QT1010_W, 0x08, 0x08 }, + { QT1010_W, 0x09, 0xff }, /* c */ + { QT1010_W, 0x0a, 0xff }, /* c */ + { QT1010_W, 0x0b, 0xff }, /* c */ + { QT1010_W, 0x0c, 0xe1 }, + { QT1010_W, 0x1a, 0xff }, /* 10 c */ + { QT1010_W, 0x1b, 0x00 }, + { QT1010_W, 0x1c, 0x89 }, + { QT1010_W, 0x11, 0xff }, /* c */ + { QT1010_W, 0x12, 0x91 }, + { QT1010_W, 0x22, 0xff }, /* c */ + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x1e, 0xd0 }, + { QT1010_R, 0x22, 0xff }, /* c read */ + { QT1010_W, 0x1e, 0x00 }, + { QT1010_R, 0x05, 0xff }, /* 20 c read */ + { QT1010_R, 0x22, 0xff }, /* c read */ + { QT1010_W, 0x23, 0xd0 }, + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x1e, 0xe0 }, + { QT1010_R, 0x23, 0xff }, /* c read */ + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x24, 0xd0 }, + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x1e, 0xf0 }, + { QT1010_R, 0x24, 0xff }, /* 30 c read */ + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x14, 0x7f }, + { QT1010_W, 0x15, 0x7f }, + { QT1010_W, 0x05, 0xff }, /* c */ + { QT1010_W, 0x06, 0x00 }, + { QT1010_W, 0x15, 0x1f }, + { QT1010_W, 0x16, 0xff }, + { QT1010_W, 0x18, 0xff }, + { QT1010_W, 0x1f, 0xff }, /* c */ + { QT1010_W, 0x20, 0xff }, /* 40 c */ + { QT1010_W, 0x21, 0x53 }, + { QT1010_W, 0x25, 0xbd }, + { QT1010_W, 0x26, 0x15 }, + { QT1010_W, 0x02, 0x00 }, + { QT1010_W, 0x01, 0x00 }, + }; + struct i2c_msg msg; + struct dvb_usb_device *d = fe->dvb->priv; + unsigned long freq = params->frequency; + + if (freq % QT1010_MIN_STEP) + printk("frequency not supported.\n"); + + (void) buf; + (void) buf_len; + + div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; + mod = (div + 16 - 9) % 16; + + /* 0x5 */ + if (div >= 377) + rd[2].value = 0x74; + else if (div >= 265) + rd[2].value = 0x54; + else if (div >= 121) + rd[2].value = 0x34; + else + rd[2].value = 0x14; + + /* 0x7 */ + rd[4].value = (((freq - QT1010_MIN_FREQ) / 1000000) * 9975 + 12960000) / 320000; + + /* 09 */ + if (mod < 4) + rd[6].value = 0x1d; + else + rd[6].value = 0x1c; + + /* 0a */ + if (mod < 2) + rd[7].value = 0x09; + else if (mod < 4) + rd[7].value = 0x08; + else if (mod < 6) + rd[7].value = 0x0f; + else if (mod < 8) + rd[7].value = 0x0e; + else if (mod < 10) + rd[7].value = 0x0d; + else if (mod < 12) + rd[7].value = 0x0c; + else if (mod < 14) + rd[7].value = 0x0b; + else + rd[7].value = 0x0a; + + /* 0b */ + if (div & 1) + rd[8].value = 0x45; + else + rd[8].value = 0x44; + + /* 1a */ + if (div & 1) + rd[10].value = 0x78; + else + rd[10].value = 0xf8; + + /* 11 */ + if (div >= 265) + rd[13].value = 0xf9; + else if (div >= 121) + rd[13].value = 0xfd; + else + rd[13].value = 0xf9; + + /* 22 */ + if (div < 201) + rd[15].value = 0xd0; + else if (div < 217) + rd[15].value = 0xd3; + else if (div < 233) + rd[15].value = 0xd6; + else if (div < 249) + rd[15].value = 0xd9; + else if (div < 265) + rd[15].value = 0xda; + else + rd[15].value = 0xd0; + + /* 05 */ + if (div >= 377) + rd[34].value = 0x70; + else if (div >= 265) + rd[34].value = 0x50; + else if (div >= 121) + rd[34].value = 0x30; + else + rd[34].value = 0x10; + + /* 1f */ + if (mod < 4) + rd[39].value = 0x64; + else if (mod < 6) + rd[39].value = 0x66; + else if (mod < 8) + rd[39].value = 0x67; + else if (mod < 12) + rd[39].value = 0x68; + else if (mod < 14) + rd[39].value = 0x69; + else + rd[39].value = 0x6a; + + /* 20 */ + if (mod < 4) + rd[40].value = 0x10; + else if (mod < 6) + rd[40].value = 0x11; + else if (mod < 10) + rd[40].value = 0x12; + else if (mod < 12) + rd[40].value = 0x13; + else if (mod < 14) + rd[40].value = 0x14; + else + rd[40].value = 0x15; + + for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { + if (rd[i].read) + continue; + + msg.flags = 0; + msg.len = 2; + msg.addr = 0xc4; + msg.buf = &rd[i].reg; + + if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { + printk("tuner write failed\n"); + return -EIO; + } + } + + return 0; +} + +#endif -- cgit v1.1 From e2adbecf72d54515b66f8631813ec49069669d5e Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Thu, 28 Sep 2006 00:47:51 -0300 Subject: V4L/DVB (5130): M920x: misc updates and fixes - hardware pid filtering no longer enabled unless in usb 1.x mode - more responsive rc handling - some minor bug fixes and code refolding - m9206_write delay dropped (doesn't seem to be needed) Signed-off-by: Aapo Tahkola Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/qt1010.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/qt1010.h b/drivers/media/dvb/frontends/qt1010.h index e526e3c..3a56608 100644 --- a/drivers/media/dvb/frontends/qt1010.h +++ b/drivers/media/dvb/frontends/qt1010.h @@ -25,7 +25,7 @@ #define QT1010_MIN_STEP 2000000 #define QT1010_MIN_FREQ 48000000 -static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) +static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { int i; int div, mod; @@ -85,9 +85,6 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame if (freq % QT1010_MIN_STEP) printk("frequency not supported.\n"); - (void) buf; - (void) buf_len; - div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; mod = (div + 16 - 9) % 16; @@ -206,7 +203,7 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame msg.flags = 0; msg.len = 2; - msg.addr = 0xc4; + msg.addr = d->adapter[0].pll_addr; msg.buf = &rd[i].reg; if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { -- cgit v1.1 From 6cf2a10180e4039aaad1e4ecba5f2520f157da40 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 28 Sep 2006 14:47:21 -0300 Subject: V4L/DVB (5133): M920x: move qt1010_tuner_attach function into qt1010.h The megasky_tuner_attach function is not specific to this device. This patch renames it to qt1010_tuner_attach and moves it into the qt1010 header file. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/qt1010.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/qt1010.h b/drivers/media/dvb/frontends/qt1010.h index 3a56608..59ee1cd 100644 --- a/drivers/media/dvb/frontends/qt1010.h +++ b/drivers/media/dvb/frontends/qt1010.h @@ -215,4 +215,12 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame return 0; } +static int qt1010_tuner_attach(struct dvb_usb_adapter *adap) +{ + adap->pll_addr = 0xc4; + adap->pll_desc = NULL; + adap->fe->ops.tuner_ops.set_params = qt1010_set_params; + + return 0; +} #endif -- cgit v1.1 From 565ef12713c5620b6f802d67861153a3f68499a4 Mon Sep 17 00:00:00 2001 From: Jan Nijs Date: Sat, 7 Oct 2006 01:06:54 -0300 Subject: V4L/DVB (5135): Qt1010: correct hardlockup when an app access the DVB dongle This patch changes qt1010.h to use dvb_usb_device struct instead of a dvb_usb_adapter for accessing the private area of the driver. Without this patch my PC hard locks when an application tries to access the DVB tuner. Signed-off-by: Jan Nijs Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/qt1010.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/qt1010.h b/drivers/media/dvb/frontends/qt1010.h index 59ee1cd..8196985 100644 --- a/drivers/media/dvb/frontends/qt1010.h +++ b/drivers/media/dvb/frontends/qt1010.h @@ -79,7 +79,7 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame { QT1010_W, 0x01, 0x00 }, }; struct i2c_msg msg; - struct dvb_usb_device *d = fe->dvb->priv; + struct dvb_usb_adapter *adap = fe->dvb->priv; unsigned long freq = params->frequency; if (freq % QT1010_MIN_STEP) @@ -203,10 +203,10 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame msg.flags = 0; msg.len = 2; - msg.addr = d->adapter[0].pll_addr; + msg.addr = adap->dev->adapter[0].pll_addr; msg.buf = &rd[i].reg; - if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { + if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { printk("tuner write failed\n"); return -EIO; } -- cgit v1.1 From cbdc80ed8f59e204c031b52ea7e44f419029f75b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 21 Jan 2007 15:56:10 -0300 Subject: V4L/DVB (5137): Dvb: add new qt1010 tuner module QT1010: - old qt1010-code totally rewritten and put in own kernel module - same enhancements as my earlier QT1010 125kHz patch - tuner initialization - register 1f calculation - register 20 calculation - register 25 calculation m920x: (MSI Megasky) - use new QT1010 module instead of old code Signed-off-by: Antti Palosaari Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 7 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/qt1010.c | 452 ++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/qt1010.h | 233 ++------------- drivers/media/dvb/frontends/qt1010_priv.h | 105 +++++++ 5 files changed, 595 insertions(+), 203 deletions(-) create mode 100644 drivers/media/dvb/frontends/qt1010.c create mode 100644 drivers/media/dvb/frontends/qt1010_priv.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index af314bb..22c2cf2 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -290,6 +290,13 @@ config DVB_TDA826X help A DVB-S 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 + default m if DVB_FE_CUSTOMISE + help + A driver for the silicon tuner QT1010 from Quantek. + config DVB_TUNER_MT2060 tristate "Microtune MT2060 silicon IF tuner" depends on I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 3fa6e5d..a646d99 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -38,5 +38,6 @@ obj-$(CONFIG_DVB_ISL6421) += isl6421.o obj-$(CONFIG_DVB_TDA10086) += tda10086.o obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o +obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o obj-$(CONFIG_DVB_TUA6100) += tua6100.o obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o diff --git a/drivers/media/dvb/frontends/qt1010.c b/drivers/media/dvb/frontends/qt1010.c new file mode 100644 index 0000000..d7360f4 --- /dev/null +++ b/drivers/media/dvb/frontends/qt1010.c @@ -0,0 +1,452 @@ +/* + * Driver for Quantek QT1010 silicon tuner + * + * Copyright (C) 2006 Antti Palosaari + * Aapo Tahkola + * + * 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 "qt1010.h" +#include "qt1010_priv.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); + +#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "QT1010: " args); printk("\n"); }} while (0) + +/* read single register */ +static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val) +{ + struct i2c_msg msg[2] = { + { .addr = priv->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, + { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 }, + }; + + if (i2c_transfer(priv->i2c, msg, 2) != 2) { + printk(KERN_WARNING "qt1010 I2C read failed\n"); + return -EREMOTEIO; + } + return 0; +} + +/* write single register */ +static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val) +{ + u8 buf[2] = { reg, val }; + struct i2c_msg msg = { + .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2 + }; + + if (i2c_transfer(priv->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "qt1010 I2C write failed\n"); + return -EREMOTEIO; + } + return 0; +} + +/* dump all registers */ +static void qt1010_dump_regs(struct qt1010_priv *priv) +{ + char buf[52], buf2[4]; + u8 reg, val; + + for (reg = 0; ; reg++) { + if (reg % 16 == 0) { + if (reg) + printk("%s\n", buf); + sprintf(buf, "%02x: ", reg); + } + if (qt1010_readreg(priv, reg, &val) == 0) + sprintf(buf2, "%02x ", val); + else + strcpy(buf2, "-- "); + strcat(buf, buf2); + if (reg == 0x2f) + break; + } + printk("%s\n", buf); +} + +static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +{ + struct qt1010_priv *priv; + int err; + u32 freq, div, mod1, mod2; + u8 i, tmpval, reg05; + qt1010_i2c_oper_t rd[48] = { + { QT1010_WR, 0x01, 0x80 }, + { QT1010_WR, 0x02, 0x3f }, + { QT1010_WR, 0x05, 0xff }, /* 02 c write */ + { QT1010_WR, 0x06, 0x44 }, + { QT1010_WR, 0x07, 0xff }, /* 04 c write */ + { QT1010_WR, 0x08, 0x08 }, + { QT1010_WR, 0x09, 0xff }, /* 06 c write */ + { QT1010_WR, 0x0a, 0xff }, /* 07 c write */ + { QT1010_WR, 0x0b, 0xff }, /* 08 c write */ + { QT1010_WR, 0x0c, 0xe1 }, + { QT1010_WR, 0x1a, 0xff }, /* 10 c write */ + { QT1010_WR, 0x1b, 0x00 }, + { QT1010_WR, 0x1c, 0x89 }, + { QT1010_WR, 0x11, 0xff }, /* 13 c write */ + { QT1010_WR, 0x12, 0xff }, /* 14 c write */ + { QT1010_WR, 0x22, 0xff }, /* 15 c write */ + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, 0xd0 }, + { QT1010_RD, 0x22, 0xff }, /* 16 c read */ + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_RD, 0x05, 0xff }, /* 20 c read */ + { QT1010_RD, 0x22, 0xff }, /* 21 c read */ + { QT1010_WR, 0x23, 0xd0 }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, 0xe0 }, + { QT1010_RD, 0x23, 0xff }, /* 25 c read */ + { QT1010_RD, 0x23, 0xff }, /* 26 c read */ + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x24, 0xd0 }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, 0xf0 }, + { QT1010_RD, 0x24, 0xff }, /* 31 c read */ + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x14, 0x7f }, + { QT1010_WR, 0x15, 0x7f }, + { QT1010_WR, 0x05, 0xff }, /* 35 c write */ + { QT1010_WR, 0x06, 0x00 }, + { QT1010_WR, 0x15, 0x1f }, + { QT1010_WR, 0x16, 0xff }, + { QT1010_WR, 0x18, 0xff }, + { QT1010_WR, 0x1f, 0xff }, /* 40 c write */ + { QT1010_WR, 0x20, 0xff }, /* 41 c write */ + { QT1010_WR, 0x21, 0x53 }, + { QT1010_WR, 0x25, 0xff }, /* 43 c write */ + { QT1010_WR, 0x26, 0x15 }, + { QT1010_WR, 0x00, 0xff }, /* 45 c write */ + { QT1010_WR, 0x02, 0x00 }, + { QT1010_WR, 0x01, 0x00 } + }; + +#define FREQ1 32000000 /* 32 MHz */ +#define FREQ2 4000000 /* 4 MHz Quartz oscillator in the stick? */ + + priv = fe->tuner_priv; + freq = params->frequency; + div = (freq + QT1010_OFFSET) / QT1010_STEP; + freq = (div * QT1010_STEP) - QT1010_OFFSET; + mod1 = (freq + QT1010_OFFSET) % FREQ1; + mod2 = (freq + QT1010_OFFSET) % FREQ2; + priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; + priv->frequency = freq; + + /* reg 05 base value */ + if (freq < 290000000) reg05 = 0x14; /* 290 MHz */ + else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */ + else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */ + else reg05 = 0x74; + + /* 0x5 */ + rd[2].val = reg05; + + /* 07 - set frequency: 32 MHz scale */ + rd[4].val = (freq + QT1010_OFFSET) / FREQ1; + + /* 09 - changes every 8/24 MHz */ + if (mod1 < 8000000) rd[6].val = 0x1d; + else rd[6].val = 0x1c; + + /* 0a - set frequency: 4 MHz scale (max 28 MHz) */ + if (mod1 < 1*FREQ2) rd[7].val = 0x09; /* +0 MHz */ + else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /* +4 MHz */ + else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /* +8 MHz */ + else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */ + else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */ + else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */ + else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */ + else rd[7].val = 0x0a; /* +28 MHz */ + + /* 0b - changes every 2/2 MHz */ + if (mod2 < 2000000) rd[8].val = 0x45; + else rd[8].val = 0x44; + + /* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/ + tmpval = 0x78; /* byte, overflows intentionally */ + rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08); + + /* 11 */ + rd[13].val = 0xfd; /* TODO: correct value calculation */ + + /* 12 */ + rd[14].val = 0x91; /* TODO: correct value calculation */ + + /* 22 */ + if (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */ + else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */ + else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */ + else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */ + else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */ + else rd[15].val = 0xd0; + + /* 05 */ + rd[35].val = (reg05 & 0xf0); + + /* 1f */ + if (mod1 < 8000000) tmpval = 0x00; + else if (mod1 < 12000000) tmpval = 0x01; + else if (mod1 < 16000000) tmpval = 0x02; + else if (mod1 < 24000000) tmpval = 0x03; + else if (mod1 < 28000000) tmpval = 0x04; + else tmpval = 0x05; + rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval); + + /* 20 */ + if (mod1 < 8000000) tmpval = 0x00; + else if (mod1 < 12000000) tmpval = 0x01; + else if (mod1 < 20000000) tmpval = 0x02; + else if (mod1 < 24000000) tmpval = 0x03; + else if (mod1 < 28000000) tmpval = 0x04; + else tmpval = 0x05; + rd[41].val = (priv->reg20_init_val + 0x0d + tmpval); + + /* 25 */ + rd[43].val = priv->reg25_init_val; + + /* 00 */ + rd[45].val = 0x92; /* TODO: correct value calculation */ + + dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x 1a:%02x 11:%02x " \ + "12:%02x 22:%02x 05:%02x 1f:%02x 20:%02x 25:%02x 00:%02x", \ + freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \ + rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \ + rd[40].val, rd[41].val, rd[43].val, rd[45].val); + + for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { + if (rd[i].oper == QT1010_WR) { + err = qt1010_writereg(priv, rd[i].reg, rd[i].val); + } else { /* read is required to proper locking */ + err = qt1010_readreg(priv, rd[i].reg, &tmpval); + } + if (err) return err; + } + + if (debug) + qt1010_dump_regs(priv); + + return 0; +} + +static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_init_val, u8 *retval) +{ + u8 i, val1, val2; + int err; + + qt1010_i2c_oper_t i2c_data[] = { + { QT1010_WR, reg, reg_init_val }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, oper }, + { QT1010_RD, reg, 0xff } + }; + + for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + if (i2c_data[i].oper == QT1010_WR) { + err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + } else { + err = qt1010_readreg(priv, i2c_data[i].reg, &val2); + } + if (err) return err; + } + + do { + val1 = val2; + err = qt1010_readreg(priv, reg, &val2); + if (err) return err; + dprintk("compare reg:%02x %02x %02x", reg, val1, val2); + } while (val1 != val2); + *retval = val1; + + return qt1010_writereg(priv, 0x1e, 0x00); +} + + +static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retval) +{ + u8 i, val; + int err; + qt1010_i2c_oper_t i2c_data[] = { + { QT1010_WR, 0x07, reg_init_val }, + { QT1010_WR, 0x22, 0xd0 }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, 0xd0 }, + { QT1010_RD, 0x22, 0xff }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x22, 0xff } + }; + for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + if (i2c_data[i].oper == QT1010_WR) { + err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + } else { + err = qt1010_readreg(priv, i2c_data[i].reg, &val); + } + if (err) return err; + } + *retval = val; + return 0; +} + +static int qt1010_init(struct dvb_frontend *fe) +{ + struct qt1010_priv *priv = fe->tuner_priv; + struct dvb_frontend_parameters params; + int err; + u8 i, tmpval, *valptr = NULL; + + qt1010_i2c_oper_t i2c_data[] = { + { QT1010_WR, 0x01, 0x80 }, + { QT1010_WR, 0x0d, 0x84 }, + { QT1010_WR, 0x0e, 0xb7 }, + { QT1010_WR, 0x2a, 0x23 }, + { QT1010_WR, 0x2c, 0xdc }, + { QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */ + { QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */ + { QT1010_WR, 0x2b, 0x70 }, + { QT1010_WR, 0x2a, 0x23 }, + { QT1010_M1, 0x26, 0x08 }, + { QT1010_M1, 0x82, 0xff }, + { QT1010_WR, 0x05, 0x14 }, + { QT1010_WR, 0x06, 0x44 }, + { QT1010_WR, 0x07, 0x28 }, + { QT1010_WR, 0x08, 0x0b }, + { QT1010_WR, 0x11, 0xfd }, + { QT1010_M1, 0x22, 0x0d }, + { QT1010_M1, 0xd0, 0xff }, + { QT1010_WR, 0x06, 0x40 }, + { QT1010_WR, 0x16, 0xf0 }, + { QT1010_WR, 0x02, 0x38 }, + { QT1010_WR, 0x03, 0x18 }, + { QT1010_WR, 0x20, 0xe0 }, + { QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */ + { QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */ + { QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */ + { QT1010_WR, 0x03, 0x19 }, + { QT1010_WR, 0x02, 0x3f }, + { QT1010_WR, 0x21, 0x53 }, + { QT1010_RD, 0x21, 0xff }, + { QT1010_WR, 0x11, 0xfd }, + { QT1010_WR, 0x05, 0x34 }, + { QT1010_WR, 0x06, 0x44 }, + { QT1010_WR, 0x08, 0x08 } + }; + + for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + switch (i2c_data[i].oper) { + case QT1010_WR: + err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + break; + case QT1010_RD: + if (i2c_data[i].val == 0x20) valptr = &priv->reg20_init_val; + else valptr = &tmpval; + err = qt1010_readreg(priv, i2c_data[i].reg, valptr); + break; + case QT1010_M1: + if (i2c_data[i].val == 0x25) valptr = &priv->reg25_init_val; + else if (i2c_data[i].val == 0x1f) valptr = &priv->reg1f_init_val; + else valptr = &tmpval; + err = qt1010_init_meas1(priv, i2c_data[i+1].reg, i2c_data[i].reg, + i2c_data[i].val, valptr); + i++; + break; + } + if (err) return err; + } + + for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */ + if ((err = qt1010_init_meas2(priv, i, &tmpval))) + return err; + + params.frequency = 545000000; /* Sigmatek DVB-110 545000000 */ + /* MSI Megasky 580 GL861 533000000 */ + return qt1010_set_params(fe, ¶ms); +} + +static int qt1010_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct qt1010_priv *priv = fe->tuner_priv; + *frequency = priv->frequency; + return 0; +} + +static int qt1010_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct qt1010_priv *priv = fe->tuner_priv; + *bandwidth = priv->bandwidth; + return 0; +} + +static const struct dvb_tuner_ops qt1010_tuner_ops = { + .info = { + .name = "Quantek QT1010", + .frequency_min = QT1010_MIN_FREQ, + .frequency_max = QT1010_MAX_FREQ, + .frequency_step = QT1010_STEP, + }, + + .release = qt1010_release, + .init = qt1010_init, + /* TODO: implement sleep */ + + .set_params = qt1010_set_params, + .get_frequency = qt1010_get_frequency, + .get_bandwidth = qt1010_get_bandwidth +}; + +struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct qt1010_config *cfg) +{ + struct qt1010_priv *priv = NULL; + u8 id; + + priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + priv->cfg = cfg; + priv->i2c = i2c; + + + /* Try to detect tuner chip. Probably this is not correct register. */ + if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) { + kfree(priv); + return NULL; + } + + printk(KERN_INFO "Quantek QT1010 successfully identified.\n"); + memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops, sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = priv; + return fe; +} +EXPORT_SYMBOL(qt1010_attach); + +MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver"); +MODULE_AUTHOR("Antti Palosaari "); +MODULE_AUTHOR("Aapo Tahkola "); +MODULE_VERSION("0.1"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/qt1010.h b/drivers/media/dvb/frontends/qt1010.h index 8196985..3ab4aa0 100644 --- a/drivers/media/dvb/frontends/qt1010.h +++ b/drivers/media/dvb/frontends/qt1010.h @@ -1,5 +1,8 @@ /* - * qt1010.h - DVB-T Tuner support + * Driver for Quantek QT1010 silicon tuner + * + * Copyright (C) 2006 Antti Palosaari + * Aapo Tahkola * * 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 @@ -16,211 +19,35 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef _QT1010_H_ -#define _QT1010_H_ - -#define QT1010_W 0 -#define QT1010_R 1 -/* Not actual hw limits. */ -#define QT1010_MIN_STEP 2000000 -#define QT1010_MIN_FREQ 48000000 - -static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - int i; - int div, mod; - struct { - u8 read, reg, value; - } rd[46] = { { QT1010_W, 0x01, 0x80 }, - { QT1010_W, 0x02, 0x3f }, - { QT1010_W, 0x05, 0xff }, /* c */ - { QT1010_W, 0x06, 0x44 }, - { QT1010_W, 0x07, 0xff }, /* c */ - { QT1010_W, 0x08, 0x08 }, - { QT1010_W, 0x09, 0xff }, /* c */ - { QT1010_W, 0x0a, 0xff }, /* c */ - { QT1010_W, 0x0b, 0xff }, /* c */ - { QT1010_W, 0x0c, 0xe1 }, - { QT1010_W, 0x1a, 0xff }, /* 10 c */ - { QT1010_W, 0x1b, 0x00 }, - { QT1010_W, 0x1c, 0x89 }, - { QT1010_W, 0x11, 0xff }, /* c */ - { QT1010_W, 0x12, 0x91 }, - { QT1010_W, 0x22, 0xff }, /* c */ - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x1e, 0xd0 }, - { QT1010_R, 0x22, 0xff }, /* c read */ - { QT1010_W, 0x1e, 0x00 }, - { QT1010_R, 0x05, 0xff }, /* 20 c read */ - { QT1010_R, 0x22, 0xff }, /* c read */ - { QT1010_W, 0x23, 0xd0 }, - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x1e, 0xe0 }, - { QT1010_R, 0x23, 0xff }, /* c read */ - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x24, 0xd0 }, - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x1e, 0xf0 }, - { QT1010_R, 0x24, 0xff }, /* 30 c read */ - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x14, 0x7f }, - { QT1010_W, 0x15, 0x7f }, - { QT1010_W, 0x05, 0xff }, /* c */ - { QT1010_W, 0x06, 0x00 }, - { QT1010_W, 0x15, 0x1f }, - { QT1010_W, 0x16, 0xff }, - { QT1010_W, 0x18, 0xff }, - { QT1010_W, 0x1f, 0xff }, /* c */ - { QT1010_W, 0x20, 0xff }, /* 40 c */ - { QT1010_W, 0x21, 0x53 }, - { QT1010_W, 0x25, 0xbd }, - { QT1010_W, 0x26, 0x15 }, - { QT1010_W, 0x02, 0x00 }, - { QT1010_W, 0x01, 0x00 }, - }; - struct i2c_msg msg; - struct dvb_usb_adapter *adap = fe->dvb->priv; - unsigned long freq = params->frequency; - - if (freq % QT1010_MIN_STEP) - printk("frequency not supported.\n"); - - div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; - mod = (div + 16 - 9) % 16; - - /* 0x5 */ - if (div >= 377) - rd[2].value = 0x74; - else if (div >= 265) - rd[2].value = 0x54; - else if (div >= 121) - rd[2].value = 0x34; - else - rd[2].value = 0x14; - - /* 0x7 */ - rd[4].value = (((freq - QT1010_MIN_FREQ) / 1000000) * 9975 + 12960000) / 320000; - - /* 09 */ - if (mod < 4) - rd[6].value = 0x1d; - else - rd[6].value = 0x1c; - - /* 0a */ - if (mod < 2) - rd[7].value = 0x09; - else if (mod < 4) - rd[7].value = 0x08; - else if (mod < 6) - rd[7].value = 0x0f; - else if (mod < 8) - rd[7].value = 0x0e; - else if (mod < 10) - rd[7].value = 0x0d; - else if (mod < 12) - rd[7].value = 0x0c; - else if (mod < 14) - rd[7].value = 0x0b; - else - rd[7].value = 0x0a; - - /* 0b */ - if (div & 1) - rd[8].value = 0x45; - else - rd[8].value = 0x44; - - /* 1a */ - if (div & 1) - rd[10].value = 0x78; - else - rd[10].value = 0xf8; +#ifndef QT1010_H +#define QT1010_H - /* 11 */ - if (div >= 265) - rd[13].value = 0xf9; - else if (div >= 121) - rd[13].value = 0xfd; - else - rd[13].value = 0xf9; +#include "dvb_frontend.h" - /* 22 */ - if (div < 201) - rd[15].value = 0xd0; - else if (div < 217) - rd[15].value = 0xd3; - else if (div < 233) - rd[15].value = 0xd6; - else if (div < 249) - rd[15].value = 0xd9; - else if (div < 265) - rd[15].value = 0xda; - else - rd[15].value = 0xd0; +struct qt1010_config { + u8 i2c_address; +}; - /* 05 */ - if (div >= 377) - rd[34].value = 0x70; - else if (div >= 265) - rd[34].value = 0x50; - else if (div >= 121) - rd[34].value = 0x30; - else - rd[34].value = 0x10; - - /* 1f */ - if (mod < 4) - rd[39].value = 0x64; - else if (mod < 6) - rd[39].value = 0x66; - else if (mod < 8) - rd[39].value = 0x67; - else if (mod < 12) - rd[39].value = 0x68; - else if (mod < 14) - rd[39].value = 0x69; - else - rd[39].value = 0x6a; - - /* 20 */ - if (mod < 4) - rd[40].value = 0x10; - else if (mod < 6) - rd[40].value = 0x11; - else if (mod < 10) - rd[40].value = 0x12; - else if (mod < 12) - rd[40].value = 0x13; - else if (mod < 14) - rd[40].value = 0x14; - else - rd[40].value = 0x15; - - for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { - if (rd[i].read) - continue; - - msg.flags = 0; - msg.len = 2; - msg.addr = adap->dev->adapter[0].pll_addr; - msg.buf = &rd[i].reg; - - if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { - printk("tuner write failed\n"); - return -EIO; - } - } - - return 0; -} - -static int qt1010_tuner_attach(struct dvb_usb_adapter *adap) +/** + * Attach a qt1010 tuner to the supplied frontend structure. + * + * @param fe frontend to attach to + * @param i2c i2c adapter to use + * @param cfg tuner hw based configuration + * @return fe pointer on success, NULL on failure + */ +#if defined(CONFIG_DVB_TUNER_QT1010) || (defined(CONFIG_DVB_TUNER_QT1010_MODULE) && defined(MODULE)) +extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct qt1010_config *cfg); +#else +static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct qt1010_config *cfg) { - adap->pll_addr = 0xc4; - adap->pll_desc = NULL; - adap->fe->ops.tuner_ops.set_params = qt1010_set_params; - - return 0; + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + return NULL; } +#endif // CONFIG_DVB_TUNER_QT1010 + #endif diff --git a/drivers/media/dvb/frontends/qt1010_priv.h b/drivers/media/dvb/frontends/qt1010_priv.h new file mode 100644 index 0000000..090cf47 --- /dev/null +++ b/drivers/media/dvb/frontends/qt1010_priv.h @@ -0,0 +1,105 @@ +/* + * Driver for Quantek QT1010 silicon tuner + * + * Copyright (C) 2006 Antti Palosaari + * Aapo Tahkola + * + * 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 QT1010_PRIV_H +#define QT1010_PRIV_H + +/* +reg def meaning +=== === ======= +00 00 ? +01 a0 ? operation start/stop; start=80, stop=00 +02 00 ? +03 19 ? +04 00 ? +05 00 ? maybe band selection +06 00 ? +07 2b set frequency: 32 MHz scale, n*32 MHz +08 0b ? +09 10 ? changes every 8/24 MHz; values 1d/1c +0a 08 set frequency: 4 MHz scale, n*4 MHz +0b 41 ? changes every 2/2 MHz; values 45/45 +0c e1 ? +0d 94 ? +0e b6 ? +0f 2c ? +10 10 ? +11 f1 ? maybe device specified adjustment +12 11 ? maybe device specified adjustment +13 3f ? +14 1f ? +15 3f ? +16 ff ? +17 ff ? +18 f7 ? +19 80 ? +1a d0 set frequency: 125 kHz scale, n*125 kHz +1b 00 ? +1c 89 ? +1d 00 ? +1e 00 ? looks like operation register; write cmd here, read result from 1f-26 +1f 20 ? chip initialization +20 e0 ? chip initialization +21 20 ? +22 d0 ? +23 d0 ? +24 d0 ? +25 40 ? chip initialization +26 08 ? +27 29 ? +28 55 ? +29 39 ? +2a 13 ? +2b 01 ? +2c ea ? +2d 00 ? +2e 00 ? not used? +2f 00 ? not used? +*/ + +#define QT1010_STEP 125000 /* 125 kHz used by Windows drivers, + hw could be more precise but we don't + know how to use */ +#define QT1010_MIN_FREQ 48000000 /* 48 MHz */ +#define QT1010_MAX_FREQ 860000000 /* 860 MHz */ +#define QT1010_OFFSET 1246000000 /* 1246 MHz */ + +#define QT1010_WR 0 +#define QT1010_RD 1 +#define QT1010_M1 3 + +typedef struct { + u8 oper, reg, val; +} qt1010_i2c_oper_t; + +struct qt1010_priv { + struct qt1010_config *cfg; + struct i2c_adapter *i2c; + + u8 reg1f_init_val; + u8 reg20_init_val; + u8 reg25_init_val; + + u32 frequency; + u32 bandwidth; +}; + +#endif -- cgit v1.1 From 346304097b47a6e1376d99af80dbffb759fa55f4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 6 Feb 2007 21:50:36 -0300 Subject: V4L/DVB (5195): Frontends: make 4 functions static This patch makes four needlessly global functions static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0299.c | 2 +- drivers/media/dvb/frontends/tda10021.c | 2 +- drivers/media/dvb/frontends/tda1004x.c | 2 +- drivers/media/dvb/frontends/zl10353.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 9348376..18768d2 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c @@ -92,7 +92,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) return (ret != 1) ? -EREMOTEIO : 0; } -int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) +static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) { struct stv0299_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index dca8917..5b9c5bb 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c @@ -201,7 +201,7 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate return 0; } -int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len) +static int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len) { struct tda10021_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 00e4bcd..f4a9cf9 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -579,7 +579,7 @@ static int tda1004x_decode_fec(int tdafec) return -1; } -int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) +static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) { struct tda1004x_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index 0e9b59a..a1b0afb 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -54,7 +54,7 @@ static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) return 0; } -int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) +static int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) { int err, i; for (i = 0; i < ilen - 1; i++) -- cgit v1.1 From 0496daa7d88d117fab4dd190c7f6e7c4a5aa15cd Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Wed, 14 Feb 2007 22:57:42 -0200 Subject: V4L/DVB (5202): DVB: Use ARRAY_SIZE macro when appropriate Use ARRAY_SIZE macro already defined in kernel.h Signed-off-by: Ahmed S. Darwish Acked-by: Manu Abraham Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/cx24110.c | 4 ++-- drivers/media/dvb/frontends/cx24123.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index ae96395..10fc0c8 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -254,7 +254,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) if (srate<500000) srate=500000; - for(i=0;(ibands[i]);i++) + for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[i]); i++) ; /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, @@ -361,7 +361,7 @@ static int cx24110_initfe(struct dvb_frontend* fe) dprintk("%s: init chip\n", __FUNCTION__); - for(i=0;iVCAarg = cx24123_AGC_vals[0].VCAprogdata; @@ -516,7 +516,7 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa vco_div = cx24123_bandselect_vals[0].VCOdivider; /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */ - for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) + for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) { if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { @@ -658,7 +658,7 @@ static int cx24123_initfe(struct dvb_frontend* fe) dprintk("%s: init frontend\n",__FUNCTION__); /* Configure the demod to a good set of defaults */ - for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) + for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); /* Set the LNB polarity */ -- cgit v1.1 From 67b60aad168cfdd40ffec12f14b93e2e68f7d486 Mon Sep 17 00:00:00 2001 From: Chris Pascoe Date: Sat, 10 Feb 2007 10:17:57 -0300 Subject: V4L/DVB (5215): Experimental support for signal strength/BER/uncorrectable count After studying many hours worth of register dumps of MT352 and ZL10353 fed with identically damaged RF signals I have made an educated guess at which registers contain the AGC level, bit error rate and uncorrectable error count values. Implement the IOCTLs that return these values to userspace. Signed-off-by: Chris Pascoe Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/zl10353.c | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index a1b0afb..0d8241d 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -213,6 +213,29 @@ static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } +static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct zl10353_state *state = fe->demodulator_priv; + + *ber = zl10353_read_register(state, 0x11) << 16 | + zl10353_read_register(state, 0x12) << 8 | + zl10353_read_register(state, 0x13); + + return 0; +} + +static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct zl10353_state *state = fe->demodulator_priv; + + u16 signal = zl10353_read_register(state, 0x0a) << 10 | + zl10353_read_register(state, 0x0b) << 2 | 3; + + *strength = ~signal; + + return 0; +} + static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) { struct zl10353_state *state = fe->demodulator_priv; @@ -227,6 +250,16 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) return 0; } +static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct zl10353_state *state = fe->demodulator_priv; + + *ucblocks = zl10353_read_register(state, 0x14) << 8 | + zl10353_read_register(state, 0x15); + + return 0; +} + static int zl10353_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *fe_tune_settings) @@ -325,7 +358,10 @@ static struct dvb_frontend_ops zl10353_ops = { .get_tune_settings = zl10353_get_tune_settings, .read_status = zl10353_read_status, + .read_ber = zl10353_read_ber, + .read_signal_strength = zl10353_read_signal_strength, .read_snr = zl10353_read_snr, + .read_ucblocks = zl10353_read_ucblocks, }; module_param(debug_regs, int, 0644); -- cgit v1.1 From 0a11bb865a88a7459855ab46f74091e6ca4a1a20 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 10 Feb 2007 10:19:08 -0300 Subject: V4L/DVB (5216): Zl10353: add i2c_gate_ctrl support Implement I2C gate control for Megasky GL861 and SigmaTek AU6610 support. Signed-off-by: Chris Pascoe Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/zl10353.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index 0d8241d..50dac20 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -142,14 +142,16 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, zl10353_single_write(fe, 0x66, 0xE9); zl10353_single_write(fe, 0x6C, 0xCD); zl10353_single_write(fe, 0x6D, 0x7E); - zl10353_single_write(fe, 0x62, 0x0A); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); // if there is no attached secondary tuner, we call set_params to program // a potential tuner attached somewhere else if (state->config.no_tuner) { if (fe->ops.tuner_ops.set_params) { fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); } } @@ -294,6 +296,16 @@ static int zl10353_init(struct dvb_frontend *fe) return 0; } +static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) +{ + u8 val = 0x0a; + + if (enable) + val |= 0x10; + + return zl10353_single_write(fe, 0x62, val); +} + static void zl10353_release(struct dvb_frontend *fe) { struct zl10353_state *state = fe->demodulator_priv; @@ -352,6 +364,7 @@ static struct dvb_frontend_ops zl10353_ops = { .init = zl10353_init, .sleep = zl10353_sleep, + .i2c_gate_ctrl = zl10353_i2c_gate_ctrl, .write = zl10353_write, .set_frontend = zl10353_set_parameters, -- cgit v1.1 From f7f57770dc610eddd678aec483263e7980327ee9 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 10 Feb 2007 10:19:11 -0300 Subject: V4L/DVB (5217): Zl10353: Implement TRL nominal rate calculation Implement trl nominal rate calculation to Zarlink ZL10353 demod, based on calculation used in Zarlink MT352. This adds support for 6 and 8MHz bandwidth transponders. Signed-off-by: Antti Palosaari Signed-off-by: Chris Pascoe Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/zl10353.c | 48 ++++++++++++++++++++++++++++-- drivers/media/dvb/frontends/zl10353.h | 3 ++ drivers/media/dvb/frontends/zl10353_priv.h | 29 ++++++++++-------- 3 files changed, 65 insertions(+), 15 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index 50dac20..dbb53ba 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -38,6 +38,12 @@ struct zl10353_state { struct zl10353_config config; }; +static int debug; +#define dprintk(args...) \ + do { \ + if (debug) printk(KERN_DEBUG "zl10353: " args); \ + } while (0) + static int debug_regs = 0; static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) @@ -113,6 +119,36 @@ static void zl10353_dump_regs(struct dvb_frontend *fe) printk(KERN_DEBUG "%s\n", buf); } +static void zl10353_calc_nominal_rate(struct dvb_frontend *fe, + enum fe_bandwidth bandwidth, + u16 *nominal_rate) +{ + u32 adc_clock = 22528; /* 20.480 MHz on the board(!?) */ + u8 bw; + struct zl10353_state *state = fe->demodulator_priv; + + if (state->config.adc_clock) + adc_clock = state->config.adc_clock; + + switch (bandwidth) { + case BANDWIDTH_6_MHZ: + bw = 6; + break; + case BANDWIDTH_7_MHZ: + bw = 7; + break; + case BANDWIDTH_8_MHZ: + default: + bw = 8; + break; + } + + *nominal_rate = (64 * bw * (1<<16) / (7 * 8) * 4000 / adc_clock + 2) / 4; + + dprintk("%s: bw %d, adc_clock %d => 0x%x\n", + __FUNCTION__, bw, adc_clock, *nominal_rate); +} + static int zl10353_sleep(struct dvb_frontend *fe) { static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 }; @@ -125,7 +161,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { struct zl10353_state *state = fe->demodulator_priv; - + u16 nominal_rate; u8 pllbuf[6] = { 0x67 }; /* These settings set "auto-everything" and start the FSM. */ @@ -138,8 +174,11 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, zl10353_single_write(fe, 0x56, 0x28); zl10353_single_write(fe, 0x89, 0x20); zl10353_single_write(fe, 0x5E, 0x00); - zl10353_single_write(fe, 0x65, 0x5A); - zl10353_single_write(fe, 0x66, 0xE9); + + zl10353_calc_nominal_rate(fe, param->u.ofdm.bandwidth, &nominal_rate); + zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate)); + zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate)); + zl10353_single_write(fe, 0x6C, 0xCD); zl10353_single_write(fe, 0x6D, 0x7E); if (fe->ops.i2c_gate_ctrl) @@ -377,6 +416,9 @@ static struct dvb_frontend_ops zl10353_ops = { .read_ucblocks = zl10353_read_ucblocks, }; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + module_param(debug_regs, int, 0644); MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off)."); diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h index 0bc0109..cb274dc 100644 --- a/drivers/media/dvb/frontends/zl10353.h +++ b/drivers/media/dvb/frontends/zl10353.h @@ -29,6 +29,9 @@ struct zl10353_config /* demodulator's I2C address */ u8 demod_address; + /* frequencies in kHz */ + int adc_clock; // default: 22528 + /* set if no pll is connected to the secondary i2c bus */ int no_tuner; diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h index b72224b..d218692 100644 --- a/drivers/media/dvb/frontends/zl10353_priv.h +++ b/drivers/media/dvb/frontends/zl10353_priv.h @@ -24,19 +24,24 @@ #define ID_ZL10353 0x14 +#define msb(x) (((x) >> 8) & 0xff) +#define lsb(x) ((x) & 0xff) + enum zl10353_reg_addr { - INTERRUPT_0 = 0x00, - INTERRUPT_1 = 0x01, - INTERRUPT_2 = 0x02, - INTERRUPT_3 = 0x03, - INTERRUPT_4 = 0x04, - INTERRUPT_5 = 0x05, - STATUS_6 = 0x06, - STATUS_7 = 0x07, - STATUS_8 = 0x08, - STATUS_9 = 0x09, - SNR = 0x10, - CHIP_ID = 0x7F, + INTERRUPT_0 = 0x00, + INTERRUPT_1 = 0x01, + INTERRUPT_2 = 0x02, + INTERRUPT_3 = 0x03, + INTERRUPT_4 = 0x04, + INTERRUPT_5 = 0x05, + STATUS_6 = 0x06, + STATUS_7 = 0x07, + STATUS_8 = 0x08, + STATUS_9 = 0x09, + SNR = 0x10, + TRL_NOMINAL_RATE_1 = 0x65, + TRL_NOMINAL_RATE_0 = 0x66, + CHIP_ID = 0x7F, }; #endif /* _ZL10353_PRIV_ */ -- cgit v1.1 From 6345f0f6428cc7a3f73b83624c6f97629a9fddd1 Mon Sep 17 00:00:00 2001 From: Chris Pascoe Date: Sat, 10 Feb 2007 10:19:16 -0300 Subject: V4L/DVB (5218): Zl10353: register definitions update Update the descriptions of "discovered" registers on the zl10353, using the equivalaent mt352 register names. Signed-off-by: Chris Pascoe Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/zl10353.c | 14 +++++++------- drivers/media/dvb/frontends/zl10353_priv.h | 7 +++++++ 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index dbb53ba..245f9b7 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -258,9 +258,9 @@ static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber) { struct zl10353_state *state = fe->demodulator_priv; - *ber = zl10353_read_register(state, 0x11) << 16 | - zl10353_read_register(state, 0x12) << 8 | - zl10353_read_register(state, 0x13); + *ber = zl10353_read_register(state, RS_ERR_CNT_2) << 16 | + zl10353_read_register(state, RS_ERR_CNT_1) << 8 | + zl10353_read_register(state, RS_ERR_CNT_0); return 0; } @@ -269,8 +269,8 @@ static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct zl10353_state *state = fe->demodulator_priv; - u16 signal = zl10353_read_register(state, 0x0a) << 10 | - zl10353_read_register(state, 0x0b) << 2 | 3; + u16 signal = zl10353_read_register(state, AGC_GAIN_1) << 10 | + zl10353_read_register(state, AGC_GAIN_0) << 2 | 3; *strength = ~signal; @@ -295,8 +295,8 @@ static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct zl10353_state *state = fe->demodulator_priv; - *ucblocks = zl10353_read_register(state, 0x14) << 8 | - zl10353_read_register(state, 0x15); + *ucblocks = zl10353_read_register(state, RS_UBC_1) << 8 | + zl10353_read_register(state, RS_UBC_0); return 0; } diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h index d218692..4962434 100644 --- a/drivers/media/dvb/frontends/zl10353_priv.h +++ b/drivers/media/dvb/frontends/zl10353_priv.h @@ -38,7 +38,14 @@ enum zl10353_reg_addr { STATUS_7 = 0x07, STATUS_8 = 0x08, STATUS_9 = 0x09, + AGC_GAIN_1 = 0x0A, + AGC_GAIN_0 = 0x0B, SNR = 0x10, + RS_ERR_CNT_2 = 0x11, + RS_ERR_CNT_1 = 0x12, + RS_ERR_CNT_0 = 0x13, + RS_UBC_1 = 0x14, + RS_UBC_0 = 0x15, TRL_NOMINAL_RATE_1 = 0x65, TRL_NOMINAL_RATE_0 = 0x66, CHIP_ID = 0x7F, -- cgit v1.1 From 705d41e5da674b449f900df97ad13ebe53e82b82 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 27 Jan 2007 16:41:35 -0300 Subject: V4L/DVB (5240): Qt1010: use i2c_gate_ctrl where appropriate This patch adds calls to i2c_gate_ctrl in the qt1010 dvb tuner module, while removing the temporary hack in au6610 and gl861. Tested successfully against fi-Oulu frequencies with MSI Megasky 580 GL861 and Sigmatek DVB-110 AU6610. Signed-off-by: Antti Palosaari Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/qt1010.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/qt1010.c b/drivers/media/dvb/frontends/qt1010.c index d7360f4..c3408dc 100644 --- a/drivers/media/dvb/frontends/qt1010.c +++ b/drivers/media/dvb/frontends/qt1010.c @@ -149,6 +149,9 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; priv->frequency = freq; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + /* reg 05 base value */ if (freq < 290000000) reg05 = 0x14; /* 290 MHz */ else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */ @@ -242,6 +245,9 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame if (debug) qt1010_dump_regs(priv); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + return 0; } @@ -277,7 +283,6 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_i return qt1010_writereg(priv, 0x1e, 0x00); } - static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retval) { u8 i, val; @@ -347,6 +352,9 @@ static int qt1010_init(struct dvb_frontend *fe) { QT1010_WR, 0x08, 0x08 } }; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { switch (i2c_data[i].oper) { case QT1010_WR: @@ -430,6 +438,9 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, priv->cfg = cfg; priv->i2c = i2c; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + /* Try to detect tuner chip. Probably this is not correct register. */ if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) { @@ -437,6 +448,9 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, return NULL; } + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + printk(KERN_INFO "Quantek QT1010 successfully identified.\n"); memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops, sizeof(struct dvb_tuner_ops)); -- cgit v1.1 From 90e3bd4ba5563f2a6efbb46ce7e10845329dfffd Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Tue, 13 Feb 2007 18:01:56 -0300 Subject: V4L/DVB (5247): Stv0297: Enable BER/UNC counting Enable BER/UNC counting for the stv0297 frontend. The idea for this patch comes from stv0297_cs.c. Signed-off-by: Hartmut Birr Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0297.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index 1ca6424..9a34397 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c @@ -35,6 +35,7 @@ struct stv0297_state { const struct stv0297_config *config; struct dvb_frontend frontend; + unsigned long last_ber; unsigned long base_freq; }; @@ -310,6 +311,8 @@ static int stv0297_init(struct dvb_frontend *fe) stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); msleep(200); + state->last_ber = 0; + return 0; } @@ -340,11 +343,13 @@ static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) struct stv0297_state *state = fe->demodulator_priv; u8 BER[3]; - stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes - mdelay(25); // Hopefully got 4096 Bytes stv0297_readregs(state, 0xA0, BER, 3); - mdelay(25); - *ber = (BER[2] << 8 | BER[1]) / (8 * 4096); + if (!(BER[0] & 0x80)) { + state->last_ber = BER[2] << 8 | BER[1]; + stv0297_writereg_mask(state, 0xA0, 0x80, 0x80); + } + + *ber = state->last_ber; return 0; } @@ -376,9 +381,14 @@ static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) { struct stv0297_state *state = fe->demodulator_priv; + stv0297_writereg_mask(state, 0xDF, 0x03, 0x03); /* freeze the counters */ + *ucblocks = (stv0297_readreg(state, 0xD5) << 8) | stv0297_readreg(state, 0xD4); + stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */ + stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */ + return 0; } @@ -648,6 +658,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, /* setup the state */ state->config = config; state->i2c = i2c; + state->last_ber = 0; state->base_freq = 0; /* check if the demod is there */ -- cgit v1.1 From b79ea694a919ebc107c90af61b5d22becb1b1324 Mon Sep 17 00:00:00 2001 From: Marco Schluessler Date: Tue, 13 Feb 2007 16:46:13 -0300 Subject: V4L/DVB (5251): Qt1010: fix compiler warning In function 'qt1010_init': Signed-off-by: Marco Schluessler Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/qt1010.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/qt1010.c b/drivers/media/dvb/frontends/qt1010.c index c3408dc..28406b3 100644 --- a/drivers/media/dvb/frontends/qt1010.c +++ b/drivers/media/dvb/frontends/qt1010.c @@ -312,7 +312,7 @@ static int qt1010_init(struct dvb_frontend *fe) { struct qt1010_priv *priv = fe->tuner_priv; struct dvb_frontend_parameters params; - int err; + int err = 0; u8 i, tmpval, *valptr = NULL; qt1010_i2c_oper_t i2c_data[] = { -- cgit v1.1 From 47e76c5c7904b8bc2d4c08fbe531017b704a877d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 13 Feb 2007 17:53:46 -0300 Subject: V4L/DVB (5252): Qt1010: use ARRAY_SIZE macro when appropriate Use ARRAY_SIZE macro already defined in kernel.h Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/qt1010.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/qt1010.c b/drivers/media/dvb/frontends/qt1010.c index 28406b3..827cb0c 100644 --- a/drivers/media/dvb/frontends/qt1010.c +++ b/drivers/media/dvb/frontends/qt1010.c @@ -233,7 +233,7 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \ rd[40].val, rd[41].val, rd[43].val, rd[45].val); - for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { + for (i = 0; i < ARRAY_SIZE(rd); i++) { if (rd[i].oper == QT1010_WR) { err = qt1010_writereg(priv, rd[i].reg, rd[i].val); } else { /* read is required to proper locking */ @@ -263,7 +263,7 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_i { QT1010_RD, reg, 0xff } }; - for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { if (i2c_data[i].oper == QT1010_WR) { err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); } else { @@ -296,7 +296,7 @@ static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retva { QT1010_WR, 0x1e, 0x00 }, { QT1010_WR, 0x22, 0xff } }; - for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { if (i2c_data[i].oper == QT1010_WR) { err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); } else { @@ -355,7 +355,7 @@ static int qt1010_init(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { switch (i2c_data[i].oper) { case QT1010_WR: err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); -- cgit v1.1 From f6982d59480953a8f5a84c237a9dabff39f788ce Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 13 Feb 2007 18:26:26 -0300 Subject: V4L/DVB (5253): Qt1010: whitespace / 80 column cleanups Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/qt1010.c | 69 +++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 25 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/qt1010.c b/drivers/media/dvb/frontends/qt1010.c index 827cb0c..825aa14 100644 --- a/drivers/media/dvb/frontends/qt1010.c +++ b/drivers/media/dvb/frontends/qt1010.c @@ -25,14 +25,19 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); -#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "QT1010: " args); printk("\n"); }} while (0) +#define dprintk(args...) \ + do { \ + if (debug) printk(KERN_DEBUG "QT1010: " args); \ + } while (0) /* read single register */ static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val) { struct i2c_msg msg[2] = { - { .addr = priv->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 }, + { .addr = priv->cfg->i2c_address, + .flags = 0, .buf = ®, .len = 1 }, + { .addr = priv->cfg->i2c_address, + .flags = I2C_M_RD, .buf = val, .len = 1 }, }; if (i2c_transfer(priv->i2c, msg, 2) != 2) { @@ -46,9 +51,8 @@ static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val) static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val) { u8 buf[2] = { reg, val }; - struct i2c_msg msg = { - .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2 - }; + struct i2c_msg msg = { .addr = priv->cfg->i2c_address, + .flags = 0, .buf = buf, .len = 2 }; if (i2c_transfer(priv->i2c, &msg, 1) != 1) { printk(KERN_WARNING "qt1010 I2C write failed\n"); @@ -80,7 +84,8 @@ static void qt1010_dump_regs(struct qt1010_priv *priv) printk("%s\n", buf); } -static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int qt1010_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) { struct qt1010_priv *priv; int err; @@ -146,7 +151,8 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame freq = (div * QT1010_STEP) - QT1010_OFFSET; mod1 = (freq + QT1010_OFFSET) % FREQ1; mod2 = (freq + QT1010_OFFSET) % FREQ2; - priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; + priv->bandwidth = + (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; priv->frequency = freq; if (fe->ops.i2c_gate_ctrl) @@ -227,8 +233,9 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame /* 00 */ rd[45].val = 0x92; /* TODO: correct value calculation */ - dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x 1a:%02x 11:%02x " \ - "12:%02x 22:%02x 05:%02x 1f:%02x 20:%02x 25:%02x 00:%02x", \ + dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \ + "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \ + "20:%02x 25:%02x 00:%02x", \ freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \ rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \ rd[40].val, rd[41].val, rd[43].val, rd[45].val); @@ -251,7 +258,8 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame return 0; } -static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_init_val, u8 *retval) +static int qt1010_init_meas1(struct qt1010_priv *priv, + u8 oper, u8 reg, u8 reg_init_val, u8 *retval) { u8 i, val1, val2; int err; @@ -265,7 +273,8 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_i for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { if (i2c_data[i].oper == QT1010_WR) { - err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + err = qt1010_writereg(priv, i2c_data[i].reg, + i2c_data[i].val); } else { err = qt1010_readreg(priv, i2c_data[i].reg, &val2); } @@ -283,7 +292,8 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_i return qt1010_writereg(priv, 0x1e, 0x00); } -static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retval) +static u8 qt1010_init_meas2(struct qt1010_priv *priv, + u8 reg_init_val, u8 *retval) { u8 i, val; int err; @@ -298,7 +308,8 @@ static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retva }; for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { if (i2c_data[i].oper == QT1010_WR) { - err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + err = qt1010_writereg(priv, i2c_data[i].reg, + i2c_data[i].val); } else { err = qt1010_readreg(priv, i2c_data[i].reg, &val); } @@ -358,19 +369,26 @@ static int qt1010_init(struct dvb_frontend *fe) for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { switch (i2c_data[i].oper) { case QT1010_WR: - err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + err = qt1010_writereg(priv, i2c_data[i].reg, + i2c_data[i].val); break; case QT1010_RD: - if (i2c_data[i].val == 0x20) valptr = &priv->reg20_init_val; - else valptr = &tmpval; + if (i2c_data[i].val == 0x20) + valptr = &priv->reg20_init_val; + else + valptr = &tmpval; err = qt1010_readreg(priv, i2c_data[i].reg, valptr); break; case QT1010_M1: - if (i2c_data[i].val == 0x25) valptr = &priv->reg25_init_val; - else if (i2c_data[i].val == 0x1f) valptr = &priv->reg1f_init_val; - else valptr = &tmpval; - err = qt1010_init_meas1(priv, i2c_data[i+1].reg, i2c_data[i].reg, - i2c_data[i].val, valptr); + if (i2c_data[i].val == 0x25) + valptr = &priv->reg25_init_val; + else if (i2c_data[i].val == 0x1f) + valptr = &priv->reg1f_init_val; + else + valptr = &tmpval; + err = qt1010_init_meas1(priv, i2c_data[i+1].reg, + i2c_data[i].reg, + i2c_data[i].val, valptr); i++; break; } @@ -435,8 +453,8 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, if (priv == NULL) return NULL; - priv->cfg = cfg; - priv->i2c = i2c; + priv->cfg = cfg; + priv->i2c = i2c; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ @@ -452,7 +470,8 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ printk(KERN_INFO "Quantek QT1010 successfully identified.\n"); - memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops, sizeof(struct dvb_tuner_ops)); + memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops, + sizeof(struct dvb_tuner_ops)); fe->tuner_priv = priv; return fe; -- cgit v1.1