From 85d7d7ca5ef820f2c637032c86d4298ce4ae491b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 9 Apr 2009 09:16:12 -0300 Subject: V4L/DVB (11490): af9015: add new dvb_usb_device_properties entry for upcoming USB IDs Add 3rd dvb_usb_device_properties entry for upcoming USB IDs because current entries are full. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 65 +++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 53bfc8e..d6662f5 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -40,7 +40,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static DEFINE_MUTEX(af9015_usb_mutex); static struct af9015_config af9015_config; -static struct dvb_usb_device_properties af9015_properties[2]; +static struct dvb_usb_device_properties af9015_properties[3]; static int af9015_properties_count = ARRAY_SIZE(af9015_properties); static struct af9013_config af9015_af9013_config[] = { @@ -1321,7 +1321,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 9, + .num_device_descs = 9, /* max 9 */ .devices = { { .name = "Afatech AF9015 DVB-T USB2.0 stick", @@ -1426,7 +1426,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 9, + .num_device_descs = 9, /* max 9 */ .devices = { { .name = "Xtensions XD-380", @@ -1478,7 +1478,64 @@ static struct dvb_usb_device_properties af9015_properties[] = { .warm_ids = {NULL}, }, } - } + }, { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = DEVICE_SPECIFIC, + .download_firmware = af9015_download_firmware, + .firmware = "dvb-usb-af9015.fw", + .no_reconnect = 1, + + .size_of_priv = sizeof(struct af9015_state), \ + + .num_adapters = 2, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + + .pid_filter_count = 32, + .pid_filter = af9015_pid_filter, + .pid_filter_ctrl = af9015_pid_filter_ctrl, + + .frontend_attach = + af9015_af9013_frontend_attach, + .tuner_attach = af9015_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 6, + .endpoint = 0x84, + }, + }, + { + .frontend_attach = + af9015_af9013_frontend_attach, + .tuner_attach = af9015_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 6, + .endpoint = 0x85, + .u = { + .bulk = { + .buffersize = + TS_USB20_MAX_PACKET_SIZE, + } + } + }, + } + }, + + .identify_state = af9015_identify_state, + + .rc_query = af9015_rc_query, + .rc_interval = 150, + + .i2c_algo = &af9015_i2c_algo, + + .num_device_descs = 0, /* max 9 */ + .devices = { + } + }, }; static int af9015_usb_probe(struct usb_interface *intf, -- cgit v1.1 From 1ed5fadec7728282466d0203851cf811864b42f7 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 9 Apr 2009 15:14:18 -0300 Subject: V4L/DVB (11491): af9015: support for AverMedia AVerTV Volar GPS 805 (A805) Add USB ID (07ca:a805) for AverMedia AVerTV Volar GPS 805 (A805). Thanks to Chris Brown for reporting and testing. Tested-by: Chris Brown Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 10 ++++++++-- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index d6662f5..85ce864 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1261,7 +1261,8 @@ static struct usb_device_id af9015_usb_table[] = { {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, +/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, + {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1532,8 +1533,13 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 0, /* max 9 */ + .num_device_descs = 1, /* max 9 */ .devices = { + { + .name = "AverMedia AVerTV Volar GPS 805 (A805)", + .cold_ids = {&af9015_usb_table[21], NULL}, + .warm_ids = {NULL}, + }, } }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index f506c74..a25b068 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -171,6 +171,7 @@ #define USB_PID_AVERMEDIA_A309 0xa309 #define USB_PID_AVERMEDIA_A310 0xa310 #define USB_PID_AVERMEDIA_A850 0x850a +#define USB_PID_AVERMEDIA_A805 0xa805 #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 -- cgit v1.1 From 734dd236a6045ca764d12ed0fd6a7c1e9a928ac1 Mon Sep 17 00:00:00 2001 From: Marcel Jueling Date: Thu, 9 Apr 2009 17:16:41 -0300 Subject: V4L/DVB (11492): af9015: support for Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0 Add USB ID (1b80:e397) for Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0. Signed-off-by: Marcel Jueling Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 9 ++++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 85ce864..965d7bd 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1263,6 +1263,7 @@ static struct usb_device_id af9015_usb_table[] = { {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, /* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1533,13 +1534,19 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 1, /* max 9 */ + .num_device_descs = 2, /* max 9 */ .devices = { { .name = "AverMedia AVerTV Volar GPS 805 (A805)", .cold_ids = {&af9015_usb_table[21], NULL}, .warm_ids = {NULL}, }, + { + .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \ + "V3.0", + .cold_ids = {&af9015_usb_table[22], NULL}, + .warm_ids = {NULL}, + }, } }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index a25b068..ca00512 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -80,6 +80,7 @@ #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d #define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 #define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 +#define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397 #define USB_PID_CONEXANT_D680_DMB 0x86d6 #define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 -- cgit v1.1 From b5d14eba2ecce23a6a1663bc5bd36c08a011b601 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Sun, 12 Apr 2009 16:58:52 -0300 Subject: V4L/DVB (11566): remove broken macro from dvb stv0900_priv.h It both has unbalanced parentheses and == is not = and it's not used anywhere anyway. Signed-off-by: Mariusz Kozlowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_priv.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h index 762d5af..67dc8ec 100644 --- a/drivers/media/dvb/frontends/stv0900_priv.h +++ b/drivers/media/dvb/frontends/stv0900_priv.h @@ -60,8 +60,6 @@ } \ } while (0) -#define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a)) - static int stvdebug; #define dprintk(args...) \ -- cgit v1.1 From 3763a8a41bd0c1ea6b055b60acaf5f9655e5c25e Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sun, 19 Apr 2009 17:21:03 -0300 Subject: V4L/DVB (11569): av7110_hw: fix compile warning Signed-off-by: Alexey Klimov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 5e3f889..e162691 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c @@ -1089,7 +1089,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) else { int i, len = dc->x0-dc->color+1; u8 __user *colors = (u8 __user *)dc->data; - u8 r, g, b, blend; + u8 r, g = 0, b = 0, blend = 0; ret = 0; for (i = 0; i Date: Mon, 20 Apr 2009 11:57:49 -0300 Subject: V4L/DVB (11571): Add Elgato EyeTV DTT deluxe to dibcom driver This patch introduces support for DVB-T for the following dibcom based card: Elgato EyeTV DTT deluxe (USB-ID: 0fd9:0020) Signed-off-by: Armin Schenker Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + drivers/media/dvb/dvb-usb/dvb-usb.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 8ddbadf..6251b38 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1493,6 +1493,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) }, { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) }, { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) }, +/* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1692,7 +1693,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 11, + .num_device_descs = 12, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1738,6 +1739,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[45], NULL }, { NULL }, }, + { "Elgato EyeTV Dtt Dlx PD378S", + { &dib0700_usb_id_table[50], NULL }, + { NULL }, + }, }, .rc_interval = DEFAULT_RC_INTERVAL, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index ca00512..6a4062d 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -253,5 +253,6 @@ #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 #define USB_PID_SONY_PLAYTV 0x0003 #define USB_PID_ELGATO_EYETV_DTT 0x0021 +#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 #endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 2d5352e..9749515 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -223,7 +223,7 @@ struct dvb_usb_device_properties { int generic_bulk_ctrl_endpoint; int num_device_descs; - struct dvb_usb_device_description devices[11]; + struct dvb_usb_device_description devices[12]; }; /** -- cgit v1.1 From e415c689a8842670e161581f060575c14957f073 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 6 Apr 2009 15:45:20 -0300 Subject: V4L/DVB (11579): Initial go at TT S2-1600 [mchehab@redhat.com: fix compilation when the new drivers aren't selected] Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 22 + drivers/media/dvb/frontends/Makefile | 4 +- drivers/media/dvb/frontends/isl6423.c | 293 ++ drivers/media/dvb/frontends/isl6423.h | 63 + drivers/media/dvb/frontends/stv090x.c | 3928 +++++++++++++++++++++++++++ drivers/media/dvb/frontends/stv090x.h | 93 + drivers/media/dvb/frontends/stv090x_priv.h | 274 ++ drivers/media/dvb/frontends/stv090x_reg.h | 2300 ++++++++++++++++ drivers/media/dvb/frontends/stv6110x.c | 372 +++ drivers/media/dvb/frontends/stv6110x.h | 71 + drivers/media/dvb/frontends/stv6110x_priv.h | 77 + drivers/media/dvb/frontends/stv6110x_reg.h | 82 + drivers/media/dvb/ttpci/budget-ci.c | 83 + 13 files changed, 7661 insertions(+), 1 deletion(-) create mode 100644 drivers/media/dvb/frontends/isl6423.c create mode 100644 drivers/media/dvb/frontends/isl6423.h create mode 100644 drivers/media/dvb/frontends/stv090x.c create mode 100644 drivers/media/dvb/frontends/stv090x.h create mode 100644 drivers/media/dvb/frontends/stv090x_priv.h create mode 100644 drivers/media/dvb/frontends/stv090x_reg.h create mode 100644 drivers/media/dvb/frontends/stv6110x.c create mode 100644 drivers/media/dvb/frontends/stv6110x.h create mode 100644 drivers/media/dvb/frontends/stv6110x_priv.h create mode 100644 drivers/media/dvb/frontends/stv6110x_reg.h (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 23e4cff..be967ac 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -35,6 +35,21 @@ config DVB_STB6100 A Silicon tuner from ST used in conjunction with the STB0899 demodulator. Say Y when you want to support this tuner. +config DVB_STV090x + tristate "STV0900/STV0903(A/B) based" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators. + Say Y when you want to support these frontends. + +config DVB_STV6110x + tristate "STV6110/(A) based tuners" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A Silicon tuner that supports DVB-S and DVB-S2 modes + comment "DVB-S (satellite) frontends" depends on DVB_CORE @@ -506,6 +521,13 @@ config DVB_ISL6421 help An SEC control chip. +config DVB_ISL6423 + tristate "ISL6423 SEC controller" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A SEC controller chip from Intersil + config DVB_LGS8GL5 tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index bc2b00a..832473c 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -71,4 +71,6 @@ obj-$(CONFIG_DVB_STB6000) += stb6000.o obj-$(CONFIG_DVB_S921) += s921.o obj-$(CONFIG_DVB_STV6110) += stv6110.o obj-$(CONFIG_DVB_STV0900) += stv0900.o - +obj-$(CONFIG_DVB_STV090x) += stv090x.o +obj-$(CONFIG_DVB_STV6110x) += stv6110x.o +obj-$(CONFIG_DVB_ISL6423) += isl6423.o diff --git a/drivers/media/dvb/frontends/isl6423.c b/drivers/media/dvb/frontends/isl6423.c new file mode 100644 index 0000000..c1943dc --- /dev/null +++ b/drivers/media/dvb/frontends/isl6423.c @@ -0,0 +1,293 @@ +/* + Intersil ISL6423 SEC and LNB Power supply controller + + Copyright (C) Manu Abraham + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "isl6423.h" + +static unsigned int verbose; +module_param(verbose, int, 0644); +MODULE_PARM_DESC(verbose, "Set Verbosity level"); + +#define FE_ERROR 0 +#define FE_NOTICE 1 +#define FE_INFO 2 +#define FE_DEBUG 3 +#define FE_DEBUGREG 4 + +#define dprintk(__y, __z, format, arg...) do { \ + if (__z) { \ + if ((verbose > FE_ERROR) && (verbose > __y)) \ + printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_NOTICE) && (verbose > __y)) \ + printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_INFO) && (verbose > __y)) \ + printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_DEBUG) && (verbose > __y)) \ + printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ + } else { \ + if (verbose > __y) \ + printk(format, ##arg); \ + } \ +} while (0) + +struct isl6423_dev { + const struct isl6423_config *config; + struct i2c_adapter *i2c; + + u8 reg_3; + u8 reg_4; + + unsigned int verbose; +}; + +static int isl6423_write(struct isl6423_dev *isl6423, u8 reg) +{ + struct i2c_adapter *i2c = isl6423->i2c; + u8 addr = isl6423->config->addr; + int err = 0; + + struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = ®, .len = 1 }; + + err = i2c_transfer(i2c, &msg, 1); + if (err < 0) + goto exit; + return 0; + +exit: + dprintk(FE_ERROR, 1, "I/O error <%d>", err); + return err; +} + +static int isl6423_set_modulation(struct dvb_frontend *fe) +{ + struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; + const struct isl6423_config *config = isl6423->config; + int err = 0; + u8 reg_2 = 0; + + reg_2 = 0x01 << 5; + + if (config->mod_extern) + reg_2 |= (1 << 3); + else + reg_2 |= (1 << 4); + + err = isl6423_write(isl6423, reg_2); + if (err < 0) + goto exit; + return 0; + +exit: + dprintk(FE_ERROR, 1, "I/O error <%d>", err); + return err; +} + +static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg) +{ + struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; + u8 reg_3 = isl6423->reg_3; + u8 reg_4 = isl6423->reg_4; + int err = 0; + + if (arg) { + /* EN = 1, VSPEN = 1, VBOT = 1 */ + reg_4 |= (1 << 4); + reg_4 |= 0x1; + reg_3 |= (1 << 3); + } else { + /* EN = 1, VSPEN = 1, VBOT = 0 */ + reg_4 |= (1 << 4); + reg_4 &= ~0x1; + reg_3 |= (1 << 3); + } + err = isl6423_write(isl6423, reg_3); + if (err < 0) + goto exit; + + err = isl6423_write(isl6423, reg_4); + if (err < 0) + goto exit; + + return 0; +exit: + dprintk(FE_ERROR, 1, "I/O error <%d>", err); + return err; +} + + +static int isl6423_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) +{ + struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; + u8 reg_4 = isl6423->reg_4; + int err = 0; + + /* SR4H = 0, SR4M = 1, SR4L = 1 */ + reg_4 = 0x03 << 5; + + switch (voltage) { + case SEC_VOLTAGE_OFF: + /* EN = 0 */ + reg_4 &= ~(1 << 4); + break; + + case SEC_VOLTAGE_13: + /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */ + reg_4 |= (1 << 4); + reg_4 &= ~0x3; + break; + + case SEC_VOLTAGE_18: + /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */ + reg_4 |= (1 << 4); + reg_4 |= 0x2; + reg_4 &= ~0x1; + break; + + default: + break; + } + err = isl6423_write(isl6423, reg_4); + if (err < 0) + goto exit; + + return 0; +exit: + dprintk(FE_ERROR, 1, "I/O error <%d>", err); + return err; +} + +static int isl6423_set_current(struct dvb_frontend *fe) +{ + struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; + u8 reg_3 = isl6423->reg_3; + const struct isl6423_config *config = isl6423->config; + int err = 0; + + /* SR3H = 0, SR3M = 1, SR3L = 0 */ + reg_3 = 0x02 << 5; + + switch (config->current_max) { + case SEC_CURRENT_275m: + /* 275mA */ + /* ISELH = 0, ISELL = 0 */ + reg_3 &= ~0x3; + break; + + case SEC_CURRENT_515m: + /* 515mA */ + /* ISELH = 0, ISELL = 1 */ + reg_3 &= ~0x2; + reg_3 |= 0x1; + break; + + case SEC_CURRENT_635m: + /* 635mA */ + /* ISELH = 1, ISELL = 0 */ + reg_3 &= ~0x1; + reg_3 |= 0x2; + break; + + case SEC_CURRENT_800m: + /* 800mA */ + /* ISELH = 1, ISELL = 1 */ + reg_3 |= 0x3; + break; + } + + err = isl6423_write(isl6423, reg_3); + if (err < 0) + goto exit; + + switch (config->curlim) { + case SEC_CURRENT_LIM_ON: + /* DCL = 1 */ + reg_3 |= 0x10; + break; + + case SEC_CURRENT_LIM_OFF: + /* DCL = 0 */ + reg_3 &= ~0x10; + break; + } + + err = isl6423_write(isl6423, reg_3); + if (err < 0) + goto exit; + + return 0; +exit: + dprintk(FE_ERROR, 1, "I/O error <%d>", err); + return err; +} + +static void isl6423_release(struct dvb_frontend *fe) +{ + isl6423_set_voltage(fe, SEC_VOLTAGE_OFF); + + kfree(fe->sec_priv); + fe->sec_priv = NULL; +} + +struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + const struct isl6423_config *config) +{ + struct isl6423_dev *isl6423; + + isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL); + if (!isl6423) + return NULL; + + isl6423->config = config; + isl6423->i2c = i2c; + fe->sec_priv = isl6423; + + if (isl6423_set_current(fe)) + goto exit; + + if (isl6423_set_modulation(fe)) + goto exit; + + fe->ops.release_sec = isl6423_release; + fe->ops.set_voltage = isl6423_set_voltage; + fe->ops.enable_high_lnb_voltage = isl6423_voltage_boost; + isl6423->verbose = verbose; + + return fe; + +exit: + kfree(isl6423); + fe->sec_priv = NULL; + return NULL; +} +EXPORT_SYMBOL(isl6423_attach); + +MODULE_DESCRIPTION("ISL6423 SEC"); +MODULE_AUTHOR("Manu Abraham"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/isl6423.h b/drivers/media/dvb/frontends/isl6423.h new file mode 100644 index 0000000..e1a37fb --- /dev/null +++ b/drivers/media/dvb/frontends/isl6423.h @@ -0,0 +1,63 @@ +/* + Intersil ISL6423 SEC and LNB Power supply controller + + Copyright (C) Manu Abraham + + 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 __ISL_6423_H +#define __ISL_6423_H + +#include + +enum isl6423_current { + SEC_CURRENT_275m = 0, + SEC_CURRENT_515m, + SEC_CURRENT_635m, + SEC_CURRENT_800m, +}; + +enum isl6423_curlim { + SEC_CURRENT_LIM_ON = 1, + SEC_CURRENT_LIM_OFF +}; + +struct isl6423_config { + enum isl6423_current current_max; + enum isl6423_curlim curlim; + u8 addr; + u8 mod_extern; +}; + +#if defined(CONFIG_DVB_ISL6423) || (defined(CONFIG_DVB_ISL6423_MODULE) && defined(MODULE)) + + +extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + const struct isl6423_config *config); + +#else +static inline struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + const struct isl6423_config *config) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +#endif /* CONFIG_DVB_ISL6423 */ + +#endif /* __ISL_6423_H */ diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c new file mode 100644 index 0000000..a65f1b7 --- /dev/null +++ b/drivers/media/dvb/frontends/stv090x.c @@ -0,0 +1,3928 @@ +/* + STV0900/0903 Multistandard Broadcast Frontend driver + Copyright (C) Manu Abraham + + Copyright (C) ST Microelectronics + + 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 "stv6110x.h" /* for demodulator internal modes */ + +#include "stv090x_reg.h" +#include "stv090x.h" +#include "stv090x_priv.h" + +static unsigned int verbose; +module_param(verbose, int, 0644); + +struct mutex demod_lock; + +/* DVBS1 and DSS C/N Lookup table */ +static const struct stv090x_tab stv090x_s1cn_tab[] = { + { 0, 8917 }, /* 0.0dB */ + { 5, 8801 }, /* 0.5dB */ + { 10, 8667 }, /* 1.0dB */ + { 15, 8522 }, /* 1.5dB */ + { 20, 8355 }, /* 2.0dB */ + { 25, 8175 }, /* 2.5dB */ + { 30, 7979 }, /* 3.0dB */ + { 35, 7763 }, /* 3.5dB */ + { 40, 7530 }, /* 4.0dB */ + { 45, 7282 }, /* 4.5dB */ + { 50, 7026 }, /* 5.0dB */ + { 55, 6781 }, /* 5.5dB */ + { 60, 6514 }, /* 6.0dB */ + { 65, 6241 }, /* 6.5dB */ + { 70, 5965 }, /* 7.0dB */ + { 75, 5690 }, /* 7.5dB */ + { 80, 5424 }, /* 8.0dB */ + { 85, 5161 }, /* 8.5dB */ + { 90, 4902 }, /* 9.0dB */ + { 95, 4654 }, /* 9.5dB */ + { 100, 4417 }, /* 10.0dB */ + { 105, 4186 }, /* 10.5dB */ + { 110, 3968 }, /* 11.0dB */ + { 115, 3757 }, /* 11.5dB */ + { 120, 3558 }, /* 12.0dB */ + { 125, 3366 }, /* 12.5dB */ + { 130, 3185 }, /* 13.0dB */ + { 135, 3012 }, /* 13.5dB */ + { 140, 2850 }, /* 14.0dB */ + { 145, 2698 }, /* 14.5dB */ + { 150, 2550 }, /* 15.0dB */ + { 160, 2283 }, /* 16.0dB */ + { 170, 2042 }, /* 17.0dB */ + { 180, 1827 }, /* 18.0dB */ + { 190, 1636 }, /* 19.0dB */ + { 200, 1466 }, /* 20.0dB */ + { 210, 1315 }, /* 21.0dB */ + { 220, 1181 }, /* 22.0dB */ + { 230, 1064 }, /* 23.0dB */ + { 240, 960 }, /* 24.0dB */ + { 250, 869 }, /* 25.0dB */ + { 260, 792 }, /* 26.0dB */ + { 270, 724 }, /* 27.0dB */ + { 280, 665 }, /* 28.0dB */ + { 290, 616 }, /* 29.0dB */ + { 300, 573 }, /* 30.0dB */ + { 310, 537 }, /* 31.0dB */ + { 320, 507 }, /* 32.0dB */ + { 330, 483 }, /* 33.0dB */ + { 400, 398 }, /* 40.0dB */ + { 450, 381 }, /* 45.0dB */ + { 500, 377 } /* 50.0dB */ +}; + +/* DVBS2 C/N Lookup table */ +static const struct stv090x_tab stv090x_s2cn_tab[] = { + { -30, 13348 }, /* -3.0dB */ + { -20, 12640 }, /* -2d.0B */ + { -10, 11883 }, /* -1.0dB */ + { 0, 11101 }, /* -0.0dB */ + { 5, 10718 }, /* 0.5dB */ + { 10, 10339 }, /* 1.0dB */ + { 15, 9947 }, /* 1.5dB */ + { 20, 9552 }, /* 2.0dB */ + { 25, 9183 }, /* 2.5dB */ + { 30, 8799 }, /* 3.0dB */ + { 35, 8422 }, /* 3.5dB */ + { 40, 8062 }, /* 4.0dB */ + { 45, 7707 }, /* 4.5dB */ + { 50, 7353 }, /* 5.0dB */ + { 55, 7025 }, /* 5.5dB */ + { 60, 6684 }, /* 6.0dB */ + { 65, 6331 }, /* 6.5dB */ + { 70, 6036 }, /* 7.0dB */ + { 75, 5727 }, /* 7.5dB */ + { 80, 5437 }, /* 8.0dB */ + { 85, 5164 }, /* 8.5dB */ + { 90, 4902 }, /* 9.0dB */ + { 95, 4653 }, /* 9.5dB */ + { 100, 4408 }, /* 10.0dB */ + { 105, 4187 }, /* 10.5dB */ + { 110, 3961 }, /* 11.0dB */ + { 115, 3751 }, /* 11.5dB */ + { 120, 3558 }, /* 12.0dB */ + { 125, 3368 }, /* 12.5dB */ + { 130, 3191 }, /* 13.0dB */ + { 135, 3017 }, /* 13.5dB */ + { 140, 2862 }, /* 14.0dB */ + { 145, 2710 }, /* 14.5dB */ + { 150, 2565 }, /* 15.0dB */ + { 160, 2300 }, /* 16.0dB */ + { 170, 2058 }, /* 17.0dB */ + { 180, 1849 }, /* 18.0dB */ + { 190, 1663 }, /* 19.0dB */ + { 200, 1495 }, /* 20.0dB */ + { 210, 1349 }, /* 21.0dB */ + { 220, 1222 }, /* 22.0dB */ + { 230, 1110 }, /* 23.0dB */ + { 240, 1011 }, /* 24.0dB */ + { 250, 925 }, /* 25.0dB */ + { 260, 853 }, /* 26.0dB */ + { 270, 789 }, /* 27.0dB */ + { 280, 734 }, /* 28.0dB */ + { 290, 690 }, /* 29.0dB */ + { 300, 650 }, /* 30.0dB */ + { 310, 619 }, /* 31.0dB */ + { 320, 593 }, /* 32.0dB */ + { 330, 571 }, /* 33.0dB */ + { 400, 498 }, /* 40.0dB */ + { 450, 484 }, /* 45.0dB */ + { 500, 481 } /* 50.0dB */ +}; + +/* RF level C/N lookup table */ +static const struct stv090x_tab stv090x_rf_tab[] = { + { -5, 0xcaa1 }, /* -5dBm */ + { -10, 0xc229 }, /* -10dBm */ + { -15, 0xbb08 }, /* -15dBm */ + { -20, 0xb4bc }, /* -20dBm */ + { -25, 0xad5a }, /* -25dBm */ + { -30, 0xa298 }, /* -30dBm */ + { -35, 0x98a8 }, /* -35dBm */ + { -40, 0x8389 }, /* -40dBm */ + { -45, 0x59be }, /* -45dBm */ + { -50, 0x3a14 }, /* -50dBm */ + { -55, 0x2d11 }, /* -55dBm */ + { -60, 0x210d }, /* -60dBm */ + { -65, 0xa14f }, /* -65dBm */ + { -70, 0x07aa } /* -70dBm */ +}; + + +static struct stv090x_reg stv0900_initval[] = { + + { STV090x_OUTCFG, 0x00 }, + { STV090x_AGCRF1CFG, 0x11 }, + { STV090x_AGCRF2CFG, 0x13 }, + { STV090x_TSTTNR2, 0x21 }, + { STV090x_TSTTNR4, 0x21 }, + { STV090x_P2_DISTXCTL, 0x22 }, + { STV090x_P2_F22TX, 0xc0 }, + { STV090x_P2_F22RX, 0xc0 }, + { STV090x_P2_DISRXCTL, 0x00 }, + { STV090x_P2_DMDCFGMD, 0xF9 }, + { STV090x_P2_DEMOD, 0x08 }, + { STV090x_P2_DMDCFG3, 0xc4 }, + { STV090x_P2_CARFREQ, 0xed }, + { STV090x_P2_LDT, 0xd0 }, + { STV090x_P2_LDT2, 0xb8 }, + { STV090x_P2_TMGCFG, 0xd2 }, + { STV090x_P2_TMGTHRISE, 0x20 }, + { STV090x_P1_TMGCFG, 0xd2 }, + + { STV090x_P2_TMGTHFALL, 0x00 }, + { STV090x_P2_FECSPY, 0x88 }, + { STV090x_P2_FSPYDATA, 0x3a }, + { STV090x_P2_FBERCPT4, 0x00 }, + { STV090x_P2_FSPYBER, 0x10 }, + { STV090x_P2_ERRCTRL1, 0x35 }, + { STV090x_P2_ERRCTRL2, 0xc1 }, + { STV090x_P2_CFRICFG, 0xf8 }, + { STV090x_P2_NOSCFG, 0x1c }, + { STV090x_P2_CORRELMANT, 0x70 }, + { STV090x_P2_CORRELABS, 0x88 }, + { STV090x_P2_AGC2REF, 0x38 }, + { STV090x_P2_CARCFG, 0xe4 }, + { STV090x_P2_ACLC, 0x1A }, + { STV090x_P2_BCLC, 0x09 }, + { STV090x_P2_CARHDR, 0x08 }, + { STV090x_P2_KREFTMG, 0xc1 }, + { STV090x_P2_SFRUPRATIO, 0xf0 }, + { STV090x_P2_SFRLOWRATIO, 0x70 }, + { STV090x_P2_SFRSTEP, 0x58 }, + { STV090x_P2_TMGCFG2, 0x01 }, + { STV090x_P2_CAR2CFG, 0x26 }, + { STV090x_P2_BCLC2S2Q, 0x86 }, + { STV090x_P2_BCLC2S28, 0x86 }, + { STV090x_P2_SMAPCOEF7, 0x77 }, + { STV090x_P2_SMAPCOEF6, 0x85 }, + { STV090x_P2_SMAPCOEF5, 0x77 }, + { STV090x_P2_TSCFGL, 0x20 }, + { STV090x_P2_DMDCFG2, 0x3b }, + { STV090x_P2_MODCODLST0, 0xff }, + { STV090x_P2_MODCODLST1, 0xff }, + { STV090x_P2_MODCODLST2, 0xff }, + { STV090x_P2_MODCODLST3, 0xff }, + { STV090x_P2_MODCODLST4, 0xff }, + { STV090x_P2_MODCODLST5, 0xff }, + { STV090x_P2_MODCODLST6, 0xff }, + { STV090x_P2_MODCODLST7, 0xcc }, + { STV090x_P2_MODCODLST8, 0xcc }, + { STV090x_P2_MODCODLST9, 0xcc }, + { STV090x_P2_MODCODLSTA, 0xcc }, + { STV090x_P2_MODCODLSTB, 0xcc }, + { STV090x_P2_MODCODLSTC, 0xcc }, + { STV090x_P2_MODCODLSTD, 0xcc }, + { STV090x_P2_MODCODLSTE, 0xcc }, + { STV090x_P2_MODCODLSTF, 0xcf }, + { STV090x_P1_DISTXCTL, 0x22 }, + { STV090x_P1_F22TX, 0xc0 }, + { STV090x_P1_F22RX, 0xc0 }, + { STV090x_P1_DISRXCTL, 0x00 }, + { STV090x_P1_DMDCFGMD, 0xf9 }, + { STV090x_P1_DEMOD, 0x08 }, + { STV090x_P1_DMDCFG3, 0xc4 }, + { STV090x_P1_CARFREQ, 0xed }, + { STV090x_P1_LDT, 0xd0 }, + { STV090x_P1_LDT2, 0xb8 }, + { STV090x_P1_TMGCFG, 0xd2 }, + { STV090x_P1_TMGTHRISE, 0x20 }, + { STV090x_P1_TMGTHFALL, 0x00 }, + { STV090x_P1_SFRUPRATIO, 0xf0 }, + { STV090x_P1_SFRLOWRATIO, 0x70 }, + { STV090x_P1_TSCFGL, 0x20 }, + { STV090x_P1_FECSPY, 0x88 }, + { STV090x_P1_FSPYDATA, 0x3a }, + { STV090x_P1_FBERCPT4, 0x00 }, + { STV090x_P1_FSPYBER, 0x10 }, + { STV090x_P1_ERRCTRL1, 0x35 }, + { STV090x_P1_ERRCTRL2, 0xc1 }, + { STV090x_P1_CFRICFG, 0xf8 }, + { STV090x_P1_NOSCFG, 0x1c }, + { STV090x_P1_CORRELMANT, 0x70 }, + { STV090x_P1_CORRELABS, 0x88 }, + { STV090x_P1_AGC2REF, 0x38 }, + { STV090x_P1_CARCFG, 0xe4 }, + { STV090x_P1_ACLC, 0x1A }, + { STV090x_P1_BCLC, 0x09 }, + { STV090x_P1_CARHDR, 0x08 }, + { STV090x_P1_KREFTMG, 0xc1 }, + { STV090x_P1_SFRSTEP, 0x58 }, + { STV090x_P1_TMGCFG2, 0x01 }, + { STV090x_P1_CAR2CFG, 0x26 }, + { STV090x_P1_BCLC2S2Q, 0x86 }, + { STV090x_P1_BCLC2S28, 0x86 }, + { STV090x_P1_SMAPCOEF7, 0x77 }, + { STV090x_P1_SMAPCOEF6, 0x85 }, + { STV090x_P1_SMAPCOEF5, 0x77 }, + { STV090x_P1_DMDCFG2, 0x3b }, + { STV090x_P1_MODCODLST0, 0xff }, + { STV090x_P1_MODCODLST1, 0xff }, + { STV090x_P1_MODCODLST2, 0xff }, + { STV090x_P1_MODCODLST3, 0xff }, + { STV090x_P1_MODCODLST4, 0xff }, + { STV090x_P1_MODCODLST5, 0xff }, + { STV090x_P1_MODCODLST6, 0xff }, + { STV090x_P1_MODCODLST7, 0xcc }, + { STV090x_P1_MODCODLST8, 0xcc }, + { STV090x_P1_MODCODLST9, 0xcc }, + { STV090x_P1_MODCODLSTA, 0xcc }, + { STV090x_P1_MODCODLSTB, 0xcc }, + { STV090x_P1_MODCODLSTC, 0xcc }, + { STV090x_P1_MODCODLSTD, 0xcc }, + { STV090x_P1_MODCODLSTE, 0xcc }, + { STV090x_P1_MODCODLSTF, 0xcf }, + { STV090x_GENCFG, 0x1d }, + { STV090x_NBITER_NF4, 0x37 }, + { STV090x_NBITER_NF5, 0x29 }, + { STV090x_NBITER_NF6, 0x37 }, + { STV090x_NBITER_NF7, 0x33 }, + { STV090x_NBITER_NF8, 0x31 }, + { STV090x_NBITER_NF9, 0x2f }, + { STV090x_NBITER_NF10, 0x39 }, + { STV090x_NBITER_NF11, 0x3a }, + { STV090x_NBITER_NF12, 0x29 }, + { STV090x_NBITER_NF13, 0x37 }, + { STV090x_NBITER_NF14, 0x33 }, + { STV090x_NBITER_NF15, 0x2f }, + { STV090x_NBITER_NF16, 0x39 }, + { STV090x_NBITER_NF17, 0x3a }, + { STV090x_NBITERNOERR, 0x04 }, + { STV090x_GAINLLR_NF4, 0x0C }, + { STV090x_GAINLLR_NF5, 0x0F }, + { STV090x_GAINLLR_NF6, 0x11 }, + { STV090x_GAINLLR_NF7, 0x14 }, + { STV090x_GAINLLR_NF8, 0x17 }, + { STV090x_GAINLLR_NF9, 0x19 }, + { STV090x_GAINLLR_NF10, 0x20 }, + { STV090x_GAINLLR_NF11, 0x21 }, + { STV090x_GAINLLR_NF12, 0x0D }, + { STV090x_GAINLLR_NF13, 0x0F }, + { STV090x_GAINLLR_NF14, 0x13 }, + { STV090x_GAINLLR_NF15, 0x1A }, + { STV090x_GAINLLR_NF16, 0x1F }, + { STV090x_GAINLLR_NF17, 0x21 }, + { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */ + { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */ + { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */ + { STV090x_P2_PRVIT, 0x2F }, /* disable PR 6/7 */ +}; + +static struct stv090x_reg stv0903_initval[] = { + { STV090x_OUTCFG, 0x00 }, + { STV090x_AGCRF1CFG, 0x11 }, + { STV090x_STOPCLK1, 0x48 }, + { STV090x_STOPCLK2, 0x14 }, + { STV090x_TSTTNR1, 0x27 }, + { STV090x_TSTTNR2, 0x21 }, + { STV090x_P1_DISTXCTL, 0x22 }, + { STV090x_P1_F22TX, 0xc0 }, + { STV090x_P1_F22RX, 0xc0 }, + { STV090x_P1_DISRXCTL, 0x00 }, + { STV090x_P1_DMDCFGMD, 0xF9 }, + { STV090x_P1_DEMOD, 0x08 }, + { STV090x_P1_DMDCFG3, 0xc4 }, + { STV090x_P1_CARFREQ, 0xed }, + { STV090x_P1_TNRCFG2, 0x82 }, + { STV090x_P1_LDT, 0xd0 }, + { STV090x_P1_LDT2, 0xb8 }, + { STV090x_P1_TMGCFG, 0xd2 }, + { STV090x_P1_TMGTHRISE, 0x20 }, + { STV090x_P1_TMGTHFALL, 0x00 }, + { STV090x_P1_SFRUPRATIO, 0xf0 }, + { STV090x_P1_SFRLOWRATIO, 0x70 }, + { STV090x_P1_TSCFGL, 0x20 }, + { STV090x_P1_FECSPY, 0x88 }, + { STV090x_P1_FSPYDATA, 0x3a }, + { STV090x_P1_FBERCPT4, 0x00 }, + { STV090x_P1_FSPYBER, 0x10 }, + { STV090x_P1_ERRCTRL1, 0x35 }, + { STV090x_P1_ERRCTRL2, 0xc1 }, + { STV090x_P1_CFRICFG, 0xf8 }, + { STV090x_P1_NOSCFG, 0x1c }, + { STV090x_P1_CORRELMANT, 0x70 }, + { STV090x_P1_CORRELABS, 0x88 }, + { STV090x_P1_AGC2REF, 0x38 } , + { STV090x_P1_CARCFG, 0xe4 }, + { STV090x_P1_ACLC, 0x1A }, + { STV090x_P1_BCLC, 0x09 } , + { STV090x_P1_CARHDR, 0x08 }, + { STV090x_P1_KREFTMG, 0xc1 }, + { STV090x_P1_SFRSTEP, 0x58 }, + { STV090x_P1_TMGCFG2, 0x01 }, + { STV090x_P1_CAR2CFG, 0x26 }, + { STV090x_P1_BCLC2S2Q, 0x86 }, + { STV090x_P1_BCLC2S28, 0x86 }, + { STV090x_P1_SMAPCOEF7, 0x77 }, + { STV090x_P1_SMAPCOEF6, 0x85 }, + { STV090x_P1_SMAPCOEF5, 0x77 }, + { STV090x_P1_DMDCFG2, 0x3b }, + { STV090x_P1_MODCODLST0, 0xff }, + { STV090x_P1_MODCODLST1, 0xff }, + { STV090x_P1_MODCODLST2, 0xff }, + { STV090x_P1_MODCODLST3, 0xff }, + { STV090x_P1_MODCODLST4, 0xff }, + { STV090x_P1_MODCODLST5, 0xff }, + { STV090x_P1_MODCODLST6, 0xff }, + { STV090x_P1_MODCODLST7, 0xcc }, + { STV090x_P1_MODCODLST8, 0xcc }, + { STV090x_P1_MODCODLST9, 0xcc }, + { STV090x_P1_MODCODLSTA, 0xcc }, + { STV090x_P1_MODCODLSTB, 0xcc }, + { STV090x_P1_MODCODLSTC, 0xcc }, + { STV090x_P1_MODCODLSTD, 0xcc }, + { STV090x_P1_MODCODLSTE, 0xcc }, + { STV090x_P1_MODCODLSTF, 0xcf }, + { STV090x_GENCFG, 0x1c }, + { STV090x_NBITER_NF4, 0x37 }, + { STV090x_NBITER_NF5, 0x29 }, + { STV090x_NBITER_NF6, 0x37 }, + { STV090x_NBITER_NF7, 0x33 }, + { STV090x_NBITER_NF8, 0x31 }, + { STV090x_NBITER_NF9, 0x2f }, + { STV090x_NBITER_NF10, 0x39 }, + { STV090x_NBITER_NF11, 0x3a }, + { STV090x_NBITER_NF12, 0x29 }, + { STV090x_NBITER_NF13, 0x37 }, + { STV090x_NBITER_NF14, 0x33 }, + { STV090x_NBITER_NF15, 0x2f }, + { STV090x_NBITER_NF16, 0x39 }, + { STV090x_NBITER_NF17, 0x3a }, + { STV090x_NBITERNOERR, 0x04 }, + { STV090x_GAINLLR_NF4, 0x0C }, + { STV090x_GAINLLR_NF5, 0x0F }, + { STV090x_GAINLLR_NF6, 0x11 }, + { STV090x_GAINLLR_NF7, 0x14 }, + { STV090x_GAINLLR_NF8, 0x17 }, + { STV090x_GAINLLR_NF9, 0x19 }, + { STV090x_GAINLLR_NF10, 0x20 }, + { STV090x_GAINLLR_NF11, 0x21 }, + { STV090x_GAINLLR_NF12, 0x0D }, + { STV090x_GAINLLR_NF13, 0x0F }, + { STV090x_GAINLLR_NF14, 0x13 }, + { STV090x_GAINLLR_NF15, 0x1A }, + { STV090x_GAINLLR_NF16, 0x1F }, + { STV090x_GAINLLR_NF17, 0x21 }, + { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */ + { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/ +}; + +static struct stv090x_reg stv0900_cut20_val[] = { + + { STV090x_P2_DMDCFG3, 0xe8 }, + { STV090x_P2_CARFREQ, 0x38 }, + { STV090x_P2_CARHDR, 0x20 }, + { STV090x_P2_KREFTMG, 0x5a }, + { STV090x_P2_SMAPCOEF7, 0x06 }, + { STV090x_P2_SMAPCOEF6, 0x00 }, + { STV090x_P2_SMAPCOEF5, 0x04 }, + { STV090x_P2_NOSCFG, 0x0c }, + { STV090x_P1_DMDCFG3, 0xe8 }, + { STV090x_P1_CARFREQ, 0x38 }, + { STV090x_P1_CARHDR, 0x20 }, + { STV090x_P1_KREFTMG, 0x5a }, + { STV090x_P1_SMAPCOEF7, 0x06 }, + { STV090x_P1_SMAPCOEF6, 0x00 }, + { STV090x_P1_SMAPCOEF5, 0x04 }, + { STV090x_P1_NOSCFG, 0x0c }, + { STV090x_GAINLLR_NF4, 0x21 }, + { STV090x_GAINLLR_NF5, 0x21 }, + { STV090x_GAINLLR_NF6, 0x20 }, + { STV090x_GAINLLR_NF7, 0x1F }, + { STV090x_GAINLLR_NF8, 0x1E }, + { STV090x_GAINLLR_NF9, 0x1E }, + { STV090x_GAINLLR_NF10, 0x1D }, + { STV090x_GAINLLR_NF11, 0x1B }, + { STV090x_GAINLLR_NF12, 0x20 }, + { STV090x_GAINLLR_NF13, 0x20 }, + { STV090x_GAINLLR_NF14, 0x20 }, + { STV090x_GAINLLR_NF15, 0x20 }, + { STV090x_GAINLLR_NF16, 0x20 }, + { STV090x_GAINLLR_NF17, 0x21 }, +}; + +static struct stv090x_reg stv0903_cut20_val[] = { + { STV090x_P1_DMDCFG3, 0xe8 }, + { STV090x_P1_CARFREQ, 0x38 }, + { STV090x_P1_CARHDR, 0x20 }, + { STV090x_P1_KREFTMG, 0x5a }, + { STV090x_P1_SMAPCOEF7, 0x06 }, + { STV090x_P1_SMAPCOEF6, 0x00 }, + { STV090x_P1_SMAPCOEF5, 0x04 }, + { STV090x_P1_NOSCFG, 0x0c }, + { STV090x_GAINLLR_NF4, 0x21 }, + { STV090x_GAINLLR_NF5, 0x21 }, + { STV090x_GAINLLR_NF6, 0x20 }, + { STV090x_GAINLLR_NF7, 0x1F }, + { STV090x_GAINLLR_NF8, 0x1E }, + { STV090x_GAINLLR_NF9, 0x1E }, + { STV090x_GAINLLR_NF10, 0x1D }, + { STV090x_GAINLLR_NF11, 0x1B }, + { STV090x_GAINLLR_NF12, 0x20 }, + { STV090x_GAINLLR_NF13, 0x20 }, + { STV090x_GAINLLR_NF14, 0x20 }, + { STV090x_GAINLLR_NF15, 0x20 }, + { STV090x_GAINLLR_NF16, 0x20 }, + { STV090x_GAINLLR_NF17, 0x21 } +}; + +/* Cut 1.x Long Frame Tracking CR loop */ +static struct stv090x_long_frame_crloop stv090x_s2_crl[] = { + /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + { STV090x_QPSK_12, 0x1c, 0x0d, 0x1b, 0x2c, 0x3a, 0x1c, 0x2a, 0x3b, 0x2a, 0x1b }, + { STV090x_QPSK_35, 0x2c, 0x0d, 0x2b, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b, 0x2a, 0x0b }, + { STV090x_QPSK_23, 0x2c, 0x0d, 0x2b, 0x2c, 0x0b, 0x0c, 0x3a, 0x1b, 0x2a, 0x3a }, + { STV090x_QPSK_34, 0x3c, 0x0d, 0x3b, 0x1c, 0x0b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, + { STV090x_QPSK_45, 0x3c, 0x0d, 0x3b, 0x1c, 0x0b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, + { STV090x_QPSK_56, 0x0d, 0x0d, 0x3b, 0x1c, 0x0b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, + { STV090x_QPSK_89, 0x0d, 0x0d, 0x3b, 0x1c, 0x1b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, + { STV090x_QPSK_910, 0x1d, 0x0d, 0x3b, 0x1c, 0x1b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, + { STV090x_8PSK_35, 0x29, 0x3b, 0x09, 0x2b, 0x38, 0x0b, 0x18, 0x1a, 0x08, 0x0a }, + { STV090x_8PSK_23, 0x0a, 0x3b, 0x29, 0x2b, 0x19, 0x0b, 0x38, 0x1a, 0x18, 0x0a }, + { STV090x_8PSK_34, 0x3a, 0x3b, 0x2a, 0x2b, 0x39, 0x0b, 0x19, 0x1a, 0x38, 0x0a }, + { STV090x_8PSK_56, 0x1b, 0x3b, 0x0b, 0x2b, 0x1a, 0x0b, 0x39, 0x1a, 0x19, 0x0a }, + { STV090x_8PSK_89, 0x3b, 0x3b, 0x0b, 0x2b, 0x2a, 0x0b, 0x39, 0x1a, 0x29, 0x39 }, + { STV090x_8PSK_910, 0x3b, 0x3b, 0x0b, 0x2b, 0x2a, 0x0b, 0x39, 0x1a, 0x29, 0x39 } +}; + +/* Cut 2.0 Long Frame Tracking CR loop */ +static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = { + /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + { STV090x_QPSK_12, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e }, + { STV090x_QPSK_35, 0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e }, + { STV090x_QPSK_23, 0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d }, + { STV090x_QPSK_34, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, + { STV090x_QPSK_45, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, + { STV090x_QPSK_56, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, + { STV090x_QPSK_89, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, + { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, + { STV090x_8PSK_35, 0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d }, + { STV090x_8PSK_23, 0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d }, + { STV090x_8PSK_34, 0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d }, + { STV090x_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d }, + { STV090x_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d }, + { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d } +}; + + +/* Cut 2.0 Long Frame Tracking CR Loop */ +static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = { + /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + { STV090x_16APSK_23, 0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c }, + { STV090x_16APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c }, + { STV090x_16APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c }, + { STV090x_16APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c }, + { STV090x_16APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c }, + { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c }, + { STV090x_32APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, + { STV090x_32APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, + { STV090x_32APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, + { STV090x_32APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, + { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c } +}; + + +static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = { + /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + { STV090x_QPSK_14, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e }, + { STV090x_QPSK_13, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e }, + { STV090x_QPSK_25, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e } +}; + + +/* Cut 1.2 & 2.0 Short Frame Tracking CR Loop */ +static struct stv090x_short_frame_crloop stv090x_s2_short_crl[] = { + /* MODCOD 2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */ + { STV090x_QPSK, 0x3c, 0x2f, 0x2b, 0x2e, 0x0b, 0x0e, 0x3a, 0x0e, 0x2a, 0x3d }, + { STV090x_8PSK, 0x0b, 0x3e, 0x2a, 0x0e, 0x0a, 0x2d, 0x19, 0x0d, 0x09, 0x3c }, + { STV090x_16APSK, 0x1b, 0x1e, 0x1b, 0x1e, 0x1b, 0x1e, 0x3a, 0x3d, 0x2a, 0x2d }, + { STV090x_32APSK, 0x1b, 0x1e, 0x1b, 0x1e, 0x1b, 0x1e, 0x3a, 0x3d, 0x2a, 0x2d } +}; + + +static inline s32 comp2(s32 __x, s32 __width) +{ + if (__width == 32) + return __x; + else + return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x; +} + +static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg) +{ + const struct stv090x_config *config = state->config; + int ret; + + u8 b0[] = { reg >> 8, reg & 0xff }; + u8 buf; + + struct i2c_msg msg[] = { + { .addr = config->address, .flags = 0, .buf = b0, .len = 2 }, + { .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 } + }; + + ret = i2c_transfer(state->i2c, msg, 2); + if (ret != 2) { + if (ret != -ERESTARTSYS) + dprintk(FE_ERROR, 1, + "Read error, Reg=[0x%02x], Status=%d", + reg, ret); + + return ret < 0 ? ret : -EREMOTEIO; + } + if (unlikely(*state->verbose >= FE_DEBUGREG)) + dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x", + reg, buf); + + return (unsigned int) buf; +} + +static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count) +{ + const struct stv090x_config *config = state->config; + int ret; + u8 buf[2 + count]; + struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count }; + + buf[0] = reg >> 8; + buf[1] = reg & 0xff; + memcpy(&buf[2], data, count); + + if (unlikely(*state->verbose >= FE_DEBUGREG)) { + int i; + + printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); + for (i = 0; i < count; i++) + printk(" %02x", data[i]); + printk("\n"); + } + + ret = i2c_transfer(state->i2c, &i2c_msg, 1); + if (ret != 1) { + if (ret != -ERESTARTSYS) + dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d", + reg, data[0], count, ret); + return ret < 0 ? ret : -EREMOTEIO; + } + + return 0; +} + +static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data) +{ + return stv090x_write_regs(state, reg, &data, 1); +} + +static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg; + + reg = STV090x_READ_DEMOD(state, I2CRPT); + + if (enable) { + STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) + goto err; + + } else { + STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0); + if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0) + goto err; + } + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static void stv090x_get_lock_tmg(struct stv090x_state *state) +{ + switch (state->algo) { + case STV090x_BLIND_SEARCH: + dprintk(FE_DEBUG, 1, "Blind Search"); + if (state->srate <= 1500000) { /*10Msps< SR <=15Msps*/ + state->DemodTimeout = 1500; + state->FecTimeout = 400; + } else if (state->srate <= 5000000) { /*10Msps< SR <=15Msps*/ + state->DemodTimeout = 1000; + state->FecTimeout = 300; + } else { /*SR >20Msps*/ + state->DemodTimeout = 700; + state->FecTimeout = 100; + } + break; + + case STV090x_COLD_SEARCH: + case STV090x_WARM_SEARCH: + default: + dprintk(FE_DEBUG, 1, "Normal Search"); + if (state->srate <= 1000000) { /*SR <=1Msps*/ + state->DemodTimeout = 4500; + state->FecTimeout = 1700; + } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */ + state->DemodTimeout = 2500; + state->FecTimeout = 1100; + } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */ + state->DemodTimeout = 1000; + state->FecTimeout = 550; + } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */ + state->DemodTimeout = 700; + state->FecTimeout = 250; + } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */ + state->DemodTimeout = 400; + state->FecTimeout = 130; + } else { /*SR >20Msps*/ + state->DemodTimeout = 300; + state->FecTimeout = 100; + } + break; + } + + if (state->algo == STV090x_WARM_SEARCH) + state->DemodTimeout /= 2; +} + +static int stv090x_set_srate(struct stv090x_state *state, u32 srate) +{ + u32 sym; + + if (srate > 6000000) { + sym = (srate / 1000) * 65536; + sym /= (state->mclk / 1000); + } else { + sym = (srate / 100) * 65536; + sym /= (state->mclk / 100); + } + + if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) /* MSB */ + goto err; + if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */ + goto err; + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate) +{ + u32 sym; + + srate = 105 * (srate / 100); + if (srate > 6000000) { + sym = (srate / 1000) * 65536; + sym /= (clk / 1000); + } else { + sym = (srate / 100) * 65536; + sym /= (clk / 100); + } + if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */ + goto err; + if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */ + goto err; + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate) +{ + u32 sym; + + srate = 95 * (srate / 100); + if (srate > 6000000) { + sym = (srate / 1000) * 65536; + sym /= (clk / 1000); + } else { + sym = (srate / 100) * 65536; + sym /= (clk / 100); + } + if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */ + goto err; + if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */ + goto err; + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static u32 stv090x_car_width(u32 srate, u32 rolloff) +{ + return srate + (srate * rolloff) / 100; +} + +static int stv090x_set_vit_thacq(struct stv090x_state *state) +{ + if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0) + goto err; + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_set_vit_thtracq(struct stv090x_state *state) +{ + if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0) + goto err; + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_set_viterbi(struct stv090x_state *state) +{ + switch (state->search_mode) { + case STV090x_SEARCH_AUTO: + if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */ + goto err; + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */ + goto err; + break; + case STV090x_SEARCH_DVBS1: + if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */ + goto err; + switch (state->fec) { + case STV090x_PR12: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0) + goto err; + break; + + case STV090x_PR23: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0) + goto err; + break; + + case STV090x_PR34: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0) + goto err; + break; + + case STV090x_PR56: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0) + goto err; + break; + + case STV090x_PR78: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0) + goto err; + break; + + default: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */ + goto err; + break; + } + break; + case STV090x_SEARCH_DSS: + if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0) + goto err; + switch (state->fec) { + case STV090x_PR12: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0) + goto err; + break; + + case STV090x_PR23: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0) + goto err; + break; + + case STV090x_PR67: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0) + goto err; + break; + + default: + if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */ + goto err; + break; + } + break; + default: + break; + } + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_stop_modcod(struct stv090x_state *state) +{ + if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0) + goto err; + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_activate_modcod(struct stv090x_state *state) +{ + u32 matype, modcod, f_mod, index; + + if (state->dev_ver <= 0x11) { + msleep(5); + modcod = STV090x_READ_DEMOD(state, PLHMODCOD); + matype = modcod & 0x03; + modcod = (modcod & 0x7f) >> 2; + index = STV090x_ADDR_OFFST(state, MODCODLSTF) - (modcod / 2); + + switch (matype) { + default: + case 0: + f_mod = 14; + break; + case 1: + f_mod = 13; + break; + case 2: + f_mod = 11; + break; + case 3: + f_mod = 7; + break; + } + if (matype <= 1) { + if (modcod % 2) { + if (stv090x_write_reg(state, index, 0xf0 | f_mod) < 0) + goto err; + } else { + if (stv090x_write_reg(state, index, (f_mod << 4) | 0x0f) < 0) + goto err; + } + } + } else if (state->dev_ver >= 0x12) { + if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0) + goto err; + } + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) +{ + u32 reg; + + switch (state->demod) { + case STV090x_DEMODULATOR_0: + mutex_lock(&demod_lock); + reg = stv090x_read_reg(state, STV090x_STOPCLK2); + STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable); + if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) + goto err; + mutex_unlock(&demod_lock); + break; + + case STV090x_DEMODULATOR_1: + mutex_lock(&demod_lock); + reg = stv090x_read_reg(state, STV090x_STOPCLK2); + STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable); + if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) + goto err; + mutex_unlock(&demod_lock); + break; + + default: + dprintk(FE_ERROR, 1, "Wrong demodulator!"); + break; + } + return 0; +err: + mutex_unlock(&demod_lock); + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_delivery_search(struct stv090x_state *state) +{ + u32 reg; + + switch (state->search_mode) { + case STV090x_SEARCH_DVBS1: + case STV090x_SEARCH_DSS: + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + + /* Activate Viterbi decoder in legacy search, do not use FRESVIT1, might impact VITERBI2 */ + if (stv090x_vitclk_ctl(state, 0) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */ + goto err; + + stv090x_set_vit_thacq(state); + stv090x_set_viterbi(state); + break; + + case STV090x_SEARCH_DVBS2: + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + + if (stv090x_vitclk_ctl(state, 1) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */ + goto err; + if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) + goto err; + + if (state->demod_mode != STV090x_SINGLE) { + if (state->dev_ver <= 0x11) /* 900 in dual TS mode */ + stv090x_stop_modcod(state); + else + stv090x_activate_modcod(state); + } + break; + + case STV090x_SEARCH_AUTO: + default: + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + + if (stv090x_vitclk_ctl(state, 1) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ACLC, 0x09) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) + goto err; + + if (state->demod_mode != STV090x_SINGLE) { + if (state->dev_ver <= 0x11) /* 900 in dual TS mode */ + stv090x_stop_modcod(state); + else + stv090x_activate_modcod(state); + } + stv090x_set_vit_thacq(state); + stv090x_set_viterbi(state); + break; + } + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_start_search(struct stv090x_state *state) +{ + u32 reg; + + reg = STV090x_READ_DEMOD(state, DMDISTATE); + STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); + if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) + goto err; + + if (state->dev_ver == 0x10) { + if (STV090x_WRITE_DEMOD(state, CORRELEXP, 0xaa) < 0) + goto err; + } + if (state->dev_ver < 0x20) { + if (STV090x_WRITE_DEMOD(state, CARHDR, 0x55) < 0) + goto err; + } + if (state->srate <= 5000000) { + if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0) + goto err; + + /*enlarge the timing bandwith for Low SR*/ + if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) + goto err; + } else { + /* If the symbol rate is >5 Msps + Set The carrier search up and low to auto mode */ + if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) + goto err; + /*reduce the timing bandwith for high SR*/ + if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) + goto err; + + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) + goto err; + + if ((state->search_mode == STV090x_DVBS1) || + (state->search_mode == STV090x_DSS) || + (state->search_mode == STV090x_SEARCH_AUTO)) { + + if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) + goto err; + } + } + + if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0) + goto err; + + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + reg = STV090x_READ_DEMOD(state, DMDCFG2); + STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0); + if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0) + goto err; + + if (state->dev_ver >= 0x20) { /*Frequency offset detector setting*/ + if (state->srate < 10000000) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0) + goto err; + } + } else { + if (state->srate < 10000000) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) + goto err; + } + } + + switch (state->algo) { + case STV090x_WARM_SEARCH:/*The symbol rate and the exact carrier Frequency are known */ + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) + goto err; + break; + + case STV090x_COLD_SEARCH:/*The symbol rate is known*/ + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) + goto err; + break; + + default: + break; + } + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_get_agc2_min_level(struct stv090x_state *state) +{ + u32 agc2_min = 0, agc2 = 0, freq_init, freq_step, reg; + s32 i, j, steps, dir; + + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) + goto err; + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */ + goto err; + if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */ + goto err; + if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */ + goto err; + stv090x_set_srate(state, 1000000); + + steps = -1 + state->search_range / 1000000; + steps /= 2; + steps = (2 * steps) + 1; + if (steps < 0) + steps = 1; + + dir = 1; + freq_step = (1000000 * 256) / (state->mclk / 256); + freq_init = 0; + + for (i = 0; i < steps; i++) { + if (dir > 0) + freq_init = freq_init + (freq_step * i); + else + freq_init = freq_init - (freq_step * i); + + dir = -1; + + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */ + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */ + goto err; + msleep(10); + for (j = 0; j < 10; j++) { + agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8; + agc2 |= STV090x_READ_DEMOD(state, AGC2I0); + } + agc2 /= 10; + agc2_min = 0xffff; + if (agc2 < 0xffff) + agc2_min = agc2; + } + + return agc2_min; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk) +{ + u8 r3, r2, r1, r0; + s32 srate, int_1, int_2, tmp_1, tmp_2; + u32 pow2; + + r3 = STV090x_READ_DEMOD(state, SFR3); + r2 = STV090x_READ_DEMOD(state, SFR2); + r1 = STV090x_READ_DEMOD(state, SFR1); + r0 = STV090x_READ_DEMOD(state, SFR0); + + srate = ((r3 << 24) | (r2 << 16) | (r1 << 8) | r0); + + pow2 = 1 << 16; + int_1 = clk / pow2; + int_2 = srate / pow2; + + tmp_1 = clk % pow2; + tmp_2 = srate % pow2; + + srate = (int_1 * int_2) + + ((int_1 * tmp_2) / pow2) + + ((int_2 * tmp_1) / pow2); + + return srate; +} + +static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) +{ + struct dvb_frontend *fe = &state->frontend; + + int tmg_lock = 0, i; + s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq; + u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; + + reg = STV090x_READ_DEMOD(state, DMDISTATE); + STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */ + if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0) + goto err; + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0) + goto err; + + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x73) < 0) + goto err; + } + + if (state->srate <= 2000000) + car_step = 1000; + else if (state->srate <= 5000000) + car_step = 2000; + else if (state->srate <= 12000000) + car_step = 3000; + else + car_step = 5000; + + steps = -1 + ((state->search_range / 1000) / car_step); + steps /= 2; + steps = (2 * steps) + 1; + if (steps < 0) + steps = 1; + else if (steps > 10) { + steps = 11; + car_step = (state->search_range / 1000) / 10; + } + cur_step = 0; + dir = 1; + freq = state->frequency; + + while ((!tmg_lock) && (cur_step < steps)) { + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */ + goto err; + reg = STV090x_READ_DEMOD(state, DMDISTATE); + STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x00); /* trigger acquisition */ + if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) + goto err; + msleep(50); + for (i = 0; i < 10; i++) { + reg = STV090x_READ_DEMOD(state, DSTATUS); + if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2) + tmg_cpt++; + agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8; + agc2 |= STV090x_READ_DEMOD(state, AGC2I0); + } + agc2 /= 10; + srate_coarse = stv090x_get_srate(state, state->mclk); + cur_step++; + dir *= -1; + if ((tmg_cpt >= 5) && (agc2 < 0x1f00) && (srate_coarse < 55000000) && (srate_coarse > 850000)) + tmg_lock = 1; + else if (cur_step < steps) { + if (dir > 0) + freq += cur_step * car_step; + else + freq -= cur_step * car_step; + + /* Setup tuner */ + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_set_frequency) + state->config->tuner_set_frequency(fe, state->frequency); + + if (state->config->tuner_set_bandwidth) + state->config->tuner_set_bandwidth(fe, state->tuner_bw); + + stv090x_i2c_gate_ctrl(fe, 0); + msleep(50); + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_get_status) + state->config->tuner_get_status(fe, ®); + + if (reg) + dprintk(FE_DEBUG, 1, "Tuner phase locked"); + else + dprintk(FE_DEBUG, 1, "Tuner unlocked"); + + stv090x_i2c_gate_ctrl(fe, 0); + + } + } + if (!tmg_lock) + srate_coarse = 0; + else + srate_coarse = stv090x_get_srate(state, state->mclk); + + return srate_coarse; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static u32 stv090x_srate_srch_fine(struct stv090x_state *state) +{ + u32 srate_coarse, freq_coarse, sym, reg; + + srate_coarse = stv090x_get_srate(state, state->mclk); + freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8; + freq_coarse |= STV090x_READ_DEMOD(state, CFR1); + sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ + + if (sym < state->srate) + srate_coarse = 0; + else { + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */ + goto err; + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0) + goto err; + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) + goto err; + } + + if (srate_coarse > 3000000) { + sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ + sym = (sym / 1000) * 65536; + sym /= (state->mclk / 1000); + if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) + goto err; + sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */ + sym = (sym / 1000) * 65536; + sym /= (state->mclk / 1000); + if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) + goto err; + sym = (srate_coarse / 1000) * 65536; + sym /= (state->mclk / 1000); + if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) + goto err; + } else { + sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ + sym = (sym / 100) * 65536; + sym /= (state->mclk / 100); + if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) + goto err; + sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */ + sym = (sym / 100) * 65536; + sym /= (state->mclk / 100); + if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) + goto err; + sym = (srate_coarse / 100) * 65536; + sym /= (state->mclk / 100); + if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */ + goto err; + } + + return srate_coarse; + +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout) +{ + s32 timer = 0, lock = 0; + u32 reg; + u8 stat; + + while ((timer < timeout) && (!lock)) { + reg = STV090x_READ_DEMOD(state, DMDSTATE); + stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); + + switch (stat) { + case 0: /* searching */ + case 1: /* first PLH detected */ + default: + dprintk(FE_DEBUG, 1, "Demodulator searching .."); + lock = 0; + break; + case 2: /* DVB-S2 mode */ + case 3: /* DVB-S1/legacy mode */ + reg = STV090x_READ_DEMOD(state, DSTATUS); + lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); + break; + } + + if (!lock) + msleep(10); + else + dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK"); + + timer += 10; + } + return lock; +} + +static int stv090x_blind_search(struct stv090x_state *state) +{ + u32 agc2, reg, srate_coarse; + s32 timeout_dmd = 500, cpt_fail, agc2_ovflw, i; + u8 k_ref, k_max, k_min; + int coarse_fail, lock; + + if (state->dev_ver < 0x20) { + k_max = 233; + k_min = 143; + } else { + k_max = 120; + k_min = 30; + } + + agc2 = stv090x_get_agc2_min_level(state); + + if (agc2 > STV090x_SEARCH_AGC2_TH) { + lock = 0; + } else { + if (state->dev_ver == 0x10) { + if (STV090x_WRITE_DEMOD(state, CORRELEXP, 0xaa) < 0) + goto err; + } + if (state->dev_ver < 0x20) { + if (STV090x_WRITE_DEMOD(state, CARHDR, 0x55) < 0) + goto err; + } + + if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) + goto err; + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */ + goto err; + } + + k_ref = k_max; + do { + if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0) + goto err; + if (stv090x_srate_srch_coarse(state) != 0) { + srate_coarse = stv090x_srate_srch_fine(state); + if (srate_coarse != 0) { + stv090x_get_lock_tmg(state); + lock = stv090x_get_dmdlock(state, timeout_dmd); + } else { + lock = 0; + } + } else { + cpt_fail = 0; + agc2_ovflw = 0; + for (i = 0; i < 10; i++) { + agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8; + agc2 |= STV090x_READ_DEMOD(state, AGC2I0); + if (agc2 >= 0xff00) + agc2_ovflw++; + reg = STV090x_READ_DEMOD(state, DSTATUS2); + if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) && + (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01)) + + cpt_fail++; + } + if ((cpt_fail > 7) || (agc2_ovflw > 7)) + coarse_fail = 1; + + lock = 0; + } + k_ref -= 30; + } while ((k_ref >= k_min) && (!lock) && (!coarse_fail)); + } + + return lock; + +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_chk_tmg(struct stv090x_state *state) +{ + u32 reg; + s32 tmg_cpt, i; + u8 freq, tmg_thh, tmg_thl; + int tmg_lock; + + freq = STV090x_READ_DEMOD(state, CARFREQ); + tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE); + tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL); + if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0) + goto err; + + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */ + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */ + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */ + goto err; + msleep(10); + + for (i = 0; i < 10; i++) { + reg = STV090x_READ_DEMOD(state, DSTATUS); + if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2) + tmg_cpt++; + msleep(1); + } + if (tmg_cpt >= 3) + tmg_lock = 1; + + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */ + goto err; + if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */ + goto err; + + if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0) + goto err; + + return tmg_lock; + +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) +{ + struct dvb_frontend *fe = &state->frontend; + + u32 reg; + s32 car_step, steps, cur_step, dir, freq, timeout_lock; + int lock = 0; + + if (state->srate >= 10000000) + timeout_lock = timeout_dmd / 3; + else + timeout_lock = timeout_dmd / 2; + + lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */ + if (!lock) { + if (state->srate >= 10000000) { + if (stv090x_chk_tmg(state)) { + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) + goto err; + lock = stv090x_get_dmdlock(state, timeout_dmd); + } else { + lock = 0; + } + } else { + if (state->srate <= 4000000) + car_step = 1000; + else if (state->srate <= 7000000) + car_step = 2000; + else if (state->srate <= 10000000) + car_step = 3000; + else + car_step = 5000; + + steps = (state->search_range / 1000) / car_step; + steps /= 2; + steps = 2 * (steps + 1); + if (steps < 0) + steps = 2; + else if (steps > 12) + steps = 12; + + cur_step = 1; + dir = 1; + + if (!lock) { + freq = state->frequency; + state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate; + while ((cur_step <= steps) && (!lock)) { + if (dir > 0) + freq += cur_step * car_step; + else + freq -= cur_step * car_step; + + /* Setup tuner */ + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_set_frequency) + state->config->tuner_set_frequency(fe, state->frequency); + + if (state->config->tuner_set_bandwidth) + state->config->tuner_set_bandwidth(fe, state->tuner_bw); + + stv090x_i2c_gate_ctrl(fe, 0); + + msleep(50); + + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_get_status) + state->config->tuner_get_status(fe, ®); + + if (reg) + dprintk(FE_DEBUG, 1, "Tuner phase locked"); + else + dprintk(FE_DEBUG, 1, "Tuner unlocked"); + + stv090x_i2c_gate_ctrl(fe, 0); + + STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); + if (state->delsys == STV090x_DVBS2) { + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) + goto err; + lock = stv090x_get_dmdlock(state, (timeout_dmd / 3)); + + dir *= -1; + cur_step++; + } + } + } + } + + return lock; + +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps) +{ + s32 timeout, inc, steps_max, srate, car_max; + + srate = state->srate; + car_max = state->search_range / 1000; + car_max = 65536 * (car_max / 2); + car_max /= (state->mclk / 1000); + + if (car_max > 0x4000) + car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */ + + inc = srate; + inc /= state->mclk / 1000; + inc *= 256; + inc *= 256; + inc /= 1000; + + switch (state->algo) { + case STV090x_SEARCH_DVBS1: + case STV090x_SEARCH_DSS: + inc *= 3; /* freq step = 3% of srate */ + timeout = 20; + break; + + case STV090x_SEARCH_DVBS2: + inc *= 4; + timeout = 25; + break; + + case STV090x_SEARCH_AUTO: + default: + inc *= 3; + timeout = 25; + break; + } + inc /= 100; + if ((inc > car_max) || (inc < 0)) + inc = car_max / 2; /* increment <= 1/8 Mclk */ + + timeout *= 27500; /* 27.5 Msps reference */ + if (srate > 0) + timeout /= (srate / 1000); + + if ((timeout > 100) || (timeout < 0)) + timeout = 100; + + steps_max = (car_max / inc) + 1; /* min steps = 3 */ + if ((steps_max > 100) || (steps_max < 0)) { + steps_max = 100; /* max steps <= 100 */ + inc = car_max / steps_max; + } + *freq_inc = inc; + *timeout_sw = timeout; + *steps = steps_max; + + return 0; +} + +static int stv090x_chk_signal(struct stv090x_state *state) +{ + s32 offst_car, agc2, car_max; + int no_signal; + + offst_car = STV090x_READ_DEMOD(state, CFR2) << 8; + offst_car |= STV090x_READ_DEMOD(state, CFR1); + + agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8; + agc2 |= STV090x_READ_DEMOD(state, AGC2I0); + car_max = state->search_range / 1000; + + car_max += (car_max / 10); /* 10% margin */ + car_max = (65536 * car_max / 2); + car_max /= state->mclk / 1000; + + if (car_max > 0x4000) + car_max = 0x4000; + + if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) { + no_signal = 1; + dprintk(FE_DEBUG, 1, "No Signal"); + } else { + no_signal = 0; + dprintk(FE_DEBUG, 1, "Found Signal"); + } + + return no_signal; +} + +static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max) +{ + int no_signal, lock = 0; + s32 cpt_step, offst_freq, car_max; + u32 reg; + + car_max = state->search_range / 1000; + car_max += (car_max / 10); + car_max = (65536 * car_max / 2); + car_max /= (state->mclk / 1000); + if (car_max > 0x4000) + car_max = 0x4000; + + if (zigzag) + offst_freq = 0; + else + offst_freq = -car_max + inc; + + cpt_step = 0; + do { + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) + goto err; + + reg = STV090x_READ_DEMOD(state, PDELCTRL1); + STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */ + if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) + goto err; + + if (state->dev_ver == 0x12) { + reg = STV090x_READ_DEMOD(state, TSCFGH); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x1); + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + } + + if (zigzag) { + if (offst_freq >= 0) + offst_freq = -offst_freq - 2 * inc; + else + offst_freq = -offst_freq; + } else { + offst_freq += 2 * inc; + } + + lock = stv090x_get_dmdlock(state, timeout); + no_signal = stv090x_chk_signal(state); + + } while ((!lock) && + (!no_signal) && + ((offst_freq - inc) < car_max) && + ((offst_freq + inc) > -car_max) && + (cpt_step < steps_max)); + + reg = STV090x_READ_DEMOD(state, PDELCTRL1); + STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) + goto err; + + return lock; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_sw_algo(struct stv090x_state *state) +{ + int no_signal, zigzag, lock = 0; + u32 reg; + + s32 dvbs2_fly_wheel; + s32 inc, timeout_step, trials, steps_max; + + stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max); /* get params */ + + switch (state->algo) { + case STV090x_SEARCH_DVBS1: + case STV090x_SEARCH_DSS: + /* accelerate the frequency detector */ + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0) + goto err; + zigzag = 0; + break; + + case STV090x_SEARCH_DVBS2: + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x68) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0) + goto err; + zigzag = 1; + break; + + case STV090x_SEARCH_AUTO: + default: + /* accelerate the frequency detector */ + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x68) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x69) < 0) + goto err; + zigzag = 0; + break; + } + + trials = 0; + do { + lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max); + no_signal = stv090x_chk_signal(state); + trials++; + + /*run the SW search 2 times maximum*/ + if (lock || no_signal || (trials == 2)) { + /*Check if the demod is not losing lock in DVBS2*/ + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x88) < 0) + goto err; + } + + reg = STV090x_READ_DEMOD(state, DMDSTATE); + if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) { + /*Check if the demod is not losing lock in DVBS2*/ + msleep(timeout_step); + reg = STV090x_READ_DEMOD(state, DMDFLYW); + dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD); + if (dvbs2_fly_wheel < 0xd) { /*if correct frames is decrementing */ + msleep(timeout_step); + reg = STV090x_READ_DEMOD(state, DMDFLYW); + dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD); + } + if (dvbs2_fly_wheel < 0xd) { + /*FALSE lock, The demod is loosing lock */ + lock = 0; + if (trials < 2) { + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x68) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0) + goto err; + } + } + } + } + } while ((!lock) && (trials < 2) && (!no_signal)); + + return lock; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state) +{ + u32 reg; + enum stv090x_delsys delsys; + + reg = STV090x_READ_DEMOD(state, DMDSTATE); + if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2) + delsys = STV090x_DVBS2; + else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) { + reg = STV090x_READ_DEMOD(state, FECM); + if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1) + delsys = STV090x_DSS; + else + delsys = STV090x_DVBS1; + } else { + delsys = STV090x_ERROR; + } + + return delsys; +} + +/* in Hz */ +static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk) +{ + s32 derot, int_1, int_2, tmp_1, tmp_2; + u32 pow2; + + derot = STV090x_READ_DEMOD(state, CFR2) << 16; + derot |= STV090x_READ_DEMOD(state, CFR1) << 8; + derot |= STV090x_READ_DEMOD(state, CFR0); + + derot = comp2(derot, 24); + pow2 = 1 << 12; + int_1 = state->mclk / pow2; + int_2 = derot / pow2; + + tmp_1 = state->mclk % pow2; + tmp_2 = derot % pow2; + + derot = (int_1 * int_2) + + ((int_1 * tmp_2) / pow2) + + ((int_1 * tmp_1) / pow2); + + return derot; +} + +static int stv090x_get_viterbi(struct stv090x_state *state) +{ + u32 reg, rate; + + reg = STV090x_READ_DEMOD(state, VITCURPUN); + rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD); + + switch (rate) { + case 13: + state->fec = STV090x_PR12; + break; + + case 18: + state->fec = STV090x_PR23; + break; + + case 21: + state->fec = STV090x_PR34; + break; + + case 24: + state->fec = STV090x_PR56; + break; + + case 25: + state->fec = STV090x_PR67; + break; + + case 26: + state->fec = STV090x_PR78; + break; + + default: + state->fec = STV090x_PRERR; + break; + } + + return 0; +} + +static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state) +{ + struct dvb_frontend *fe = &state->frontend; + + u8 tmg; + u32 reg; + s32 i = 0, offst_freq; + + msleep(5); + + if (state->algo == STV090x_BLIND_SEARCH) { + tmg = STV090x_READ_DEMOD(state, TMGREG2); + STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c); + while ((i <= 50) && (!tmg) && (tmg != 0xff)) { + tmg = STV090x_READ_DEMOD(state, TMGREG2); + msleep(5); + i += 5; + } + } + state->delsys = stv090x_get_std(state); + + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_get_frequency) + state->config->tuner_get_frequency(fe, &state->frequency); + + stv090x_i2c_gate_ctrl(fe, 0); + + offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000; + state->frequency += offst_freq; + stv090x_get_viterbi(state); + reg = STV090x_READ_DEMOD(state, DMDMODCOD); + state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); + state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; + state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1; + reg = STV090x_READ_DEMOD(state, TMGOBS); + state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); + reg = STV090x_READ_DEMOD(state, FECM); + state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD); + + if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) { + + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_get_frequency) + state->config->tuner_get_frequency(fe, &state->frequency); + + stv090x_i2c_gate_ctrl(fe, 0); + + if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) + return STV090x_RANGEOK; + else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000)) + return STV090x_RANGEOK; + else + return STV090x_OUTOFRANGE; /* Out of Range */ + } else { + if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) + return STV090x_RANGEOK; + else + return STV090x_OUTOFRANGE; + } + + return STV090x_OUTOFRANGE; +} + +static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate) +{ + s32 offst_tmg; + s32 pow2; + + offst_tmg = STV090x_READ_DEMOD(state, TMGREG2) << 16; + offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) << 8; + offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0); + + pow2 = 1 << 24; + + offst_tmg = comp2(offst_tmg, 24); /* 2's complement */ + if (!offst_tmg) + offst_tmg = 1; + + offst_tmg = ((s32) srate * 10) / (pow2 / offst_tmg); + offst_tmg /= 320; + + return offst_tmg; +} + +static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots) +{ + u8 aclc = 0x29; + s32 i; + struct stv090x_long_frame_crloop *car_loop; + + if (state->dev_ver <= 0x12) + car_loop = stv090x_s2_crl; + else if (state->dev_ver == 0x20) + car_loop = stv090x_s2_crl_cut20; + else + car_loop = stv090x_s2_crl; + + + if (modcod < STV090x_QPSK_12) { + i = 0; + while ((i < 3) && (modcod != stv090x_s2_lowqpsk_crl_cut20[i].modcod)) + i++; + + if (i >= 3) + i = 2; + + } else { + i = 0; + while ((i < 14) && (modcod != car_loop[i].modcod)) + i++; + + if (i >= 14) { + i = 0; + while ((i < 11) && (modcod != stv090x_s2_lowqpsk_crl_cut20[i].modcod)) + i++; + + if (i >= 11) + i = 10; + } + } + + if (modcod <= STV090x_QPSK_25) { + if (pilots) { + if (state->srate <= 3000000) + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_2; + else if (state->srate <= 7000000) + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_5; + else if (state->srate <= 15000000) + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_10; + else if (state->srate <= 25000000) + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_20; + else + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_30; + } else { + if (state->srate <= 3000000) + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_2; + else if (state->srate <= 7000000) + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_5; + else if (state->srate <= 15000000) + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_10; + else if (state->srate <= 25000000) + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_20; + else + aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_30; + } + + } else if (modcod <= STV090x_8PSK_910) { + if (pilots) { + if (state->srate <= 3000000) + aclc = car_loop[i].crl_pilots_on_2; + else if (state->srate <= 7000000) + aclc = car_loop[i].crl_pilots_on_5; + else if (state->srate <= 15000000) + aclc = car_loop[i].crl_pilots_on_10; + else if (state->srate <= 25000000) + aclc = car_loop[i].crl_pilots_on_20; + else + aclc = car_loop[i].crl_pilots_on_30; + } else { + if (state->srate <= 3000000) + aclc = car_loop[i].crl_pilots_off_2; + else if (state->srate <= 7000000) + aclc = car_loop[i].crl_pilots_off_5; + else if (state->srate <= 15000000) + aclc = car_loop[i].crl_pilots_off_10; + else if (state->srate <= 25000000) + aclc = car_loop[i].crl_pilots_off_20; + else + aclc = car_loop[i].crl_pilots_off_30; + } + } else { /* 16APSK and 32APSK */ + if (state->srate <= 3000000) + aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_2; + else if (state->srate <= 7000000) + aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_5; + else if (state->srate <= 15000000) + aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_10; + else if (state->srate <= 25000000) + aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_20; + else + aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_30; + } + + return aclc; +} + +static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) +{ + s32 index = 0; + u8 aclc = 0x0b; + + switch (state->modulation) { + case STV090x_QPSK: + default: + index = 0; + break; + case STV090x_8PSK: + index = 1; + break; + case STV090x_16APSK: + index = 2; + break; + case STV090x_32APSK: + index = 3; + break; + } + + switch (state->dev_ver) { + case 0x20: + if (state->srate <= 3000000) + aclc = stv090x_s2_short_crl[index].crl_cut20_2; + else if (state->srate <= 7000000) + aclc = stv090x_s2_short_crl[index].crl_cut20_5; + else if (state->srate <= 15000000) + aclc = stv090x_s2_short_crl[index].crl_cut20_10; + else if (state->srate <= 25000000) + aclc = stv090x_s2_short_crl[index].crl_cut20_20; + else + aclc = stv090x_s2_short_crl[index].crl_cut20_30; + break; + + case 0x12: + default: + if (state->srate <= 3000000) + aclc = stv090x_s2_short_crl[index].crl_cut12_2; + else if (state->srate <= 7000000) + aclc = stv090x_s2_short_crl[index].crl_cut12_5; + else if (state->srate <= 15000000) + aclc = stv090x_s2_short_crl[index].crl_cut12_10; + else if (state->srate <= 25000000) + aclc = stv090x_s2_short_crl[index].crl_cut12_20; + else + aclc = stv090x_s2_short_crl[index].crl_cut12_30; + break; + } + + return aclc; +} + +static int stv090x_optimize_track(struct stv090x_state *state) +{ + struct dvb_frontend *fe = &state->frontend; + + enum stv090x_rolloff rolloff; + enum stv090x_modcod modcod; + + s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; + u32 reg; + + srate = stv090x_get_srate(state, state->mclk); + srate += stv090x_get_tmgoffst(state, srate); + + switch (state->delsys) { + case STV090x_DVBS1: + case STV090x_DSS: + if (state->algo == STV090x_SEARCH_AUTO) { + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + } + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff); + STV090x_SETFIELD_Px(reg, MANUAL_ROLLOFF_FIELD, 0x01); + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0) + goto err; + break; + + case STV090x_DVBS2: + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0) + goto err; + if (state->frame_len == STV090x_LONG_FRAME) { + reg = STV090x_READ_DEMOD(state, DMDMODCOD); + modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); + pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; + aclc = stv090x_optimize_carloop(state, modcod, pilots); + if (modcod <= STV090x_QPSK_910) { + STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc); + } else if (modcod <= STV090x_8PSK_910) { + if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0) + goto err; + } + if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) { + if (modcod <= STV090x_16APSK_910) { + if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0) + goto err; + } + } + } else { + /*Carrier loop setting for short frame*/ + aclc = stv090x_optimize_carloop_short(state); + if (state->modulation == STV090x_QPSK) { + if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0) + goto err; + } else if (state->modulation == STV090x_8PSK) { + if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0) + goto err; + } else if (state->modulation == STV090x_16APSK) { + if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0) + goto err; + } else if (state->modulation == STV090x_32APSK) { + if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0) + goto err; + } + } + if (state->dev_ver <= 0x11) { + if (state->demod_mode != STV090x_SINGLE) + stv090x_activate_modcod(state); /* link to LDPC after demod LOCK */ + } + STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */ + break; + + case STV090x_UNKNOWN: + default: + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + break; + } + + f_1 = STV090x_READ_DEMOD(state, CFR2); + f_0 = STV090x_READ_DEMOD(state, CFR1); + reg = STV090x_READ_DEMOD(state, TMGOBS); + rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); + + if (state->algo == STV090x_BLIND_SEARCH) { + STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00); + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0) + goto err; + stv090x_set_srate(state, srate); + stv090x_set_max_srate(state, state->mclk, srate); + stv090x_set_min_srate(state, state->mclk, srate); + blind_tune = 1; + } + + if (state->dev_ver >= 0x20) { + if ((state->search_mode == STV090x_SEARCH_DVBS1) || + (state->search_mode == STV090x_SEARCH_DSS) || + (state->search_mode == STV090x_SEARCH_AUTO)) { + + if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0) + goto err; + } + } + + if (state->dev_ver < 0x20) { + if (STV090x_WRITE_DEMOD(state, CARHDR, 0x08) < 0) + goto err; + } + if (state->dev_ver == 0x10) { + if (STV090x_WRITE_DEMOD(state, CORRELEXP, 0x0a) < 0) + goto err; + } + + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) + goto err; + + if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) { + + if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) + goto err; + state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000; + + if ((state->dev_ver >= 0x20) || (blind_tune == 1)) { + + if (state->algo != STV090x_WARM_SEARCH) { + + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_set_bandwidth) + state->config->tuner_set_bandwidth(fe, state->tuner_bw); + + stv090x_i2c_gate_ctrl(fe, 0); + + } + } + if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) + msleep(50); /* blind search: wait 50ms for SR stabilization */ + else + msleep(5); + + stv090x_get_lock_tmg(state); + + if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) { + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) + goto err; + + i = 0; + + while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) { + + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) + goto err; + i++; + } + } + + } + + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) + goto err; + } + if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS)) + stv090x_set_vit_thtracq(state); + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_get_feclock(struct stv090x_state *state, s32 timeout) +{ + s32 timer = 0, lock = 0, stat; + u32 reg; + + while ((timer < timeout) && (!lock)) { + reg = STV090x_READ_DEMOD(state, DMDSTATE); + stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); + + switch (stat) { + case 0: /* searching */ + case 1: /* first PLH detected */ + default: + lock = 0; + break; + + case 2: /* DVB-S2 mode */ + reg = STV090x_READ_DEMOD(state, PDELSTATUS1); + lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD); + break; + + case 3: /* DVB-S1/legacy mode */ + reg = STV090x_READ_DEMOD(state, VSTATUSVIT); + lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD); + break; + } + if (!lock) { + msleep(10); + timer += 10; + } + } + return lock; +} + +static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec) +{ + u32 reg; + s32 timer = 0; + int lock; + + lock = stv090x_get_dmdlock(state, timeout_dmd); + if (lock) + lock = stv090x_get_feclock(state, timeout_fec); + + if (lock) { + lock = 0; + + while ((timer < timeout_fec) && (!lock)) { + reg = STV090x_READ_DEMOD(state, TSSTATUS); + lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD); + msleep(1); + timer++; + } + } + + return lock; +} + +static int stv090x_set_s2rolloff(struct stv090x_state *state) +{ + s32 rolloff; + u32 reg; + + if (state->dev_ver == 0x10) { + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, MANUAL_ROLLOFF_FIELD, 0x01); + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + goto err; + rolloff = STV090x_READ_DEMOD(state, MATSTR1) & 0x03; + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, reg); + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + goto err; + } else { + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, MANUAL_ROLLOFF_FIELD, 0x00); + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + goto err; + } + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static enum stv090x_signal_state stv090x_acq_fixs1(struct stv090x_state *state) +{ + s32 srate, f_1, f_2; + enum stv090x_signal_state signal_state = STV090x_NODATA; + u32 reg; + int lock; + + reg = STV090x_READ_DEMOD(state, DMDSTATE); + if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) { /* DVB-S mode */ + srate = stv090x_get_srate(state, state->mclk); + srate += stv090x_get_tmgoffst(state, state->srate); + + if (state->algo == STV090x_BLIND_SEARCH) + stv090x_set_srate(state, state->srate); + + stv090x_get_lock_tmg(state); + + f_1 = STV090x_READ_DEMOD(state, CFR2); + f_2 = STV090x_READ_DEMOD(state, CFR1); + + reg = STV090x_READ_DEMOD(state, DMDCFGMD); + STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) + goto err; + + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, STV090x_IQ_SWAP); + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0) /* stop demod */ + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_2) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* warm start trigger */ + goto err; + + if (stv090x_get_lock(state, state->DemodTimeout, state->FecTimeout)) { + lock = 1; + stv090x_get_sig_params(state); + stv090x_optimize_track(state); + } else { + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, STV090x_IQ_NORMAL); + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_2) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* warm start trigger */ + goto err; + if (stv090x_get_lock(state, state->DemodTimeout, state->FecTimeout)) { + lock = 1; + signal_state = stv090x_get_sig_params(state); + stv090x_optimize_track(state); + } + } + } else { + lock = 0; + } + + return signal_state; + +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) +{ + struct dvb_frontend *fe = &state->frontend; + enum stv090x_signal_state signal_state = STV090x_NOCARRIER; + u32 reg; + s32 timeout_dmd = 500, timeout_fec = 50; + int lock = 0, low_sr, no_signal = 0; + + reg = STV090x_READ_DEMOD(state, TSCFGH); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */ + goto err; + + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */ + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x88) < 0) /* cut 1.x */ + goto err; + } + + stv090x_get_lock_tmg(state); + + if (state->algo == STV090x_BLIND_SEARCH) { + state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */ + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x00) < 0) /* wider srate scan */ + goto err; + stv090x_set_srate(state, 1000000); /* inital srate = 1Msps */ + } else { + /* known srate */ + if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0) + goto err; + + if (state->srate >= 10000000) { + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) /* High SR */ + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0) /* Low SR */ + goto err; + } + + if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) + goto err; + if (state->algo == STV090x_COLD_SEARCH) + state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 1000000)) / 10; + else if (state->algo == STV090x_WARM_SEARCH) + state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000; + } else { + if (STV090x_WRITE_DEMOD(state, KREFTMG, 0xc1) < 0) + goto err; + state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10; + } + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0) /* narrow srate scan */ + goto err; + stv090x_set_srate(state, state->srate); + stv090x_set_max_srate(state, state->mclk, state->srate); + stv090x_set_min_srate(state, state->mclk, state->srate); + + if (state->srate >= 10000000) + low_sr = 1; + } + + /* Setup tuner */ + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_set_bbgain) + state->config->tuner_set_bbgain(fe, 10); /* 10dB */ + + if (state->config->tuner_set_frequency) + state->config->tuner_set_frequency(fe, state->frequency); + + if (state->config->tuner_set_bandwidth) + state->config->tuner_set_bandwidth(fe, state->tuner_bw); + + stv090x_i2c_gate_ctrl(fe, 0); + + msleep(50); + + stv090x_i2c_gate_ctrl(fe, 1); + + if (state->config->tuner_get_status) + state->config->tuner_get_status(fe, ®); + + if (reg) + dprintk(FE_DEBUG, 1, "Tuner phase locked"); + else + dprintk(FE_DEBUG, 1, "Tuner unlocked"); + + stv090x_i2c_gate_ctrl(fe, 0); + + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); + STV090x_SETFIELD_Px(reg, MANUAL_ROLLOFF_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + goto err; + stv090x_delivery_search(state); + if (state->algo == STV090x_BLIND_SEARCH) + stv090x_start_search(state); + + if (state->dev_ver == 0x12) { + reg = STV090x_READ_DEMOD(state, TSCFGH); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + msleep(3); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + } + + if (state->algo == STV090x_BLIND_SEARCH) + lock = stv090x_blind_search(state); + else if (state->algo == STV090x_COLD_SEARCH) + lock = stv090x_get_coldlock(state, timeout_dmd); + else if (state->algo == STV090x_WARM_SEARCH) + lock = stv090x_get_dmdlock(state, timeout_dmd); + + if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) { + if (!low_sr) { + if (stv090x_chk_tmg(state)) + lock = stv090x_sw_algo(state); + } + } + + if (lock) + signal_state = stv090x_get_sig_params(state); + + if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ + stv090x_optimize_track(state); + if (state->dev_ver <= 0x11) { /*workaround for dual DVBS1 cut 1.1 and 1.0 only*/ + if (stv090x_get_std(state) == STV090x_DVBS1) { + msleep(20); + reg = STV090x_READ_DEMOD(state, TSCFGH); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + } else { + reg = STV090x_READ_DEMOD(state, TSCFGH); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + msleep(3); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + } + } else if (state->dev_ver == 0x20) { /*cut 2.0 :release TS reset after demod lock and TrackingOptimization*/ + reg = STV090x_READ_DEMOD(state, TSCFGH); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + msleep(3); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; + } + + if (stv090x_get_lock(state, timeout_fec, timeout_fec)) { + lock = 1; + if (state->delsys == STV090x_DVBS2) { + stv090x_set_s2rolloff(state); + if (STV090x_WRITE_DEMOD(state, PDELCTRL2, 0x40) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, PDELCTRL2, 0x00) < 0) /* RESET counter */ + goto err; + if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */ + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) + goto err; + } else { + lock = 0; + signal_state = STV090x_NODATA; + no_signal = stv090x_chk_signal(state); + } + } + if ((signal_state == STV090x_NODATA) && (!no_signal)) { + if (state->dev_ver <= 0x11) { + reg = STV090x_READ_DEMOD(state, DMDSTATE); + if (((STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD)) == STV090x_DVBS2) && (state->inversion == INVERSION_AUTO)) + signal_state = stv090x_acq_fixs1(state); + } + } + return signal_state; + +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +{ + struct stv090x_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *props = &fe->dtv_property_cache; + + state->delsys = props->delivery_system; + state->frequency = p->frequency; + state->srate = p->u.qpsk.symbol_rate; + + if (!stv090x_algo(state)) { + dprintk(FE_DEBUG, 1, "Search success!"); + return DVBFE_ALGO_SEARCH_SUCCESS; + } else { + dprintk(FE_DEBUG, 1, "Search failed!"); + return DVBFE_ALGO_SEARCH_FAILED; + } + + return DVBFE_ALGO_SEARCH_ERROR; +} + +/* FIXME! */ +static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg; + u8 search_state; + int locked = 0; + + reg = STV090x_READ_DEMOD(state, DMDSTATE); + search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); + + switch (search_state) { + case 0: /* searching */ + case 1: /* first PLH detected */ + default: + dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)"); + locked = 0; + break; + + case 2: /* DVB-S2 mode */ + dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2"); + reg = STV090x_READ_DEMOD(state, DSTATUS); + if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { + reg = STV090x_READ_DEMOD(state, TSSTATUS); + if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { + locked = 1; + *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + } + } + break; + + case 3: /* DVB-S1/legacy mode */ + dprintk(FE_DEBUG, 1, "Delivery system: DVB-S"); + reg = STV090x_READ_DEMOD(state, DSTATUS); + if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { + reg = STV090x_READ_DEMOD(state, VSTATUSVIT); + if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { + reg = STV090x_READ_DEMOD(state, TSSTATUS); + if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { + locked = 1; + *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + } + } + } + break; + } + + return locked; +} + +static int stv090x_read_per(struct dvb_frontend *fe, u32 *per) +{ + struct stv090x_state *state = fe->demodulator_priv; + + s32 count_4, count_3, count_2, count_1, count_0, count; + u32 reg, h, m, l; + enum fe_status status; + + if (!stv090x_read_status(fe, &status)) { + *per = 1 << 23; /* Max PER */ + } else { + /* Counter 2 */ + reg = STV090x_READ_DEMOD(state, ERRCNT22); + h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD); + + reg = STV090x_READ_DEMOD(state, ERRCNT21); + m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD); + + reg = STV090x_READ_DEMOD(state, ERRCNT20); + l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD); + + *per = ((h << 16) | (m << 8) | l); + + count_4 = STV090x_READ_DEMOD(state, FBERCPT4); + count_3 = STV090x_READ_DEMOD(state, FBERCPT3); + count_2 = STV090x_READ_DEMOD(state, FBERCPT2); + count_1 = STV090x_READ_DEMOD(state, FBERCPT1); + count_0 = STV090x_READ_DEMOD(state, FBERCPT0); + + if ((!count_4) && (!count_3)) { + count = (count_2 & 0xff) << 16; + count |= (count_1 & 0xff) << 8; + count |= count_0 & 0xff; + } else { + count = 1 << 24; + } + if (count == 0) + *per = 1; + } + if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) + goto err; + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) +{ + int res = 0; + int min = 0, med; + + if (val < tab[min].read) + res = tab[min].real; + else if (val >= tab[max].read) + res = tab[max].real; + else { + while ((max - min) > 1) { + med = (max + min) / 2; + if (val >= tab[min].read && val < tab[med].read) + max = med; + else + min = med; + } + res = ((val - tab[min].read) * + (tab[max].real - tab[min].real) / + (tab[max].read - tab[min].read)) + + tab[min].real; + } + + return res; +} + +static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg; + s32 agc; + + reg = STV090x_READ_DEMOD(state, AGCIQIN1); + agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); + + *strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc); + if (agc > stv090x_rf_tab[0].read) + *strength = 5; + else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read) + *strength = -100; + + return 0; +} + +static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg_0, reg_1, reg, i; + s32 val_0, val_1, val = 0; + u8 lock_f; + + switch (state->delsys) { + case STV090x_DVBS2: + reg = STV090x_READ_DEMOD(state, DSTATUS); + lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); + if (lock_f) { + msleep(5); + for (i = 0; i < 16; i++) { + reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1); + val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); + reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0); + val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); + val += MAKEWORD16(val_1, val_0); + msleep(1); + } + val /= 16; + *cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val); + if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read) + *cnr = 1000; + } + break; + + case STV090x_DVBS1: + case STV090x_DSS: + reg = STV090x_READ_DEMOD(state, DSTATUS); + lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); + if (lock_f) { + msleep(5); + for (i = 0; i < 16; i++) { + reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1); + val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); + reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0); + val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); + val += MAKEWORD16(val_1, val_0); + msleep(1); + } + val /= 16; + *cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val); + if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read) + *cnr = 1000; + } + break; + default: + break; + } + + return 0; +} + +static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg; + + reg = STV090x_READ_DEMOD(state, DISTXCTL); + switch (tone) { + case SEC_TONE_ON: + STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0); + STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + break; + + case SEC_TONE_OFF: + STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0); + STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + break; + default: + return -EINVAL; + } + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + + +static enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_CUSTOM; +} + +static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg, idle = 0, fifo_full = 1; + int i; + + reg = STV090x_READ_DEMOD(state, DISTXCTL); + STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + + for (i = 0; i < cmd->msg_len; i++) { + + while (fifo_full) { + reg = STV090x_READ_DEMOD(state, DISTXSTATUS); + fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD); + } + + if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0) + goto err; + i++; + } + reg = STV090x_READ_DEMOD(state, DISTXCTL); + STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + + i = 0; + + while ((!idle) && (i < 10)) { + reg = STV090x_READ_DEMOD(state, DISTXSTATUS); + idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD); + msleep(10); + i++; + } + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg = 0, i = 0, rx_end = 0; + + while ((rx_end != 1) && (i < 10)) { + msleep(10); + i++; + reg = STV090x_READ_DEMOD(state, DISRX_ST0); + rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD); + } + + if (rx_end) { + reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD); + for (i = 0; i < reply->msg_len; i++) + reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA); + } + + return 0; +} + +static int stv090x_sleep(struct dvb_frontend *fe) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg; + + dprintk(FE_DEBUG, 1, "Set %s to sleep", + state->device == STV0900 ? "STV0900" : "STV0903"); + + reg = stv090x_read_reg(state, STV090x_SYNTCTRL); + STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); + if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) + goto err; + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_wakeup(struct dvb_frontend *fe) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg; + + dprintk(FE_DEBUG, 1, "Wake %s from standby", + state->device == STV0900 ? "STV0900" : "STV0903"); + + reg = stv090x_read_reg(state, STV090x_SYNTCTRL); + STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00); + if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) + goto err; + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static void stv090x_release(struct dvb_frontend *fe) +{ + struct stv090x_state *state = fe->demodulator_priv; + + kfree(state); +} + +static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode) +{ + u32 reg; + + switch (ldpc_mode) { + case STV090x_DUAL: + default: + reg = stv090x_read_reg(state, STV090x_GENCFG); + if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) { + /* follow LDPC default state */ + if (stv090x_write_reg(state, STV090x_GENCFG, reg) < 0) + goto err; + state->demod_mode = STV090x_DUAL; + reg = stv090x_read_reg(state, STV090x_TSTRES0); + STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1); + if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) + goto err; + STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0); + if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) + goto err; + } + break; + + case STV090x_SINGLE: + if (state->demod == STV090x_DEMODULATOR_1) { + if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */ + goto err; + } else { + if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */ + goto err; + } + + reg = stv090x_read_reg(state, STV090x_TSTRES0); + STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1); + if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) + goto err; + STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0); + if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) + goto err; + + reg = STV090x_READ_DEMOD(state, PDELCTRL1); + STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01); + if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00); + if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) + goto err; + break; + } + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +/* return (Hz), clk in Hz*/ +static u32 stv090x_get_mclk(struct stv090x_state *state) +{ + const struct stv090x_config *config = state->config; + u32 div, reg; + u8 ratio; + + div = stv090x_read_reg(state, STV090x_NCOARSE); + reg = stv090x_read_reg(state, STV090x_SYNTCTRL); + ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6; + + return (div + 1) * config->xtal / ratio; /* kHz */ +} + +static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk) +{ + const struct stv090x_config *config = state->config; + u32 reg, div, clk_sel; + + reg = stv090x_read_reg(state, STV090x_SYNTCTRL); + clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6); + + div = ((clk_sel * mclk) / config->xtal) - 1; + + reg = stv090x_read_reg(state, STV090x_NCOARSE); + STV090x_SETFIELD(reg, M_DIV_FIELD, div); + if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0) + goto err; + + state->mclk = stv090x_get_mclk(state); + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_set_tspath(struct stv090x_state *state) +{ + u32 reg; + + if (state->dev_ver >= 0x20) { + switch (state->config->ts1_mode) { + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: + switch (state->config->ts2_mode) { + case STV090x_TSMODE_SERIAL_PUNCTURED: + case STV090x_TSMODE_SERIAL_CONTINUOUS: + default: + stv090x_write_reg(state, STV090x_TSGENERAL, 0x00); + break; + + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: + if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */ + goto err; + reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); + STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); + if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) + goto err; + reg = stv090x_read_reg(state, STV090x_P2_TSCFGM); + STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); + if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0) + goto err; + break; + } + break; + + case STV090x_TSMODE_SERIAL_PUNCTURED: + case STV090x_TSMODE_SERIAL_CONTINUOUS: + default: + switch (state->config->ts2_mode) { + case STV090x_TSMODE_SERIAL_PUNCTURED: + case STV090x_TSMODE_SERIAL_CONTINUOUS: + default: + if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) + goto err; + break; + + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: + if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0) + goto err; + break; + } + break; + } + } else { + switch (state->config->ts1_mode) { + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: + switch (state->config->ts2_mode) { + case STV090x_TSMODE_SERIAL_PUNCTURED: + case STV090x_TSMODE_SERIAL_CONTINUOUS: + default: + break; + + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); + STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); + if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) + goto err; + reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); + STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0); + if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0) + goto err; + break; + } + break; + + case STV090x_TSMODE_SERIAL_PUNCTURED: + case STV090x_TSMODE_SERIAL_CONTINUOUS: + default: + switch (state->config->ts2_mode) { + case STV090x_TSMODE_SERIAL_PUNCTURED: + case STV090x_TSMODE_SERIAL_CONTINUOUS: + default: + break; + + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: + break; + } + break; + } + } + + switch (state->config->ts1_mode) { + case STV090x_TSMODE_PARALLEL_PUNCTURED: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); + STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + break; + + case STV090x_TSMODE_DVBCI: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); + STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + break; + + case STV090x_TSMODE_SERIAL_PUNCTURED: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); + STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + break; + + case STV090x_TSMODE_SERIAL_CONTINUOUS: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); + STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + break; + + default: + break; + } + + switch (state->config->ts2_mode) { + case STV090x_TSMODE_PARALLEL_PUNCTURED: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); + STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + break; + + case STV090x_TSMODE_DVBCI: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); + STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + break; + + case STV090x_TSMODE_SERIAL_PUNCTURED: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); + STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + break; + + case STV090x_TSMODE_SERIAL_CONTINUOUS: + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); + STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + break; + + default: + break; + } + reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); + if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00); + if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) + goto err; + + reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00); + if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + goto err; + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_init(struct dvb_frontend *fe) +{ + struct stv090x_state *state = fe->demodulator_priv; + const struct stv090x_config *config = state->config; + u32 reg; + + stv090x_ldpc_mode(state, state->demod_mode); + + reg = STV090x_READ_DEMOD(state, TNRCFG2); + STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion); + if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0) + goto err; + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff); + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + goto err; + + stv090x_i2c_gate_ctrl(fe, 1); + + if (config->tuner_init) + config->tuner_init(fe); + + stv090x_i2c_gate_ctrl(fe, 0); + + stv090x_set_tspath(state); + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_setup(struct dvb_frontend *fe) +{ + struct stv090x_state *state = fe->demodulator_priv; + const struct stv090x_config *config = state->config; + const struct stv090x_reg *stv090x_initval = NULL; + const struct stv090x_reg *stv090x_cut20_val = NULL; + unsigned long t1_size = 0, t2_size = 0; + + int i; + + if (state->device == STV0900) { + dprintk(FE_DEBUG, 1, "Initializing STV0900"); + stv090x_initval = stv0900_initval; + t1_size = ARRAY_SIZE(stv0900_initval); + stv090x_cut20_val = stv0900_cut20_val; + t2_size = ARRAY_SIZE(stv0900_cut20_val); + } else if (state->device == STV0903) { + dprintk(FE_DEBUG, 1, "Initializing STV0903"); + stv090x_initval = stv0903_initval; + t1_size = ARRAY_SIZE(stv0903_initval); + stv090x_cut20_val = stv0903_cut20_val; + t2_size = ARRAY_SIZE(stv0903_cut20_val); + } + + /* STV090x init */ + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Stop Demod */ + goto err; + + msleep(5); + + if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */ + goto err; + + if (STV090x_WRITE_DEMOD(state, I2CRPT, 0x00) < 0) /* repeater OFF */ + goto err; + + if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ + goto err; + msleep(5); + if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */ + goto err; + if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */ + goto err; + msleep(5); + + /* write initval */ + for (i = 0; i < t1_size; i++) { + dprintk(FE_DEBUG, 1, "Setting up initial values"); + if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0) + goto err; + } + + if (state->dev_ver >= 0x20) { + if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) + goto err; + + /* write cut20_val*/ + dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values"); + for (i = 0; i < t2_size; i++) { + if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0) + goto err; + } + } + + if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) + goto err; + if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) + goto err; + + stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ + msleep(5); + if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) + goto err; + stv090x_get_mclk(state); + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static struct dvb_frontend_ops stv090x_ops = { + + .info = { + .name = "STV090x Multistandard", + }, + + .release = stv090x_release, + .init = stv090x_init, + + .sleep = stv090x_sleep, + .get_frontend_algo = stv090x_frontend_algo, + + .i2c_gate_ctrl = stv090x_i2c_gate_ctrl, + + .diseqc_send_master_cmd = stv090x_send_diseqc_msg, + .diseqc_recv_slave_reply = stv090x_recv_slave_reply, + .set_tone = stv090x_set_tone, + + .search = stv090x_search, + .read_status = stv090x_read_status, + .read_ber = stv090x_read_per, + .read_signal_strength = stv090x_read_signal_strength, + .read_snr = stv090x_read_cnr +}; + + +struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, + struct i2c_adapter *i2c, + enum stv090x_demodulator demod) +{ + struct stv090x_state *state = NULL; + + state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL); + if (state == NULL) + goto error; + + state->verbose = &verbose; + state->config = config; + state->i2c = i2c; + state->frontend.ops = stv090x_ops; + state->frontend.demodulator_priv = state; + state->demod_mode = config->demod_mode; /* Single or Dual mode */ + state->device = config->device; + state->rolloff = 35; /* default */ + + if (state->demod == STV090x_DEMODULATOR_0) + mutex_init(&demod_lock); + + if (stv090x_sleep(&state->frontend) < 0) { + dprintk(FE_ERROR, 1, "Error putting device to sleep"); + goto error; + } + + if (stv090x_setup(&state->frontend) < 0) { + dprintk(FE_ERROR, 1, "Error setting up device"); + goto error; + } + if (stv090x_wakeup(&state->frontend) < 0) { + dprintk(FE_ERROR, 1, "Error waking device"); + goto error; + } + state->dev_ver = stv090x_read_reg(state, STV090x_MID); + + dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n", + state->device == STV0900 ? "STV0900" : "STV0903", + demod, + state->dev_ver); + + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(stv090x_attach); +MODULE_PARM_DESC(verbose, "Set Verbosity level"); +MODULE_AUTHOR("Manu Abraham"); +MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h new file mode 100644 index 0000000..e56489c --- /dev/null +++ b/drivers/media/dvb/frontends/stv090x.h @@ -0,0 +1,93 @@ +/* + STV0900/0903 Multistandard Broadcast Frontend driver + Copyright (C) Manu Abraham + + Copyright (C) ST Microelectronics + + 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 __STV090x_H +#define __STV090x_H + +enum stv090x_demodulator { + STV090x_DEMODULATOR_0 = 1, + STV090x_DEMODULATOR_1 +}; + +enum stv090x_device { + STV0903 = 0, + STV0900, +}; + +enum stv090x_mode { + STV090x_DUAL = 0, + STV090x_SINGLE +}; + +enum stv090x_tsmode { + STV090x_TSMODE_SERIAL_PUNCTURED = 1, + STV090x_TSMODE_SERIAL_CONTINUOUS, + STV090x_TSMODE_PARALLEL_PUNCTURED, + STV090x_TSMODE_DVBCI +}; + +enum stv090x_clkmode { + STV090x_CLK_INT = 0, /* Clk i/p = CLKI */ + STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */ +}; + +struct stv090x_config { + enum stv090x_device device; + enum stv090x_mode demod_mode; + enum stv090x_clkmode clk_mode; + + u32 xtal; /* default: 8000000 */ + u8 address; /* default: 0x68 */ + + u32 ref_clk; /* default: 16000000 FIXME to tuner config */ + + u8 ts1_mode; + u8 ts2_mode; + + int (*tuner_init) (struct dvb_frontend *fe); + int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); + int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); + int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); + int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth); + int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth); + int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain); + int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); + int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk); + int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); +}; + +#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE)) + +extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, + struct i2c_adapter *i2c, + enum stv090x_demodulator demod); +#else + +static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, + struct i2c_adapter *i2c, + enum stv090x_demodulator demod) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_STV090x */ + +#endif /* __STV090x_H */ diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h new file mode 100644 index 0000000..9d53622 --- /dev/null +++ b/drivers/media/dvb/frontends/stv090x_priv.h @@ -0,0 +1,274 @@ +/* + STV0900/0903 Multistandard Broadcast Frontend driver + Copyright (C) Manu Abraham + + Copyright (C) ST Microelectronics + + 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 __STV090x_PRIV_H +#define __STV090x_PRIV_H + +#include "dvb_frontend.h" + +#define FE_ERROR 0 +#define FE_NOTICE 1 +#define FE_INFO 2 +#define FE_DEBUG 3 +#define FE_DEBUGREG 4 + +#define dprintk(__y, __z, format, arg...) do { \ + if (__z) { \ + if ((verbose > FE_ERROR) && (verbose > __y)) \ + printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_NOTICE) && (verbose > __y)) \ + printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_INFO) && (verbose > __y)) \ + printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_DEBUG) && (verbose > __y)) \ + printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ + } else { \ + if (verbose > __y) \ + printk(format, ##arg); \ + } \ +} while (0) + +#define STV090x_READ_DEMOD(__state, __reg) (( \ + (__state)->demod == STV090x_DEMODULATOR_1) ? \ + stv090x_read_reg(__state, STV090x_P2_##__reg) : \ + stv090x_read_reg(__state, STV090x_P1_##__reg)) + +#define STV090x_WRITE_DEMOD(__state, __reg, __data) (( \ + (__state)->demod == STV090x_DEMODULATOR_1) ? \ + stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\ + stv090x_write_reg(__state, STV090x_P1_##__reg, __data)) + +#define STV090x_ADDR_OFFST(__state, __x) (( \ + (__state->demod) == STV090x_DEMODULATOR_1) ? \ + STV090x_P1_##__x : \ + STV090x_P2_##__x) + + +#define STV090x_SETFIELD(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\ + STV090x_OFFST_##bitf))) | \ + (val << STV090x_OFFST_##bitf)) + +#define STV090x_GETFIELD(val, bitf) ((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1)) + + +#define STV090x_SETFIELD_Px(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\ + STV090x_OFFST_Px_##bitf))) | \ + (val << STV090x_OFFST_Px_##bitf)) + +#define STV090x_GETFIELD_Px(val, bitf) ((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1)) + +#define MAKEWORD16(__a, __b) (((__a) << 8) | (__b)) + +#define STV090x_SEARCH_AGC2_TH 700 + +enum stv090x_signal_state { + STV090x_NOCARRIER, + STV090x_NODATA, + STV090x_DATAOK, + STV090x_RANGEOK, + STV090x_OUTOFRANGE +}; + +enum stv090x_fec { + STV090x_PR12 = 0, + STV090x_PR23, + STV090x_PR34, + STV090x_PR45, + STV090x_PR56, + STV090x_PR67, + STV090x_PR78, + STV090x_PR89, + STV090x_PR910, + STV090x_PRERR +}; + +enum stv090x_modulation { + STV090x_QPSK, + STV090x_8PSK, + STV090x_16APSK, + STV090x_32APSK, + STV090x_UNKNOWN +}; + +enum stv090x_frame { + STV090x_LONG_FRAME, + STV090x_SHORT_FRAME +}; + +enum stv090x_pilot { + STV090x_PILOTS_OFF, + STV090x_PILOTS_ON +}; + +enum stv090x_rolloff { + STV090x_RO_35, + STV090x_RO_25, + STV090x_RO_20 +}; + +enum stv090x_inversion { + STV090x_IQ_AUTO, + STV090x_IQ_NORMAL, + STV090x_IQ_SWAP +}; + +enum stv090x_modcod { + STV090x_DUMMY_PLF = 0, + STV090x_QPSK_14, + STV090x_QPSK_13, + STV090x_QPSK_25, + STV090x_QPSK_12, + STV090x_QPSK_35, + STV090x_QPSK_23, + STV090x_QPSK_34, + STV090x_QPSK_45, + STV090x_QPSK_56, + STV090x_QPSK_89, + STV090x_QPSK_910, + STV090x_8PSK_35, + STV090x_8PSK_23, + STV090x_8PSK_34, + STV090x_8PSK_56, + STV090x_8PSK_89, + STV090x_8PSK_910, + STV090x_16APSK_23, + STV090x_16APSK_34, + STV090x_16APSK_45, + STV090x_16APSK_56, + STV090x_16APSK_89, + STV090x_16APSK_910, + STV090x_32APSK_34, + STV090x_32APSK_45, + STV090x_32APSK_56, + STV090x_32APSK_89, + STV090x_32APSK_910, + STV090x_MODCODE_UNKNOWN +}; + +enum stv090x_search { + STV090x_SEARCH_DSS = 0, + STV090x_SEARCH_DVBS1, + STV090x_SEARCH_DVBS2, + STV090x_SEARCH_AUTO +}; + +enum stv090x_algo { + STV090x_BLIND_SEARCH, + STV090x_COLD_SEARCH, + STV090x_WARM_SEARCH +}; + +enum stv090x_delsys { + STV090x_ERROR = 0, + STV090x_DVBS1 = 1, + STV090x_DVBS2, + STV090x_DSS +}; + +struct stv090x_long_frame_crloop { + enum stv090x_modcod modcod; + + u8 crl_pilots_on_2; + u8 crl_pilots_off_2; + u8 crl_pilots_on_5; + u8 crl_pilots_off_5; + u8 crl_pilots_on_10; + u8 crl_pilots_off_10; + u8 crl_pilots_on_20; + u8 crl_pilots_off_20; + u8 crl_pilots_on_30; + u8 crl_pilots_off_30; +}; + +struct stv090x_short_frame_crloop { + enum stv090x_modulation modulation; + + u8 crl_cut12_2; /* Cut 1.2, SR <= 3M */ + u8 crl_cut20_2; /* Cut 2.0, SR < 3M */ + u8 crl_cut12_5; /* Cut 1.2, 3 < SR <= 7M */ + u8 crl_cut20_5; /* Cut 2.0, 3 < SR <= 7M */ + u8 crl_cut12_10; /* Cut 1.2, 7 < SR <= 15M */ + u8 crl_cut20_10; /* Cut 2.0, 7 < SR <= 15M */ + u8 crl_cut12_20; /* Cut 1.2, 10 < SR <= 25M */ + u8 crl_cut20_20; /* Cut 2.0, 10 < SR <= 25M */ + u8 crl_cut12_30; /* Cut 1.2, 25 < SR <= 45M */ + u8 crl_cut20_30; /* Cut 2.0, 10 < SR <= 45M */ +}; + + +struct stv090x_short_frame_vsmod_crloop { + enum stv090x_modulation modulation; + + u8 crl_2; /* < 3M */ + u8 crl_5; /* 3 < SR <= 7M */ + u8 crl_10; /* 7 < SR <= 15M */ + u8 crl_20; /* 10 < SR <= 25M */ + u8 crl_30; /* 10 < SR <= 45M */ +}; + +struct stv090x_reg { + u16 addr; + u8 data; +}; + +struct stv090x_tab { + s32 real; + s32 read; +}; + +struct stv090x_state { + enum stv090x_device device; + enum stv090x_demodulator demod; + enum stv090x_mode demod_mode; + u32 dev_ver; + + struct i2c_adapter *i2c; + const struct stv090x_config *config; + struct dvb_frontend frontend; + + u32 *verbose; /* Cached module verbosity */ + + enum stv090x_delsys delsys; + enum stv090x_fec fec; + enum stv090x_modulation modulation; + enum stv090x_modcod modcod; + enum stv090x_search search_mode; + enum stv090x_frame frame_len; + enum stv090x_pilot pilots; + enum stv090x_rolloff rolloff; + enum stv090x_inversion inversion; + enum stv090x_algo algo; + + u32 frequency; + u32 srate; + + s32 mclk; /* Masterclock Divider factor */ + s32 tuner_bw; + + u32 tuner_refclk; + + s32 search_range; + + s32 DemodTimeout; + s32 FecTimeout; +}; + +#endif /* __STV090x_PRIV_H */ diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h new file mode 100644 index 0000000..b59eca9 --- /dev/null +++ b/drivers/media/dvb/frontends/stv090x_reg.h @@ -0,0 +1,2300 @@ +/* + STV0900/0903 Multistandard Broadcast Frontend driver + Copyright (C) Manu Abraham + + Copyright (C) ST Microelectronics + + 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 __STV090x_REG_H +#define __STV090x_REG_H + +#define STV090x_MID 0xf100 +#define STV090x_OFFST_MCHIP_IDENT_FIELD 4 +#define STV090x_WIDTH_MCHIP_IDENT_FIELD 4 +#define STV090x_OFFST_MRELEASE_FIELD 0 +#define STV090x_WIDTH_MRELEASE_FIELD 4 + +#define STV090x_DACR1 0xf113 +#define STV090x_OFFST_DACR1_MODE_FIELD 5 +#define STV090x_WIDTH_DACR1_MODE_FIELD 3 +#define STV090x_OFFST_DACR1_VALUE_FIELD 0 +#define STV090x_WIDTH_DACR1_VALUE_FIELD 4 + +#define STV090x_DACR2 0xf114 +#define STV090x_OFFST_DACR2_VALUE_FIELD 0 +#define STV090x_WIDTH_DACR2_VALUE_FIELD 8 + +#define STV090x_OUTCFG 0xf11c +#define STV090x_OFFST_OUTSERRS1_HZ_FIELD 6 +#define STV090x_WIDTH_OUTSERRS1_HZ_FIELD 1 +#define STV090x_OFFST_OUTSERRS2_HZ_FIELD 5 +#define STV090x_WIDTH_OUTSERRS2_HZ_FIELD 1 +#define STV090x_OFFST_OUTSERRS3_HZ_FIELD 4 +#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 +#define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3 +#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 + +#define STV090x_IRQSTATUS3 0xf120 +#define STV090x_OFFST_SPLL_LOCK_FIELD 5 +#define STV090x_WIDTH_SPLL_LOCK_FIELD 1 +#define STV090x_OFFST_SSTREAM_LCK_3_FIELD 4 +#define STV090x_WIDTH_SSTREAM_LCK_3_FIELD 1 +#define STV090x_OFFST_SSTREAM_LCK_2_FIELD 3 +#define STV090x_WIDTH_SSTREAM_LCK_2_FIELD 1 +#define STV090x_OFFST_SSTREAM_LCK_1_FIELD 2 +#define STV090x_WIDTH_SSTREAM_LCK_1_FIELD 1 +#define STV090x_OFFST_SDVBS1_PRF_2_FIELD 1 +#define STV090x_WIDTH_SDVBS1_PRF_2_FIELD 1 +#define STV090x_OFFST_SDVBS1_PRF_1_FIELD 0 +#define STV090x_WIDTH_SDVBS1_PRF_1_FIELD 1 + +#define STV090x_IRQSTATUS2 0xf121 +#define STV090x_OFFST_SSPY_ENDSIM_3_FIELD 7 +#define STV090x_WIDTH_SSPY_ENDSIM_3_FIELD 1 +#define STV090x_OFFST_SSPY_ENDSIM_2_FIELD 6 +#define STV090x_WIDTH_SSPY_ENDSIM_2_FIELD 1 +#define STV090x_OFFST_SSPY_ENDSIM_1_FIELD 5 +#define STV090x_WIDTH_SSPY_ENDSIM_1_FIELD 1 +#define STV090x_OFFST_SPKTDEL_ERROR_2_FIELD 4 +#define STV090x_WIDTH_SPKTDEL_ERROR_2_FIELD 1 +#define STV090x_OFFST_SPKTDEL_LOCKB_2_FIELD 3 +#define STV090x_WIDTH_SPKTDEL_LOCKB_2_FIELD 1 +#define STV090x_OFFST_SPKTDEL_LOCK_2_FIELD 2 +#define STV090x_WIDTH_SPKTDEL_LOCK_2_FIELD 1 +#define STV090x_OFFST_SPKTDEL_ERROR_1_FIELD 1 +#define STV090x_WIDTH_SPKTDEL_ERROR_1_FIELD 1 +#define STV090x_OFFST_SPKTDEL_LOCKB_1_FIELD 0 +#define STV090x_WIDTH_SPKTDEL_LOCKB_1_FIELD 1 + +#define STV090x_IRQSTATUS1 0xf122 +#define STV090x_OFFST_SPKTDEL_LOCK_1_FIELD 7 +#define STV090x_WIDTH_SPKTDEL_LOCK_1_FIELD 1 +#define STV090x_OFFST_SDEMOD_LOCKB_2_FIELD 2 +#define STV090x_WIDTH_SDEMOD_LOCKB_2_FIELD 1 +#define STV090x_OFFST_SDEMOD_LOCK_2_FIELD 1 +#define STV090x_WIDTH_SDEMOD_LOCK_2_FIELD 1 +#define STV090x_OFFST_SDEMOD_IRQ_2_FIELD 0 +#define STV090x_WIDTH_SDEMOD_IRQ_2_FIELD 1 + +#define STV090x_IRQSTATUS0 0xf123 +#define STV090x_OFFST_SDEMOD_LOCKB_1_FIELD 7 +#define STV090x_WIDTH_SDEMOD_LOCKB_1_FIELD 1 +#define STV090x_OFFST_SDEMOD_LOCK_1_FIELD 6 +#define STV090x_WIDTH_SDEMOD_LOCK_1_FIELD 1 +#define STV090x_OFFST_SDEMOD_IRQ_1_FIELD 5 +#define STV090x_WIDTH_SDEMOD_IRQ_1_FIELD 1 +#define STV090x_OFFST_SBCH_ERRFLAG_FIELD 4 +#define STV090x_WIDTH_SBCH_ERRFLAG_FIELD 1 +#define STV090x_OFFST_SDISEQC2RX_IRQ_FIELD 3 +#define STV090x_WIDTH_SDISEQC2RX_IRQ_FIELD 1 +#define STV090x_OFFST_SDISEQC2TX_IRQ_FIELD 2 +#define STV090x_WIDTH_SDISEQC2TX_IRQ_FIELD 1 +#define STV090x_OFFST_SDISEQC1RX_IRQ_FIELD 1 +#define STV090x_WIDTH_SDISEQC1RX_IRQ_FIELD 1 +#define STV090x_OFFST_SDISEQC1TX_IRQ_FIELD 0 +#define STV090x_WIDTH_SDISEQC1TX_IRQ_FIELD 1 + +#define STV090x_IRQMASK3 0xf124 +#define STV090x_OFFST_MPLL_LOCK_FIELD 5 +#define STV090x_WIDTH_MPLL_LOCK_FIELD 1 +#define STV090x_OFFST_MSTREAM_LCK_3_FIELD 2 +#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 3 +#define STV090x_OFFST_MSTREAM_LCK_2_FIELD 2 +#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 3 +#define STV090x_OFFST_MSTREAM_LCK_1_FIELD 2 +#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 3 +#define STV090x_OFFST_MDVBS1_PRF_2_FIELD 1 +#define STV090x_WIDTH_MDVBS1_PRF_2_FIELD 1 +#define STV090x_OFFST_MDVBS1_PRF_1_FIELD 0 +#define STV090x_WIDTH_MDVBS1_PRF_1_FIELD 1 + +#define STV090x_IRQMASK2 0xf125 +#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 5 +#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 3 +#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 5 +#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 3 +#define STV090x_OFFST_MSPY_ENDSIM_1_FIELD 5 +#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 3 +#define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD 4 +#define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD 1 +#define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD 3 +#define STV090x_WIDTH_MPKTDEL_LOCKB_2_FIELD 1 +#define STV090x_OFFST_MPKTDEL_LOCK_2_FIELD 2 +#define STV090x_WIDTH_MPKTDEL_LOCK_2_FIELD 1 +#define STV090x_OFFST_MPKTDEL_ERROR_1_FIELD 1 +#define STV090x_WIDTH_MPKTDEL_ERROR_1_FIELD 1 +#define STV090x_OFFST_MPKTDEL_LOCKB_1_FIELD 0 +#define STV090x_WIDTH_MPKTDEL_LOCKB_1_FIELD 1 + +#define STV090x_IRQMASK1 0xf126 +#define STV090x_OFFST_MPKTDEL_LOCK_1_FIELD 7 +#define STV090x_WIDTH_MPKTDEL_LOCK_1_FIELD 1 +#define STV090x_OFFST_MEXTPINB2_FIELD 6 +#define STV090x_WIDTH_MEXTPINB2_FIELD 1 +#define STV090x_OFFST_MEXTPIN2_FIELD 5 +#define STV090x_WIDTH_MEXTPIN2_FIELD 1 +#define STV090x_OFFST_MEXTPINB1_FIELD 4 +#define STV090x_WIDTH_MEXTPINB1_FIELD 1 +#define STV090x_OFFST_MEXTPIN1_FIELD 3 +#define STV090x_WIDTH_MEXTPIN1_FIELD 1 +#define STV090x_OFFST_MDEMOD_LOCKB_2_FIELD 2 +#define STV090x_WIDTH_MDEMOD_LOCKB_2_FIELD 1 +#define STV090x_OFFST_MDEMOD_LOCK_2_FIELD 1 +#define STV090x_WIDTH_MDEMOD_LOCK_2_FIELD 1 +#define STV090x_OFFST_MDEMOD_IRQ_2_FIELD 0 +#define STV090x_WIDTH_MDEMOD_IRQ_2_FIELD 1 + +#define STV090x_IRQMASK0 0xf127 +#define STV090x_OFFST_MDEMOD_LOCKB_1_FIELD 7 +#define STV090x_WIDTH_MDEMOD_LOCKB_1_FIELD 1 +#define STV090x_OFFST_MDEMOD_LOCK_1_FIELD 6 +#define STV090x_WIDTH_MDEMOD_LOCK_1_FIELD 1 +#define STV090x_OFFST_MDEMOD_IRQ_1_FIELD 5 +#define STV090x_WIDTH_MDEMOD_IRQ_1_FIELD 1 +#define STV090x_OFFST_MBCH_ERRFLAG_FIELD 4 +#define STV090x_WIDTH_MBCH_ERRFLAG_FIELD 1 +#define STV090x_OFFST_MDISEQC2RX_IRQ_FIELD 3 +#define STV090x_WIDTH_MDISEQC2RX_IRQ_FIELD 1 +#define STV090x_OFFST_MDISEQC2TX_IRQ_FIELD 2 +#define STV090x_WIDTH_MDISEQC2TX_IRQ_FIELD 1 +#define STV090x_OFFST_MDISEQC1RX_IRQ_FIELD 1 +#define STV090x_WIDTH_MDISEQC1RX_IRQ_FIELD 1 +#define STV090x_OFFST_MDISEQC1TX_IRQ_FIELD 0 +#define STV090x_WIDTH_MDISEQC1TX_IRQ_FIELD 1 + +#define STV090x_I2CCFG 0xf129 +#define STV090x_OFFST_12C_FASTMODE_FIELD 3 +#define STV090x_WIDTH_12C_FASTMODE_FIELD 1 +#define STV090x_OFFST_12CADDR_INC_FIELD 0 +#define STV090x_WIDTH_12CADDR_INC_FIELD 2 + +#define STV090x_Px_I2CRPT(__x) (0xf12a + (__x - 1) * 0x1) +#define STV090x_P1_I2CRPT STV090x_Px_I2CRPT(1) +#define STV090x_P2_I2CRPT STV090x_Px_I2CRPT(2) +#define STV090x_OFFST_Px_I2CT_ON_FIELD 7 +#define STV090x_WIDTH_Px_I2CT_ON_FIELD 1 +#define STV090x_OFFST_Px_ENARPT_LEVEL_FIELD 4 +#define STV090x_WIDTH_Px_ENARPT_LEVEL_FIELD 3 +#define STV090x_OFFST_Px_SCLT_DELAY_FIELD 3 +#define STV090x_WIDTH_Px_SCLT_DELAY_FIELD 1 +#define STV090x_OFFST_Px_STOP_ENABLE_FIELD 2 +#define STV090x_WIDTH_Px_STOP_ENABLE_FIELD 1 +#define STV090x_OFFST_Px_STOP_SDAT2SDA_FIELD 1 +#define STV090x_WIDTH_Px_STOP_SDAT2SDA_FIELD 1 + +#define STV090x_CLKI2CFG 0xf140 +#define STV090x_OFFST_CLKI2_OPD_FIELD 7 +#define STV090x_WIDTH_CLKI2_OPD_FIELD 1 +#define STV090x_OFFST_CLKI2_CONFIG_FIELD 1 +#define STV090x_WIDTH_CLKI2_CONFIG_FIELD 6 +#define STV090x_OFFST_CLKI2_XOR_FIELD 0 +#define STV090x_WIDTH_CLKI2_XOR_FIELD 1 + +#define STV090x_GPIOxCFG(__x) (0xf141 + (__x - 1)) +#define STV090x_GPIO1CFG STV090x_GPIOxCFG(1) +#define STV090x_GPIO2CFG STV090x_GPIOxCFG(2) +#define STV090x_GPIO3CFG STV090x_GPIOxCFG(3) +#define STV090x_GPIO4CFG STV090x_GPIOxCFG(4) +#define STV090x_GPIO5CFG STV090x_GPIOxCFG(5) +#define STV090x_GPIO6CFG STV090x_GPIOxCFG(6) +#define STV090x_GPIO7CFG STV090x_GPIOxCFG(7) +#define STV090x_GPIO8CFG STV090x_GPIOxCFG(8) +#define STV090x_GPIO9CFG STV090x_GPIOxCFG(9) +#define STV090x_GPIO10CFG STV090x_GPIOxCFG(10) +#define STV090x_GPIO11CFG STV090x_GPIOxCFG(11) +#define STV090x_GPIO12CFG STV090x_GPIOxCFG(12) +#define STV090x_GPIO13CFG STV090x_GPIOxCFG(13) +#define STV090x_OFFST_GPIOx_OPD_FIELD 7 +#define STV090x_WIDTH_GPIOx_OPD_FIELD 1 +#define STV090x_OFFST_GPIOx_CONFIG_FIELD 1 +#define STV090x_WIDTH_GPIOx_CONFIG_FIELD 6 +#define STV090x_OFFST_GPIOx_XOR_FIELD 0 +#define STV090x_WIDTH_GPIOx_XOR_FIELD 1 + +#define STV090x_CSxCFG(__x) (0xf14e + __x * 0x1) +#define STV090x_CS0CFG STV090x_CSxCFG(0) +#define STV090x_CS1CFG STV090x_CSxCFG(1) +#define STV090x_OFFST_CSX_OPD_FIELD 7 +#define STV090x_WIDTH_CSX_OPD_FIELD 1 +#define STV090x_OFFST_CSX_CONFIG_FIELD 1 +#define STV090x_WIDTH_CSX_CONFIG_FIELD 6 +#define STV090x_OFFST_CSX_XOR_FIELD 0 +#define STV090x_WIDTH_CSX_XOR_FIELD 1 + + +#define STV090x_STDBYCFG 0xf150 +#define STV090x_OFFST_STDBY_OPD_FIELD 7 +#define STV090x_WIDTH_STDBY_OPD_FIELD 1 +#define STV090x_OFFST_STDBY_CONFIG_FIELD 1 +#define STV090x_WIDTH_STDBY_CONFIG_FIELD 6 +#define STV090x_OFFST_STDBY_XOR_FIELD 0 +#define STV090x_WIDTH_STDBY_XOR_FIELD 1 + +#define STV090x_DIRCLKCFG 0xf151 +#define STV090x_OFFST_DIRCLK_OPD_FIELD 7 +#define STV090x_WIDTH_DIRCLK_OPD_FIELD 1 +#define STV090x_OFFST_DIRCLK_CONFIG_FIELD 1 +#define STV090x_WIDTH_DIRCLK_CONFIG_FIELD 6 +#define STV090x_OFFST_DIRCLK_XOR_FIELD 0 +#define STV090x_WIDTH_DIRCLK_XOR_FIELD 1 + + +#define STV090x_AGCRFxCFG(__x) (0xf152 + (__x - 1) * 0x4) +#define STV090x_AGCRF1CFG STV090x_AGCRFxCFG(1) +#define STV090x_AGCRF2CFG STV090x_AGCRFxCFG(2) +#define STV090x_OFFST_AGCRFx_OPD_FIELD 7 +#define STV090x_WIDTH_AGCRFx_OPD_FIELD 1 +#define STV090x_OFFST_AGCRFx_CONFIG_FIELD 1 +#define STV090x_WIDTH_AGCRFx_CONFIG_FIELD 6 +#define STV090x_OFFST_AGCRFx_XOR_FIELD 0 +#define STV090x_WIDTH_AGCRFx_XOR_FIELD 1 + +#define STV090x_SDATxCFG(__x) (0xf153 + (__x - 1) * 0x4) +#define STV090x_SDAT1CFG STV090x_SDATxCFG(1) +#define STV090x_SDAT2CFG STV090x_SDATxCFG(2) +#define STV090x_OFFST_SDATx_OPD_FIELD 7 +#define STV090x_WIDTH_SDATx_OPD_FIELD 1 +#define STV090x_OFFST_SDATx_CONFIG_FIELD 1 +#define STV090x_WIDTH_SDATx_CONFIG_FIELD 6 +#define STV090x_OFFST_SDATx_XOR_FIELD 0 +#define STV090x_WIDTH_SDATx_XOR_FIELD 1 + +#define STV090x_SCLTxCFG(__x) (0xf154 + (__x - 1) * 0x4) +#define STV090x_SCLT1CFG STV090x_SCLTxCFG(1) +#define STV090x_SCLT2CFG STV090x_SCLTxCFG(2) +#define STV090x_OFFST_SCLTx_OPD_FIELD 7 +#define STV090x_WIDTH_SCLTx_OPD_FIELD 1 +#define STV090x_OFFST_SCLTx_CONFIG_FIELD 1 +#define STV090x_WIDTH_SCLTx_CONFIG_FIELD 6 +#define STV090x_OFFST_SCLTx_XOR_FIELD 0 +#define STV090x_WIDTH_SCLTx_XOR_FIELD 1 + +#define STV090x_DISEQCOxCFG(__x) (0xf155 + (__x - 1) * 0x4) +#define STV090x_DISEQCO1CFG STV090x_DISEQCOxCFG(1) +#define STV090x_DISEQCO2CFG STV090x_DISEQCOxCFG(2) +#define STV090x_OFFST_DISEQCOx_OPD_FIELD 7 +#define STV090x_WIDTH_DISEQCOx_OPD_FIELD 1 +#define STV090x_OFFST_DISEQCOx_CONFIG_FIELD 1 +#define STV090x_WIDTH_DISEQCOx_CONFIG_FIELD 6 +#define STV090x_OFFST_DISEQCOx_XOR_FIELD 0 +#define STV090x_WIDTH_DISEQCOx_XOR_FIELD 1 + +#define STV090x_CLKOUT27CFG 0xf15a +#define STV090x_OFFST_CLKOUT27_OPD_FIELD 7 +#define STV090x_WIDTH_CLKOUT27_OPD_FIELD 1 +#define STV090x_OFFST_CLKOUT27_CONFIG_FIELD 1 +#define STV090x_WIDTH_CLKOUT27_CONFIG_FIELD 6 +#define STV090x_OFFST_CLKOUT27_XOR_FIELD 0 +#define STV090x_WIDTH_CLKOUT27_XOR_FIELD 1 + +#define STV090x_ERRORxCFG(__x) (0xf15b + (__x - 1) * 0x5) +#define STV090x_ERROR1CFG STV090x_ERRORxCFG(1) +#define STV090x_ERROR2CFG STV090x_ERRORxCFG(2) +#define STV090x_ERROR3CFG STV090x_ERRORxCFG(3) +#define STV090x_OFFST_ERRORx_OPD_FIELD 7 +#define STV090x_WIDTH_ERRORx_OPD_FIELD 1 +#define STV090x_OFFST_ERRORx_CONFIG_FIELD 1 +#define STV090x_WIDTH_ERRORx_CONFIG_FIELD 6 +#define STV090x_OFFST_ERRORx_XOR_FIELD 0 +#define STV090x_WIDTH_ERRORx_XOR_FIELD 1 + +#define STV090x_DPNxCFG(__x) (0xf15c + (__x - 1) * 0x5) +#define STV090x_DPN1CFG STV090x_DPNxCFG(1) +#define STV090x_DPN2CFG STV090x_DPNxCFG(2) +#define STV090x_DPN3CFG STV090x_DPNxCFG(3) +#define STV090x_OFFST_DPNx_OPD_FIELD 7 +#define STV090x_WIDTH_DPNx_OPD_FIELD 1 +#define STV090x_OFFST_DPNx_CONFIG_FIELD 1 +#define STV090x_WIDTH_DPNx_CONFIG_FIELD 6 +#define STV090x_OFFST_DPNx_XOR_FIELD 0 +#define STV090x_WIDTH_DPNx_XOR_FIELD 1 + +#define STV090x_STROUTxCFG(__x) (0xf15d + (__x - 1) * 0x5) +#define STV090x_STROUT1CFG STV090x_STROUTxCFG(1) +#define STV090x_STROUT2CFG STV090x_STROUTxCFG(2) +#define STV090x_STROUT3CFG STV090x_STROUTxCFG(3) +#define STV090x_OFFST_STROUTx_OPD_FIELD 7 +#define STV090x_WIDTH_STROUTx_OPD_FIELD 1 +#define STV090x_OFFST_STROUTx_CONFIG_FIELD 1 +#define STV090x_WIDTH_STROUTx_CONFIG_FIELD 6 +#define STV090x_OFFST_STROUTx_XOR_FIELD 0 +#define STV090x_WIDTH_STROUTx_XOR_FIELD 1 + +#define STV090x_CLKOUTxCFG(__x) (0xf15e + (__x - 1) * 0x5) +#define STV090x_CLKOUT1CFG STV090x_CLKOUTxCFG(1) +#define STV090x_CLKOUT2CFG STV090x_CLKOUTxCFG(2) +#define STV090x_CLKOUT3CFG STV090x_CLKOUTxCFG(3) +#define STV090x_OFFST_CLKOUTx_OPD_FIELD 7 +#define STV090x_WIDTH_CLKOUTx_OPD_FIELD 1 +#define STV090x_OFFST_CLKOUTx_CONFIG_FIELD 1 +#define STV090x_WIDTH_CLKOUTx_CONFIG_FIELD 6 +#define STV090x_OFFST_CLKOUTx_XOR_FIELD 0 +#define STV090x_WIDTH_CLKOUTx_XOR_FIELD 1 + +#define STV090x_DATAxCFG(__x) (0xf15f + (__x - 71) * 0x5) +#define STV090x_DATA71CFG STV090x_DATAxCFG(71) +#define STV090x_DATA72CFG STV090x_DATAxCFG(72) +#define STV090x_DATA73CFG STV090x_DATAxCFG(73) +#define STV090x_OFFST_DATAx_OPD_FIELD 7 +#define STV090x_WIDTH_DATAx_OPD_FIELD 1 +#define STV090x_OFFST_DATAx_CONFIG_FIELD 1 +#define STV090x_WIDTH_DATAx_CONFIG_FIELD 6 +#define STV090x_OFFST_DATAx_XOR_FIELD 0 +#define STV090x_WIDTH_DATAx_XOR_FIELD 1 + +#define STV090x_NCOARSE 0xf1b3 +#define STV090x_OFFST_M_DIV_FIELD 0 +#define STV090x_WIDTH_M_DIV_FIELD 8 + +#define STV090x_SYNTCTRL 0xf1b6 +#define STV090x_OFFST_STANDBY_FIELD 7 +#define STV090x_WIDTH_STANDBY_FIELD 1 +#define STV090x_OFFST_BYPASSPLLCORE_FIELD 6 +#define STV090x_WIDTH_BYPASSPLLCORE_FIELD 1 +#define STV090x_OFFST_SELX1RATIO_FIELD 5 +#define STV090x_WIDTH_SELX1RATIO_FIELD 1 +#define STV090x_OFFST_STOP_PLL_FIELD 3 +#define STV090x_WIDTH_SELX1RATIO_FIELD 1 +#define STV090x_OFFST_BYPASSPLLFSK_FIELD 2 +#define STV090x_WIDTH_BYPASSPLLFSK_FIELD 1 +#define STV090x_OFFST_SELOSCI_FIELD 1 +#define STV090x_WIDTH_SELOSCI_FIELD 1 +#define STV090x_OFFST_BYPASSPLLADC_FIELD 0 +#define STV090x_WIDTH_BYPASSPLLADC_FIELD 1 + +#define STV090x_FILTCTRL 0xf1b7 +#define STV090x_OFFST_INV_CLK135_FIELD 7 +#define STV090x_WIDTH_INV_CLK135_FIELD 1 +#define STV090x_OFFST_SEL_FSKCKDIV_FIELD 2 +#define STV090x_WIDTH_SEL_FSKCKDIV_FIELD 1 +#define STV090x_OFFST_INV_CLKFSK_FIELD 1 +#define STV090x_WIDTH_INV_CLKFSK_FIELD 1 +#define STV090x_OFFST_BYPASS_APPLI_FIELD 0 +#define STV090x_WIDTH_BYPASS_APPLI_FIELD 1 + +#define STV090x_PLLSTAT 0xf1b8 +#define STV090x_OFFST_PLLLOCK_FIELD 0 +#define STV090x_WIDTH_PLLLOCK_FIELD 1 + +#define STV090x_STOPCLK1 0xf1c2 +#define STV090x_OFFST_STOP_CLKPKDT2_FIELD 6 +#define STV090x_WIDTH_STOP_CLKPKDT2_FIELD 1 +#define STV090x_OFFST_STOP_CLKPKDT1_FIELD 5 +#define STV090x_WIDTH_STOP_CLKPKDT1_FIELD 1 +#define STV090x_OFFST_STOP_CLKFEC_FIELD 4 +#define STV090x_WIDTH_STOP_CLKFEC_FIELD 1 +#define STV090x_OFFST_STOP_CLKADCI2_FIELD 3 +#define STV090x_WIDTH_STOP_CLKADCI2_FIELD 1 +#define STV090x_OFFST_INV_CLKADCI2_FIELD 2 +#define STV090x_WIDTH_INV_CLKADCI2_FIELD 1 +#define STV090x_OFFST_STOP_CLKADCI1_FIELD 1 +#define STV090x_WIDTH_STOP_CLKADCI1_FIELD 1 +#define STV090x_OFFST_INV_CLKADCI1_FIELD 0 +#define STV090x_WIDTH_INV_CLKADCI1_FIELD 1 + +#define STV090x_STOPCLK2 0xf1c3 +#define STV090x_OFFST_STOP_CLKSAMP2_FIELD 4 +#define STV090x_WIDTH_STOP_CLKSAMP2_FIELD 1 +#define STV090x_OFFST_STOP_CLKSAMP1_FIELD 3 +#define STV090x_WIDTH_STOP_CLKSAMP1_FIELD 1 +#define STV090x_OFFST_STOP_CLKVIT2_FIELD 2 +#define STV090x_WIDTH_STOP_CLKVIT2_FIELD 1 +#define STV090x_OFFST_STOP_CLKVIT1_FIELD 1 +#define STV090x_WIDTH_STOP_CLKVIT1_FIELD 1 +#define STV090x_OFFST_STOP_CLKTS_FIELD 0 +#define STV090x_WIDTH_STOP_CLKTS_FIELD 1 + +#define STV090x_TSTTNR0 0xf1df +#define STV090x_OFFST_SEL_FSK_FIELD 7 +#define STV090x_WIDTH_SEL_FSK_FIELD 1 +#define STV090x_OFFST_FSK_PON_FIELD 2 +#define STV090x_WIDTH_FSK_PON_FIELD 1 + +#define STV090x_TSTTNR1 0xf1e0 +#define STV090x_OFFST_ADC1_PON_FIELD 1 +#define STV090x_WIDTH_ADC1_PON_FIELD 1 +#define STV090x_OFFST_ADC1_INMODE_FIELD 0 +#define STV090x_WIDTH_ADC1_INMODE_FIELD 1 + +#define STV090x_TSTTNR2 0xf1e1 +#define STV090x_OFFST_DISEQC1_PON_FIELD 5 +#define STV090x_WIDTH_DISEQC1_PON_FIELD 1 + +#define STV090x_TSTTNR3 0xf1e2 +#define STV090x_OFFST_ADC2_PON_FIELD 1 +#define STV090x_WIDTH_ADC2_PON_FIELD 1 +#define STV090x_OFFST_ADC2_INMODE_FIELD 0 +#define STV090x_WIDTH_ADC2_INMODE_FIELD 1 + +#define STV090x_TSTTNR4 0xf1e3 +#define STV090x_OFFST_DISEQC2_PON_FIELD 5 +#define STV090x_WIDTH_DISEQC2_PON_FIELD 1 + +#define STV090x_FSKTFC2 0xf170 +#define STV090x_OFFST_FSKT_KMOD_FIELD 2 +#define STV090x_WIDTH_FSKT_KMOD_FIELD 6 +#define STV090x_OFFST_FSKT_CAR_FIELD 0 +#define STV090x_WIDTH_FSKT_CAR_FIELD 2 + +#define STV090x_FSKTFC1 0xf171 +#define STV090x_OFFST_FSKTC1_CAR_FIELD 0 +#define STV090x_WIDTH_FSKTC1_CAR_FIELD 8 + +#define STV090x_FSKTFC0 0xf172 +#define STV090x_OFFST_FSKTC0_CAR_FIELD 0 +#define STV090x_WIDTH_FSKTC0_CAR_FIELD 8 + +#define STV090x_FSKTDELTAF1 0xf173 +#define STV090x_OFFST_FSKTF1_DELTAF_FIELD 0 +#define STV090x_WIDTH_FSKTF1_DELTAF_FIELD 4 + +#define STV090x_FSKTDELTAF0 0xf174 +#define STV090x_OFFST_FSKTF0_DELTAF_FIELD 0 +#define STV090x_WIDTH_FSKTF0_DELTAF_FIELD 8 + +#define STV090x_FSKTCTRL 0xf175 +#define STV090x_OFFST_FSKT_EN_SGN_FIELD 6 +#define STV090x_WIDTH_FSKT_EN_SGN__FIELD 1 +#define STV090x_OFFST_FSKT_MOD_SGN_FIELD 5 +#define STV090x_WIDTH_FSKT_MOD_SGN_FIELD 1 +#define STV090x_OFFST_FSKT_MOD_EN_FIELD 2 +#define STV090x_WIDTH_FSKT_MOD_EN_FIELD 3 +#define STV090x_OFFST_FSKT_DACMODE_FIELD 0 +#define STV090x_WIDTH_FSKT_DACMODE_FIELD 2 + +#define STV090x_FSKRFC2 0xf176 +#define STV090x_OFFST_FSKRC2_DETSGN_FIELD 6 +#define STV090x_WIDTH_FSKRC2_DETSGN_FIELD 1 +#define STV090x_OFFST_FSKRC2_OUTSGN_FIELD 5 +#define STV090x_WIDTH_FSKRC2_OUTSGN_FIELD 1 +#define STV090x_OFFST_FSKRC2_KAGC_FIELD 2 +#define STV090x_WIDTH_FSKRC2_KAGC_FIELD 3 +#define STV090x_OFFST_FSKRC2_CAR_FIELD 0 +#define STV090x_WIDTH_FSKRC2_CAR_FIELD 2 + +#define STV090x_FSKRFC1 0xf177 +#define STV090x_OFFST_FSKRC1_CAR_FIELD 0 +#define STV090x_WIDTH_FSKRC1_CAR_FIELD 8 + +#define STV090x_FSKRFC0 0xf178 +#define STV090x_OFFST_FSKRC0_CAR_FIELD 0 +#define STV090x_WIDTH_FSKRC0_CAR_FIELD 8 + +#define STV090x_FSKRK1 0xf179 +#define STV090x_OFFST_FSKR_K1_EXP_FIELD 5 +#define STV090x_WIDTH_FSKR_K1_EXP_FIELD 3 +#define STV090x_OFFST_FSKR_K1_MANT_FIELD 0 +#define STV090x_WIDTH_FSKR_K1_MANT_FIELD 5 + +#define STV090x_FSKRK2 0xf17a +#define STV090x_OFFST_FSKR_K2_EXP_FIELD 5 +#define STV090x_WIDTH_FSKR_K2_EXP_FIELD 3 +#define STV090x_OFFST_FSKR_K2_MANT_FIELD 0 +#define STV090x_WIDTH_FSKR_K2_MANT_FIELD 5 + +#define STV090x_FSKRAGCR 0xf17b +#define STV090x_OFFST_FSKR_OUTCTL_FIELD 6 +#define STV090x_WIDTH_FSKR_OUTCTL_FIELD 2 +#define STV090x_OFFST_FSKR_AGC_REF_FIELD 0 +#define STV090x_WIDTH_FSKR_AGC_REF_FIELD 6 + +#define STV090x_FSKRAGC 0xf17c +#define STV090x_OFFST_FSKR_AGC_ACCU_FIELD 0 +#define STV090x_WIDTH_FSKR_AGC_ACCU_FIELD 8 + +#define STV090x_FSKRALPHA 0xf17d +#define STV090x_OFFST_FSKR_ALPHA_EXP_FIELD 2 +#define STV090x_WIDTH_FSKR_ALPHA_EXP_FIELD 3 +#define STV090x_OFFST_FSKR_ALPHA_M_FIELD 0 +#define STV090x_WIDTH_FSKR_ALPHA_M_FIELD 2 + +#define STV090x_FSKRPLTH1 0xf17e +#define STV090x_OFFST_FSKR_BETA_FIELD 4 +#define STV090x_WIDTH_FSKR_BETA_FIELD 4 +#define STV090x_OFFST_FSKR_PLL_TRESH1_FIELD 0 +#define STV090x_WIDTH_FSKR_PLL_TRESH1_FIELD 4 + +#define STV090x_FSKRPLTH0 0xf17f +#define STV090x_OFFST_FSKR_PLL_TRESH0_FIELD 0 +#define STV090x_WIDTH_FSKR_PLL_TRESH0_FIELD 8 + +#define STV090x_FSKRDF1 0xf180 +#define STV090x_OFFST_FSKR_DELTAF1_FIELD 0 +#define STV090x_WIDTH_FSKR_DELTAF1_FIELD 5 + +#define STV090x_FSKRDF0 0xf181 +#define STV090x_OFFST_FSKR_DELTAF0_FIELD 0 +#define STV090x_WIDTH_FSKR_DELTAF0_FIELD 8 + +#define STV090x_FSKRSTEPP 0xf182 +#define STV090x_OFFST_FSKR_STEP_PLUS_FIELD 0 +#define STV090x_WIDTH_FSKR_STEP_PLUS_FIELD 8 + +#define STV090x_FSKRSTEPM 0xf183 +#define STV090x_OFFST_FSKR_STEP_MINUS_FIELD 0 +#define STV090x_WIDTH_FSKR_STEP_MINUS_FIELD 8 + +#define STV090x_FSKRDET1 0xf184 +#define STV090x_OFFST_FSKR_CARDET1_ACCU_FIELD 0 +#define STV090x_WIDTH_FSKR_CARDET1_ACCU_FIELD 4 + +#define STV090x_FSKRDET0 0xf185 +#define STV090x_OFFST_FSKR_CARDET0_ACCU_FIELD 0 +#define STV090x_WIDTH_FSKR_CARDET0_ACCU_FIELD 8 + +#define STV090x_FSKRDTH1 0xf186 +#define STV090x_OFFST_FSKR_CARLOSS_THRESH1_FIELD 4 +#define STV090x_WIDTH_FSKR_CARLOSS_THRESH1_FIELD 4 +#define STV090x_OFFST_FSKR_CARDET_THRESH1_FIELD 0 +#define STV090x_WIDTH_FSKR_CARDET_THRESH1_FIELD 4 + +#define STV090x_FSKRDTH0 0xf187 +#define STV090x_OFFST_FSKR_CARDET_THRESH0_FIELD 0 +#define STV090x_WIDTH_FSKR_CARDET_THRESH0_FIELD 8 + +#define STV090x_FSKRLOSS 0xf188 +#define STV090x_OFFST_FSKR_CARLOSS_THRESH_FIELD 0 +#define STV090x_WIDTH_FSKR_CARLOSS_THRESH_FIELD 8 + +#define STV090x_Px_DISTXCTL(__x) (0xF1A0 - (__x - 1) * 0x10) +#define STV090x_P1_DISTXCTL (1) +#define STV090x_P2_DISTXCTL (2) +#define STV090x_OFFST_Px_TIM_OFF_FIELD 7 +#define STV090x_WIDTH_Px_TIM_OFF_FIELD 1 +#define STV090x_OFFST_Px_DISEQC_RESET_FIELD 6 +#define STV090x_WIDTH_Px_DISEQC_RESET_FIELD 1 +#define STV090x_OFFST_Px_TIM_CMD_FIELD 4 +#define STV090x_WIDTH_Px_TIM_CMD_FIELD 2 +#define STV090x_OFFST_Px_DIS_PRECHARGE_FIELD 3 +#define STV090x_WIDTH_Px_DIS_PRECHARGE_FIELD 1 +#define STV090x_OFFST_Px_DISTX_MODE_FIELD 0 +#define STV090x_WIDTH_Px_DISTX_MODE_FIELD 3 + +#define STV090x_Px_DISRXCTL(__x) (0xf1a1 - (__x - 1) * 0x10) +#define STV090x_P1_DISRXCTL (1) +#define STV090x_P2_DISRXCTL (2) +#define STV090x_OFFST_Px_RECEIVER_ON_FIELD 7 +#define STV090x_WIDTH_Px_RECEIVER_ON_FIELD 1 +#define STV090x_OFFST_Px_IGNO_SHORT22K_FIELD 6 +#define STV090x_WIDTH_Px_IGNO_SHORT22K_FIELD 1 +#define STV090x_OFFST_Px_ONECHIP_TRX_FIELD 5 +#define STV090x_WIDTH_Px_ONECHIP_TRX_FIELD 1 +#define STV090x_OFFST_Px_EXT_ENVELOP_FIELD 4 +#define STV090x_WIDTH_Px_EXT_ENVELOP_FIELD 1 +#define STV090x_OFFST_Px_PIN_SELECT_FIELD 2 +#define STV090x_WIDTH_Px_PIN_SELECT_FIELD 2 +#define STV090x_OFFST_Px_IRQ_RXEND_FIELD 1 +#define STV090x_WIDTH_Px_IRQ_RXEND_FIELD 1 +#define STV090x_OFFST_Px_IRQ_4NBYTES_FIELD 0 +#define STV090x_WIDTH_Px_IRQ_4NBYTES_FIELD 1 + +#define STV090x_Px_DISRX_ST0(__x) (0xf1a4 - (__x - 1) * 0x10) +#define STV090x_P1_DISRX_ST0 (1) +#define STV090x_P2_DISRX_ST0 (2) +#define STV090x_OFFST_Px_RX_END_FIELD 7 +#define STV090x_WIDTH_Px_RX_END_FIELD 1 +#define STV090x_OFFST_Px_RX_ACTIVE_FIELD 6 +#define STV090x_WIDTH_Px_RX_ACTIVE_FIELD 1 +#define STV090x_OFFST_Px_SHORT_22KHZ_FIELD 5 +#define STV090x_WIDTH_Px_SHORT_22KHZ_FIELD 1 +#define STV090x_OFFST_Px_CONT_TONE_FIELD 4 +#define STV090x_WIDTH_Px_CONT_TONE_FIELD 1 +#define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3 +#define STV090x_WIDTH_Px_FIFO_4BREADYFIELD 2 +#define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2 +#define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1 +#define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0 +#define STV090x_WIDTH_Px_ABORT_DISRX_FIELD 1 + +#define STV090x_Px_DISRX_ST1(__x) (0xf1a5 - (__x - 1) * 0x10) +#define STV090x_P1_DISRX_ST1 (1) +#define STV090x_P2_DISRX_ST1 (2) +#define STV090x_OFFST_Px_RX_FAIL_FIELD 7 +#define STV090x_WIDTH_Px_RX_FAIL_FIELD 1 +#define STV090x_OFFST_Px_FIFO_PARITYFAIL_FIELD 6 +#define STV090x_WIDTH_Px_FIFO_PARITYFAIL_FIELD 1 +#define STV090x_OFFST_Px_RX_NONBYTE_FIELD 5 +#define STV090x_WIDTH_Px_RX_NONBYTE_FIELD 1 +#define STV090x_OFFST_Px_FIFO_OVERFLOW_FIELD 4 +#define STV090x_WIDTH_Px_FIFO_OVERFLOW_FIELD 1 +#define STV090x_OFFST_Px_FIFO_BYTENBR_FIELD 0 +#define STV090x_WIDTH_Px_FIFO_BYTENBR_FIELD 4 + +#define STV090x_Px_DISRXDATA(__x) (0xf1a6 - (__x - 1) * 0x10) +#define STV090x_P1_DISRXDATA (1) +#define STV090x_P2_DISRXDATA (2) +#define STV090x_OFFST_Px_DISRX_DATA_FIELD 0 +#define STV090x_WIDTH_Px_DISRX_DATA_FIELD 8 + +#define STV090x_Px_DISTXDATA(__x) (0xf1a7 - (__x - 1) * 0x10) +#define STV090x_P1_DISTXDATA (1) +#define STV090x_P2_DISTXDATA (2) +#define STV090x_OFFST_Px_DISEQC_FIFO_FIELD 0 +#define STV090x_WIDTH_Px_DISEQC_FIFO_FIELD 8 + +#define STV090x_Px_DISTXSTATUS(__x) (0xf1a8 - (__x - 1) * 0x10) +#define STV090x_P1_DISTXSTATUS (1) +#define STV090x_P2_DISTXSTATUS (2) +#define STV090x_OFFST_Px_TX_FAIL_FIELD 7 +#define STV090x_WIDTH_Px_TX_FAIL_FIELD 1 +#define STV090x_OFFST_Px_FIFO_FULL_FIELD 6 +#define STV090x_WIDTH_Px_FIFO_FULL_FIELD 1 +#define STV090x_OFFST_Px_TX_IDLE_FIELD 5 +#define STV090x_WIDTH_Px_TX_IDLE_FIELD 1 +#define STV090x_OFFST_Px_GAP_BURST_FIELD 4 +#define STV090x_WIDTH_Px_GAP_BURST_FIELD 1 +#define STV090x_OFFST_Px_TXFIFO_BYTES_FIELD 0 +#define STV090x_WIDTH_Px_TXFIFO_BYTES_FIELD 4 + +#define STV090x_Px_F22TX(__x) (0xf1a9 - (__x - 1) * 0x10) +#define STV090x_P1_F22TX (1) +#define STV090x_P2_F22TX (2) +#define STV090x_OFFST_Px_F22_REG_FIELD 0 +#define STV090x_WIDTH_Px_F22_REG_FIELD 8 + +#define STV090x_Px_F22RX(__x) (0xf1aa - (__x - 1) * 0x10) +#define STV090x_P1_F22RX (1) +#define STV090x_P2_F22RX (2) +#define STV090x_OFFST_Px_F22RX_REG_FIELD 0 +#define STV090x_WIDTH_Px_F22RX_REG_FIELD 8 + +#define STV090x_Px_ACRPRESC(__x) (0xf1ac - (__x - 1) * 0x10) +#define STV090x_P1_ACRPRESC (1) +#define STV090x_P2_ACRPRESC (2) +#define STV090x_OFFST_Px_ACR_PRESC_FIELD 0 +#define STV090x_WIDTH_Px_ACR_PRESC_FIELD 3 + +#define STV090x_Px_ACRDIV(__x) (0xf1ad - (__x - 1) * 0x10) +#define STV090x_P1_ACRDIV (1) +#define STV090x_P2_ACRDIV (2) +#define STV090x_OFFST_Px_ACR_DIV_FIELD 0 +#define STV090x_WIDTH_Px_ACR_DIV_FIELD 8 + +#define STV090x_Px_IQCONST(__x) (0xF400 - (__x - 1) * 0x200) +#define STV090x_P1_IQCONST STV090x_Px_IQCONST(1) +#define STV090x_P2_IQCONST STV090x_Px_IQCONST(2) +#define STV090x_OFFST_Px_CONSTEL_SELECT_FIELD 5 +#define STV090x_WIDTH_Px_CONSTEL_SELECT_FIELD 2 + +#define STV090x_Px_NOSCFG(__x) (0xF401 - (__x - 1) * 0x200) +#define STV090x_P1_NOSCFG STV090x_Px_NOSCFG(1) +#define STV090x_P2_NOSCFG STV090x_Px_NOSCFG(2) +#define STV090x_OFFST_Px_NOSPLH_BETA_FIELD 3 +#define STV090x_WIDTH_Px_NOSPLH_BETA_FIELD 2 +#define STV090x_OFFST_Px_NOSDATA_BETA_FIELD 0 +#define STV090x_WIDTH_Px_NOSDATA_BETA_FIELD 3 + +#define STV090x_Px_ISYMB(__x) (0xF402 - (__x - 1) * 0x200) +#define STV090x_P1_ISYMB STV090x_Px_ISYMB(1) +#define STV090x_P2_ISYMB STV090x_Px_ISYMB(2) +#define STV090x_OFFST_Px_I_SYMBOL_FIELD 0 +#define STV090x_WIDTH_Px_I_SYMBOL_FIELD 8 + +#define STV090x_Px_QSYMB(__x) (0xF403 - (__x - 1) * 0x200) +#define STV090x_P1_QSYMB STV090x_Px_QSYMB(1) +#define STV090x_P2_QSYMB STV090x_Px_QSYMB(2) +#define STV090x_OFFST_Px_Q_SYMBOL_FIELD 0 +#define STV090x_WIDTH_Px_Q_SYMBOL_FIELD 8 + +#define STV090x_Px_AGC1CFG(__x) (0xF404 - (__x - 1) * 0x200) +#define STV090x_P1_AGC1CFG STV090x_Px_AGC1CFG(1) +#define STV090x_P2_AGC1CFG STV090x_Px_AGC1CFG(2) +#define STV090x_OFFST_Px_DC_FROZEN_FIELD 7 +#define STV090x_WIDTH_Px_DC_FROZEN_FIELD 1 +#define STV090x_OFFST_Px_DC_CORRECT_FIELD 6 +#define STV090x_WIDTH_Px_DC_CORRECT_FIELD 1 +#define STV090x_OFFST_Px_AMM_FROZEN_FIELD 5 +#define STV090x_WIDTH_Px_AMM_FROZEN_FIELD 1 +#define STV090x_OFFST_Px_AMM_CORRECT_FIELD 4 +#define STV090x_WIDTH_Px_AMM_CORRECT_FIELD 1 +#define STV090x_OFFST_Px_QUAD_FROZEN_FIELD 3 +#define STV090x_WIDTH_Px_QUAD_FROZEN_FIELD 1 +#define STV090x_OFFST_Px_QUAD_CORRECT_FIELD 2 +#define STV090x_WIDTH_Px_QUAD_CORRECT_FIELD 1 + +#define STV090x_Px_AGC1CN(__x) (0xF406 - (__x - 1) * 0x200) +#define STV090x_P1_AGC1CN STV090x_Px_AGC1CN(1) +#define STV090x_P2_AGC1CN STV090x_Px_AGC1CN(2) +#define STV090x_WIDTH_Px_AGC1_LOCKED_FIELD 7 +#define STV090x_OFFST_Px_AGC1_LOCKED_FIELD 1 +#define STV090x_OFFST_Px_AGC1_MINPOWER_FIELD 4 +#define STV090x_WIDTH_Px_AGC1_MINPOWER_FIELD 1 +#define STV090x_OFFST_Px_AGCOUT_FAST_FIELD 3 +#define STV090x_WIDTH_Px_AGCOUT_FAST_FIELD 1 +#define STV090x_OFFST_Px_AGCIQ_BETA_FIELD 0 +#define STV090x_WIDTH_Px_AGCIQ_BETA_FIELD 3 + +#define STV090x_Px_AGC1REF(__x) (0xF407 - (__x - 1) * 0x200) +#define STV090x_P1_AGC1REF STV090x_Px_AGC1REF(1) +#define STV090x_P2_AGC1REF STV090x_Px_AGC1REF(2) +#define STV090x_OFFST_Px_AGCIQ_REF_FIELD 0 +#define STV090x_WIDTH_Px_AGCIQ_REF_FIELD 8 + +#define STV090x_Px_IDCCOMP(__x) (0xF408 - (__x - 1) * 0x200) +#define STV090x_P1_IDCCOMP STV090x_Px_IDCCOMP(1) +#define STV090x_P2_IDCCOMP STV090x_Px_IDCCOMP(2) +#define STV090x_OFFST_Px_IAVERAGE_ADJ_FIELD 0 +#define STV090x_WIDTH_Px_IAVERAGE_ADJ_FIELD 8 + +#define STV090x_Px_QDCCOMP(__x) (0xF409 - (__x - 1) * 0x200) +#define STV090x_P1_QDCCOMP STV090x_Px_QDCCOMP(1) +#define STV090x_P2_QDCCOMP STV090x_Px_QDCCOMP(2) +#define STV090x_OFFST_Px_QAVERAGE_ADJ_FIELD 0 +#define STV090x_WIDTH_Px_QAVERAGE_ADJ_FIELD 8 + +#define STV090x_Px_POWERI(__x) (0xF40A - (__x - 1) * 0x200) +#define STV090x_P1_POWERI STV090x_Px_POWERI(1) +#define STV090x_P2_POWERI STV090x_Px_POWERI(2) +#define STV090x_OFFST_Px_POWER_I_FIELD 0 +#define STV090x_WIDTH_Px_POWER_I_FIELD 8 + +#define STV090x_Px_POWERQ(__x) (0xF40B - (__x - 1) * 0x200) +#define STV090x_P1_POWERQ STV090x_Px_POWERQ(1) +#define STV090x_P2_POWERQ STV090x_Px_POWERQ(2) +#define STV090x_OFFST_Px_POWER_Q_FIELD 0 +#define STV090x_WIDTH_Px_POWER_Q_FIELD 8 + +#define STV090x_Px_AGC1AMM(__x) (0xF40C - (__x - 1) * 0x200) +#define STV090x_P1_AGC1AMM STV090x_Px_AGC1AMM(1) +#define STV090x_P2_AGC1AMM STV090x_Px_AGC1AMM(2) +#define STV090x_OFFST_Px_AMM_VALUE_FIELD 0 +#define STV090x_WIDTH_Px_AMM_VALUE_FIELD 8 + +#define STV090x_Px_AGC1QUAD(__x) (0xF40D - (__x - 1) * 0x200) +#define STV090x_P1_AGC1QUAD STV090x_Px_AGC1QUAD(1) +#define STV090x_P2_AGC1QUAD STV090x_Px_AGC1QUAD(2) +#define STV090x_OFFST_Px_QUAD_VALUE_FIELD 0 +#define STV090x_WIDTH_Px_QUAD_VALUE_FIELD 8 + +#define STV090x_Px_AGCIQINy(__x, __y) (0xF40F - (__x-1) * 0x200 - __y * 0x1) +#define STV090x_P1_AGCIQIN0 STV090x_Px_AGCIQINy(1, 0) +#define STV090x_P1_AGCIQIN1 STV090x_Px_AGCIQINy(1, 1) +#define STV090x_P2_AGCIQIN0 STV090x_Px_AGCIQINy(2, 0) +#define STV090x_P2_AGCIQIN1 STV090x_Px_AGCIQINy(2, 1) +#define STV090x_OFFST_Px_AGCIQ_VALUE_FIELD 0 +#define STV090x_WIDTH_Px_AGCIQ_VALUE_FIELD 8 + +#define STV090x_Px_DEMOD(__x) (0xF410 - (__x - 1) * 0x200) +#define STV090x_P1_DEMOD STV090x_Px_DEMOD(1) +#define STV090x_P2_DEMOD STV090x_Px_DEMOD(2) +#define STV090x_OFFST_Px_SPECINV_CONTROL_FIELD 4 +#define STV090x_WIDTH_Px_SPECINV_CONTROL_FIELD 2 +#define STV090x_OFFST_Px_MANUAL_ROLLOFF_FIELD 2 +#define STV090x_WIDTH_Px_MANUAL_ROLLOFF_FIELD 1 +#define STV090x_OFFST_Px_ROLLOFF_CONTROL_FIELD 0 +#define STV090x_WIDTH_Px_ROLLOFF_CONTROL_FIELD 2 + +#define STV090x_Px_DMDMODCOD(__x) (0xF411 - (__x - 1) * 0x200) +#define STV090x_P1_DMDMODCOD STV090x_Px_DMDMODCOD(1) +#define STV090x_P2_DMDMODCOD STV090x_Px_DMDMODCOD(2) +#define STV090x_OFFST_Px_MANUAL_MODCOD_FIELD 7 +#define STV090x_WIDTH_Px_MANUAL_MODCOD_FIELD 1 +#define STV090x_OFFST_Px_DEMOD_MODCOD_FIELD 2 +#define STV090x_WIDTH_Px_DEMOD_MODCOD_FIELD 5 +#define STV090x_OFFST_Px_DEMOD_TYPE_FIELD 0 +#define STV090x_WIDTH_Px_DEMOD_TYPE_FIELD 2 + +#define STV090x_Px_DSTATUS(__x) (0xF412 - (__x - 1) * 0x200) +#define STV090x_P1_DSTATUS STV090x_Px_DSTATUS(1) +#define STV090x_P2_DSTATUS STV090x_Px_DSTATUS(2) +#define STV090x_OFFST_Px_CAR_LOCK_FIELD 7 +#define STV090x_WIDTH_Px_CAR_LOCK_FIELD 1 +#define STV090x_OFFST_Px_TMGLOCK_QUALITY_FIELD 5 +#define STV090x_WIDTH_Px_TMGLOCK_QUALITY_FIELD 2 +#define STV090x_OFFST_Px_LOCK_DEFINITIF_FIELD 3 +#define STV090x_WIDTH_Px_LOCK_DEFINITIF_FIELD 1 + +#define STV090x_Px_DSTATUS2(__x) (0xF413 - (__x - 1) * 0x200) +#define STV090x_P1_DSTATUS2 STV090x_Px_DSTATUS2(1) +#define STV090x_P2_DSTATUS2 STV090x_Px_DSTATUS2(2) +#define STV090x_OFFST_Px_DEMOD_DELOCK_FIELD 7 +#define STV090x_WIDTH_Px_DEMOD_DELOCK_FIELD 1 +#define STV090x_OFFST_Px_AGC1_NOSIGNALACK_FIELD 3 +#define STV090x_WIDTH_Px_AGC1_NOSIGNALACK_FIELD 1 +#define STV090x_OFFST_Px_AGC2_OVERFLOW_FIELD 2 +#define STV090x_WIDTH_Px_AGC2_OVERFLOW_FIELD 1 +#define STV090x_OFFST_Px_CFR_OVERFLOW_FIELD 1 +#define STV090x_WIDTH_Px_CFR_OVERFLOW_FIELD 1 +#define STV090x_OFFST_Px_GAMMA_OVERUNDER_FIELD 0 +#define STV090x_WIDTH_Px_GAMMA_OVERUNDER_FIELD 1 + +#define STV090x_Px_DMDCFGMD(__x) (0xF414 - (__x - 1) * 0x200) +#define STV090x_P1_DMDCFGMD STV090x_Px_DMDCFGMD(1) +#define STV090x_P2_DMDCFGMD STV090x_Px_DMDCFGMD(2) +#define STV090x_OFFST_Px_DVBS2_ENABLE_FIELD 7 +#define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD 1 +#define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD 6 +#define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD 1 +#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 5 /* check */ +#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1 +#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4 /* check */ +#define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD 1 +#define STV090x_OFFST_Px_TUN_AUTOSCAN_FIELD 3 +#define STV090x_WIDTH_Px_TUN_AUTOSCAN_FIELD 1 +#define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD 2 +#define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD 1 +#define STV090x_OFFST_Px_TUN_RNG_FIELD 0 +#define STV090x_WIDTH_Px_TUN_RNG_FIELD 2 + +#define STV090x_Px_DMDCFG2(__x) (0xF415 - (__x - 1) * 0x200) +#define STV090x_P1_DMDCFG2 STV090x_Px_DMDCFG2(1) +#define STV090x_P2_DMDCFG2 STV090x_Px_DMDCFG2(2) +#define STV090x_OFFST_Px_S1S2_SEQUENTIAL_FIELD 6 +#define STV090x_WIDTH_Px_S1S2_SEQUENTIAL_FIELD 1 + +#define STV090x_Px_DMDISTATE(__x) (0xF416 - (__x - 1) * 0x200) +#define STV090x_P1_DMDISTATE STV090x_Px_DMDISTATE(1) +#define STV090x_P2_DMDISTATE STV090x_Px_DMDISTATE(2) +#define STV090x_OFFST_Px_I2C_DEMOD_MODE_FIELD 0 +#define STV090x_WIDTH_Px_I2C_DEMOD_MODE_FIELD 5 + +#define STV090x_Px_DMDTOM(__x) (0xF417 - (__x - 1) * 0x200) /* check */ +#define STV090x_P1_DMDTOM STV090x_Px_DMDTOM(1) +#define STV090x_P2_DMDTOM STV090x_Px_DMDTOM(2) + +#define STV090x_Px_DMDSTATE(__x) (0xF41B - (__x - 1) * 0x200) +#define STV090x_P1_DMDSTATE STV090x_Px_DMDSTATE(1) +#define STV090x_P2_DMDSTATE STV090x_Px_DMDSTATE(2) +#define STV090x_OFFST_Px_HEADER_MODE_FIELD 5 +#define STV090x_WIDTH_Px_HEADER_MODE_FIELD 2 + +#define STV090x_Px_DMDFLYW(__x) (0xF41C - (__x - 1) * 0x200) +#define STV090x_P1_DMDFLYW STV090x_Px_DMDFLYW(1) +#define STV090x_P2_DMDFLYW STV090x_Px_DMDFLYW(2) +#define STV090x_OFFST_Px_I2C_IRQVAL_FIELD 4 +#define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD 4 +#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0 /* check */ +#define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD 4 + +#define STV090x_Px_DSTATUS3(__x) (0xF41D - (__x - 1) * 0x200) +#define STV090x_P1_DSTATUS3 STV090x_Px_DSTATUS3(1) +#define STV090x_P2_DSTATUS3 STV090x_Px_DSTATUS3(2) +#define STV090x_OFFST_Px_DEMOD_CFGMODE_FIELD 5 +#define STV090x_WIDTH_Px_DEMOD_CFGMODE_FIELD 2 + +#define STV090x_Px_DMDCFG3(__x) (0xF41E - (__x - 1) * 0x200) +#define STV090x_P1_DMDCFG3 STV090x_Px_DMDCFG3(1) +#define STV090x_P2_DMDCFG3 STV090x_Px_DMDCFG3(2) +#define STV090x_OFFST_Px_NOSTOP_FIFOFULL_FIELD 3 +#define STV090x_WIDTH_Px_NOSTOP_FIFOFULL_FIELD 1 + +#define STV090x_Px_CORRELMANT(__x) (0xF420 - (__x - 1) * 0x200) +#define STV090x_P1_CORRELMANT STV090x_Px_CORRELMANT(1) +#define STV090x_P2_CORRELMANT STV090x_Px_CORRELMANT(2) +#define STV090x_OFFST_Px_CORREL_MANT_FIELD 0 +#define STV090x_WIDTH_Px_CORREL_MANT_FIELD 8 + +#define STV090x_Px_CORRELABS(__x) (0xF421 - (__x - 1) * 0x200) +#define STV090x_P1_CORRELABS STV090x_Px_CORRELABS(1) +#define STV090x_P2_CORRELABS STV090x_Px_CORRELABS(2) +#define STV090x_OFFST_Px_CORREL_ABS_FIELD 0 +#define STV090x_WIDTH_Px_CORREL_ABS_FIELD 8 + +#define STV090x_Px_CORRELEXP(__x) (0xF422 - (__x - 1) * 0x200) +#define STV090x_P1_CORRELEXP STV090x_Px_CORRELEXP(1) +#define STV090x_P2_CORRELEXP STV090x_Px_CORRELEXP(2) +#define STV090x_OFFST_Px_CORREL_ABSEXP_FIELD 4 +#define STV090x_WIDTH_Px_CORREL_ABSEXP_FIELD 4 +#define STV090x_OFFST_Px_CORREL_EXP_FIELD 0 +#define STV090x_WIDTH_Px_CORREL_EXP_FIELD 4 + +#define STV090x_Px_PLHMODCOD(__x) (0xF424 - (__x - 1) * 0x200) +#define STV090x_P1_PLHMODCOD STV090x_Px_PLHMODCOD(1) +#define STV090x_P2_PLHMODCOD STV090x_Px_PLHMODCOD(2) +#define STV090x_OFFST_Px_SPECINV_DEMOD_FIELD 7 +#define STV090x_WIDTH_Px_SPECINV_DEMOD_FIELD 1 +#define STV090x_OFFST_Px_PLH_MODCOD_FIELD 2 +#define STV090x_WIDTH_Px_PLH_MODCOD_FIELD 5 +#define STV090x_OFFST_Px_PLH_TYPE_FIELD 0 +#define STV090x_WIDTH_Px_PLH_TYPE_FIELD 2 + +#define STV090x_Px_AGC2REF(__x) (0xF42D - (__x - 1) * 0x200) +#define STV090x_P1_AGC2REF STV090x_Px_AGC2REF(1) +#define STV090x_P2_AGC2REF STV090x_Px_AGC2REF(2) +#define STV090x_OFFST_Px_AGC2_REF_FIELD 0 +#define STV090x_WIDTH_Px_AGC2_REF_FIELD 8 + +#define STV090x_Px_AGC1ADJ(__x) (0xF42E - (__x - 1) * 0x200) +#define STV090x_P1_AGC1ADJ STV090x_Px_AGC1ADJ(1) +#define STV090x_P2_AGC1ADJ STV090x_Px_AGC1ADJ(2) +#define STV090x_OFFST_Px_AGC1_ADJUSTED_FIELD 0 +#define STV090x_WIDTH_Px_AGC1_ADJUSTED_FIELD 7 + +#define STV090x_Px_AGC2Iy(__x, __y) (0xF437 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_AGC2I0 STV090x_Px_AGC2Iy(1, 0) +#define STV090x_P1_AGC2I1 STV090x_Px_AGC2Iy(1, 1) +#define STV090x_P2_AGC2I0 STV090x_Px_AGC2Iy(2, 0) +#define STV090x_P2_AGC2I1 STV090x_Px_AGC2Iy(2, 1) +#define STV090x_OFFST_Px_AGC2_INTEGRATOR_FIELD 0 +#define STV090x_WIDTH_Px_AGC2_INTEGRATOR_FIELD 8 + +#define STV090x_Px_CARCFG(__x) (0xF438 - (__x - 1) * 0x200) +#define STV090x_P1_CARCFG STV090x_Px_CARCFG(1) +#define STV090x_P2_CARCFG STV090x_Px_CARCFG(2) +#define STV090x_OFFST_Px_EN_CAR2CENTER_FIELD 5 +#define STV090x_WIDTH_Px_EN_CAR2CENTER_FIELD 1 +#define STV090x_OFFST_Px_ROTATON_FIELD 2 +#define STV090x_WIDTH_Px_ROTATON_FIELD 1 +#define STV090x_OFFST_Px_PH_DET_ALGO_FIELD 0 +#define STV090x_WIDTH_Px_PH_DET_ALGO_FIELD 2 + +#define STV090x_Px_ACLC(__x) (0xF439 - (__x - 1) * 0x200) +#define STV090x_P1_ACLC STV090x_Px_ACLC(1) +#define STV090x_P2_ACLC STV090x_Px_ACLC(2) +#define STV090x_OFFST_Px_CAR_ALPHA_MANT_FIELD 4 +#define STV090x_WIDTH_Px_CAR_ALPHA_MANT_FIELD 2 +#define STV090x_OFFST_Px_CAR_ALPHA_EXP_FIELD 0 +#define STV090x_WIDTH_Px_CAR_ALPHA_EXP_FIELD 4 + +#define STV090x_Px_BCLC(__x) (0xF43A - (__x - 1) * 0x200) +#define STV090x_P1_BCLC STV090x_Px_BCLC(1) +#define STV090x_P2_BCLC STV090x_Px_BCLC(2) +#define STV090x_OFFST_Px_CAR_BETA_MANT_FIELD 4 +#define STV090x_WIDTH_Px_CAR_BETA_MANT_FIELD 2 +#define STV090x_OFFST_Px_CAR_BETA_EXP_FIELD 0 +#define STV090x_WIDTH_Px_CAR_BETA_EXP_FIELD 4 + +#define STV090x_Px_CARFREQ(__x) (0xF43D - (__x - 1) * 0x200) +#define STV090x_P1_CARFREQ STV090x_Px_CARFREQ(1) +#define STV090x_P2_CARFREQ STV090x_Px_CARFREQ(2) +#define STV090x_OFFST_Px_KC_COARSE_EXP_FIELD 4 +#define STV090x_WIDTH_Px_KC_COARSE_EXP_FIELD 4 +#define STV090x_OFFST_Px_BETA_FREQ_FIELD 0 +#define STV090x_WIDTH_Px_BETA_FREQ_FIELD 4 + +#define STV090x_Px_CARHDR(__x) (0xF43E - (__x - 1) * 0x200) +#define STV090x_P1_CARHDR STV090x_Px_CARHDR(1) +#define STV090x_P2_CARHDR STV090x_Px_CARHDR(2) +#define STV090x_OFFST_Px_FREQ_HDR_FIELD 0 +#define STV090x_WIDTH_Px_FREQ_HDR_FIELD 8 + +#define STV090x_Px_LDT(__x) (0xF43F - (__x - 1) * 0x200) +#define STV090x_P1_LDT STV090x_Px_LDT(1) +#define STV090x_P2_LDT STV090x_Px_LDT(2) +#define STV090x_OFFST_Px_CARLOCK_THRES_FIELD 0 +#define STV090x_WIDTH_Px_CARLOCK_THRES_FIELD 8 + +#define STV090x_Px_LDT2(__x) (0xF440 - (__x - 1) * 0x200) +#define STV090x_P1_LDT2 STV090x_Px_LDT2(1) +#define STV090x_P2_LDT2 STV090x_Px_LDT2(2) +#define STV090x_OFFST_Px_CARLOCK_THRES2_FIELD 0 +#define STV090x_WIDTH_Px_CARLOCK_THRES2_FIELD 8 + +#define STV090x_Px_CFRICFG(__x) (0xF441 - (__x - 1) * 0x200) +#define STV090x_P1_CFRICFG STV090x_Px_CFRICFG(1) +#define STV090x_P2_CFRICFG STV090x_Px_CFRICFG(2) +#define STV090x_OFFST_Px_NEG_CFRSTEP_FIELD 0 +#define STV090x_WIDTH_Px_NEG_CFRSTEP_FIELD 1 + +#define STV090x_Pn_CFRUPy(__x, __y) (0xF443 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_CFRUP0 STV090x_Pn_CFRUPy(1, 0) +#define STV090x_P1_CFRUP1 STV090x_Pn_CFRUPy(1, 1) +#define STV090x_P2_CFRUP0 STV090x_Pn_CFRUPy(2, 0) +#define STV090x_P2_CFRUP1 STV090x_Pn_CFRUPy(2, 1) +#define STV090x_OFFST_Px_CFR_UP_FIELD 0 +#define STV090x_WIDTH_Px_CFR_UP_FIELD 8 + +#define STV090x_Pn_CFRLOWy(__x, __y) (0xF447 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_CFRLOW0 STV090x_Pn_CFRLOWy(1, 0) +#define STV090x_P1_CFRLOW1 STV090x_Pn_CFRLOWy(1, 1) +#define STV090x_P2_CFRLOW0 STV090x_Pn_CFRLOWy(2, 0) +#define STV090x_P2_CFRLOW1 STV090x_Pn_CFRLOWy(2, 1) +#define STV090x_OFFST_Px_CFR_LOW_FIELD 0 +#define STV090x_WIDTH_Px_CFR_LOW_FIELD 8 + +#define STV090x_Pn_CFRINITy(__x, __y) (0xF449 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_CFRINIT0 STV090x_Pn_CFRINITy(1, 0) +#define STV090x_P1_CFRINIT1 STV090x_Pn_CFRINITy(1, 1) +#define STV090x_P2_CFRINIT0 STV090x_Pn_CFRINITy(2, 0) +#define STV090x_P2_CFRINIT1 STV090x_Pn_CFRINITy(2, 1) +#define STV090x_OFFST_Px_CFR_INIT_FIELD 0 +#define STV090x_WIDTH_Px_CFR_INIT_FIELD 8 + +#define STV090x_Px_CFRINC1(__x) (0xF44A - (__x - 1) * 0x200) +#define STV090x_P1_CFRINC1 STV090x_Px_CFRINC1(1) +#define STV090x_P2_CFRINC1 STV090x_Px_CFRINC1(2) +#define STV090x_OFFST_Px_CFR_INC1_FIELD 0 +#define STV090x_WIDTH_Px_CFR_INC1_FIELD 7 + +#define STV090x_Px_CFRINC0(__x) (0xF44B - (__x - 1) * 0x200) +#define STV090x_P1_CFRINC0 STV090x_Px_CFRINC0(1) +#define STV090x_P2_CFRINC0 STV090x_Px_CFRINC0(2) +#define STV090x_OFFST_Px_CFR_INC0_FIELD 4 +#define STV090x_WIDTH_Px_CFR_INC0_FIELD 4 + +#define STV090x_Pn_CFRy(__x, __y) (0xF44E - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_CFR0 STV090x_Pn_CFRy(1, 0) +#define STV090x_P1_CFR1 STV090x_Pn_CFRy(1, 1) +#define STV090x_P1_CFR2 STV090x_Pn_CFRy(1, 2) +#define STV090x_P2_CFR0 STV090x_Pn_CFRy(2, 0) +#define STV090x_P2_CFR1 STV090x_Pn_CFRy(2, 1) +#define STV090x_P2_CFR2 STV090x_Pn_CFRy(2, 2) +#define STV090x_OFFST_Px_CAR_FREQ_FIELD 0 +#define STV090x_WIDTH_Px_CAR_FREQ_FIELD 8 + +#define STV090x_Px_LDI(__x) (0xF44F - (__x - 1) * 0x200) +#define STV090x_P1_LDI STV090x_Px_LDI(1) +#define STV090x_P2_LDI STV090x_Px_LDI(2) +#define STV090x_OFFST_Px_LOCK_DET_INTEGR_FIELD 0 +#define STV090x_WIDTH_Px_LOCK_DET_INTEGR_FIELD 8 + +#define STV090x_Px_TMGCFG(__x) (0xF450 - (__x - 1) * 0x200) +#define STV090x_P1_TMGCFG STV090x_Px_TMGCFG(1) +#define STV090x_P2_TMGCFG STV090x_Px_TMGCFG(2) +#define STV090x_OFFST_Px_TMGLOCK_BETA_FIELD 6 +#define STV090x_WIDTH_Px_TMGLOCK_BETA_FIELD 2 +#define STV090x_OFFST_Px_DO_TIMING_FIELD 4 +#define STV090x_WIDTH_Px_DO_TIMING_FIELD 1 +#define STV090x_OFFST_Px_TMG_MINFREQ_FIELD 0 +#define STV090x_WIDTH_Px_TMG_MINFREQ_FIELD 2 + +#define STV090x_Px_RTC(__x) (0xF451 - (__x - 1) * 0x200) +#define STV090x_P1_RTC STV090x_Px_RTC(1) +#define STV090x_P2_RTC STV090x_Px_RTC(2) +#define STV090x_OFFST_Px_TMGALPHA_EXP_FIELD 4 +#define STV090x_WIDTH_Px_TMGALPHA_EXP_FIELD 4 +#define STV090x_OFFST_Px_TMGBETA_EXP_FIELD 0 +#define STV090x_WIDTH_Px_TMGBETA_EXP_FIELD 4 + +#define STV090x_Px_RTCS2(__x) (0xF452 - (__x - 1) * 0x200) +#define STV090x_P1_RTCS2 STV090x_Px_RTCS2(1) +#define STV090x_P2_RTCS2 STV090x_Px_RTCS2(2) +#define STV090x_OFFST_Px_TMGALPHAS2_EXP_FIELD 4 +#define STV090x_WIDTH_Px_TMGALPHAS2_EXP_FIELD 4 +#define STV090x_OFFST_Px_TMGBETAS2_EXP_FIELD 0 +#define STV090x_WIDTH_Px_TMGBETAS2_EXP_FIELD 4 + +#define STV090x_Px_TMGTHRISE(__x) (0xF453 - (__x - 1) * 0x200) +#define STV090x_P1_TMGTHRISE STV090x_Px_TMGTHRISE(1) +#define STV090x_P2_TMGTHRISE STV090x_Px_TMGTHRISE(2) +#define STV090x_OFFST_Px_TMGLOCK_THRISE_FIELD 0 +#define STV090x_WIDTH_Px_TMGLOCK_THRISE_FIELD 8 + +#define STV090x_Px_TMGTHFALL(__x) (0xF454 - (__x - 1) * 0x200) +#define STV090x_P1_TMGTHFALL STV090x_Px_TMGTHFALL(1) +#define STV090x_P2_TMGTHFALL STV090x_Px_TMGTHFALL(2) +#define STV090x_OFFST_Px_TMGLOCK_THFALL_FIELD 0 +#define STV090x_WIDTH_Px_TMGLOCK_THFALL_FIELD 8 + +#define STV090x_Px_SFRUPRATIO(__x) (0xF455 - (__x - 1) * 0x200) +#define STV090x_P1_SFRUPRATIO STV090x_Px_SFRUPRATIO(1) +#define STV090x_P2_SFRUPRATIO STV090x_Px_SFRUPRATIO(2) +#define STV090x_OFFST_Px_SFR_UPRATIO_FIELD 0 +#define STV090x_WIDTH_Px_SFR_UPRATIO_FIELD 8 + +#define STV090x_Px_SFRLOWRATIO(__x) (0xF456 - (__x - 1) * 0x200) +#define STV090x_P1_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(1) +#define STV090x_P2_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(2) +#define STV090x_OFFST_Px_SFR_LOWRATIO_FIELD 0 +#define STV090x_WIDTH_Px_SFR_LOWRATIO_FIELD 8 + +#define STV090x_Px_KREFTMG(__x) (0xF458 - (__x - 1) * 0x200) +#define STV090x_P1_KREFTMG STV090x_Px_KREFTMG(1) +#define STV090x_P2_KREFTMG STV090x_Px_KREFTMG(2) +#define STV090x_OFFST_Px_KREF_TMG_FIELD 0 +#define STV090x_WIDTH_Px_KREF_TMG_FIELD 8 + +#define STV090x_Px_SFRSTEP(__x) (0xF459 - (__x - 1) * 0x200) +#define STV090x_P1_SFRSTEP STV090x_Px_SFRSTEP(1) +#define STV090x_P2_SFRSTEP STV090x_Px_SFRSTEP(2) +#define STV090x_OFFST_Px_SFR_SCANSTEP_FIELD 4 +#define STV090x_WIDTH_Px_SFR_SCANSTEP_FIELD 4 +#define STV090x_OFFST_Px_SFR_CENTERSTEP_FIELD 0 +#define STV090x_WIDTH_Px_SFR_CENTERSTEP_FIELD 4 + +#define STV090x_Px_TMGCFG2(__x) (0xF45A - (__x - 1) * 0x200) +#define STV090x_P1_TMGCFG2 STV090x_Px_TMGCFG2(1) +#define STV090x_P2_TMGCFG2 STV090x_Px_TMGCFG2(2) +#define STV090x_OFFST_Px_SFRRATIO_FINE_FIELD 0 +#define STV090x_WIDTH_Px_SFRRATIO_FINE_FIELD 1 + +#define STV090x_Px_SFRINIT1(__x) (0xF45E - (__x - 1) * 0x200) +#define STV090x_P1_SFRINIT1 STV090x_Px_SFRINIT1(1) +#define STV090x_P2_SFRINIT1 STV090x_Px_SFRINIT1(2) +#define STV090x_OFFST_Px_SFR_INIT_FIELD 0 +#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8 + +#define STV090x_Px_SFRINIT0(__x) (0xF45F - (__x - 1) * 0x200) +#define STV090x_P1_SFRINIT0 STV090x_Px_SFRINIT0(1) +#define STV090x_P2_SFRINIT0 STV090x_Px_SFRINIT0(2) +#define STV090x_OFFST_Px_SFR_INIT_FIELD 0 +#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8 + +#define STV090x_Px_SFRUP1(__x) (0xF460 - (__x - 1) * 0x200) +#define STV090x_P1_SFRUP1 STV090x_Px_SFRUP1(1) +#define STV090x_P2_SFRUP1 STV090x_Px_SFRUP1(2) +#define STV090x_OFFST_Px_SYMB_FREQ_UP1_FIELD 0 +#define STV090x_WIDTH_Px_SYMB_FREQ_UP1_FIELD 7 + +#define STV090x_Px_SFRUP0(__x) (0xF461 - (__x - 1) * 0x200) +#define STV090x_P1_SFRUP0 STV090x_Px_SFRUP0(1) +#define STV090x_P2_SFRUP0 STV090x_Px_SFRUP0(2) +#define STV090x_OFFST_Px_SYMB_FREQ_UP0_FIELD 0 +#define STV090x_WIDTH_Px_SYMB_FREQ_UP0_FIELD 8 + +#define STV090x_Px_SFRLOW1(__x) (0xF462 - (__x - 1) * 0x200) +#define STV090x_P1_SFRLOW1 STV090x_Px_SFRLOW1(1) +#define STV090x_P2_SFRLOW1 STV090x_Px_SFRLOW1(2) +#define STV090x_OFFST_Px_SYMB_FREQ_LOW1_FIELD 0 +#define STV090x_WIDTH_Px_SYMB_FREQ_LOW1_FIELD 7 + +#define STV090x_Px_SFRLOW0(__x) (0xF463 - (__x - 1) * 0x200) +#define STV090x_P1_SFRLOW0 STV090x_Px_SFRLOW0(1) +#define STV090x_P2_SFRLOW0 STV090x_Px_SFRLOW0(2) +#define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD 0 +#define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD 8 + +#define STV090x_Px_SFRy(__x, __y) (0xF464 - (__x-1) * 0x200 + (3 - __y)) +#define STV090x_P1_SFR0 STV090x_Px_SFRy(1, 0) +#define STV090x_P1_SFR1 STV090x_Px_SFRy(1, 1) +#define STV090x_P1_SFR2 STV090x_Px_SFRy(1, 2) +#define STV090x_P1_SFR3 STV090x_Px_SFRy(1, 3) +#define STV090x_P2_SFR0 STV090x_Px_SFRy(2, 0) +#define STV090x_P2_SFR1 STV090x_Px_SFRy(2, 1) +#define STV090x_P2_SFR2 STV090x_Px_SFRy(2, 2) +#define STV090x_P2_SFR3 STV090x_Px_SFRy(2, 3) +#define STV090x_OFFST_Px_SYMB_FREQ_FIELD 0 +#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 32 + +#define STV090x_Px_TMGREG2(__x) (0xF468 - (__x - 1) * 0x200) +#define STV090x_P1_TMGREG2 STV090x_Px_TMGREG2(1) +#define STV090x_P2_TMGREG2 STV090x_Px_TMGREG2(2) +#define STV090x_OFFST_Px_TMGREG_FIELD 0 +#define STV090x_WIDTH_Px_TMGREG_FIELD 8 + +#define STV090x_Px_TMGREG1(__x) (0xF469 - (__x - 1) * 0x200) +#define STV090x_P1_TMGREG1 STV090x_Px_TMGREG1(1) +#define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2) +#define STV090x_OFFST_Px_TMGREG_FIELD 0 +#define STV090x_WIDTH_Px_TMGREG_FIELD 8 + +#define STV090x_Px_TMGREG0(__x) (0xF46A - (__x - 1) * 0x200) +#define STV090x_P1_TMGREG0 STV090x_Px_TMGREG0(1) +#define STV090x_P2_TMGREG0 STV090x_Px_TMGREG0(2) +#define STV090x_OFFST_Px_TMGREG_FIELD 0 +#define STV090x_WIDTH_Px_TMGREG_FIELD 8 + +#define STV090x_Px_TMGLOCKy(__x, __y) (0xF46C - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_TMGLOCK0 STV090x_Px_TMGLOCKy(1, 0) +#define STV090x_P1_TMGLOCK1 STV090x_Px_TMGLOCKy(1, 1) +#define STV090x_P2_TMGLOCK0 STV090x_Px_TMGLOCKy(2, 0) +#define STV090x_P2_TMGLOCK1 STV090x_Px_TMGLOCKy(2, 1) +#define STV090x_OFFST_Px_TMGLOCK_LEVEL_FIELD 0 +#define STV090x_WIDTH_Px_TMGLOCK_LEVEL_FIELD 8 + +#define STV090x_Px_TMGOBS(__x) (0xF46D - (__x - 1) * 0x200) +#define STV090x_P1_TMGOBS STV090x_Px_TMGOBS(1) +#define STV090x_P2_TMGOBS STV090x_Px_TMGOBS(2) +#define STV090x_OFFST_Px_ROLLOFF_STATUS_FIELD 6 +#define STV090x_WIDTH_Px_ROLLOFF_STATUS_FIELD 2 + +#define STV090x_Px_EQUALCFG(__x) (0xF46F - (__x - 1) * 0x200) +#define STV090x_P1_EQUALCFG STV090x_Px_EQUALCFG(1) +#define STV090x_P2_EQUALCFG STV090x_Px_EQUALCFG(2) +#define STV090x_OFFST_Px_EQUAL_ON_FIELD 6 +#define STV090x_WIDTH_Px_EQUAL_ON_FIELD 1 +#define STV090x_OFFST_Px_MU_EQUALDFE_FIELD 0 +#define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD 3 + +#define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x - 1) * 0x200 + (__y - 1)) +#define STV090x_P1_EQUAI1 STV090x_Px_EQUAIy(1, 1) +#define STV090x_P1_EQUAI2 STV090x_Px_EQUAIy(1, 2) +#define STV090x_P1_EQUAI3 STV090x_Px_EQUAIy(1, 3) +#define STV090x_P1_EQUAI4 STV090x_Px_EQUAIy(1, 4) +#define STV090x_P1_EQUAI5 STV090x_Px_EQUAIy(1, 5) +#define STV090x_P1_EQUAI6 STV090x_Px_EQUAIy(1, 6) +#define STV090x_P1_EQUAI7 STV090x_Px_EQUAIy(1, 7) +#define STV090x_P1_EQUAI8 STV090x_Px_EQUAIy(1, 8) + +#define STV090x_P2_EQUAI1 STV090x_Px_EQUAIy(2, 1) +#define STV090x_P2_EQUAI2 STV090x_Px_EQUAIy(2, 2) +#define STV090x_P2_EQUAI3 STV090x_Px_EQUAIy(2, 3) +#define STV090x_P2_EQUAI4 STV090x_Px_EQUAIy(2, 4) +#define STV090x_P2_EQUAI5 STV090x_Px_EQUAIy(2, 5) +#define STV090x_P2_EQUAI6 STV090x_Px_EQUAIy(2, 6) +#define STV090x_P2_EQUAI7 STV090x_Px_EQUAIy(2, 7) +#define STV090x_P2_EQUAI8 STV090x_Px_EQUAIy(2, 8) +#define STV090x_OFFST_Px_EQUA_ACCIy_FIELD 0 +#define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD 8 + +#define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x - 1) * 0x200 + (__y - 1)) +#define STV090x_P1_EQUAQ1 STV090x_Px_EQUAQy(1, 1) +#define STV090x_P1_EQUAQ2 STV090x_Px_EQUAQy(1, 2) +#define STV090x_P1_EQUAQ3 STV090x_Px_EQUAQy(1, 3) +#define STV090x_P1_EQUAQ4 STV090x_Px_EQUAQy(1, 4) +#define STV090x_P1_EQUAQ5 STV090x_Px_EQUAQy(1, 5) +#define STV090x_P1_EQUAQ6 STV090x_Px_EQUAQy(1, 6) +#define STV090x_P1_EQUAQ7 STV090x_Px_EQUAQy(1, 7) +#define STV090x_P1_EQUAQ8 STV090x_Px_EQUAQy(1, 8) + +#define STV090x_P2_EQUAQ1 STV090x_Px_EQUAQy(2, 1) +#define STV090x_P2_EQUAQ2 STV090x_Px_EQUAQy(2, 2) +#define STV090x_P2_EQUAQ3 STV090x_Px_EQUAQy(2, 3) +#define STV090x_P2_EQUAQ4 STV090x_Px_EQUAQy(2, 4) +#define STV090x_P2_EQUAQ5 STV090x_Px_EQUAQy(2, 5) +#define STV090x_P2_EQUAQ6 STV090x_Px_EQUAQy(2, 6) +#define STV090x_P2_EQUAQ7 STV090x_Px_EQUAQy(2, 7) +#define STV090x_P2_EQUAQ8 STV090x_Px_EQUAQy(2, 8) +#define STV090x_OFFST_Px_EQUA_ACCQy_FIELD 0 +#define STV090x_WIDTH_Px_EQUA_ACCQy_FIELD 8 + +#define STV090x_Px_NNOSDATATy(__x, __y) (0xf481 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_NNOSDATAT0 STV090x_Px_NNOSDATATy(1, 0) +#define STV090x_P1_NNOSDATAT1 STV090x_Px_NNOSDATATy(1, 1) +#define STV090x_P2_NNOSDATAT0 STV090x_Px_NNOSDATATy(2, 0) +#define STV090x_P2_NNOSDATAT1 STV090x_Px_NNOSDATATy(2, 1) +#define STV090x_OFFST_Px_NOSDATAT_NORMED_FIELD 0 +#define STV090x_WIDTH_Px_NOSDATAT_NORMED_FIELD 8 + +#define STV090x_Px_NNOSDATAy(__x, __y) (0xf483 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_NNOSDATA0 STV090x_Px_NNOSDATAy(1, 0) +#define STV090x_P1_NNOSDATA1 STV090x_Px_NNOSDATAy(1, 1) +#define STV090x_P2_NNOSDATA0 STV090x_Px_NNOSDATAy(2, 0) +#define STV090x_P2_NNOSDATA1 STV090x_Px_NNOSDATAy(2, 1) +#define STV090x_OFFST_Px_NOSDATA_NORMED_FIELD 0 +#define STV090x_WIDTH_Px_NOSDATA_NORMED_FIELD 8 + +#define STV090x_Px_NNOSPLHTy(__x, __y) (0xf485 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_NNOSPLHT0 STV090x_Px_NNOSPLHTy(1, 0) +#define STV090x_P1_NNOSPLHT1 STV090x_Px_NNOSPLHTy(1, 1) +#define STV090x_P2_NNOSPLHT0 STV090x_Px_NNOSPLHTy(2, 0) +#define STV090x_P2_NNOSPLHT1 STV090x_Px_NNOSPLHTy(2, 1) +#define STV090x_OFFST_Px_NOSPLHT_NORMED_FIELD 0 +#define STV090x_WIDTH_Px_NOSPLHT_NORMED_FIELD 8 + +#define STV090x_Px_NNOSPLHy(__x, __y) (0xf487 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_NNOSPLH0 STV090x_Px_NNOSPLHy(1, 0) +#define STV090x_P1_NNOSPLH1 STV090x_Px_NNOSPLHy(1, 1) +#define STV090x_P2_NNOSPLH0 STV090x_Px_NNOSPLHy(2, 0) +#define STV090x_P2_NNOSPLH1 STV090x_Px_NNOSPLHy(2, 1) +#define STV090x_OFFST_Px_NOSPLH_NORMED_FIELD 0 +#define STV090x_WIDTH_Px_NOSPLH_NORMED_FIELD 8 + +#define STV090x_Px_NOSDATATy(__x, __y) (0xf489 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_NOSDATAT0 STV090x_Px_NOSDATATy(1, 0) +#define STV090x_P1_NOSDATAT1 STV090x_Px_NOSDATATy(1, 1) +#define STV090x_P2_NOSDATAT0 STV090x_Px_NOSDATATy(2, 0) +#define STV090x_P2_NOSDATAT1 STV090x_Px_NOSDATATy(2, 1) +#define STV090x_OFFST_Px_NOSDATAT_UNNORMED_FIELD 0 +#define STV090x_WIDTH_Px_NOSDATAT_UNNORMED_FIELD 8 + +#define STV090x_Px_NOSDATAy(__x, __y) (0xf48b - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_NOSDATA0 STV090x_Px_NOSDATAy(1, 0) +#define STV090x_P1_NOSDATA1 STV090x_Px_NOSDATAy(1, 1) +#define STV090x_P2_NOSDATA0 STV090x_Px_NOSDATAy(2, 0) +#define STV090x_P2_NOSDATA1 STV090x_Px_NOSDATAy(2, 1) +#define STV090x_OFFST_Px_NOSDATA_UNNORMED_FIELD 0 +#define STV090x_WIDTH_Px_NOSDATA_UNNORMED_FIELD 8 + +#define STV090x_Px_NOSPLHTy(__x, __y) (0xf48d - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_NOSPLHT0 STV090x_Px_NOSPLHTy(1, 0) +#define STV090x_P1_NOSPLHT1 STV090x_Px_NOSPLHTy(1, 1) +#define STV090x_P2_NOSPLHT0 STV090x_Px_NOSPLHTy(2, 0) +#define STV090x_P2_NOSPLHT1 STV090x_Px_NOSPLHTy(2, 1) +#define STV090x_OFFST_Px_NOSPLHT_UNNORMED_FIELD 0 +#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8 + +#define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1) +#define STv090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0) +#define STv090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1) +#define STv090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0) +#define STv090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1) +#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0 +#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8 + +#define STV090x_Px_CAR2CFG(__x) (0xf490 - (__x - 1) * 0x200) +#define STV090x_P1_CAR2CFG STV090x_Px_CAR2CFG(1) +#define STV090x_P2_CAR2CFG STV090x_Px_CAR2CFG(2) +#define STV090x_OFFST_Px_PN4_SELECT_FIELD 6 +#define STV090x_WIDTH_Px_PN4_SELECT_FIELD 1 +#define STV090x_OFFST_Px_CFR2_STOPDVBS1_FIELD 5 +#define STV090x_WIDTH_Px_CFR2_STOPDVBS1_FIELD 1 +#define STV090x_OFFST_Px_ROTA2ON_FIELD 2 +#define STV090x_WIDTH_Px_ROTA2ON_FIELD 1 +#define STV090x_OFFST_Px_PH_DET_ALGO2_FIELD 0 +#define STV090x_WIDTH_Px_PH_DET_ALGO2_FIELD 2 + +#define STV090x_Px_ACLC2(__x) (0xf491 - (__x - 1) * 0x200) +#define STV090x_P1_ACLC2 STV090x_Px_ACLC2(1) +#define STV090x_P2_ACLC2 STV090x_Px_ACLC2(2) +#define STV090x_OFFST_Px_CAR2_ALPHA_MANT_FIELD 4 +#define STV090x_WIDTH_Px_CAR2_ALPHA_MANT_FIELD 2 +#define STV090x_OFFST_Px_CAR2_ALPHA_EXP_FIELD 0 +#define STV090x_WIDTH_Px_CAR2_ALPHA_EXP_FIELD 4 + +#define STV090x_Px_BCLC2(__x) (0xf492 - (__x - 1) * 0x200) +#define STV090x_P1_BCLC2 STV090x_Px_BCLC2(1) +#define STV090x_P2_BCLC2 STV090x_Px_BCLC2(2) +#define STV090x_OFFST_Px_CAR2_BETA_MANT_FIELD 4 +#define STV090x_WIDTH_Px_CAR2_BETA_MANT_FIELD 2 +#define STV090x_OFFST_Px_CAR2_BETA_EXP_FIELD 0 +#define STV090x_WIDTH_Px_CAR2_BETA_EXP_FIELD 4 + +#define STV090x_Px_ACLC2S2Q(__x) (0xf497 - (__x - 1) * 0x200) +#define STV090x_P1_ACLC2S2Q STV090x_Px_ACLC2S2Q(1) +#define STV090x_P2_ACLC2S2Q STV090x_Px_ACLC2S2Q(2) +#define STV090x_OFFST_Px_ENAB_SPSKSYMB_FIELD 7 +#define STV090x_WIDTH_Px_ENAB_SPSKSYMB_FIELD 1 +#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_M_FIELD 4 +#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_M_FIELD 2 +#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_E_FIELD 0 +#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_E_FIELD 4 + +#define STV090x_Px_ACLC2S28(__x) (0xf498 - (__x - 1) * 0x200) +#define STV090x_P1_ACLC2S28 STV090x_Px_ACLC2S28(1) +#define STV090x_P2_ACLC2S28 STV090x_Px_ACLC2S28(2) +#define STV090x_OFFST_Px_CAR2S2_8_ALPH_M_FIELD 4 +#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_M_FIELD 2 +#define STV090x_OFFST_Px_CAR2S2_8_ALPH_E_FIELD 0 +#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_E_FIELD 4 + +#define STV090x_Px_ACLC2S216A(__x) (0xf499 - (__x - 1) * 0x200) +#define STV090x_P1_ACLC2S216A STV090x_Px_ACLC2S216A(1) +#define STV090x_P2_ACLC2S216A STV090x_Px_ACLC2S216A(2) +#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_M_FIELD 4 +#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_M_FIELD 2 +#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD 0 +#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4 + +#define STV090x_Px_ACLC2S232A(__x) (0xf499 - (__x - 1) * 0x200) +#define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S216A(1) +#define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S216A(2) +#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4 +#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_M_FIELD 2 +#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_E_FIELD 0 +#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_E_FIELD 4 + +#define STV090x_Px_BCLC2S2Q(__x) (0xf49c - (__x - 1) * 0x200) +#define STV090x_P1_BCLC2S2Q STV090x_Px_BCLC2S2Q(1) +#define STV090x_P2_BCLC2S2Q STV090x_Px_BCLC2S2Q(2) +#define STV090x_OFFST_Px_CAR2S2_Q_BETA_M_FIELD 4 +#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_M_FIELD 2 +#define STV090x_OFFST_Px_CAR2S2_Q_BETA_E_FIELD 0 +#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_E_FIELD 4 + +#define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200) +#define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1) +#define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(1) +#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4 +#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2 +#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0 +#define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4 + +#define STV090x_Px_BCLC2S216A(__x) (0xf49d - (__x - 1) * 0x200) +#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1) +#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1) +#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4 +#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2 +#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0 +#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD 4 + +#define STV090x_Px_BCLC2S232A(__x) (0xf49d - (__x - 1) * 0x200) +#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1) +#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1) +#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4 +#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2 +#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0 +#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_E_FIELD 4 + +#define STV090x_Px_PLROOT2(__x) (0xf4ac - (__x - 1) * 0x200) +#define STV090x_P1_PLROOT2 STV090x_Px_PLROOT2(1) +#define STV090x_P2_PLROOT2 STV090x_Px_PLROOT2(2) +#define STV090x_OFFST_Px_PLSCRAMB_MODE_FIELD 2 +#define STV090x_WIDTH_Px_PLSCRAMB_MODE_FIELD 2 +#define STV090x_OFFST_Px_PLSCRAMB_ROOT_FIELD 0 +#define STV090x_WIDTH_Px_PLSCRAMB_ROOT_FIELD 2 + +#define STV090x_Px_PLROOT1(__x) (0xf4ad - (__x - 1) * 0x200) +#define STV090x_P1_PLROOT1 STV090x_Px_PLROOT1(1) +#define STV090x_P2_PLROOT1 STV090x_Px_PLROOT1(2) +#define STV090x_OFFST_Px_PLSCRAMB_ROOT1_FIELD 0 +#define STV090x_WIDTH_Px_PLSCRAMB_ROOT1_FIELD 8 + +#define STV090x_Px_PLROOT0(__x) (0xf4ae - (__x - 1) * 0x200) +#define STV090x_P1_PLROOT0 STV090x_Px_PLROOT0(1) +#define STV090x_P2_PLROOT0 STV090x_Px_PLROOT0(2) +#define STV090x_OFFST_Px_PLSCRAMB_ROOT0_FIELD 0 +#define STV090x_WIDTH_Px_PLSCRAMB_ROOT0_FIELD 8 + +#define STV090x_Px_MODCODLST0(__x) (0xf4b0 - (__x - 1) * 0x200) /* check */ +#define STV090x_P1_MODCODLST0 STV090x_Px_MODCODLST0(1) +#define STV090x_P2_MODCODLST0 STV090x_Px_MODCODLST0(2) + +#define STV090x_Px_MODCODLST1(__x) (0xf4b1 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST1 STV090x_Px_MODCODLST1(1) +#define STV090x_P2_MODCODLST1 STV090x_Px_MODCODLST1(2) +#define STV090x_OFFST_Px_DIS_MODCOD29_FIELD 4 +#define STV090x_WIDTH_Px_DIS_MODCOD29T_FIELD 4 +#define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD 0 +#define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD 4 + +#define STV090x_Px_MODCODLST2(__x) (0xf4b2 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST2 STV090x_Px_MODCODLST2(1) +#define STV090x_P2_MODCODLST2 STV090x_Px_MODCODLST2(2) +#define STV090x_OFFST_Px_DIS_32PSK_8_9_FIELD 4 +#define STV090x_WIDTH_Px_DIS_32PSK_8_9_FIELD 4 +#define STV090x_OFFST_Px_DIS_32PSK_5_6_FIELD 0 +#define STV090x_WIDTH_Px_DIS_32PSK_5_6_FIELD 4 + +#define STV090x_Px_MODCODLST3(__x) (0xf4b3 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST3 STV090x_Px_MODCODLST3(1) +#define STV090x_P2_MODCODLST3 STV090x_Px_MODCODLST3(2) +#define STV090x_OFFST_Px_DIS_32PSK_4_5_FIELD 4 +#define STV090x_WIDTH_Px_DIS_32PSK_4_5_FIELD 4 +#define STV090x_OFFST_Px_DIS_32PSK_3_4_FIELD 0 +#define STV090x_WIDTH_Px_DIS_32PSK_3_4_FIELD 4 + +#define STV090x_Px_MODCODLST4(__x) (0xf4b4 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST4 STV090x_Px_MODCODLST4(1) +#define STV090x_P2_MODCODLST4 STV090x_Px_MODCODLST4(2) +#define STV090x_OFFST_Px_DIS_16PSK_9_10_FIELD 4 +#define STV090x_WIDTH_Px_DIS_16PSK_9_10_FIELD 4 +#define STV090x_OFFST_Px_DIS_16PSK_8_9_FIELD 0 +#define STV090x_WIDTH_Px_DIS_16PSK_8_9_FIELD 4 + +#define STV090x_Px_MODCODLST5(__x) (0xf4b5 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST5 STV090x_Px_MODCODLST5(1) +#define STV090x_P2_MODCODLST5 STV090x_Px_MODCODLST5(2) +#define STV090x_OFFST_Px_DIS_16PSK_5_6_FIELD 4 +#define STV090x_WIDTH_Px_DIS_16PSK_5_6_FIELD 4 +#define STV090x_OFFST_Px_DIS_16PSK_4_5_FIELD 0 +#define STV090x_WIDTH_Px_DIS_16PSK_4_5_FIELD 4 + +#define STV090x_Px_MODCODLST6(__x) (0xf4b6 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST6 STV090x_Px_MODCODLST6(1) +#define STV090x_P2_MODCODLST6 STV090x_Px_MODCODLST6(2) +#define STV090x_OFFST_Px_DIS_16PSK_3_4_FIELD 4 +#define STV090x_WIDTH_Px_DIS_16PSK_3_4_FIELD 4 +#define STV090x_OFFST_Px_DIS_16PSK_2_3_FIELD 0 +#define STV090x_WIDTH_Px_DIS_16PSK_2_3_FIELD 4 + +#define STV090x_Px_MODCODLST7(__x) (0xf4b7 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST7 STV090x_Px_MODCODLST7(1) +#define STV090x_P2_MODCODLST7 STV090x_Px_MODCODLST7(2) +#define STV090x_OFFST_Px_DIS_8P_9_10_FIELD 4 +#define STV090x_WIDTH_Px_DIS_8P_9_10_FIELD 4 +#define STV090x_OFFST_Px_DIS_8P_8_9_FIELD 0 +#define STV090x_WIDTH_Px_DIS_8P_8_9_FIELD 4 + +#define STV090x_Px_MODCODLST8(__x) (0xf4b8 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST8 STV090x_Px_MODCODLST8(1) +#define STV090x_P2_MODCODLST8 STV090x_Px_MODCODLST8(2) +#define STV090x_OFFST_Px_DIS_8P_5_6_FIELD 4 +#define STV090x_WIDTH_Px_DIS_8P_5_6_FIELD 4 +#define STV090x_OFFST_Px_DIS_8P_3_4_FIELD 0 +#define STV090x_WIDTH_Px_DIS_8P_3_4_FIELD 4 + +#define STV090x_Px_MODCODLST9(__x) (0xf4b9 - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLST9 STV090x_Px_MODCODLST9(1) +#define STV090x_P2_MODCODLST9 STV090x_Px_MODCODLST9(2) +#define STV090x_OFFST_Px_DIS_8P_2_3_FIELD 4 +#define STV090x_WIDTH_Px_DIS_8P_2_3_FIELD 4 +#define STV090x_OFFST_Px_DIS_8P_3_5_FIELD 0 +#define STV090x_WIDTH_Px_DIS_8P_3_5_FIELD 4 + +#define STV090x_Px_MODCODLSTA(__x) (0xf4ba - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLSTA STV090x_Px_MODCODLSTA(1) +#define STV090x_P2_MODCODLSTA STV090x_Px_MODCODLSTA(2) +#define STV090x_OFFST_Px_DIS_QP_9_10_FIELD 4 +#define STV090x_WIDTH_Px_DIS_QP_9_10_FIELD 4 +#define STV090x_OFFST_Px_DIS_QP_8_9_FIELD 0 +#define STV090x_WIDTH_Px_DIS_QP_8_9_FIELD 4 + +#define STV090x_Px_MODCODLSTB(__x) (0xf4bb - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLSTB STV090x_Px_MODCODLSTB(1) +#define STV090x_P2_MODCODLSTB STV090x_Px_MODCODLSTB(2) +#define STV090x_OFFST_Px_DIS_QP_5_6_FIELD 4 +#define STV090x_WIDTH_Px_DIS_QP_5_6_FIELD 4 +#define STV090x_OFFST_Px_DIS_QP_4_5_FIELD 0 +#define STV090x_WIDTH_Px_DIS_QP_4_5_FIELD 4 + +#define STV090x_Px_MODCODLSTC(__x) (0xf4bc - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLSTC STV090x_Px_MODCODLSTC(1) +#define STV090x_P2_MODCODLSTC STV090x_Px_MODCODLSTC(2) +#define STV090x_OFFST_Px_DIS_QP_3_4_FIELD 4 +#define STV090x_WIDTH_Px_DIS_QP_3_4_FIELD 4 +#define STV090x_OFFST_Px_DIS_QP_2_3_FIELD 0 +#define STV090x_WIDTH_Px_DIS_QP_2_3_FIELD 4 + +#define STV090x_Px_MODCODLSTD(__x) (0xf4bd - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLSTD STV090x_Px_MODCODLSTD(1) +#define STV090x_P2_MODCODLSTD STV090x_Px_MODCODLSTD(2) +#define STV090x_OFFST_Px_DIS_QP_3_5_FIELD 4 +#define STV090x_WIDTH_Px_DIS_QP_3_5_FIELD 4 +#define STV090x_OFFST_Px_DIS_QP_1_2_FIELD 0 +#define STV090x_WIDTH_Px_DIS_QP_1_2_FIELD 4 + +#define STV090x_Px_MODCODLSTE(__x) (0xf4be - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLSTE STV090x_Px_MODCODLSTE(1) +#define STV090x_P2_MODCODLSTE STV090x_Px_MODCODLSTE(2) +#define STV090x_OFFST_Px_DIS_QP_2_5_FIELD 4 +#define STV090x_WIDTH_Px_DIS_QP_2_5_FIELD 4 +#define STV090x_OFFST_Px_DIS_QP_1_3_FIELD 0 +#define STV090x_WIDTH_Px_DIS_QP_1_3_FIELD 4 + +#define STV090x_Px_MODCODLSTF(__x) (0xf4bf - (__x - 1) * 0x200) +#define STV090x_P1_MODCODLSTF STV090x_Px_MODCODLSTF(1) +#define STV090x_P2_MODCODLSTF STV090x_Px_MODCODLSTF(2) +#define STV090x_OFFST_Px_DIS_QP_1_4_FIELD 4 +#define STV090x_WIDTH_Px_DIS_QP_1_4_FIELD 4 + +#define STV090x_Px_DMDRESCFG(__x) (0xF4C6 - (__x - 1) * 0x200) +#define STV090x_P1_DMDRESCFG STV090x_Px_DMDRESCFG(1) +#define STV090x_P2_DMDRESCFG STV090x_Px_DMDRESCFG(2) +#define STV090x_OFFST_Px_DMDRES_RESET_FIELD 7 +#define STV090x_WIDTH_Px_DMDRES_RESET_FIELD 1 + +#define STV090x_Px_DMDRESADR(__x) (0xF4C7 - (__x - 1) * 0x200) +#define STV090x_P1_DMDRESADR STV090x_Px_DMDRESADR(1) +#define STV090x_P2_DMDRESADR STV090x_Px_DMDRESADR(2) +#define STV090x_OFFST_Px_DMDRES_RESNBR_FIELD 0 +#define STV090x_WIDTH_Px_DMDRES_RESNBR_FIELD 4 + +#define STV090x_Px_DMDRESDATAy(__x, __y) (0xF4C8 - (__x - 1) * 0x200 + (7 - __y)) +#define STV090x_P1_DMDRESDATA0 STV090x_Px_DMDRESDATAy(1, 0) +#define STV090x_P1_DMDRESDATA1 STV090x_Px_DMDRESDATAy(1, 1) +#define STV090x_P1_DMDRESDATA2 STV090x_Px_DMDRESDATAy(1, 2) +#define STV090x_P1_DMDRESDATA3 STV090x_Px_DMDRESDATAy(1, 3) +#define STV090x_P1_DMDRESDATA4 STV090x_Px_DMDRESDATAy(1, 4) +#define STV090x_P1_DMDRESDATA5 STV090x_Px_DMDRESDATAy(1, 5) +#define STV090x_P1_DMDRESDATA6 STV090x_Px_DMDRESDATAy(1, 6) +#define STV090x_P1_DMDRESDATA7 STV090x_Px_DMDRESDATAy(1, 7) +#define STV090x_P2_DMDRESDATA0 STV090x_Px_DMDRESDATAy(2, 0) +#define STV090x_P2_DMDRESDATA1 STV090x_Px_DMDRESDATAy(2, 1) +#define STV090x_P2_DMDRESDATA2 STV090x_Px_DMDRESDATAy(2, 2) +#define STV090x_P2_DMDRESDATA3 STV090x_Px_DMDRESDATAy(2, 3) +#define STV090x_P2_DMDRESDATA4 STV090x_Px_DMDRESDATAy(2, 4) +#define STV090x_P2_DMDRESDATA5 STV090x_Px_DMDRESDATAy(2, 5) +#define STV090x_P2_DMDRESDATA6 STV090x_Px_DMDRESDATAy(2, 6) +#define STV090x_P2_DMDRESDATA7 STV090x_Px_DMDRESDATAy(2, 7) +#define STV090x_OFFST_Px_DMDRES_DATA_FIELD 0 +#define STV090x_WIDTH_Px_DMDRES_DATA_FIELD 8 + +#define STV090x_Px_FFEIy(__x, __y) (0xf4d0 - (__x - 1) * 0x200 + 0x2 * (__y - 1)) +#define STV090x_P1_FFEI1 STV090x_Px_FFEIy(1, 1) +#define STV090x_P1_FFEI2 STV090x_Px_FFEIy(1, 2) +#define STV090x_P1_FFEI3 STV090x_Px_FFEIy(1, 3) +#define STV090x_P1_FFEI4 STV090x_Px_FFEIy(1, 4) +#define STV090x_P2_FFEI1 STV090x_Px_FFEIy(2, 1) +#define STV090x_P2_FFEI2 STV090x_Px_FFEIy(2, 2) +#define STV090x_P2_FFEI3 STV090x_Px_FFEIy(2, 3) +#define STV090x_P2_FFEI4 STV090x_Px_FFEIy(2, 4) +#define STV090x_OFFST_Px_FFE_ACCIy_FIELD 0 +#define STV090x_WIDTH_Px_FFE_ACCIy_FIELD 8 + +#define STV090x_Px_FFEQy(__x, __y) (0xf4d1 - (__x - 1) * 0x200 + 0x2 * (__y - 1)) +#define STV090x_P1_FFEQ1 STV090x_Px_FFEQy(1, 1) +#define STV090x_P1_FFEQ2 STV090x_Px_FFEQy(1, 2) +#define STV090x_P1_FFEQ3 STV090x_Px_FFEQy(1, 3) +#define STV090x_P1_FFEQ4 STV090x_Px_FFEQy(1, 4) +#define STV090x_P2_FFEQ1 STV090x_Px_FFEQy(2, 1) +#define STV090x_P2_FFEQ2 STV090x_Px_FFEQy(2, 2) +#define STV090x_P2_FFEQ3 STV090x_Px_FFEQy(2, 3) +#define STV090x_P2_FFEQ4 STV090x_Px_FFEQy(2, 4) +#define STV090x_OFFST_Px_FFE_ACCQy_FIELD 0 +#define STV090x_WIDTH_Px_FFE_ACCQy_FIELD 8 + +#define STV090x_Px_FFECFG(__x) (0xf4d8 - (__x - 1) * 0x200) +#define STV090x_P1_FFECFG STV090x_Px_FFECFG(1) +#define STV090x_P2_FFECFG STV090x_Px_FFECFG(2) +#define STV090x_OFFST_Px_EQUALFFE_ON_FIELD 6 +#define STV090x_WIDTH_Px_EQUALFFE_ON_FIELD 1 + +#define STV090x_Px_SMAPCOEF7(__x) (0xf500 - (__x - 1) * 0x200) +#define STV090x_P1_SMAPCOEF7 STV090x_Px_SMAPCOEF7(1) +#define STV090x_P2_SMAPCOEF7 STV090x_Px_SMAPCOEF7(2) +#define STV090x_OFFST_Px_DIS_QSCALE_FIELD 7 +#define STV090x_WIDTH_Px_DIS_QSCALE_FIELD 1 +#define STV090x_OFFST_Px_SMAPCOEF_Q_LLR12_FIELD 0 +#define STV090x_WIDTH_Px_SMAPCOEF_Q_LLR12_FIELD 7 + +#define STV090x_Px_SMAPCOEF6(__x) (0xf501 - (__x - 1) * 0x200) +#define STV090x_P1_SMAPCOEF6 STV090x_Px_SMAPCOEF6(1) +#define STV090x_P2_SMAPCOEF6 STV090x_Px_SMAPCOEF6(2) +#define STV090x_OFFST_Px_ADJ_8PSKLLR1_FIELD 2 +#define STV090x_WIDTH_Px_ADJ_8PSKLLR1_FIELD 1 +#define STV090x_OFFST_Px_OLD_8PSKLLR1_FIELD 1 +#define STV090x_WIDTH_Px_OLD_8PSKLLR1_FIELD 1 +#define STV090x_OFFST_Px_DIS_AB8PSK_FIELD 0 +#define STV090x_WIDTH_Px_DIS_AB8PSK_FIELD 1 + +#define STV090x_Px_SMAPCOEF5(__x) (0xf502 - (__x - 1) * 0x200) +#define STV090x_P1_SMAPCOEF5 STV090x_Px_SMAPCOEF5(1) +#define STV090x_P2_SMAPCOEF5 STV090x_Px_SMAPCOEF5(2) +#define STV090x_OFFST_Px_DIS_8SCALE_FIELD 7 +#define STV090x_WIDTH_Px_DIS_8SCALE_FIELD 1 +#define STV090x_OFFST_Px_SMAPCOEF_8P_LLR23_FIELD 0 +#define STV090x_WIDTH_Px_SMAPCOEF_8P_LLR23_FIELD 7 + +#define STV090x_Px_DMDPLHSTAT(__x) (0xF520 - (__x - 1) * 0x200) +#define STV090x_P1_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(1) +#define STV090x_P2_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(2) +#define STV090x_OFFST_Px_PLH_STATISTIC_FIELD 0 +#define STV090x_WIDTH_Px_PLH_STATISTIC_FIELD 8 + +#define STV090x_Px_LOCKTIMEy(__x, __y) (0xF525 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_LOCKTIME0 STV090x_Px_LOCKTIMEy(1, 0) +#define STV090x_P1_LOCKTIME1 STV090x_Px_LOCKTIMEy(1, 1) +#define STV090x_P1_LOCKTIME2 STV090x_Px_LOCKTIMEy(1, 2) +#define STV090x_P1_LOCKTIME3 STV090x_Px_LOCKTIMEy(1, 3) +#define STV090x_P2_LOCKTIME0 STV090x_Px_LOCKTIMEy(2, 0) +#define STV090x_P2_LOCKTIME1 STV090x_Px_LOCKTIMEy(2, 1) +#define STV090x_P2_LOCKTIME2 STV090x_Px_LOCKTIMEy(2, 2) +#define STV090x_P2_LOCKTIME3 STV090x_Px_LOCKTIMEy(2, 3) +#define STV090x_OFFST_Px_DEMOD_LOCKTIME_FIELD 0 +#define STV090x_WIDTH_Px_DEMOD_LOCKTIME_FIELD 8 + +#define STV090x_Px_TNRCFG(__x) (0xf4e0 - (__x - 1) * 0x200) /* check */ +#define STV090x_P1_TNRCFG STV090x_Px_TNRCFG(1) +#define STV090x_P2_TNRCFG STV090x_Px_TNRCFG(2) + +#define STV090x_Px_TNRCFG2(__x) (0xf4e1 - (__x - 1) * 0x200) +#define STV090x_P1_TNRCFG2 STV090x_Px_TNRCFG2(1) +#define STV090x_P2_TNRCFG2 STV090x_Px_TNRCFG2(2) +#define STV090x_OFFST_Px_TUN_IQSWAP_FIELD 7 +#define STV090x_WIDTH_Px_TUN_IQSWAP_FIELD 1 + +#define STV090x_Px_VITSCALE(__x) (0xf532 - (__x - 1) * 0x200) +#define STV090x_P1_VITSCALE STV090x_Px_VITSCALE(1) +#define STV090x_P2_VITSCALE STV090x_Px_VITSCALE(2) +#define STV090x_OFFST_Px_NVTH_NOSRANGE_FIELD 7 +#define STV090x_WIDTH_Px_NVTH_NOSRANGE_FIELD 1 +#define STV090x_OFFST_Px_VERROR_MAXMODE_FIELD 6 +#define STV090x_WIDTH_Px_VERROR_MAXMODE_FIELD 1 +#define STV090x_OFFST_Px_NSLOWSN_LOCKED_FIELD 3 +#define STV090x_WIDTH_Px_NSLOWSN_LOCKED_FIELD 1 +#define STV090x_OFFST_Px_DIS_RSFLOCK_FIELD 1 +#define STV090x_WIDTH_Px_DIS_RSFLOCK_FIELD 1 + +#define STV090x_Px_FECM(__x) (0xf533 - (__x - 1) * 0x200) +#define STV090x_P1_FECM STV090x_Px_FECM(1) +#define STV090x_P2_FECM STV090x_Px_FECM(2) +#define STV090x_OFFST_Px_DSS_DVB_FIELD 7 +#define STV090x_WIDTH_Px_DSS_DVB_FIELD 1 +#define STV090x_OFFST_Px_DSS_SRCH_FIELD 4 +#define STV090x_WIDTH_Px_DSS_SRCH_FIELD 1 +#define STV090x_OFFST_Px_SYNCVIT_FIELD 1 +#define STV090x_WIDTH_Px_SYNCVIT_FIELD 1 +#define STV090x_OFFST_Px_IQINV_FIELD 0 +#define STV090x_WIDTH_Px_IQINV_FIELD 1 + +#define STV090x_Px_VTH12(__x) (0xf534 - (__x - 1) * 0x200) +#define STV090x_P1_VTH12 STV090x_Px_VTH12(1) +#define STV090x_P2_VTH12 STV090x_Px_VTH12(2) +#define STV090x_OFFST_Px_VTH12_FIELD 0 +#define STV090x_WIDTH_Px_VTH12_FIELD 8 + +#define STV090x_Px_VTH23(__x) (0xf535 - (__x - 1) * 0x200) +#define STV090x_P1_VTH23 STV090x_Px_VTH23(1) +#define STV090x_P2_VTH23 STV090x_Px_VTH23(2) +#define STV090x_OFFST_Px_VTH23_FIELD 0 +#define STV090x_WIDTH_Px_VTH23_FIELD 8 + +#define STV090x_Px_VTH34(__x) (0xf536 - (__x - 1) * 0x200) +#define STV090x_P1_VTH34 STV090x_Px_VTH34(1) + #define STV090x_P2_VTH34 STV090x_Px_VTH34(2) +#define STV090x_OFFST_Px_VTH34_FIELD 0 +#define STV090x_WIDTH_Px_VTH34_FIELD 8 + +#define STV090x_Px_VTH56(__x) (0xf537 - (__x - 1) * 0x200) +#define STV090x_P1_VTH56 STV090x_Px_VTH56(1) +#define STV090x_P2_VTH56 STV090x_Px_VTH56(2) +#define STV090x_OFFST_Px_VTH56_FIELD 0 +#define STV090x_WIDTH_Px_VTH56_FIELD 8 + +#define STV090x_Px_VTH67(__x) (0xf538 - (__x - 1) * 0x200) +#define STV090x_P1_VTH67 STV090x_Px_VTH67(1) +#define STV090x_P2_VTH67 STV090x_Px_VTH67(2) +#define STV090x_OFFST_Px_VTH67_FIELD 0 +#define STV090x_WIDTH_Px_VTH67_FIELD 8 + +#define STV090x_Px_VTH78(__x) (0xf539 - (__x - 1) * 0x200) +#define STV090x_P1_VTH78 STV090x_Px_VTH78(1) +#define STV090x_P2_VTH78 STV090x_Px_VTH78(2) +#define STV090x_OFFST_Px_VTH78_FIELD 0 +#define STV090x_WIDTH_Px_VTH78_FIELD 8 + +#define STV090x_Px_VITCURPUN(__x) (0xf53a - (__x - 1) * 0x200) +#define STV090x_P1_VITCURPUN STV090x_Px_VITCURPUN(1) +#define STV090x_P2_VITCURPUN STV090x_Px_VITCURPUN(2) +#define STV090x_OFFST_Px_VIT_CURPUN_FIELD 0 +#define STV090x_WIDTH_Px_VIT_CURPUN_FIELD 5 + +#define STV090x_Px_VERROR(__x) (0xf53b - (__x - 1) * 0x200) +#define STV090x_P1_VERROR STV090x_Px_VERROR(1) +#define STV090x_P2_VERROR STV090x_Px_VERROR(2) +#define STV090x_OFFST_Px_REGERR_VIT_FIELD 0 +#define STV090x_WIDTH_Px_REGERR_VIT_FIELD 8 + +#define STV090x_Px_PRVIT(__x) (0xf53c - (__x - 1) * 0x200) +#define STV090x_P1_PRVIT STV090x_Px_PRVIT(1) +#define STV090x_P2_PRVIT STV090x_Px_PRVIT(2) +#define STV090x_OFFST_Px_DIS_VTHLOCK_FIELD 6 +#define STV090x_WIDTH_Px_DIS_VTHLOCK_FIELD 1 +#define STV090x_OFFST_Px_E7_8VIT_FIELD 5 +#define STV090x_WIDTH_Px_E7_8VIT_FIELD 1 +#define STV090x_OFFST_Px_E6_7VIT_FIELD 4 +#define STV090x_WIDTH_Px_E6_7VIT_FIELD 1 +#define STV090x_OFFST_Px_E5_6VIT_FIELD_ 3 +#define STV090x_WIDTH_Px_E5_6VIT_FIELD 1 +#define STV090x_OFFST_Px_E3_4VIT_FIELD 2 +#define STV090x_WIDTH_Px_E3_4VIT_FIELD 1 +#define STV090x_OFFST_Px_E2_3VIT_FIELD 1 +#define STV090x_WIDTH_Px_E2_3VIT_FIELD 1 +#define STV090x_OFFST_Px_E1_2VIT_FIELD 0 +#define STV090x_WIDTH_Px_E1_2VIT_FIELD 1 + +#define STV090x_Px_VAVSRVIT(__x) (0xf53d - (__x - 1) * 0x200) +#define STV090x_P1_VAVSRVIT STV090x_Px_VAVSRVIT(1) +#define STV090x_P2_VAVSRVIT STV090x_Px_VAVSRVIT(2) +#define STV090x_OFFST_Px_SNVIT_FIELD 4 +#define STV090x_WIDTH_Px_SNVIT_FIELD 2 +#define STV090x_OFFST_Px_TOVVIT_FIELD 2 +#define STV090x_WIDTH_Px_TOVVIT_FIELD 2 +#define STV090x_OFFST_Px_HYPVIT_FIELD 0 +#define STV090x_WIDTH_Px_HYPVIT_FIELD 2 + +#define STV090x_Px_VSTATUSVIT(__x) (0xf53e - (__x - 1) * 0x200) +#define STV090x_P1_VSTATUSVIT STV090x_Px_VSTATUSVIT(1) +#define STV090x_P2_VSTATUSVIT STV090x_Px_VSTATUSVIT(2) +#define STV090x_OFFST_Px_PRFVIT_FIELD 4 +#define STV090x_WIDTH_Px_PRFVIT_FIELD 1 +#define STV090x_OFFST_Px_LOCKEDVIT_FIELD 3 +#define STV090x_WIDTH_Px_LOCKEDVIT_FIELD 1 + +#define STV090x_Px_VTHINUSE(__x) (0xf53f - (__x - 1) * 0x200) +#define STV090x_P1_VTHINUSE STV090x_Px_VTHINUSE(1) +#define STV090x_P2_VTHINUSE STV090x_Px_VTHINUSE(2) +#define STV090x_OFFST_Px_VIT_INUSE_FIELD 0 +#define STV090x_WIDTH_Px_VIT_INUSE_FIELD 8 + +#define STV090x_Px_KDIV12(__x) (0xf540 - (__x - 1) * 0x200) +#define STV090x_P1_KDIV12 STV090x_Px_KDIV12(1) +#define STV090x_P2_KDIV12 STV090x_Px_KDIV12(2) +#define STV090x_OFFST_Px_K_DIVIDER_12_FIELD 0 +#define STV090x_WIDTH_Px_K_DIVIDER_12_FIELD 7 + +#define STV090x_Px_KDIV23(__x) (0xf541 - (__x - 1) * 0x200) +#define STV090x_P1_KDIV23 STV090x_Px_KDIV23(1) +#define STV090x_P2_KDIV23 STV090x_Px_KDIV23(2) +#define STV090x_OFFST_Px_K_DIVIDER_23_FIELD 0 +#define STV090x_WIDTH_Px_K_DIVIDER_23_FIELD 7 + +#define STV090x_Px_KDIV34(__x) (0xf542 - (__x - 1) * 0x200) +#define STV090x_P1_KDIV34 STV090x_Px_KDIV34(1) +#define STV090x_P2_KDIV34 STV090x_Px_KDIV34(2) +#define STV090x_OFFST_Px_K_DIVIDER_34_FIELD 0 +#define STV090x_WIDTH_Px_K_DIVIDER_34_FIELD 7 + +#define STV090x_Px_KDIV56(__x) (0xf543 - (__x - 1) * 0x200) +#define STV090x_P1_KDIV56 STV090x_Px_KDIV56(1) +#define STV090x_P2_KDIV56 STV090x_Px_KDIV56(2) +#define STV090x_OFFST_Px_K_DIVIDER_56_FIELD 0 +#define STV090x_WIDTH_Px_K_DIVIDER_56_FIELD 7 + +#define STV090x_Px_KDIV67(__x) (0xf544 - (__x - 1) * 0x200) +#define STV090x_P1_KDIV67 STV090x_Px_KDIV67(1) +#define STV090x_P2_KDIV67 STV090x_Px_KDIV67(2) +#define STV090x_OFFST_Px_K_DIVIDER_67_FIELD 0 +#define STV090x_WIDTH_Px_K_DIVIDER_67_FIELD 7 + +#define STV090x_Px_KDIV78(__x) (0xf545 - (__x - 1) * 0x200) +#define STV090x_P1_KDIV78 STV090x_Px_KDIV78(1) +#define STV090x_P2_KDIV78 STV090x_Px_KDIV78(2) +#define STV090x_OFFST_Px_K_DIVIDER_78_FIELD 0 +#define STV090x_WIDTH_Px_K_DIVIDER_78_FIELD 7 + +#define STV090x_Px_PDELCTRL1(__x) (0xf550 - (__x - 1) * 0x200) +#define STV090x_P1_PDELCTRL1 STV090x_Px_PDELCTRL1(1) +#define STV090x_P2_PDELCTRL1 STV090x_Px_PDELCTRL1(2) +#define STV090x_OFFST_Px_INV_MISMASK_FIELD 7 +#define STV090x_WIDTH_Px_INV_MISMASK_FIELD 1 +#define STV090x_OFFST_Px_FILTER_EN_FIELD 5 +#define STV090x_WIDTH_Px_FILTER_EN_FIELD 1 +#define STV090x_OFFST_Px_EN_MIS00_FIELD 1 +#define STV090x_WIDTH_Px_EN_MIS00_FIELD 1 +#define STV090x_OFFST_Px_ALGOSWRST_FIELD 0 +#define STV090x_WIDTH_Px_ALGOSWRST_FIELD 1 + +#define STV090x_Px_PDELCTRL2(__x) (0xf551 - (__x - 1) * 0x200) +#define STV090x_P1_PDELCTRL2 STV090x_Px_PDELCTRL2(1) +#define STV090x_P2_PDELCTRL2 STV090x_Px_PDELCTRL2(2) +#define STV090x_OFFST_Px_FRAME_MODE_FIELD 1 +#define STV090x_WIDTH_Px_FRAME_MODE_FIELD 1 + +#define STV090x_Px_HYSTTHRESH(__x) (0xf554 - (__x - 1) * 0x200) +#define STV090x_P1_HYSTTHRESH STV090x_Px_HYSTTHRESH(1) +#define STV090x_P2_HYSTTHRESH STV090x_Px_HYSTTHRESH(2) +#define STV090x_OFFST_Px_UNLCK_THRESH_FIELD 4 +#define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD 4 +#define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD 0 +#define STV090x_WIDTH_Px_DELIN_LCK_THRESH__FIELD 4 + +#define STV090x_Px_ISIENTRY(__x) (0xf55e - (__x - 1) * 0x200) +#define STV090x_P1_ISIENTRY STV090x_Px_ISIENTRY(1) +#define STV090x_P2_ISIENTRY STV090x_Px_ISIENTRY(2) +#define STV090x_OFFST_Px_ISI_ENTRY_FIELD 0 +#define STV090x_WIDTH_Px_ISI_ENTRY__FIELD 8 + +#define STV090x_Px_ISIBITENA(__x) (0xf55f - (__x - 1) * 0x200) +#define STV090x_P1_ISIBITENA STV090x_Px_ISIBITENA(1) +#define STV090x_P2_ISIBITENA STV090x_Px_ISIBITENA(2) +#define STV090x_OFFST_Px_ISI_BIT_EN_FIELD 0 +#define STV090x_WIDTH_Px_ISI_BIT_EN_FIELD 8 + +#define STV090x_Px_MATSTRy(__x, __y) (0xf561 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_MATSTR0 STV090x_Px_MATSTRy(1, 0) +#define STV090x_P1_MATSTR1 STV090x_Px_MATSTRy(1, 1) +#define STV090x_P2_MATSTR0 STV090x_Px_MATSTRy(2, 0) +#define STV090x_P2_MATSTR1 STV090x_Px_MATSTRy(2, 1) +#define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD 0 +#define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD 8 + +#define STV090x_Px_UPLSTRy(__x, __y) (0xf563 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_UPLSTR0 STV090x_Px_UPLSTRy(1, 0) +#define STV090x_P1_UPLSTR1 STV090x_Px_UPLSTRy(1, 1) +#define STV090x_P2_UPLSTR0 STV090x_Px_UPLSTRy(2, 0) +#define STV090x_P2_UPLSTR1 STV090x_Px_UPLSTRy(2, 1) +#define STV090x_OFFST_Px_UPL_CURRENT_FIELD 0 +#define STV090x_WIDTH_Px_UPL_CURRENT_FIELD 8 + +#define STV090x_Px_DFLSTRy(__x, __y) (0xf565 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_DFLSTR0 STV090x_Px_DFLSTRy(1, 0) +#define STV090x_P1_DFLSTR1 STV090x_Px_DFLSTRy(1, 1) +#define STV090x_P2_DFLSTR0 STV090x_Px_DFLSTRy(2, 0) +#define STV090x_P2_DFLSTR1 STV090x_Px_DFLSTRy(2, 1) +#define STV090x_OFFST_Px_DFL_CURRENT_FIELD 0 +#define STV090x_WIDTH_Px_DFL_CURRENT_FIELD 8 + +#define STV090x_Px_SYNCSTR(__x) (0xf566 - (__x - 1) * 0x200) +#define STV090x_P1_SYNCSTR STV090x_Px_SYNCSTR(1) +#define STV090x_P2_SYNCSTR STV090x_Px_SYNCSTR(2) +#define STV090x_OFFST_Px_SYNC_CURRENT_FIELD 0 +#define STV090x_WIDTH_Px_SYNC_CURRENT_FIELD 8 + +#define STV090x_Px_SYNCDSTRy(__x, __y) (0xf568 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_SYNCDSTR0 STV090x_Px_SYNCDSTRy(1, 0) +#define STV090x_P1_SYNCDSTR1 STV090x_Px_SYNCDSTRy(1, 1) +#define STV090x_P2_SYNCDSTR0 STV090x_Px_SYNCDSTRy(2, 0) +#define STV090x_P2_SYNCDSTR1 STV090x_Px_SYNCDSTRy(2, 1) +#define STV090x_OFFST_Px_SYNCD_CURRENT_FIELD 0 +#define STV090x_WIDTH_Px_SYNCD_CURRENT_FIELD 8 + +#define STV090x_Px_PDELSTATUS1(__x) (0xf569 - (__x - 1) * 0x200) +#define STV090x_P1_PDELSTATUS1 STV090x_Px_PDELSTATUS1(1) +#define STV090x_P2_PDELSTATUS1 STV090x_Px_PDELSTATUS1(2) +#define STV090x_OFFST_Px_PKTDELIN_LOCK_FIELD 1 +#define STV090x_WIDTH_Px_PKTDELIN_LOCK_FIELD 1 +#define STV090x_OFFST_Px_FIRST_LOCK_FIELD 0 +#define STV090x_WIDTH_Px_FIRST_LOCK_FIELD 1 + +#define STV090x_Px_PDELSTATUS2(__x) (0xf56a - (__x - 1) * 0x200) +#define STV090x_P1_PDELSTATUS2 STV090x_Px_PDELSTATUS2(1) +#define STV090x_P2_PDELSTATUS2 STV090x_Px_PDELSTATUS2(2) +#define STV090x_OFFST_Px_FRAME_MODCOD_FIELD 2 +#define STV090x_WIDTH_Px_FRAME_MODCOD_FIELD 5 +#define STV090x_OFFST_Px_FRAME_TYPE_FIELD 0 +#define STV090x_WIDTH_Px_FRAME_TYPE_FIELD 2 + +#define STV090x_Px_BBFCRCKO1(__x) (0xf56b - (__x - 1) * 0x200) +#define STV090x_P1_BBFCRCKO1 STV090x_Px_BBFCRCKO1(1) +#define STV090x_P2_BBFCRCKO1 STV090x_Px_BBFCRCKO1(2) +#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0 +#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8 + +#define STV090x_Px_BBFCRCKO0(__x) (0xf56c - (__x - 1) * 0x200) +#define STV090x_P1_BBFCRCKO0 STV090x_Px_BBFCRCKO0(1) +#define STV090x_P2_BBFCRCKO0 STV090x_Px_BBFCRCKO0(2) +#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0 +#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8 + +#define STV090x_Px_UPCRCKO1(__x) (0xf56d - (__x - 1) * 0x200) +#define STV090x_P1_UPCRCKO1 STV090x_Px_UPCRCKO1(1) +#define STV090x_P2_UPCRCKO1 STV090x_Px_UPCRCKO1(2) +#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0 +#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8 + +#define STV090x_Px_UPCRCKO0(__x) (0xf56e - (__x - 1) * 0x200) +#define STV090x_P1_UPCRCKO0 STV090x_Px_UPCRCKO0(1) +#define STV090x_P2_UPCRCKO0 STV090x_Px_UPCRCKO0(2) +#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0 +#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8 + +#define STV090x_NBITER_NFx(__x) (0xFA03 + (__x - 4) * 0x1) +#define STV090x_NBITER_NF4 STV090x_NBITER_NFx(4) +#define STV090x_NBITER_NF5 STV090x_NBITER_NFx(5) +#define STV090x_NBITER_NF6 STV090x_NBITER_NFx(6) +#define STV090x_NBITER_NF7 STV090x_NBITER_NFx(7) +#define STV090x_NBITER_NF8 STV090x_NBITER_NFx(8) +#define STV090x_NBITER_NF9 STV090x_NBITER_NFx(9) +#define STV090x_NBITER_NF10 STV090x_NBITER_NFx(10) +#define STV090x_NBITER_NF11 STV090x_NBITER_NFx(11) +#define STV090x_NBITER_NF12 STV090x_NBITER_NFx(12) +#define STV090x_NBITER_NF13 STV090x_NBITER_NFx(13) +#define STV090x_NBITER_NF14 STV090x_NBITER_NFx(14) +#define STV090x_NBITER_NF15 STV090x_NBITER_NFx(15) +#define STV090x_NBITER_NF16 STV090x_NBITER_NFx(16) +#define STV090x_NBITER_NF17 STV090x_NBITER_NFx(17) + +#define STV090x_NBITERNOERR 0xFA3F +#define STV090x_OFFST_NBITER_STOP_CRIT_FIELD 0 +#define STV090x_WIDTH_NBITER_STOP_CRIT_FIELD 4 + +#define STV090x_GAINLLR_NFx(__x) (0xFA43 + (__x - 4) * 0x1) +#define STV090x_GAINLLR_NF4 STV090x_GAINLLR_NFx(4) +#define STV090x_OFFST_GAINLLR_NF_QP_1_2_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_QP_1_2_FIELD 7 + +#define STV090x_GAINLLR_NF5 STV090x_GAINLLR_NFx(5) +#define STV090x_OFFST_GAINLLR_NF_QP_3_5_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_QP_3_5_FIELD 7 + +#define STV090x_GAINLLR_NF6 STV090x_GAINLLR_NFx(6) +#define STV090x_OFFST_GAINLLR_NF_QP_2_3_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_QP_2_3_FIELD 7 + +#define STV090x_GAINLLR_NF7 STV090x_GAINLLR_NFx(7) +#define STV090x_OFFST_GAINLLR_NF_QP_3_4_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_QP_3_4_FIELD 7 + +#define STV090x_GAINLLR_NF8 STV090x_GAINLLR_NFx(8) +#define STV090x_OFFST_GAINLLR_NF_QP_4_5_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_QP_4_5_FIELD 7 + +#define STV090x_GAINLLR_NF9 STV090x_GAINLLR_NFx(9) +#define STV090x_OFFST_GAINLLR_NF_QP_5_6_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_QP_5_6_FIELD 7 + +#define STV090x_GAINLLR_NF10 STV090x_GAINLLR_NFx(10) +#define STV090x_OFFST_GAINLLR_NF_QP_8_9_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_QP_8_9_FIELD 7 + +#define STV090x_GAINLLR_NF11 STV090x_GAINLLR_NFx(11) +#define STV090x_OFFST_GAINLLR_NF_QP_9_10_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_QP_9_10IELD 7 + +#define STV090x_GAINLLR_NF12 STV090x_GAINLLR_NFx(12) +#define STV090x_OFFST_GAINLLR_NF_8P_3_5_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_8P_3_5_FIELD 7 + +#define STV090x_GAINLLR_NF13 STV090x_GAINLLR_NFx(13) +#define STV090x_OFFST_GAINLLR_NF_8P_2_3_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_8P_2_3_FIELD 7 + +#define STV090x_GAINLLR_NF14 STV090x_GAINLLR_NFx(14) +#define STV090x_OFFST_GAINLLR_NF_8P_3_4_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_8P_3_4_FIELD 7 + +#define STV090x_GAINLLR_NF15 STV090x_GAINLLR_NFx(15) +#define STV090x_OFFST_GAINLLR_NF_8P_5_6_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_8P_5_6_FIELD 7 + +#define STV090x_GAINLLR_NF16 STV090x_GAINLLR_NFx(16) +#define STV090x_OFFST_GAINLLR_NF_8P_8_9_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_8P_8_9_FIELD 7 + +#define STV090x_GAINLLR_NF17 STV090x_GAINLLR_NFx(17) +#define STV090x_OFFST_GAINLLR_NF_8P_9_10_FIELD 0 +#define STV090x_WIDTH_GAINLLR_NF_8P_9_10_FIELD 7 + +#define STV090x_GENCFG 0xFA86 +#define STV090x_OFFST_BROADCAST_FIELD 4 +#define STV090x_WIDTH_BROADCAST_FIELD 1 +#define STV090x_OFFST_PRIORITY_FIELD 1 +#define STV090x_WIDTH_PRIORITY_FIELD 1 +#define STV090x_OFFST_DDEMOD_FIELD 0 +#define STV090x_WIDTH_DDEMOD_FIELD 1 + +#define STV090x_LDPCERRx(__x) (0xFA97 - (__x * 0x1)) +#define STV090x_LDPCERR0 STV090x_LDPCERRx(0) +#define STV090x_LDPCERR1 STV090x_LDPCERRx(1) +#define STV090x_OFFST_Px_LDPC_ERRORS_COUNTER_FIELD 0 +#define STV090x_WIDTH_Px_LDPC_ERRORS_COUNTER_FIELD 8 + +#define STV090x_BCHERR 0xFA98 +#define STV090x_OFFST_Px_ERRORFLAG_FIELD 4 +#define STV090x_WIDTH_Px_ERRORFLAG_FIELD 1 +#define STV090x_OFFST_Px_BCH_ERRORS_COUNTER_FIELD 0 +#define STV090x_WIDTH_Px_BCH_ERRORS_COUNTER_FIELD 4 + +#define STV090x_Px_TSSTATEM(__x) (0xF570 - (__x - 1) * 0x200) +#define STV090x_P1_TSSTATEM STV090x_Px_TSSTATEM(1) +#define STV090x_P2_TSSTATEM STV090x_Px_TSSTATEM(2) +#define STV090x_OFFST_Px_TSDIL_ON_FIELD 7 +#define STV090x_WIDTH_Px_TSDIL_ON_FIELD 1 +#define STV090x_OFFST_Px_TSRS_ON_FIELD 5 +#define STV090x_WIDTH_Px_TSRS_ON_FIELD 1 + +#define STV090x_Px_TSCFGH(__x) (0xF572 - (__x - 1) * 0x200) +#define STV090x_P1_TSCFGH STV090x_Px_TSCFGH(1) +#define STV090x_P2_TSCFGH STV090x_Px_TSCFGH(2) +#define STV090x_OFFST_Px_TSFIFO_DVBCI_FIELD 7 +#define STV090x_WIDTH_Px_TSFIFO_DVBCI_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_SERIAL_FIELD 6 +#define STV090x_WIDTH_Px_TSFIFO_SERIAL_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_TEIUPDATE_FIELD 5 +#define STV090x_WIDTH_Px_TSFIFO_TEIUPDATE_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_DUTY50_FIELD 4 +#define STV090x_WIDTH_Px_TSFIFO_DUTY50_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_HSGNLOUT_FIELD 3 +#define STV090x_WIDTH_Px_TSFIFO_HSGNLOUT_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_ERRORMODE_FIELD 1 +#define STV090x_WIDTH_Px_TSFIFO_ERRORMODE_FIELD 2 +#define STV090x_OFFST_Px_RST_HWARE_FIELD 0 +#define STV090x_WIDTH_Px_RST_HWARE_FIELD 1 + +#define STV090x_Px_TSCFGM(__x) (0xF573 - (__x - 1) * 0x200) +#define STV090x_P1_TSCFGM STV090x_Px_TSCFGM(1) +#define STV090x_P2_TSCFGM STV090x_Px_TSCFGM(2) +#define STV090x_OFFST_Px_TSFIFO_MANSPEED_FIELD 6 +#define STV090x_WIDTH_Px_TSFIFO_MANSPEED_FIELD 2 +#define STV090x_OFFST_Px_TSFIFO_PERMDATA_FIELD 5 +#define STV090x_WIDTH_Px_TSFIFO_PERMDATA_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_INVDATA_FIELD 0 +#define STV090x_WIDTH_Px_TSFIFO_INVDATA__FIELD 1 + +#define STV090x_Px_TSCFGL(__x) (0xF574 - (__x - 1) * 0x200) +#define STV090x_P1_TSCFGL STV090x_Px_TSCFGL(1) +#define STV090x_P2_TSCFGL STV090x_Px_TSCFGL(2) +#define STV090x_OFFST_Px_TSFIFO_BCLKDEL1CK_FIELD 6 +#define STV090x_WIDTH_Px_TSFIFO_BCLKDEL1CK_FIELD 2 +#define STV090x_OFFST_Px_BCHERROR_MODE_FIELD 4 +#define STV090x_WIDTH_Px_BCHERROR_MODE_FIELD 2 +#define STV090x_OFFST_Px_TSFIFO_NSGNL2DATA_FIELD 3 +#define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA__FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_EMBINDVB_FIELD 2 +#define STV090x_WIDTH_Px_TSFIFO_EMBINDVB_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD 1 +#define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD 1 + +#define STV090x_Px_TSINSDELH(__x) (0xF576 - (__x - 1) * 0x200) +#define STV090x_P1_TSINSDELH STV090x_Px_TSINSDELH(1) +#define STV090x_P2_TSINSDELH STV090x_Px_TSINSDELH(2) +#define STV090x_OFFST_Px_TSDEL_SYNCBYTE_FIELD 7 +#define STV090x_WIDTH_Px_TSDEL_SYNCBYTE_FIELD 1 +#define STV090x_OFFST_Px_TSDEL_XXHEADER_FIELD 6 +#define STV090x_WIDTH_Px_TSDEL_XXHEADER_FIELD 1 + +#define STV090x_Px_TSSPEED(__x) (0xF580 - (__x - 1) * 0x200) +#define STV090x_P1_TSSPEED STV090x_Px_TSSPEED(1) +#define STV090x_P2_TSSPEED STV090x_Px_TSSPEED(2) +#define STV090x_OFFST_Px_TSFIFO_OUTSPEED_FIELD 0 +#define STV090x_WIDTH_Px_TSFIFO_OUTSPEED_FIELD 8 + +#define STV090x_Px_TSSTATUS(__x) (0xF581 - (__x - 1) * 0x200) +#define STV090x_P1_TSSTATUS STV090x_Px_TSSTATUS(1) +#define STV090x_P2_TSSTATUS STV090x_Px_TSSTATUS(2) +#define STV090x_OFFST_Px_TSFIFO_LINEOK_FIELD 7 +#define STV090x_WIDTH_Px_TSFIFO_LINEOK_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_ERROR_FIELD 6 +#define STV090x_WIDTH_Px_TSFIFO_ERROR_FIELD 1 + +#define STV090x_Px_TSSTATUS2(__x) (0xF582 - (__x - 1) * 0x200) +#define STV090x_P1_TSSTATUS2 STV090x_Px_TSSTATUS2(1) +#define STV090x_P2_TSSTATUS2 STV090x_Px_TSSTATUS2(2) +#define STV090x_OFFST_Px_TSFIFO_DEMODSEL_FIELD 7 +#define STV090x_WIDTH_Px_TSFIFO_DEMODSEL_FIELD 1 +#define STV090x_OFFST_Px_TSFIFOSPEED_STORE_FIELD 6 +#define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD 1 +#define STV090x_OFFST_Px_DILXX_RESET_FIELD 5 +#define STV090x_WIDTH_Px_DILXX_RESET_FIELD 1 +#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 5 +#define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD 1 +#define STV090x_OFFST_Px_SCRAMBDETECT_FIELD 1 +#define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD 1 + +#define STV090x_Px_TSBITRATEy(__x, __y) (0xF584 - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_TSBITRATE0 STV090x_Px_TSBITRATEy(1, 0) +#define STV090x_P1_TSBITRATE1 STV090x_Px_TSBITRATEy(1, 1) +#define STV090x_P2_TSBITRATE0 STV090x_Px_TSBITRATEy(2, 0) +#define STV090x_P2_TSBITRATE1 STV090x_Px_TSBITRATEy(2, 1) +#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 7 +#define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD 8 + +#define STV090x_Px_ERRCTRL1(__x) (0xF598 - (__x - 1) * 0x200) +#define STV090x_P1_ERRCTRL1 STV090x_Px_ERRCTRL1(1) +#define STV090x_P2_ERRCTRL1 STV090x_Px_ERRCTRL1(2) +#define STV090x_OFFST_Px_ERR_SOURCE_FIELD 4 +#define STV090x_WIDTH_Px_ERR_SOURCE_FIELD 4 +#define STV090x_OFFST_Px_NUM_EVENT_FIELD 0 +#define STV090x_WIDTH_Px_NUM_EVENT_FIELD 3 + +#define STV090x_Px_ERRCNT12(__x) (0xF599 - (__x - 1) * 0x200) +#define STV090x_P1_ERRCNT12 STV090x_Px_ERRCNT12(1) +#define STV090x_P2_ERRCNT12 STV090x_Px_ERRCNT12(2) +#define STV090x_OFFST_Px_ERRCNT1_OLDVALUE__FIELD 7 +#define STV090x_WIDTH_Px_ERRCNT1_OLDVALUE_FIELD 1 +#define STV090x_OFFST_Px_ERR_CNT12_FIELD 0 +#define STV090x_WIDTH_Px_ERR_CNT12_FIELD 7 + +#define STV090x_Px_ERRCNT11(__x) (0xF59A - (__x - 1) * 0x200) +#define STV090x_P1_ERRCNT11 STV090x_Px_ERRCNT11(1) +#define STV090x_P2_ERRCNT11 STV090x_Px_ERRCNT11(2) +#define STV090x_OFFST_Px_ERR_CNT11_FIELD 0 +#define STV090x_WIDTH_Px_ERR_CNT11_FIELD 8 + +#define STV090x_Px_ERRCNT10(__x) (0xF59B - (__x - 1) * 0x200) +#define STV090x_P1_ERRCNT10 STV090x_Px_ERRCNT10(1) +#define STV090x_P2_ERRCNT10 STV090x_Px_ERRCNT10(2) +#define STV090x_OFFST_Px_ERR_CNT10_FIELD 0 +#define STV090x_WIDTH_Px_ERR_CNT10_FIELD 8 + +#define STV090x_Px_ERRCTRL2(__x) (0xF59C - (__x - 1) * 0x200) +#define STV090x_P1_ERRCTRL2 STV090x_Px_ERRCTRL2(1) +#define STV090x_P2_ERRCTRL2 STV090x_Px_ERRCTRL2(2) +#define STV090x_OFFST_Px_ERR_SOURCE2_FIELD 4 +#define STV090x_WIDTH_Px_ERR_SOURCE2_FIELD 4 +#define STV090x_OFFST_Px_NUM_EVENT2_FIELD 0 +#define STV090x_WIDTH_Px_NUM_EVENT2_FIELD 3 + +#define STV090x_Px_ERRCNT22(__x) (0xF59D - (__x - 1) * 0x200) +#define STV090x_P1_ERRCNT22 STV090x_Px_ERRCNT22(1) +#define STV090x_P2_ERRCNT22 STV090x_Px_ERRCNT22(2) +#define STV090x_OFFST_Px_ERRCNT2_OLDVALUE_FIELD 7 +#define STV090x_WIDTH_Px_ERRCNT2_OLDVALUE_FIELD 1 +#define STV090x_OFFST_Px_ERR_CNT2_FIELD 0 +#define STV090x_WIDTH_Px_ERR_CNT2_FIELD 7 + +#define STV090x_Px_ERRCNT21(__x) (0xF59E - (__x - 1) * 0x200) +#define STV090x_P1_ERRCNT21 STV090x_Px_ERRCNT21(1) +#define STV090x_P2_ERRCNT21 STV090x_Px_ERRCNT21(2) +#define STV090x_OFFST_Px_ERR_CNT21_FIELD 0 +#define STV090x_WIDTH_Px_ERR_CNT21_FIELD 8 + +#define STV090x_Px_ERRCNT20(__x) (0xF59F - (__x - 1) * 0x200) +#define STV090x_P1_ERRCNT20 STV090x_Px_ERRCNT20(1) +#define STV090x_P2_ERRCNT20 STV090x_Px_ERRCNT20(2) +#define STV090x_OFFST_Px_ERR_CNT20_FIELD 0 +#define STV090x_WIDTH_Px_ERR_CNT20_FIELD 8 + +#define STV090x_Px_FECSPY(__x) (0xF5A0 - (__x - 1) * 0x200) +#define STV090x_P1_FECSPY STV090x_Px_FECSPY(1) +#define STV090x_P2_FECSPY STV090x_Px_FECSPY(2) +#define STV090x_OFFST_Px_SPY_ENABLE_FIELD 7 +#define STV090x_WIDTH_Px_SPY_ENABLE_FIELD 1 +#define STV090x_OFFST_Px_BERMETER_DATAMAODE_FIELD 2 +#define STV090x_WIDTH_Px_BERMETER_DATAMAODE_FIELD 2 + +#define STV090x_Px_FSPYCFG(__x) (0xF5A1 - (__x - 1) * 0x200) +#define STV090x_P1_FSPYCFG STV090x_Px_FSPYCFG(1) +#define STV090x_P2_FSPYCFG STV090x_Px_FSPYCFG(2) +#define STV090x_OFFST_Px_RST_ON_ERROR_FIELD 5 +#define STV090x_WIDTH_Px_RST_ON_ERROR_FIELD 1 +#define STV090x_OFFST_Px_ONE_SHOT_FIELD 4 +#define STV090x_WIDTH_Px_ONE_SHOT_FIELD 1 +#define STV090x_OFFST_Px_I2C_MODE_FIELD 2 +#define STV090x_WIDTH_Px_I2C_MODE_FIELD 2 + +#define STV090x_Px_FSPYDATA(__x) (0xF5A2 - (__x - 1) * 0x200) +#define STV090x_P1_FSPYDATA STV090x_Px_FSPYDATA(1) +#define STV090x_P2_FSPYDATA STV090x_Px_FSPYDATA(2) +#define STV090x_OFFST_Px_SPY_STUFFING_FIELD 7 +#define STV090x_WIDTH_Px_SPY_STUFFING_FIELD 1 +#define STV090x_OFFST_Px_SPY_CNULLPKT_FIELD 5 +#define STV090x_WIDTH_Px_SPY_CNULLPKT_FIELD 1 +#define STV090x_OFFST_Px_SPY_OUTDATA_MODE_FIELD 0 +#define STV090x_WIDTH_Px_SPY_OUTDATA_MODE_FIELD 5 + +#define STV090x_Px_FSPYOUT(__x) (0xF5A3 - (__x - 1) * 0x200) +#define STV090x_P1_FSPYOUT STV090x_Px_FSPYOUT(1) +#define STV090x_P2_FSPYOUT STV090x_Px_FSPYOUT(2) +#define STV090x_OFFST_Px_FSPY_DIRECT_FIELD 7 +#define STV090x_WIDTH_Px_FSPY_DIRECT_FIELD 1 +#define STV090x_OFFST_Px_STUFF_MODE_FIELD 0 +#define STV090x_WIDTH_Px_STUFF_MODE_FIELD 3 + +#define STV090x_Px_FSTATUS(__x) (0xF5A4 - (__x - 1) * 0x200) +#define STV090x_P1_FSTATUS STV090x_Px_FSTATUS(1) +#define STV090x_P2_FSTATUS STV090x_Px_FSTATUS(2) +#define STV090x_OFFST_Px_SPY_ENDSIM_FIELD 7 +#define STV090x_WIDTH_Px_SPY_ENDSIM_FIELD 1 +#define STV090x_OFFST_Px_VALID_SIM_FIELD 6 +#define STV090x_WIDTH_Px_VALID_SIM_FIELD 1 +#define STV090x_OFFST_Px_FOUND_SIGNAL_FIELD 5 +#define STV090x_WIDTH_Px_FOUND_SIGNAL_FIELD 1 +#define STV090x_OFFST_Px_DSS_SYNCBYTE_FIELD 4 +#define STV090x_WIDTH_Px_DSS_SYNCBYTE_FIELD 1 +#define STV090x_OFFST_Px_RESULT_STATE_FIELD 0 +#define STV090x_WIDTH_Px_RESULT_STATE_FIELD 4 + +#define STV090x_Px_FBERCPT4(__x) (0xF5A8 - (__x - 1) * 0x200) +#define STV090x_P1_FBERCPT4 STV090x_Px_FBERCPT4(1) +#define STV090x_P2_FBERCPT4 STV090x_Px_FBERCPT4(2) +#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 +#define STV090x_WIDTH_Px_BERMETER_CPT_FIELD 8 + +#define STV090x_Px_FBERCPT3(__x) (0xF5A9 - (__x - 1) * 0x200) +#define STV090x_P1_FBERCPT3 STV090x_Px_FBERCPT3(1) +#define STV090x_P2_FBERCPT3 STV090x_Px_FBERCPT3(2) +#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 +#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 + +#define STV090x_Px_FBERCPT2(__x) (0xF5AA - (__x - 1) * 0x200) +#define STV090x_P1_FBERCPT2 STV090x_Px_FBERCPT2(1) +#define STV090x_P2_FBERCPT2 STV090x_Px_FBERCPT2(2) +#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 +#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 + +#define STV090x_Px_FBERCPT1(__x) (0xF5AB - (__x - 1) * 0x200) +#define STV090x_P1_FBERCPT1 STV090x_Px_FBERCPT1(1) +#define STV090x_P2_FBERCPT1 STV090x_Px_FBERCPT1(2) +#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 +#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 + +#define STV090x_Px_FBERCPT0(__x) (0xF5AC - (__x - 1) * 0x200) +#define STV090x_P1_FBERCPT0 STV090x_Px_FBERCPT0(1) +#define STV090x_P2_FBERCPT0 STV090x_Px_FBERCPT0(2) +#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 +#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 + +#define STV090x_Px_FBERERRy(__x, __y) (0xF5AF - (__x - 1) * 0x200 - __y * 0x1) +#define STV090x_P1_FBERERR0 STV090x_Px_FBERERRy(1, 0) +#define STV090x_P1_FBERERR1 STV090x_Px_FBERERRy(1, 1) +#define STV090x_P1_FBERERR2 STV090x_Px_FBERERRy(1, 2) +#define STV090x_P2_FBERERR0 STV090x_Px_FBERERRy(2, 0) +#define STV090x_P2_FBERERR1 STV090x_Px_FBERERRy(2, 1) +#define STV090x_P2_FBERERR2 STV090x_Px_FBERERRy(2, 2) +#define STV090x_OFFST_Px_FBERMETER_CPT_ERR_FIELD 0 +#define STV090x_WIDTH_Px_FBERMETER_CPT_ERR_FIELD 8 + +#define STV090x_Px_FSPYBER(__x) (0xF5B2 - (__x - 1) * 0x200) +#define STV090x_P1_FSPYBER STV090x_Px_FSPYBER(1) +#define STV090x_P2_FSPYBER STV090x_Px_FSPYBER(2) +#define STV090x_OFFST_Px_FSPYBER_SYNCBYTE_FIELD 4 +#define STV090x_WIDTH_Px_FSPYBER_SYNCBYTE_FIELD 1 +#define STV090x_OFFST_Px_FSPYBER_UNSYNC_FIELD 3 +#define STV090x_WIDTH_Px_FSPYBER_UNSYNC_FIELD 1 +#define STV090x_OFFST_Px_FSPYBER_CTIME_FIELD 0 +#define STV090x_WIDTH_Px_FSPYBER_CTIME_FIELD 3 + +#define STV090x_TSGENERAL 0xF630 +#define STV090x_OFFST_Px_MUXSTREAM_OUT_FIELD 3 +#define STV090x_WIDTH_Px_MUXSTREAM_OUT_FIELD 1 +#define STV090x_OFFST_Px_TSFIFO_PERMPARAL_FIELD 1 +#define STV090x_WIDTH_Px_TSFIFO_PERMPARAL_FIELD 2 + +#define STV090x_TSTRES0 0xFF11 +#define STV090x_OFFST_FRESFEC_FIELD 7 +#define STV090x_WIDTH_FRESFEC_FIELD 1 + +#define STV090x_Px_TSTDISRX(__x) (0xFF67 - (__x - 1) * 0x2) +#define STV090x_P1_TSTDISRX STV090x_Px_TSTDISRX(1) +#define STV090x_P2_TSTDISRX STV090x_Px_TSTDISRX(2) +#define STV090x_OFFST_Px_TSTDISRX_SELECT_FIELD 3 +#define STV090x_WIDTH_Px_TSTDISRX_SELECT_FIELD 1 + +#endif /* __STV090x_REG_H */ diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c new file mode 100644 index 0000000..7386181 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110x.c @@ -0,0 +1,372 @@ +/* + STV6110(A) Silicon tuner driver + + Copyright (C) Manu Abraham + + Copyright (C) ST Microelectronics + + 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 "dvb_frontend.h" + +#include "stv6110x_reg.h" +#include "stv6110x.h" +#include "stv6110x_priv.h" + +static unsigned int verbose; +module_param(verbose, int, 0644); +MODULE_PARM_DESC(verbose, "Set Verbosity level"); + +static u8 stv6110x_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; + +static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) +{ + int ret; + const struct stv6110x_config *config = stv6110x->config; + u8 b0[] = { reg }; + u8 b1[] = { 0 }; + struct i2c_msg msg[] = { + { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 }, + { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } + }; + + ret = i2c_transfer(stv6110x->i2c, msg, 2); + if (ret != 2) { + dprintk(FE_ERROR, 1, "I/O Error"); + return -EREMOTEIO; + } + + return 0; +} + +static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) +{ + int ret; + const struct stv6110x_config *config = stv6110x->config; + u8 buf[] = { reg, data }; + struct i2c_msg msg = { .addr = config->addr, .flags = 0, . buf = buf, .len = 2 }; + + ret = i2c_transfer(stv6110x->i2c, &msg, 1); + if (ret != 1) { + dprintk(FE_ERROR, 1, "I/O Error"); + return -EREMOTEIO; + } + + return 0; +} + +static int stv6110x_init(struct dvb_frontend *fe) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + int ret; + u8 i; + + for (i = 0; i < ARRAY_SIZE(stv6110x_regs); i++) { + ret = stv6110x_write_reg(stv6110x, i, stv6110x_regs[i]); + if (ret < 0) { + dprintk(FE_ERROR, 1, "Initialization failed"); + return -1; + } + } + + return 0; +} + +static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + u32 rDiv, divider; + s32 pVal, pCalc, rDivOpt = 0; + u8 i; + + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); + + if (frequency <= 1023000) { + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); + pVal = 40; + } else if (frequency <= 1300000) { + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); + pVal = 40; + } else if (frequency <= 2046000) { + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); + pVal = 20; + } else { + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); + pVal = 20; + } + + for (rDiv = 0; rDiv <= 3; rDiv++) { + pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv); + + if ((abs((s32)(pCalc - pVal))) < (abs((s32)(1000 - pVal)))) + rDivOpt = rDiv; + } + + divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; + divider = (divider + 5) / 10; + + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); + + /* VCO Auto calibration */ + STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); + + stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); + stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x_regs[STV6110x_TNG1]); + stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x_regs[STV6110x_TNG0]); + stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); + + for (i = 0; i < TRIALS; i++) { + stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); + if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x_regs[STV6110x_STAT1])) + break; + msleep(1); + } + + return 0; +} + +static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x_regs[STV6110x_TNG1]); + stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x_regs[STV6110x_TNG0]); + + *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x_regs[STV6110x_TNG1]), + STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x_regs[STV6110x_TNG0]))) * REFCLOCK_kHz; + + *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x_regs[STV6110x_TNG1]) + + STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x_regs[STV6110x_TNG1]))); + + *frequency >>= 2; + + return 0; +} + +static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + u32 halfbw; + u8 i; + + halfbw = bandwidth >> 1; + + if (halfbw > 36000000) + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ + else if (halfbw < 5000000) + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ + else + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ + + + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ + STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ + + stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); + stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); + + for (i = 0; i < TRIALS; i++) { + stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); + if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x_regs[STV6110x_STAT1])) + break; + msleep(1); + } + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ + stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); + + return 0; +} + +static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x_regs[STV6110x_CTRL3]); + *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x_regs[STV6110x_CTRL3]) + 5) * 2000000; + + return 0; +} + +static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + /* setup divider */ + switch (refclock) { + default: + case 1: + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); + break; + case 2: + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); + break; + case 4: + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); + break; + case 8: + case 0: + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); + break; + } + stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); + + return 0; +} + +static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x_regs[STV6110x_CTRL2]); + *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x_regs[STV6110x_CTRL2]); + + return 0; +} + +static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); + stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); + + return 0; +} + +static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + int ret; + + switch (mode) { + case TUNER_SLEEP: + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 0); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 0); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 0); + break; + + case TUNER_WAKE: + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 1); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 1); + STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 1); + break; + } + + ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); + if (ret < 0) { + dprintk(FE_ERROR, 1, "I/O Error"); + return -EIO; + } + + return 0; +} + +static int stv6110x_sleep(struct dvb_frontend *fe) +{ + return stv6110x_set_mode(fe, TUNER_SLEEP); +} + +static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); + + if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x_regs[STV6110x_STAT1])) + *status = TUNER_PHASELOCKED; + else + *status = 0; + + return 0; +} + + +static int stv6110x_release(struct dvb_frontend *fe) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(stv6110x); + + return 0; +} + +static struct dvb_tuner_ops stv6110x_ops = { + .info = { + .name = "STV6110(A) Silicon Tuner", + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 0, + }, + + .init = stv6110x_init, + .sleep = stv6110x_sleep, + .release = stv6110x_release +}; + +static struct stv6110x_devctl stv6110x_ctl = { + .tuner_init = stv6110x_init, + .tuner_set_mode = stv6110x_set_mode, + .tuner_set_frequency = stv6110x_set_frequency, + .tuner_get_frequency = stv6110x_get_frequency, + .tuner_set_bandwidth = stv6110x_set_bandwidth, + .tuner_get_bandwidth = stv6110x_get_bandwidth, + .tuner_set_bbgain = stv6110x_set_bbgain, + .tuner_get_bbgain = stv6110x_get_bbgain, + .tuner_set_refclk = stv6110x_set_refclock, + .tuner_get_status = stv6110x_get_status, +}; + +struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, + const struct stv6110x_config *config, + struct i2c_adapter *i2c) +{ + struct stv6110x_state *stv6110x; + + stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); + if (stv6110x == NULL) + goto error; + + stv6110x->i2c = i2c; + stv6110x->config = config; + stv6110x->devctl = &stv6110x_ctl; + + fe->tuner_priv = stv6110x; + fe->ops.tuner_ops = stv6110x_ops; + + printk("%s: Attaching STV6110x \n", __func__); + return stv6110x->devctl; + +error: + kfree(stv6110x); + return NULL; +} +EXPORT_SYMBOL(stv6110x_attach); + +MODULE_AUTHOR("Manu Abraham"); +MODULE_DESCRIPTION("STV6110x Silicon tuner"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h new file mode 100644 index 0000000..a382570 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110x.h @@ -0,0 +1,71 @@ +/* + STV6110(A) Silicon tuner driver + + Copyright (C) Manu Abraham + + Copyright (C) ST Microelectronics + + 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 __STV6110x_H +#define __STV6110x_H + +struct stv6110x_config { + u8 addr; + u32 refclk; +}; + +enum tuner_mode { + TUNER_SLEEP = 1, + TUNER_WAKE, +}; + +enum tuner_status { + TUNER_PHASELOCKED = 1, +}; + +struct stv6110x_devctl { + int (*tuner_init) (struct dvb_frontend *fe); + int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); + int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); + int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); + int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth); + int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth); + int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain); + int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); + int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk); + int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); +}; + + +#if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE)) + +extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, + const struct stv6110x_config *config, + struct i2c_adapter *i2c); + +#else +static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, + const struct stv6110x_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +#endif /* CONFIG_DVB_STV6110x */ + +#endif /* __STV6110x_H */ diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h new file mode 100644 index 0000000..1295272 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110x_priv.h @@ -0,0 +1,77 @@ +/* + STV6110(A) Silicon tuner driver + + Copyright (C) Manu Abraham + + Copyright (C) ST Microelectronics + + 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 __STV6110x_PRIV_H +#define __STV6110x_PRIV_H + +#define FE_ERROR 0 +#define FE_NOTICE 1 +#define FE_INFO 2 +#define FE_DEBUG 3 +#define FE_DEBUGREG 4 + +#define dprintk(__y, __z, format, arg...) do { \ + if (__z) { \ + if ((verbose > FE_ERROR) && (verbose > __y)) \ + printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_NOTICE) && (verbose > __y)) \ + printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_INFO) && (verbose > __y)) \ + printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ + else if ((verbose > FE_DEBUG) && (verbose > __y)) \ + printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ + } else { \ + if (verbose > __y) \ + printk(format, ##arg); \ + } \ +} while (0) + + +#define STV6110x_SETFIELD(mask, bitf, val) \ + (mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) << \ + STV6110x_OFFST_##bitf))) | \ + (val << STV6110x_OFFST_##bitf)) + +#define STV6110x_GETFIELD(bitf, val) \ + ((val >> STV6110x_OFFST_##bitf) & \ + ((1 << STV6110x_WIDTH_##bitf) - 1)) + +#define MAKEWORD16(a, b) (((a) << 8) | (b)) + +#define LSB(x) ((x & 0xff)) +#define MSB(y) ((y >> 8) & 0xff) + +#define TRIALS 10 +#define R_DIV(__div) (1 << (__div + 1)) +#define REFCLOCK_kHz (stv6110x->reference / 1000) +#define REFCLOCK_MHz (stv6110x->reference / 1000000) + +struct stv6110x_state { + struct i2c_adapter *i2c; + const struct stv6110x_config *config; + + struct stv6110x_devctl *devctl; + + u32 reference; +}; + +#endif /* __STV6110x_PRIV_H */ diff --git a/drivers/media/dvb/frontends/stv6110x_reg.h b/drivers/media/dvb/frontends/stv6110x_reg.h new file mode 100644 index 0000000..93e5c70 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110x_reg.h @@ -0,0 +1,82 @@ +/* + STV6110(A) Silicon tuner driver + + Copyright (C) Manu Abraham + + Copyright (C) ST Microelectronics + + 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 __STV6110x_REG_H +#define __STV6110x_REG_H + +#define STV6110x_CTRL1 0x00 +#define STV6110x_OFFST_CTRL1_K 3 +#define STV6110x_WIDTH_CTRL1_K 5 +#define STV6110x_OFFST_CTRL1_LPT 2 +#define STV6110x_WIDTH_CTRL1_LPT 1 +#define STV6110x_OFFST_CTRL1_RX 1 +#define STV6110x_WIDTH_CTRL1_RX 1 +#define STV6110x_OFFST_CTRL1_SYN 0 +#define STV6110x_WIDTH_CTRL1_SYN 1 + +#define STV6110x_CTRL2 0x01 +#define STV6110x_OFFST_CTRL2_CO_DIV 6 +#define STV6110x_WIDTH_CTRL2_CO_DIV 2 +#define STV6110x_OFFST_CTRL2_RSVD 5 +#define STV6110x_WIDTH_CTRL2_RSVD 1 +#define STV6110x_OFFST_CTRL2_REFOUT_SEL 4 +#define STV6110x_WIDTH_CTRL2_REFOUT_SEL 1 +#define STV6110x_OFFST_CTRL2_BBGAIN 0 +#define STV6110x_WIDTH_CTRL2_BBGAIN 4 + +#define STV6110x_TNG0 0x02 +#define STV6110x_OFFST_TNG0_N_DIV_7_0 0 +#define STV6110x_WIDTH_TNG0_N_DIV_7_0 8 + +#define STV6110x_TNG1 0x03 +#define STV6110x_OFFST_TNG1_R_DIV 6 +#define STV6110x_WIDTH_TNG1_R_DIV 2 +#define STV6110x_OFFST_TNG1_PRESC32_ON 5 +#define STV6110x_WIDTH_TNG1_PRESC32_ON 1 +#define STV6110x_OFFST_TNG1_DIV4SEL 4 +#define STV6110x_WIDTH_TNG1_DIV4SEL 1 +#define STV6110x_OFFST_TNG1_N_DIV_11_8 0 +#define STV6110x_WIDTH_TNG1_N_DIV_11_8 4 + + +#define STV6110x_CTRL3 0x04 +#define STV6110x_OFFST_CTRL3_DCLOOP_OFF 7 +#define STV6110x_WIDTH_CTRL3_DCLOOP_OFF 1 +#define STV6110x_OFFST_CTRL3_RCCLK_OFF 6 +#define STV6110x_WIDTH_CTRL3_RCCLK_OFF 1 +#define STV6110x_OFFST_CTRL3_ICP 5 +#define STV6110x_WIDTH_CTRL3_ICP 1 +#define STV6110x_OFFST_CTRL3_CF 0 +#define STV6110x_WIDTH_CTRL3_CF 5 + +#define STV6110x_STAT1 0x05 +#define STV6110x_OFFST_STAT1_CALVCO_STRT 2 +#define STV6110x_WIDTH_STAT1_CALVCO_STRT 1 +#define STV6110x_OFFST_STAT1_CALRC_STRT 1 +#define STV6110x_WIDTH_STAT1_CALRC_STRT 1 +#define STV6110x_OFFST_STAT1_LOCK 0 +#define STV6110x_WIDTH_STAT1_LOCK 1 + +#define STV6110x_STAT2 0x06 +#define STV6110x_STAT3 0x07 + +#endif /* __STV6110x_REG_H */ diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 371a716..2ee0320 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -53,6 +53,9 @@ #include "bsru6.h" #include "tda1002x.h" #include "tda827x.h" +#include "stv6110x.h" +#include "stv090x.h" +#include "isl6423.h" /* * Regarding DEBIADDR_IR: @@ -1346,6 +1349,41 @@ static struct stb6100_config tt3200_stb6100_config = { .refclock = 27000000, }; +static struct stv090x_config tt1600_stv090x_config = { + .device = STV0903, + .demod_mode = STV090x_SINGLE, + .clk_mode = STV090x_CLK_INT, + + .xtal = 8000000, + .address = 0x68, + .ref_clk = 16000000, + + .ts1_mode = STV090x_TSMODE_DVBCI, + .ts2_mode = STV090x_TSMODE_DVBCI, + + .tuner_init = NULL, + .tuner_set_mode = NULL, + .tuner_set_frequency = NULL, + .tuner_get_frequency = NULL, + .tuner_set_bandwidth = NULL, + .tuner_get_bandwidth = NULL, + .tuner_set_bbgain = NULL, + .tuner_get_bbgain = NULL, + .tuner_set_refclk = NULL, + .tuner_get_status = NULL, +}; + +static struct stv6110x_config tt1600_stv6110x_config = { + .addr = 0x60, + .refclk = 16000000, +}; + +static struct isl6423_config tt1600_isl6423_config = { + .current_max = SEC_CURRENT_800m, + .curlim = SEC_CURRENT_LIM_ON, + .addr = 0x08, +}; + static void frontend_init(struct budget_ci *budget_ci) { switch (budget_ci->budget.dev->pci->subsystem_device) { @@ -1465,6 +1503,49 @@ static void frontend_init(struct budget_ci *budget_ci) } break; + case 0x101c: { /* TT S2-1600 */ + struct stv6110x_devctl *ctl; + /* TODO! must verify with Andreas */ + saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO); + msleep(50); + saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI); + msleep(250); + + budget_ci->budget.dvb_frontend = dvb_attach(stv090x_attach, + &tt1600_stv090x_config, + &budget_ci->budget.i2c_adap, + STV090x_DEMODULATOR_0); + + if (budget_ci->budget.dvb_frontend) { + + ctl = dvb_attach(stv6110x_attach, + budget_ci->budget.dvb_frontend, + &tt1600_stv6110x_config, + &budget_ci->budget.i2c_adap); + + tt1600_stv090x_config.tuner_init = ctl->tuner_init; + tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; + tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; + tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; + tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; + tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; + tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; + tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; + tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; + tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; + + dvb_attach(isl6423_attach, + budget_ci->budget.dvb_frontend, + &budget_ci->budget.i2c_adap, + &tt1600_isl6423_config); + + } else { + dvb_frontend_detach(budget_ci->budget.dvb_frontend); + budget_ci->budget.dvb_frontend = NULL; + } + } + break; + } if (budget_ci->budget.dvb_frontend == NULL) { @@ -1556,6 +1637,7 @@ MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT); +MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT); static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), @@ -1566,6 +1648,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019), + MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c), { .vendor = 0, } -- cgit v1.1 From dd4c2b3f6a2d30602d22485ab725c84f2fb074b6 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Mon, 6 Apr 2009 15:46:50 -0300 Subject: V4L/DVB (11580): budget-ci: Fix incorrect default CLOCK setup Signed-off-by: Andreas Regel Signed-off-by: MAnu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-ci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 2ee0320..7222030 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -1352,11 +1352,11 @@ static struct stb6100_config tt3200_stb6100_config = { static struct stv090x_config tt1600_stv090x_config = { .device = STV0903, .demod_mode = STV090x_SINGLE, - .clk_mode = STV090x_CLK_INT, + .clk_mode = STV090x_CLK_EXT, - .xtal = 8000000, + .xtal = 27000000, .address = 0x68, - .ref_clk = 16000000, + .ref_clk = 27000000, .ts1_mode = STV090x_TSMODE_DVBCI, .ts2_mode = STV090x_TSMODE_DVBCI, @@ -1375,11 +1375,11 @@ static struct stv090x_config tt1600_stv090x_config = { static struct stv6110x_config tt1600_stv6110x_config = { .addr = 0x60, - .refclk = 16000000, + .refclk = 27000000, }; static struct isl6423_config tt1600_isl6423_config = { - .current_max = SEC_CURRENT_800m, + .current_max = SEC_CURRENT_515m, .curlim = SEC_CURRENT_LIM_ON, .addr = 0x08, }; -- cgit v1.1 From 017eb0381fedbfdcad1e8e536d014c4064e6687f Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 7 Apr 2009 05:19:54 -0300 Subject: V4L/DVB (11581): stv090x and stv6110x: fix repeater level setup and ref clock * Reference clock was unused * Fix missing repeater level setup Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 9 +++++++-- drivers/media/dvb/frontends/stv090x.h | 13 +++++++++++++ drivers/media/dvb/frontends/stv6110x_priv.h | 6 ++---- drivers/media/dvb/ttpci/budget-ci.c | 2 ++ 4 files changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index a65f1b7..e80d163 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -640,16 +640,19 @@ static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 d static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { struct stv090x_state *state = fe->demodulator_priv; + const struct stv090x_config *config = state->config; u32 reg; reg = STV090x_READ_DEMOD(state, I2CRPT); - +// STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); if (enable) { + dprintk(FE_DEBUG, 1, "Enable Gate"); STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1); if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) goto err; } else { + dprintk(FE_DEBUG, 1, "Disable Gate"); STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0); if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0) goto err; @@ -3773,6 +3776,7 @@ static int stv090x_setup(struct dvb_frontend *fe) const struct stv090x_reg *stv090x_initval = NULL; const struct stv090x_reg *stv090x_cut20_val = NULL; unsigned long t1_size = 0, t2_size = 0; + u32 reg = 0; int i; @@ -3799,7 +3803,8 @@ static int stv090x_setup(struct dvb_frontend *fe) if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */ goto err; - if (STV090x_WRITE_DEMOD(state, I2CRPT, 0x00) < 0) /* repeater OFF */ + STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); + if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) /* repeater OFF */ goto err; if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h index e56489c..e968c98 100644 --- a/drivers/media/dvb/frontends/stv090x.h +++ b/drivers/media/dvb/frontends/stv090x.h @@ -49,6 +49,17 @@ enum stv090x_clkmode { STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */ }; +enum stv090x_i2crpt { + STV090x_RPTLEVEL_256 = 0, + STV090x_RPTLEVEL_128 = 1, + STV090x_RPTLEVEL_64 = 2, + STV090x_RPTLEVEL_32 = 3, + STV090x_RPTLEVEL_16 = 4, + STV090x_RPTLEVEL_8 = 5, + STV090x_RPTLEVEL_4 = 6, + STV090x_RPTLEVEL_2 = 7, +}; + struct stv090x_config { enum stv090x_device device; enum stv090x_mode demod_mode; @@ -62,6 +73,8 @@ struct stv090x_config { u8 ts1_mode; u8 ts2_mode; + enum stv090x_i2crpt repeater_level; + int (*tuner_init) (struct dvb_frontend *fe); int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h index 1295272..7260da6 100644 --- a/drivers/media/dvb/frontends/stv6110x_priv.h +++ b/drivers/media/dvb/frontends/stv6110x_priv.h @@ -62,16 +62,14 @@ #define TRIALS 10 #define R_DIV(__div) (1 << (__div + 1)) -#define REFCLOCK_kHz (stv6110x->reference / 1000) -#define REFCLOCK_MHz (stv6110x->reference / 1000000) +#define REFCLOCK_kHz (stv6110x->config->refclk / 1000) +#define REFCLOCK_MHz (stv6110x->config->refclk / 1000000) struct stv6110x_state { struct i2c_adapter *i2c; const struct stv6110x_config *config; struct stv6110x_devctl *devctl; - - u32 reference; }; #endif /* __STV6110x_PRIV_H */ diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 7222030..dbdc795 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -1361,6 +1361,8 @@ static struct stv090x_config tt1600_stv090x_config = { .ts1_mode = STV090x_TSMODE_DVBCI, .ts2_mode = STV090x_TSMODE_DVBCI, + .repeater_level = STV090x_RPTLEVEL_16, + .tuner_init = NULL, .tuner_set_mode = NULL, .tuner_set_frequency = NULL, -- cgit v1.1 From 5657150759ab67292db0333808a069970328663b Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 7 Apr 2009 16:08:26 -0300 Subject: V4L/DVB (11582): stv090x: fix Undocumented Registers Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 24 +++++++++-- drivers/media/dvb/frontends/stv090x_reg.h | 69 ++++++++++++++++++++----------- 2 files changed, 64 insertions(+), 29 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index e80d163..b450bf1 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -176,8 +176,10 @@ static const struct stv090x_tab stv090x_rf_tab[] = { static struct stv090x_reg stv0900_initval[] = { { STV090x_OUTCFG, 0x00 }, + { STV090x_MODECFG, 0xff }, { STV090x_AGCRF1CFG, 0x11 }, { STV090x_AGCRF2CFG, 0x13 }, + { STV090x_TSGENERAL1X, 0x14 }, { STV090x_TSTTNR2, 0x21 }, { STV090x_TSTTNR4, 0x21 }, { STV090x_P2_DISTXCTL, 0x22 }, @@ -203,8 +205,10 @@ static struct stv090x_reg stv0900_initval[] = { { STV090x_P2_ERRCTRL2, 0xc1 }, { STV090x_P2_CFRICFG, 0xf8 }, { STV090x_P2_NOSCFG, 0x1c }, + { STV090x_P2_DMDTOM, 0x20 }, { STV090x_P2_CORRELMANT, 0x70 }, { STV090x_P2_CORRELABS, 0x88 }, + { STV090x_P2_AGC2O, 0x5b }, { STV090x_P2_AGC2REF, 0x38 }, { STV090x_P2_CARCFG, 0xe4 }, { STV090x_P2_ACLC, 0x1A }, @@ -246,6 +250,7 @@ static struct stv090x_reg stv0900_initval[] = { { STV090x_P1_DMDCFGMD, 0xf9 }, { STV090x_P1_DEMOD, 0x08 }, { STV090x_P1_DMDCFG3, 0xc4 }, + { STV090x_P1_DMDTOM, 0x20 }, { STV090x_P1_CARFREQ, 0xed }, { STV090x_P1_LDT, 0xd0 }, { STV090x_P1_LDT2, 0xb8 }, @@ -265,6 +270,7 @@ static struct stv090x_reg stv0900_initval[] = { { STV090x_P1_NOSCFG, 0x1c }, { STV090x_P1_CORRELMANT, 0x70 }, { STV090x_P1_CORRELABS, 0x88 }, + { STV090x_P1_AGC2O, 0x5b }, { STV090x_P1_AGC2REF, 0x38 }, { STV090x_P1_CARCFG, 0xe4 }, { STV090x_P1_ACLC, 0x1A }, @@ -326,6 +332,7 @@ static struct stv090x_reg stv0900_initval[] = { { STV090x_GAINLLR_NF15, 0x1A }, { STV090x_GAINLLR_NF16, 0x1F }, { STV090x_GAINLLR_NF17, 0x21 }, + { STV090x_RCCFGH, 0x20 }, { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */ { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */ { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */ @@ -364,12 +371,14 @@ static struct stv090x_reg stv0903_initval[] = { { STV090x_P1_ERRCTRL2, 0xc1 }, { STV090x_P1_CFRICFG, 0xf8 }, { STV090x_P1_NOSCFG, 0x1c }, + { STV090x_P1_DMDTOM, 0x20 }, { STV090x_P1_CORRELMANT, 0x70 }, { STV090x_P1_CORRELABS, 0x88 }, - { STV090x_P1_AGC2REF, 0x38 } , + { STV090x_P1_AGC2O, 0x5b }, + { STV090x_P1_AGC2REF, 0x38 }, { STV090x_P1_CARCFG, 0xe4 }, { STV090x_P1_ACLC, 0x1A }, - { STV090x_P1_BCLC, 0x09 } , + { STV090x_P1_BCLC, 0x09 }, { STV090x_P1_CARHDR, 0x08 }, { STV090x_P1_KREFTMG, 0xc1 }, { STV090x_P1_SFRSTEP, 0x58 }, @@ -427,6 +436,7 @@ static struct stv090x_reg stv0903_initval[] = { { STV090x_GAINLLR_NF15, 0x1A }, { STV090x_GAINLLR_NF16, 0x1F }, { STV090x_GAINLLR_NF17, 0x21 }, + { STV090x_RCCFGH, 0x20 }, { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */ { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/ }; @@ -434,6 +444,7 @@ static struct stv090x_reg stv0903_initval[] = { static struct stv090x_reg stv0900_cut20_val[] = { { STV090x_P2_DMDCFG3, 0xe8 }, + { STV090x_P2_DMDCFG4, 0x10 }, { STV090x_P2_CARFREQ, 0x38 }, { STV090x_P2_CARHDR, 0x20 }, { STV090x_P2_KREFTMG, 0x5a }, @@ -442,6 +453,7 @@ static struct stv090x_reg stv0900_cut20_val[] = { { STV090x_P2_SMAPCOEF5, 0x04 }, { STV090x_P2_NOSCFG, 0x0c }, { STV090x_P1_DMDCFG3, 0xe8 }, + { STV090x_P1_DMDCFG4, 0x10 }, { STV090x_P1_CARFREQ, 0x38 }, { STV090x_P1_CARHDR, 0x20 }, { STV090x_P1_KREFTMG, 0x5a }, @@ -467,6 +479,7 @@ static struct stv090x_reg stv0900_cut20_val[] = { static struct stv090x_reg stv0903_cut20_val[] = { { STV090x_P1_DMDCFG3, 0xe8 }, + { STV090x_P1_DMDCFG4, 0x10 }, { STV090x_P1_CARFREQ, 0x38 }, { STV090x_P1_CARHDR, 0x20 }, { STV090x_P1_KREFTMG, 0x5a }, @@ -640,11 +653,9 @@ static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 d static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { struct stv090x_state *state = fe->demodulator_priv; - const struct stv090x_config *config = state->config; u32 reg; reg = STV090x_READ_DEMOD(state, I2CRPT); -// STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); if (enable) { dprintk(FE_DEBUG, 1, "Enable Gate"); STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1); @@ -3605,10 +3616,12 @@ static int stv090x_set_tspath(struct stv090x_state *state) case STV090x_TSMODE_SERIAL_PUNCTURED: case STV090x_TSMODE_SERIAL_CONTINUOUS: default: + stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10); break; case STV090x_TSMODE_PARALLEL_PUNCTURED: case STV090x_TSMODE_DVBCI: + stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16); reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) @@ -3632,10 +3645,12 @@ static int stv090x_set_tspath(struct stv090x_state *state) case STV090x_TSMODE_SERIAL_PUNCTURED: case STV090x_TSMODE_SERIAL_CONTINUOUS: default: + stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14); break; case STV090x_TSMODE_PARALLEL_PUNCTURED: case STV090x_TSMODE_DVBCI: + stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12); break; } break; @@ -3893,6 +3908,7 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, state->i2c = i2c; state->frontend.ops = stv090x_ops; state->frontend.demodulator_priv = state; + state->demod = demod; state->demod_mode = config->demod_mode; /* Single or Dual mode */ state->device = config->device; state->rolloff = 35; /* default */ diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h index b59eca9..0dff56d 100644 --- a/drivers/media/dvb/frontends/stv090x_reg.h +++ b/drivers/media/dvb/frontends/stv090x_reg.h @@ -48,6 +48,8 @@ #define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3 #define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 +#define STV090x_MODECFG 0xf11d + #define STV090x_IRQSTATUS3 0xf120 #define STV090x_OFFST_SPLL_LOCK_FIELD 5 #define STV090x_WIDTH_SPLL_LOCK_FIELD 1 @@ -312,9 +314,9 @@ #define STV090x_OFFST_ERRORx_XOR_FIELD 0 #define STV090x_WIDTH_ERRORx_XOR_FIELD 1 -#define STV090x_DPNxCFG(__x) (0xf15c + (__x - 1) * 0x5) +#define STV090x_DPNxCFG(__x) (0xf15c + (__x - 1) * 0x5) #define STV090x_DPN1CFG STV090x_DPNxCFG(1) -#define STV090x_DPN2CFG STV090x_DPNxCFG(2) +#define STV090x_DPN2CFG STV090x_DPNxCFG(2) #define STV090x_DPN3CFG STV090x_DPNxCFG(3) #define STV090x_OFFST_DPNx_OPD_FIELD 7 #define STV090x_WIDTH_DPNx_OPD_FIELD 1 @@ -571,8 +573,8 @@ #define STV090x_WIDTH_FSKR_CARLOSS_THRESH_FIELD 8 #define STV090x_Px_DISTXCTL(__x) (0xF1A0 - (__x - 1) * 0x10) -#define STV090x_P1_DISTXCTL (1) -#define STV090x_P2_DISTXCTL (2) +#define STV090x_P1_DISTXCTL STV090x_Px_DISTXCTL(1) +#define STV090x_P2_DISTXCTL STV090x_Px_DISTXCTL(2) #define STV090x_OFFST_Px_TIM_OFF_FIELD 7 #define STV090x_WIDTH_Px_TIM_OFF_FIELD 1 #define STV090x_OFFST_Px_DISEQC_RESET_FIELD 6 @@ -585,8 +587,8 @@ #define STV090x_WIDTH_Px_DISTX_MODE_FIELD 3 #define STV090x_Px_DISRXCTL(__x) (0xf1a1 - (__x - 1) * 0x10) -#define STV090x_P1_DISRXCTL (1) -#define STV090x_P2_DISRXCTL (2) +#define STV090x_P1_DISRXCTL STV090x_Px_DISRXCTL(1) +#define STV090x_P2_DISRXCTL STV090x_Px_DISRXCTL(2) #define STV090x_OFFST_Px_RECEIVER_ON_FIELD 7 #define STV090x_WIDTH_Px_RECEIVER_ON_FIELD 1 #define STV090x_OFFST_Px_IGNO_SHORT22K_FIELD 6 @@ -603,8 +605,8 @@ #define STV090x_WIDTH_Px_IRQ_4NBYTES_FIELD 1 #define STV090x_Px_DISRX_ST0(__x) (0xf1a4 - (__x - 1) * 0x10) -#define STV090x_P1_DISRX_ST0 (1) -#define STV090x_P2_DISRX_ST0 (2) +#define STV090x_P1_DISRX_ST0 STV090x_Px_DISRX_ST0(1) +#define STV090x_P2_DISRX_ST0 STV090x_Px_DISRX_ST0(2) #define STV090x_OFFST_Px_RX_END_FIELD 7 #define STV090x_WIDTH_Px_RX_END_FIELD 1 #define STV090x_OFFST_Px_RX_ACTIVE_FIELD 6 @@ -621,8 +623,8 @@ #define STV090x_WIDTH_Px_ABORT_DISRX_FIELD 1 #define STV090x_Px_DISRX_ST1(__x) (0xf1a5 - (__x - 1) * 0x10) -#define STV090x_P1_DISRX_ST1 (1) -#define STV090x_P2_DISRX_ST1 (2) +#define STV090x_P1_DISRX_ST1 STV090x_Px_DISRX_ST1(1) +#define STV090x_P2_DISRX_ST1 STV090x_Px_DISRX_ST1(2) #define STV090x_OFFST_Px_RX_FAIL_FIELD 7 #define STV090x_WIDTH_Px_RX_FAIL_FIELD 1 #define STV090x_OFFST_Px_FIFO_PARITYFAIL_FIELD 6 @@ -635,20 +637,20 @@ #define STV090x_WIDTH_Px_FIFO_BYTENBR_FIELD 4 #define STV090x_Px_DISRXDATA(__x) (0xf1a6 - (__x - 1) * 0x10) -#define STV090x_P1_DISRXDATA (1) -#define STV090x_P2_DISRXDATA (2) +#define STV090x_P1_DISRXDATA STV090x_Px_DISRXDATA(1) +#define STV090x_P2_DISRXDATA STV090x_Px_DISRXDATA(2) #define STV090x_OFFST_Px_DISRX_DATA_FIELD 0 #define STV090x_WIDTH_Px_DISRX_DATA_FIELD 8 #define STV090x_Px_DISTXDATA(__x) (0xf1a7 - (__x - 1) * 0x10) -#define STV090x_P1_DISTXDATA (1) -#define STV090x_P2_DISTXDATA (2) +#define STV090x_P1_DISTXDATA STV090x_Px_DISTXDATA(1) +#define STV090x_P2_DISTXDATA STV090x_Px_DISTXDATA(2) #define STV090x_OFFST_Px_DISEQC_FIFO_FIELD 0 #define STV090x_WIDTH_Px_DISEQC_FIFO_FIELD 8 #define STV090x_Px_DISTXSTATUS(__x) (0xf1a8 - (__x - 1) * 0x10) -#define STV090x_P1_DISTXSTATUS (1) -#define STV090x_P2_DISTXSTATUS (2) +#define STV090x_P1_DISTXSTATUS STV090x_Px_DISTXSTATUS(1) +#define STV090x_P2_DISTXSTATUS STV090x_Px_DISTXSTATUS(2) #define STV090x_OFFST_Px_TX_FAIL_FIELD 7 #define STV090x_WIDTH_Px_TX_FAIL_FIELD 1 #define STV090x_OFFST_Px_FIFO_FULL_FIELD 6 @@ -661,26 +663,26 @@ #define STV090x_WIDTH_Px_TXFIFO_BYTES_FIELD 4 #define STV090x_Px_F22TX(__x) (0xf1a9 - (__x - 1) * 0x10) -#define STV090x_P1_F22TX (1) -#define STV090x_P2_F22TX (2) +#define STV090x_P1_F22TX STV090x_Px_F22TX(1) +#define STV090x_P2_F22TX STV090x_Px_F22TX(2) #define STV090x_OFFST_Px_F22_REG_FIELD 0 #define STV090x_WIDTH_Px_F22_REG_FIELD 8 #define STV090x_Px_F22RX(__x) (0xf1aa - (__x - 1) * 0x10) -#define STV090x_P1_F22RX (1) -#define STV090x_P2_F22RX (2) +#define STV090x_P1_F22RX STV090x_Px_F22RX(1) +#define STV090x_P2_F22RX STV090x_Px_F22RX(2) #define STV090x_OFFST_Px_F22RX_REG_FIELD 0 #define STV090x_WIDTH_Px_F22RX_REG_FIELD 8 #define STV090x_Px_ACRPRESC(__x) (0xf1ac - (__x - 1) * 0x10) -#define STV090x_P1_ACRPRESC (1) -#define STV090x_P2_ACRPRESC (2) +#define STV090x_P1_ACRPRESC STV090x_Px_ACRPRESC(1) +#define STV090x_P2_ACRPRESC STV090x_Px_ACRPRESC(2) #define STV090x_OFFST_Px_ACR_PRESC_FIELD 0 #define STV090x_WIDTH_Px_ACR_PRESC_FIELD 3 #define STV090x_Px_ACRDIV(__x) (0xf1ad - (__x - 1) * 0x10) -#define STV090x_P1_ACRDIV (1) -#define STV090x_P2_ACRDIV (2) +#define STV090x_P1_ACRDIV STV090x_Px_ACRDIV(1) +#define STV090x_P2_ACRDIV STV090x_Px_ACRDIV(2) #define STV090x_OFFST_Px_ACR_DIV_FIELD 0 #define STV090x_WIDTH_Px_ACR_DIV_FIELD 8 @@ -892,6 +894,10 @@ #define STV090x_OFFST_Px_NOSTOP_FIFOFULL_FIELD 3 #define STV090x_WIDTH_Px_NOSTOP_FIFOFULL_FIELD 1 +#define STV090x_Px_DMDCFG4(__x) (0xf41f - (__x - 1) * 0x200) +#define STV090x_P1_DMDCFG4 STV090x_Px_DMDCFG4(1) +#define STV090x_P2_DMDCFG4 STV090x_Px_DMDCFG4(2) + #define STV090x_Px_CORRELMANT(__x) (0xF420 - (__x - 1) * 0x200) #define STV090x_P1_CORRELMANT STV090x_Px_CORRELMANT(1) #define STV090x_P2_CORRELMANT STV090x_Px_CORRELMANT(2) @@ -922,6 +928,14 @@ #define STV090x_OFFST_Px_PLH_TYPE_FIELD 0 #define STV090x_WIDTH_Px_PLH_TYPE_FIELD 2 +#define STV090x_Px_AGCK32(__x) (0xf42b - (__x - 1) * 0x200) +#define STV090x_P1_AGCK32 STV090x_Px_AGCK32(1) +#define STV090x_P2_AGCK32 STV090x_Px_AGCK32(2) + +#define STV090x_Px_AGC2O(__x) (0xF42C - (__x - 1) * 0x200) +#define STV090x_P1_AGC2O STV090x_Px_AGC2O(1) +#define STV090x_P2_AGC2O STV090x_Px_AGC2O(2) + #define STV090x_Px_AGC2REF(__x) (0xF42D - (__x - 1) * 0x200) #define STV090x_P1_AGC2REF STV090x_Px_AGC2REF(1) #define STV090x_P2_AGC2REF STV090x_Px_AGC2REF(2) @@ -1640,7 +1654,7 @@ #define STV090x_OFFST_Px_SMAPCOEF_8P_LLR23_FIELD 0 #define STV090x_WIDTH_Px_SMAPCOEF_8P_LLR23_FIELD 7 -#define STV090x_Px_DMDPLHSTAT(__x) (0xF520 - (__x - 1) * 0x200) +#define STV090x_Px_DMDPLHSTAT(__x) (0xF520 - (__x - 1) * 0x200) #define STV090x_P1_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(1) #define STV090x_P2_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(2) #define STV090x_OFFST_Px_PLH_STATISTIC_FIELD 0 @@ -2281,12 +2295,17 @@ #define STV090x_OFFST_Px_FSPYBER_CTIME_FIELD 0 #define STV090x_WIDTH_Px_FSPYBER_CTIME_FIELD 3 +#define STV090x_RCCFGH 0xf600 + #define STV090x_TSGENERAL 0xF630 #define STV090x_OFFST_Px_MUXSTREAM_OUT_FIELD 3 #define STV090x_WIDTH_Px_MUXSTREAM_OUT_FIELD 1 #define STV090x_OFFST_Px_TSFIFO_PERMPARAL_FIELD 1 #define STV090x_WIDTH_Px_TSFIFO_PERMPARAL_FIELD 2 +#define STV090x_TSGENERAL1X 0xf670 +#define STV090x_CFGEXT 0xfa80 + #define STV090x_TSTRES0 0xFF11 #define STV090x_OFFST_FRESFEC_FIELD 7 #define STV090x_WIDTH_FRESFEC_FIELD 1 -- cgit v1.1 From 54d859ec563d2f0cbbc03e45e204325c5f2118bf Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Tue, 7 Apr 2009 16:09:52 -0300 Subject: V4L/DVB (11583): isl6423: Various fixes to use external modulation Use external modulation Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/isl6423.c | 35 +++++++++++++++++++++++++---------- drivers/media/dvb/ttpci/budget-ci.c | 1 + 2 files changed, 26 insertions(+), 10 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/isl6423.c b/drivers/media/dvb/frontends/isl6423.c index c1943dc..dca5beb 100644 --- a/drivers/media/dvb/frontends/isl6423.c +++ b/drivers/media/dvb/frontends/isl6423.c @@ -73,6 +73,7 @@ static int isl6423_write(struct isl6423_dev *isl6423, u8 reg) struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = ®, .len = 1 }; + dprintk(FE_DEBUG, 1, "write reg %02X", reg); err = i2c_transfer(i2c, &msg, 1); if (err < 0) goto exit; @@ -133,6 +134,9 @@ static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg) if (err < 0) goto exit; + isl6423->reg_3 = reg_3; + isl6423->reg_4 = reg_4; + return 0; exit: dprintk(FE_ERROR, 1, "I/O error <%d>", err); @@ -144,12 +148,10 @@ static int isl6423_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; + u8 reg_3 = isl6423->reg_3; u8 reg_4 = isl6423->reg_4; int err = 0; - /* SR4H = 0, SR4M = 1, SR4L = 1 */ - reg_4 = 0x03 << 5; - switch (voltage) { case SEC_VOLTAGE_OFF: /* EN = 0 */ @@ -160,6 +162,7 @@ static int isl6423_set_voltage(struct dvb_frontend *fe, /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */ reg_4 |= (1 << 4); reg_4 &= ~0x3; + reg_3 |= (1 << 3); break; case SEC_VOLTAGE_18: @@ -167,15 +170,23 @@ static int isl6423_set_voltage(struct dvb_frontend *fe, reg_4 |= (1 << 4); reg_4 |= 0x2; reg_4 &= ~0x1; + reg_3 |= (1 << 3); break; default: break; } + err = isl6423_write(isl6423, reg_3); + if (err < 0) + goto exit; + err = isl6423_write(isl6423, reg_4); if (err < 0) goto exit; + isl6423->reg_3 = reg_3; + isl6423->reg_4 = reg_4; + return 0; exit: dprintk(FE_ERROR, 1, "I/O error <%d>", err); @@ -189,9 +200,6 @@ static int isl6423_set_current(struct dvb_frontend *fe) const struct isl6423_config *config = isl6423->config; int err = 0; - /* SR3H = 0, SR3M = 1, SR3L = 0 */ - reg_3 = 0x02 << 5; - switch (config->current_max) { case SEC_CURRENT_275m: /* 275mA */ @@ -226,13 +234,13 @@ static int isl6423_set_current(struct dvb_frontend *fe) switch (config->curlim) { case SEC_CURRENT_LIM_ON: - /* DCL = 1 */ - reg_3 |= 0x10; + /* DCL = 0 */ + reg_3 &= ~0x10; break; case SEC_CURRENT_LIM_OFF: - /* DCL = 0 */ - reg_3 &= ~0x10; + /* DCL = 1 */ + reg_3 |= 0x10; break; } @@ -240,6 +248,8 @@ static int isl6423_set_current(struct dvb_frontend *fe) if (err < 0) goto exit; + isl6423->reg_3 = reg_3; + return 0; exit: dprintk(FE_ERROR, 1, "I/O error <%d>", err); @@ -268,6 +278,11 @@ struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, isl6423->i2c = i2c; fe->sec_priv = isl6423; + /* SR3H = 0, SR3M = 1, SR3L = 0 */ + isl6423->reg_3 = 0x02 << 5; + /* SR4H = 0, SR4M = 1, SR4L = 1 */ + isl6423->reg_4 = 0x03 << 5; + if (isl6423_set_current(fe)) goto exit; diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index dbdc795..e1c83c5 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -1383,6 +1383,7 @@ static struct stv6110x_config tt1600_stv6110x_config = { static struct isl6423_config tt1600_isl6423_config = { .current_max = SEC_CURRENT_515m, .curlim = SEC_CURRENT_LIM_ON, + .mod_extern = 1, .addr = 0x08, }; -- cgit v1.1 From f9ed95d03e3a736627493690bfd1cb893ebaa200 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Wed, 8 Apr 2009 17:27:51 -0300 Subject: V4L/DVB (11584): stv090x: add tone burst control Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index b450bf1..0643bff 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3360,6 +3360,15 @@ static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma int i; reg = STV090x_READ_DEMOD(state, DISTXCTL); + + STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 2); + STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1); if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) goto err; @@ -3373,8 +3382,64 @@ static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0) goto err; + } + reg = STV090x_READ_DEMOD(state, DISTXCTL); + STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + + i = 0; + + while ((!idle) && (i < 10)) { + reg = STV090x_READ_DEMOD(state, DISTXSTATUS); + idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD); + msleep(10); i++; } + + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) +{ + struct stv090x_state *state = fe->demodulator_priv; + u32 reg, idle = 0, fifo_full = 1; + u8 mode, value; + int i; + + reg = STV090x_READ_DEMOD(state, DISTXCTL); + + if (burst == SEC_MINI_A) { + mode = 3; + value = 0x00; + } else { + mode = 2; + value = 0xFF; + } + + STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode); + STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + + STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1); + if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) + goto err; + + while (fifo_full) { + reg = STV090x_READ_DEMOD(state, DISTXSTATUS); + fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD); + } + + if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0) + goto err; + reg = STV090x_READ_DEMOD(state, DISTXCTL); STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0); if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) @@ -3882,6 +3947,7 @@ static struct dvb_frontend_ops stv090x_ops = { .i2c_gate_ctrl = stv090x_i2c_gate_ctrl, .diseqc_send_master_cmd = stv090x_send_diseqc_msg, + .diseqc_send_burst = stv090x_send_diseqc_burst, .diseqc_recv_slave_reply = stv090x_recv_slave_reply, .set_tone = stv090x_set_tone, -- cgit v1.1 From 72982f761526278e1ca7dce0507ed9f33b952fee Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Wed, 8 Apr 2009 17:28:41 -0300 Subject: V4L/DVB (11585): stv090x: fix incorrectly used mode Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 0643bff..6aaeda1 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -1922,7 +1922,7 @@ static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s inc *= 256; inc /= 1000; - switch (state->algo) { + switch (state->search_mode) { case STV090x_SEARCH_DVBS1: case STV090x_SEARCH_DSS: inc *= 3; /* freq step = 3% of srate */ @@ -2073,7 +2073,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max); /* get params */ - switch (state->algo) { + switch (state->search_mode) { case STV090x_SEARCH_DVBS1: case STV090x_SEARCH_DSS: /* accelerate the frequency detector */ -- cgit v1.1 From 26b03bc6c2fa72e3aaed19fba125c2f438bf9261 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 8 Apr 2009 18:27:10 -0300 Subject: V4L/DVB (11586): stv090x: switch i/p ADC as well during Power management Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 6aaeda1..4dc723c 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3494,6 +3494,11 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) goto err; + reg = stv090x_read_reg(state, STV090x_TSTTNR1); + STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); + if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) + goto err; + return 0; err: dprintk(FE_ERROR, 1, "I/O error"); @@ -3513,6 +3518,11 @@ static int stv090x_wakeup(struct dvb_frontend *fe) if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) goto err; + reg = stv090x_read_reg(state, STV090x_TSTTNR1); + STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1); + if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) + goto err; + return 0; err: dprintk(FE_ERROR, 1, "I/O error"); -- cgit v1.1 From 94a809143a47343b45c73e84f7f26e3087c2fd62 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 8 Apr 2009 19:45:43 -0300 Subject: V4L/DVB (11587): stv090x: set DiSEqC frequency to 22kHz Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 4dc723c..a350364 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3623,6 +3623,13 @@ static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk) state->mclk = stv090x_get_mclk(state); + /*Set the DiseqC frequency to 22KHz */ + div = state->mclk / 704000; + if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0) + goto err; + return 0; err: dprintk(FE_ERROR, 1, "I/O error"); -- cgit v1.1 From 15bb366e86e07820374ec313170aab65d4e1d983 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 8 Apr 2009 20:14:00 -0300 Subject: V4L/DVB (11588): stv090x: support > 60MSPS, simplify Srate calculation Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 60 +++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index a350364..6e7c47a 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -725,18 +725,22 @@ static int stv090x_set_srate(struct stv090x_state *state, u32 srate) { u32 sym; - if (srate > 6000000) { - sym = (srate / 1000) * 65536; - sym /= (state->mclk / 1000); + if (srate > 60000000) { + sym = (srate << 4); /* SR * 2^16 / master_clk */ + sym /= (state->mclk >> 12); + } else if (srate > 6000000) { + sym = (srate << 6); + sym /= (state->mclk >> 10); } else { - sym = (srate / 100) * 65536; - sym /= (state->mclk / 100); + sym = (srate << 9); + sym /= (state->mclk >> 7); } - if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) /* MSB */ + if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */ goto err; if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */ goto err; + return 0; err: dprintk(FE_ERROR, 1, "I/O error"); @@ -748,17 +752,29 @@ static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate u32 sym; srate = 105 * (srate / 100); - if (srate > 6000000) { - sym = (srate / 1000) * 65536; - sym /= (clk / 1000); + if (srate > 60000000) { + sym = (srate << 4); /* SR * 2^16 / master_clk */ + sym /= (state->mclk >> 12); + } else if (srate > 6000000) { + sym = (srate << 6); + sym /= (state->mclk >> 10); } else { - sym = (srate / 100) * 65536; - sym /= (clk / 100); + sym = (srate << 9); + sym /= (state->mclk >> 7); } - if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */ - goto err; - if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */ - goto err; + + if (sym < 0x7fff) { + if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */ + goto err; + if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */ + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */ + goto err; + if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */ + goto err; + } + return 0; err: dprintk(FE_ERROR, 1, "I/O error"); @@ -770,13 +786,17 @@ static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate u32 sym; srate = 95 * (srate / 100); - if (srate > 6000000) { - sym = (srate / 1000) * 65536; - sym /= (clk / 1000); + if (srate > 60000000) { + sym = (srate << 4); /* SR * 2^16 / master_clk */ + sym /= (state->mclk >> 12); + } else if (srate > 6000000) { + sym = (srate << 6); + sym /= (state->mclk >> 10); } else { - sym = (srate / 100) * 65536; - sym /= (clk / 100); + sym = (srate << 9); + sym /= (state->mclk >> 7); } + if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */ goto err; if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */ -- cgit v1.1 From f430fff101dd2cdbf5db1cf274a1591ae2b6e05c Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 8 Apr 2009 20:18:50 -0300 Subject: V4L/DVB (11589): stv090x: code simplification Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 6e7c47a..fee7917 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -1368,7 +1368,6 @@ static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk) { u8 r3, r2, r1, r0; s32 srate, int_1, int_2, tmp_1, tmp_2; - u32 pow2; r3 = STV090x_READ_DEMOD(state, SFR3); r2 = STV090x_READ_DEMOD(state, SFR2); @@ -1377,16 +1376,15 @@ static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk) srate = ((r3 << 24) | (r2 << 16) | (r1 << 8) | r0); - pow2 = 1 << 16; - int_1 = clk / pow2; - int_2 = srate / pow2; + int_1 = clk >> 16; + int_2 = srate >> 16; - tmp_1 = clk % pow2; - tmp_2 = srate % pow2; + tmp_1 = clk % 0x10000; + tmp_2 = srate % 0x10000; srate = (int_1 * int_2) + - ((int_1 * tmp_2) / pow2) + - ((int_2 * tmp_1) / pow2); + ((int_1 * tmp_2) >> 16) + + ((int_2 * tmp_1) >> 16); return srate; } -- cgit v1.1 From 5f99feffc0426f88db07e2d777d9dd4aa2205c2f Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 8 Apr 2009 20:24:53 -0300 Subject: V4L/DVB (11590): stv090x: code simplification Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index fee7917..b3a0279 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -2351,19 +2351,16 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate) { s32 offst_tmg; - s32 pow2; offst_tmg = STV090x_READ_DEMOD(state, TMGREG2) << 16; offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) << 8; offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0); - pow2 = 1 << 24; - offst_tmg = comp2(offst_tmg, 24); /* 2's complement */ if (!offst_tmg) offst_tmg = 1; - offst_tmg = ((s32) srate * 10) / (pow2 / offst_tmg); + offst_tmg = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg); offst_tmg /= 320; return offst_tmg; -- cgit v1.1 From da4b9059c948ce35ce9d34b982b6a9934a9251ef Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Wed, 8 Apr 2009 20:30:29 -0300 Subject: V4L/DVB (11591): stv090x: code simplification Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index b3a0279..3e0acd7 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -2222,23 +2222,22 @@ static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state) static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk) { s32 derot, int_1, int_2, tmp_1, tmp_2; - u32 pow2; derot = STV090x_READ_DEMOD(state, CFR2) << 16; derot |= STV090x_READ_DEMOD(state, CFR1) << 8; derot |= STV090x_READ_DEMOD(state, CFR0); derot = comp2(derot, 24); - pow2 = 1 << 12; - int_1 = state->mclk / pow2; - int_2 = derot / pow2; + int_1 = state->mclk >> 12; + int_2 = derot >> 12; - tmp_1 = state->mclk % pow2; - tmp_2 = derot % pow2; + /* carrier_frequency = MasterClock * Reg / 2^24 */ + tmp_1 = state->mclk % 0x1000; + tmp_2 = derot % 0x1000; derot = (int_1 * int_2) + - ((int_1 * tmp_2) / pow2) + - ((int_1 * tmp_1) / pow2); + ((int_1 * tmp_2) >> 12) + + ((int_1 * tmp_1) >> 12); return derot; } -- cgit v1.1 From f2b2fd401343b188f251b29ec2981ea8054ce1b7 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 16 Apr 2009 08:38:46 -0300 Subject: V4L/DVB (11592): stv6110x: Fix read bug Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv6110x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c index 7386181..3d8a2e0 100644 --- a/drivers/media/dvb/frontends/stv6110x.c +++ b/drivers/media/dvb/frontends/stv6110x.c @@ -53,6 +53,7 @@ static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) dprintk(FE_ERROR, 1, "I/O Error"); return -EREMOTEIO; } + *data = b1[0]; return 0; } -- cgit v1.1 From 4e58a6827a7d67f65d166d28635ac13bdf65dbb0 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 16 Apr 2009 08:40:36 -0300 Subject: V4L/DVB (11593): stv090x: Fix Rolloff Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 37 +++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 3e0acd7..db3c091 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -807,9 +807,24 @@ err: return -1; } -static u32 stv090x_car_width(u32 srate, u32 rolloff) +static u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff) { - return srate + (srate * rolloff) / 100; + u32 ro; + + switch (rolloff) { + case STV090x_RO_20: + ro = 20; + break; + case STV090x_RO_25: + ro = 25; + break; + case STV090x_RO_35: + default: + ro = 35; + break; + } + + return srate + (srate * ro) / 100; } static int stv090x_set_vit_thacq(struct stv090x_state *state) @@ -1148,12 +1163,12 @@ static int stv090x_delivery_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) goto err; - if (stv090x_vitclk_ctl(state, 1) < 0) + if (stv090x_vitclk_ctl(state, 0) < 0) goto err; if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, ACLC, 0x09) < 0) + if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) goto err; if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) goto err; @@ -2904,7 +2919,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) enum stv090x_signal_state signal_state = STV090x_NOCARRIER; u32 reg; s32 timeout_dmd = 500, timeout_fec = 50; - int lock = 0, low_sr, no_signal = 0; + int lock = 0, low_sr = 0, no_signal = 0; reg = STV090x_READ_DEMOD(state, TSCFGH); STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */ @@ -2948,7 +2963,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) goto err; if (state->algo == STV090x_COLD_SEARCH) - state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 1000000)) / 10; + state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10; else if (state->algo == STV090x_WARM_SEARCH) state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000; } else { @@ -2963,6 +2978,8 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) stv090x_set_min_srate(state, state->mclk, state->srate); if (state->srate >= 10000000) + low_sr = 0; + else low_sr = 1; } @@ -3000,7 +3017,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) goto err; stv090x_delivery_search(state); - if (state->algo == STV090x_BLIND_SEARCH) + if (state->algo != STV090x_BLIND_SEARCH) stv090x_start_search(state); if (state->dev_ver == 0x12) { @@ -3117,6 +3134,10 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron state->delsys = props->delivery_system; state->frequency = p->frequency; state->srate = p->u.qpsk.symbol_rate; + state->search_mode = STV090x_SEARCH_AUTO; + state->algo = STV090x_COLD_SEARCH; + state->fec = STV090x_PRERR; + state->search_range = 2000000; if (!stv090x_algo(state)) { dprintk(FE_DEBUG, 1, "Search success!"); @@ -4008,7 +4029,7 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, state->demod = demod; state->demod_mode = config->demod_mode; /* Single or Dual mode */ state->device = config->device; - state->rolloff = 35; /* default */ + state->rolloff = STV090x_RO_35; /* default */ if (state->demod == STV090x_DEMODULATOR_0) mutex_init(&demod_lock); -- cgit v1.1 From 64104dc9014d717335ed8ff987feaec1b17c1cd5 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 16 Apr 2009 08:43:41 -0300 Subject: V4L/DVB (11594): stv090x: Fix incorrect TSMODE usage Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 16 ++++++++-------- drivers/media/dvb/ttpci/budget-ci.c | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index db3c091..3601132 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3813,34 +3813,34 @@ static int stv090x_set_tspath(struct stv090x_state *state) switch (state->config->ts2_mode) { case STV090x_TSMODE_PARALLEL_PUNCTURED: - reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); - if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) goto err; break; case STV090x_TSMODE_DVBCI: - reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); - if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) goto err; break; case STV090x_TSMODE_SERIAL_PUNCTURED: - reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); - if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) goto err; break; case STV090x_TSMODE_SERIAL_CONTINUOUS: - reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); + reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); - if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) + if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) goto err; break; diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index e1c83c5..351481d 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -1358,8 +1358,8 @@ static struct stv090x_config tt1600_stv090x_config = { .address = 0x68, .ref_clk = 27000000, - .ts1_mode = STV090x_TSMODE_DVBCI, - .ts2_mode = STV090x_TSMODE_DVBCI, + .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED, + .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, .repeater_level = STV090x_RPTLEVEL_16, -- cgit v1.1 From 2f5914be7c2277cf19699e437cf2c6c15556a085 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 23 Apr 2009 14:56:41 -0300 Subject: V4L/DVB (11595): stv090x: fixes a few bugs This patch fixes: * Cut revision was read too late * Missing increment * wrong return value * mismatched entries Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 3601132..004b774 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -1943,6 +1943,7 @@ static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s srate = state->srate; car_max = state->search_range / 1000; + car_max += car_max / 10; car_max = 65536 * (car_max / 2); car_max /= (state->mclk / 1000); @@ -2003,6 +2004,7 @@ static int stv090x_chk_signal(struct stv090x_state *state) offst_car = STV090x_READ_DEMOD(state, CFR2) << 8; offst_car |= STV090x_READ_DEMOD(state, CFR1); + offst_car = comp2(offst_car, 16); agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8; agc2 |= STV090x_READ_DEMOD(state, AGC2I0); @@ -2065,6 +2067,9 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x1); if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) goto err; + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x0); + if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + goto err; } if (zigzag) { @@ -2076,6 +2081,8 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim offst_freq += 2 * inc; } + cpt_step++; + lock = stv090x_get_dmdlock(state, timeout); no_signal = stv090x_chk_signal(state); @@ -2149,7 +2156,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x68) < 0) goto err; } - if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x69) < 0) + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0) goto err; zigzag = 0; break; @@ -2310,7 +2317,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st if (state->algo == STV090x_BLIND_SEARCH) { tmg = STV090x_READ_DEMOD(state, TMGREG2); STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c); - while ((i <= 50) && (!tmg) && (tmg != 0xff)) { + while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) { tmg = STV090x_READ_DEMOD(state, TMGREG2); msleep(5); i += 5; @@ -2347,7 +2354,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st stv090x_i2c_gate_ctrl(fe, 0); if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) - return STV090x_RANGEOK; + return STV090x_RANGEOK; else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000)) return STV090x_RANGEOK; else @@ -2569,8 +2576,8 @@ static int stv090x_optimize_track(struct stv090x_state *state) case STV090x_DVBS2: reg = STV090x_READ_DEMOD(state, DMDCFGMD); - STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); - STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); + STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); + STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) goto err; if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0) @@ -3115,7 +3122,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if ((signal_state == STV090x_NODATA) && (!no_signal)) { if (state->dev_ver <= 0x11) { reg = STV090x_READ_DEMOD(state, DMDSTATE); - if (((STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD)) == STV090x_DVBS2) && (state->inversion == INVERSION_AUTO)) + if (((STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD)) == STV090x_DVBS1) && (state->inversion == INVERSION_AUTO)) signal_state = stv090x_acq_fixs1(state); } } @@ -3139,7 +3146,7 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron state->fec = STV090x_PRERR; state->search_range = 2000000; - if (!stv090x_algo(state)) { + if (stv090x_algo(state) == STV090x_RANGEOK) { dprintk(FE_DEBUG, 1, "Search success!"); return DVBFE_ALGO_SEARCH_SUCCESS; } else { @@ -3949,12 +3956,13 @@ static int stv090x_setup(struct dvb_frontend *fe) msleep(5); /* write initval */ + dprintk(FE_DEBUG, 1, "Setting up initial values"); for (i = 0; i < t1_size; i++) { - dprintk(FE_DEBUG, 1, "Setting up initial values"); if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0) goto err; } + state->dev_ver = stv090x_read_reg(state, STV090x_MID); if (state->dev_ver >= 0x20) { if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) goto err; @@ -4047,7 +4055,6 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, dprintk(FE_ERROR, 1, "Error waking device"); goto error; } - state->dev_ver = stv090x_read_reg(state, STV090x_MID); dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n", state->device == STV0900 ? "STV0900" : "STV0903", -- cgit v1.1 From 94871465b6a82de3882a61bf1e3c202725688294 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 23 Apr 2009 14:57:24 -0300 Subject: V4L/DVB (11596): stv090x: fixes some register definitions Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x_reg.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h index 0dff56d..5573707 100644 --- a/drivers/media/dvb/frontends/stv090x_reg.h +++ b/drivers/media/dvb/frontends/stv090x_reg.h @@ -470,7 +470,7 @@ #define STV090x_FSKTCTRL 0xf175 #define STV090x_OFFST_FSKT_EN_SGN_FIELD 6 -#define STV090x_WIDTH_FSKT_EN_SGN__FIELD 1 +#define STV090x_WIDTH_FSKT_EN_SGN_FIELD 1 #define STV090x_OFFST_FSKT_MOD_SGN_FIELD 5 #define STV090x_WIDTH_FSKT_MOD_SGN_FIELD 1 #define STV090x_OFFST_FSKT_MOD_EN_FIELD 2 @@ -616,7 +616,7 @@ #define STV090x_OFFST_Px_CONT_TONE_FIELD 4 #define STV090x_WIDTH_Px_CONT_TONE_FIELD 1 #define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3 -#define STV090x_WIDTH_Px_FIFO_4BREADYFIELD 2 +#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 2 #define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2 #define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1 #define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0 @@ -1385,8 +1385,8 @@ #define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4 #define STV090x_Px_ACLC2S232A(__x) (0xf499 - (__x - 1) * 0x200) -#define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S216A(1) -#define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S216A(2) +#define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S232A(1) +#define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S232A(2) #define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4 #define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_M_FIELD 2 #define STV090x_OFFST_Px_CAR2S2_32A_ALPH_E_FIELD 0 @@ -1720,7 +1720,7 @@ #define STV090x_Px_VTH34(__x) (0xf536 - (__x - 1) * 0x200) #define STV090x_P1_VTH34 STV090x_Px_VTH34(1) - #define STV090x_P2_VTH34 STV090x_Px_VTH34(2) +#define STV090x_P2_VTH34 STV090x_Px_VTH34(2) #define STV090x_OFFST_Px_VTH34_FIELD 0 #define STV090x_WIDTH_Px_VTH34_FIELD 8 @@ -1763,7 +1763,7 @@ #define STV090x_WIDTH_Px_E7_8VIT_FIELD 1 #define STV090x_OFFST_Px_E6_7VIT_FIELD 4 #define STV090x_WIDTH_Px_E6_7VIT_FIELD 1 -#define STV090x_OFFST_Px_E5_6VIT_FIELD_ 3 +#define STV090x_OFFST_Px_E5_6VIT_FIELD 3 #define STV090x_WIDTH_Px_E5_6VIT_FIELD 1 #define STV090x_OFFST_Px_E3_4VIT_FIELD 2 #define STV090x_WIDTH_Px_E3_4VIT_FIELD 1 @@ -1856,13 +1856,13 @@ #define STV090x_OFFST_Px_UNLCK_THRESH_FIELD 4 #define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD 4 #define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD 0 -#define STV090x_WIDTH_Px_DELIN_LCK_THRESH__FIELD 4 +#define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD 4 #define STV090x_Px_ISIENTRY(__x) (0xf55e - (__x - 1) * 0x200) #define STV090x_P1_ISIENTRY STV090x_Px_ISIENTRY(1) #define STV090x_P2_ISIENTRY STV090x_Px_ISIENTRY(2) #define STV090x_OFFST_Px_ISI_ENTRY_FIELD 0 -#define STV090x_WIDTH_Px_ISI_ENTRY__FIELD 8 +#define STV090x_WIDTH_Px_ISI_ENTRY_FIELD 8 #define STV090x_Px_ISIBITENA(__x) (0xf55f - (__x - 1) * 0x200) #define STV090x_P1_ISIBITENA STV090x_Px_ISIBITENA(1) @@ -1968,7 +1968,7 @@ #define STV090x_OFFST_NBITER_STOP_CRIT_FIELD 0 #define STV090x_WIDTH_NBITER_STOP_CRIT_FIELD 4 -#define STV090x_GAINLLR_NFx(__x) (0xFA43 + (__x - 4) * 0x1) +#define STV090x_GAINLLR_NFx(__x) (0xFA43 + (__x - 4) * 0x1) #define STV090x_GAINLLR_NF4 STV090x_GAINLLR_NFx(4) #define STV090x_OFFST_GAINLLR_NF_QP_1_2_FIELD 0 #define STV090x_WIDTH_GAINLLR_NF_QP_1_2_FIELD 7 @@ -1999,7 +1999,7 @@ #define STV090x_GAINLLR_NF11 STV090x_GAINLLR_NFx(11) #define STV090x_OFFST_GAINLLR_NF_QP_9_10_FIELD 0 -#define STV090x_WIDTH_GAINLLR_NF_QP_9_10IELD 7 +#define STV090x_WIDTH_GAINLLR_NF_QP_9_10_FIELD 7 #define STV090x_GAINLLR_NF12 STV090x_GAINLLR_NFx(12) #define STV090x_OFFST_GAINLLR_NF_8P_3_5_FIELD 0 @@ -2079,7 +2079,7 @@ #define STV090x_OFFST_Px_TSFIFO_PERMDATA_FIELD 5 #define STV090x_WIDTH_Px_TSFIFO_PERMDATA_FIELD 1 #define STV090x_OFFST_Px_TSFIFO_INVDATA_FIELD 0 -#define STV090x_WIDTH_Px_TSFIFO_INVDATA__FIELD 1 +#define STV090x_WIDTH_Px_TSFIFO_INVDATA_FIELD 1 #define STV090x_Px_TSCFGL(__x) (0xF574 - (__x - 1) * 0x200) #define STV090x_P1_TSCFGL STV090x_Px_TSCFGL(1) @@ -2089,7 +2089,7 @@ #define STV090x_OFFST_Px_BCHERROR_MODE_FIELD 4 #define STV090x_WIDTH_Px_BCHERROR_MODE_FIELD 2 #define STV090x_OFFST_Px_TSFIFO_NSGNL2DATA_FIELD 3 -#define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA__FIELD 1 +#define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA_FIELD 1 #define STV090x_OFFST_Px_TSFIFO_EMBINDVB_FIELD 2 #define STV090x_WIDTH_Px_TSFIFO_EMBINDVB_FIELD 1 #define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD 1 @@ -2150,7 +2150,7 @@ #define STV090x_Px_ERRCNT12(__x) (0xF599 - (__x - 1) * 0x200) #define STV090x_P1_ERRCNT12 STV090x_Px_ERRCNT12(1) #define STV090x_P2_ERRCNT12 STV090x_Px_ERRCNT12(2) -#define STV090x_OFFST_Px_ERRCNT1_OLDVALUE__FIELD 7 +#define STV090x_OFFST_Px_ERRCNT1_OLDVALUE_FIELD 7 #define STV090x_WIDTH_Px_ERRCNT1_OLDVALUE_FIELD 1 #define STV090x_OFFST_Px_ERR_CNT12_FIELD 0 #define STV090x_WIDTH_Px_ERR_CNT12_FIELD 7 @@ -2249,7 +2249,7 @@ #define STV090x_P1_FBERCPT4 STV090x_Px_FBERCPT4(1) #define STV090x_P2_FBERCPT4 STV090x_Px_FBERCPT4(2) #define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 -#define STV090x_WIDTH_Px_BERMETER_CPT_FIELD 8 +#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 #define STV090x_Px_FBERCPT3(__x) (0xF5A9 - (__x - 1) * 0x200) #define STV090x_P1_FBERCPT3 STV090x_Px_FBERCPT3(1) -- cgit v1.1 From 9629c5b69dd016e990603fd7fd9899f0af57610c Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 23 Apr 2009 14:58:36 -0300 Subject: V4L/DVB (11597): stv090x: fixes read_status to return 0 in case of no error Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 004b774..6c0378d 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3163,7 +3163,6 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) struct stv090x_state *state = fe->demodulator_priv; u32 reg; u8 search_state; - int locked = 0; reg = STV090x_READ_DEMOD(state, DMDSTATE); search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); @@ -3173,7 +3172,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) case 1: /* first PLH detected */ default: dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)"); - locked = 0; + *status = 0; break; case 2: /* DVB-S2 mode */ @@ -3182,7 +3181,6 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { reg = STV090x_READ_DEMOD(state, TSSTATUS); if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { - locked = 1; *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; } } @@ -3196,7 +3194,6 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { reg = STV090x_READ_DEMOD(state, TSSTATUS); if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { - locked = 1; *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; } } @@ -3204,7 +3201,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) break; } - return locked; + return 0; } static int stv090x_read_per(struct dvb_frontend *fe, u32 *per) @@ -3215,7 +3212,8 @@ static int stv090x_read_per(struct dvb_frontend *fe, u32 *per) u32 reg, h, m, l; enum fe_status status; - if (!stv090x_read_status(fe, &status)) { + stv090x_read_status(fe, &status); + if (!(status & FE_HAS_LOCK)) { *per = 1 << 23; /* Max PER */ } else { /* Counter 2 */ -- cgit v1.1 From cbc320d2782cbb0c19e67522167843d9eb738722 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 23 Apr 2009 14:59:03 -0300 Subject: V4L/DVB (11598): stv090x: fix missing wakeup in init Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 6c0378d..9f69317 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3880,6 +3880,11 @@ static int stv090x_init(struct dvb_frontend *fe) const struct stv090x_config *config = state->config; u32 reg; + if (stv090x_wakeup(fe) < 0) { + dprintk(FE_ERROR, 1, "Error waking device"); + goto err; + } + stv090x_ldpc_mode(state, state->demod_mode); reg = STV090x_READ_DEMOD(state, TNRCFG2); @@ -3893,6 +3898,8 @@ static int stv090x_init(struct dvb_frontend *fe) stv090x_i2c_gate_ctrl(fe, 1); + if (config->tuner_set_mode) + config->tuner_set_mode(fe, TUNER_WAKE); if (config->tuner_init) config->tuner_init(fe); -- cgit v1.1 From 62ad7c11883ab7b4642da7d220a2bee7a37e3bad Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 23 Apr 2009 14:59:36 -0300 Subject: V4L/DVB (11599): S2-1600: Use budget driver instead of budged-ci Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-ci.c | 86 ------------------------------------- drivers/media/dvb/ttpci/budget.c | 85 ++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 86 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 351481d..371a716 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -53,9 +53,6 @@ #include "bsru6.h" #include "tda1002x.h" #include "tda827x.h" -#include "stv6110x.h" -#include "stv090x.h" -#include "isl6423.h" /* * Regarding DEBIADDR_IR: @@ -1349,44 +1346,6 @@ static struct stb6100_config tt3200_stb6100_config = { .refclock = 27000000, }; -static struct stv090x_config tt1600_stv090x_config = { - .device = STV0903, - .demod_mode = STV090x_SINGLE, - .clk_mode = STV090x_CLK_EXT, - - .xtal = 27000000, - .address = 0x68, - .ref_clk = 27000000, - - .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED, - .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, - - .repeater_level = STV090x_RPTLEVEL_16, - - .tuner_init = NULL, - .tuner_set_mode = NULL, - .tuner_set_frequency = NULL, - .tuner_get_frequency = NULL, - .tuner_set_bandwidth = NULL, - .tuner_get_bandwidth = NULL, - .tuner_set_bbgain = NULL, - .tuner_get_bbgain = NULL, - .tuner_set_refclk = NULL, - .tuner_get_status = NULL, -}; - -static struct stv6110x_config tt1600_stv6110x_config = { - .addr = 0x60, - .refclk = 27000000, -}; - -static struct isl6423_config tt1600_isl6423_config = { - .current_max = SEC_CURRENT_515m, - .curlim = SEC_CURRENT_LIM_ON, - .mod_extern = 1, - .addr = 0x08, -}; - static void frontend_init(struct budget_ci *budget_ci) { switch (budget_ci->budget.dev->pci->subsystem_device) { @@ -1506,49 +1465,6 @@ static void frontend_init(struct budget_ci *budget_ci) } break; - case 0x101c: { /* TT S2-1600 */ - struct stv6110x_devctl *ctl; - /* TODO! must verify with Andreas */ - saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO); - msleep(50); - saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI); - msleep(250); - - budget_ci->budget.dvb_frontend = dvb_attach(stv090x_attach, - &tt1600_stv090x_config, - &budget_ci->budget.i2c_adap, - STV090x_DEMODULATOR_0); - - if (budget_ci->budget.dvb_frontend) { - - ctl = dvb_attach(stv6110x_attach, - budget_ci->budget.dvb_frontend, - &tt1600_stv6110x_config, - &budget_ci->budget.i2c_adap); - - tt1600_stv090x_config.tuner_init = ctl->tuner_init; - tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; - tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; - tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; - tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; - tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; - tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; - tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; - tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; - tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; - - dvb_attach(isl6423_attach, - budget_ci->budget.dvb_frontend, - &budget_ci->budget.i2c_adap, - &tt1600_isl6423_config); - - } else { - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - break; - } if (budget_ci->budget.dvb_frontend == NULL) { @@ -1640,7 +1556,6 @@ MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT); static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), @@ -1651,7 +1566,6 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019), - MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c), { .vendor = 0, } diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 83e9e77..07dced4 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -47,6 +47,9 @@ #include "bsru6.h" #include "bsbe1.h" #include "tdhd1.h" +#include "stv6110x.h" +#include "stv090x.h" +#include "isl6423.h" static int diseqc_method; module_param(diseqc_method, int, 0444); @@ -425,6 +428,44 @@ static u8 read_pwm(struct budget* budget) return pwm; } +static struct stv090x_config tt1600_stv090x_config = { + .device = STV0903, + .demod_mode = STV090x_SINGLE, + .clk_mode = STV090x_CLK_EXT, + + .xtal = 27000000, + .address = 0x68, + .ref_clk = 27000000, + + .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED, + .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + + .repeater_level = STV090x_RPTLEVEL_16, + + .tuner_init = NULL, + .tuner_set_mode = NULL, + .tuner_set_frequency = NULL, + .tuner_get_frequency = NULL, + .tuner_set_bandwidth = NULL, + .tuner_get_bandwidth = NULL, + .tuner_set_bbgain = NULL, + .tuner_get_bbgain = NULL, + .tuner_set_refclk = NULL, + .tuner_get_status = NULL, +}; + +static struct stv6110x_config tt1600_stv6110x_config = { + .addr = 0x60, + .refclk = 27000000, +}; + +static struct isl6423_config tt1600_isl6423_config = { + .current_max = SEC_CURRENT_515m, + .curlim = SEC_CURRENT_LIM_ON, + .mod_extern = 1, + .addr = 0x08, +}; + static void frontend_init(struct budget *budget) { (void)alps_bsbe1_config; /* avoid warning */ @@ -566,6 +607,48 @@ static void frontend_init(struct budget *budget) } break; } + + case 0x101c: { /* TT S2-1600 */ + struct stv6110x_devctl *ctl; + saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); + msleep(50); + saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); + msleep(250); + + budget->dvb_frontend = dvb_attach(stv090x_attach, + &tt1600_stv090x_config, + &budget->i2c_adap, + STV090x_DEMODULATOR_0); + + if (budget->dvb_frontend) { + + ctl = dvb_attach(stv6110x_attach, + budget->dvb_frontend, + &tt1600_stv6110x_config, + &budget->i2c_adap); + + tt1600_stv090x_config.tuner_init = ctl->tuner_init; + tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; + tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; + tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; + tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; + tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; + tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; + tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; + tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; + tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; + + dvb_attach(isl6423_attach, + budget->dvb_frontend, + &budget->i2c_adap, + &tt1600_isl6423_config); + + } else { + dvb_frontend_detach(budget->dvb_frontend); + budget->dvb_frontend = NULL; + } + } + break; } if (budget->dvb_frontend == NULL) { @@ -641,6 +724,7 @@ MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); +MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT); MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); @@ -653,6 +737,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), + MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c), MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), -- cgit v1.1 From 560db4a1a0aaa8920995e60a6a8bbc9f8708f0a3 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 23 Apr 2009 15:00:04 -0300 Subject: V4L/DVB (11600): budget: Use Continuous clock Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 07dced4..e48380c 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -437,8 +437,8 @@ static struct stv090x_config tt1600_stv090x_config = { .address = 0x68, .ref_clk = 27000000, - .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED, - .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + .ts1_mode = STV090x_TSMODE_DVBCI, + .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, .repeater_level = STV090x_RPTLEVEL_16, -- cgit v1.1 From 7fc08bbb9965206c57270a911d0e9430aaf347f7 Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Thu, 23 Apr 2009 15:00:40 -0300 Subject: V4L/DVB (11601): stv090x: update demodulator capabilities Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 9f69317..fc87dfa 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -4001,6 +4001,17 @@ static struct dvb_frontend_ops stv090x_ops = { .info = { .name = "STV090x Multistandard", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_2G_MODULATION }, .release = stv090x_release, -- cgit v1.1 From 27d403214317d42fbeaf626f2734a1028087fd16 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 2 May 2009 18:26:58 -0300 Subject: V4L/DVB (11682): STV0900/STV0903: Add support for Silicon cut >= 3 1. Support Silicon Cut >= 3.0 2. Remove support for obsolete cuts: 1.0. 1.1. 1.2 3. Try to catch more error cases Driver doesn't now attach to obsolete silcon cuts, It just simply quits. Results in code simplification, with removal of the obsolete cuts. Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv090x.c | 1169 ++++++++++++++++------------ drivers/media/dvb/frontends/stv090x_priv.h | 33 +- drivers/media/dvb/frontends/stv090x_reg.h | 72 +- 3 files changed, 766 insertions(+), 508 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index fc87dfa..96ef745 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -503,25 +503,6 @@ static struct stv090x_reg stv0903_cut20_val[] = { { STV090x_GAINLLR_NF17, 0x21 } }; -/* Cut 1.x Long Frame Tracking CR loop */ -static struct stv090x_long_frame_crloop stv090x_s2_crl[] = { - /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ - { STV090x_QPSK_12, 0x1c, 0x0d, 0x1b, 0x2c, 0x3a, 0x1c, 0x2a, 0x3b, 0x2a, 0x1b }, - { STV090x_QPSK_35, 0x2c, 0x0d, 0x2b, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b, 0x2a, 0x0b }, - { STV090x_QPSK_23, 0x2c, 0x0d, 0x2b, 0x2c, 0x0b, 0x0c, 0x3a, 0x1b, 0x2a, 0x3a }, - { STV090x_QPSK_34, 0x3c, 0x0d, 0x3b, 0x1c, 0x0b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, - { STV090x_QPSK_45, 0x3c, 0x0d, 0x3b, 0x1c, 0x0b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, - { STV090x_QPSK_56, 0x0d, 0x0d, 0x3b, 0x1c, 0x0b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, - { STV090x_QPSK_89, 0x0d, 0x0d, 0x3b, 0x1c, 0x1b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, - { STV090x_QPSK_910, 0x1d, 0x0d, 0x3b, 0x1c, 0x1b, 0x3b, 0x3a, 0x0b, 0x2a, 0x3a }, - { STV090x_8PSK_35, 0x29, 0x3b, 0x09, 0x2b, 0x38, 0x0b, 0x18, 0x1a, 0x08, 0x0a }, - { STV090x_8PSK_23, 0x0a, 0x3b, 0x29, 0x2b, 0x19, 0x0b, 0x38, 0x1a, 0x18, 0x0a }, - { STV090x_8PSK_34, 0x3a, 0x3b, 0x2a, 0x2b, 0x39, 0x0b, 0x19, 0x1a, 0x38, 0x0a }, - { STV090x_8PSK_56, 0x1b, 0x3b, 0x0b, 0x2b, 0x1a, 0x0b, 0x39, 0x1a, 0x19, 0x0a }, - { STV090x_8PSK_89, 0x3b, 0x3b, 0x0b, 0x2b, 0x2a, 0x0b, 0x39, 0x1a, 0x29, 0x39 }, - { STV090x_8PSK_910, 0x3b, 0x3b, 0x0b, 0x2b, 0x2a, 0x0b, 0x39, 0x1a, 0x29, 0x39 } -}; - /* Cut 2.0 Long Frame Tracking CR loop */ static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = { /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ @@ -541,6 +522,24 @@ static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = { { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d } }; +/* Cut 3.0 Long Frame Tracking CR loop */ +static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = { + /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + { STV090x_QPSK_12, 0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b }, + { STV090x_QPSK_35, 0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, + { STV090x_QPSK_23, 0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, + { STV090x_QPSK_34, 0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, + { STV090x_QPSK_45, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, + { STV090x_QPSK_56, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, + { STV090x_QPSK_89, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, + { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, + { STV090x_8PSK_35, 0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 }, + { STV090x_8PSK_23, 0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a }, + { STV090x_8PSK_34, 0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a }, + { STV090x_8PSK_56, 0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b }, + { STV090x_8PSK_89, 0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b }, + { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b } +}; /* Cut 2.0 Long Frame Tracking CR Loop */ static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = { @@ -558,6 +557,21 @@ static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = { { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c } }; +/* Cut 3.0 Long Frame Tracking CR Loop */ +static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut30[] = { + /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + { STV090x_16APSK_23, 0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a }, + { STV090x_16APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a }, + { STV090x_16APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a }, + { STV090x_16APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a }, + { STV090x_16APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a }, + { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a }, + { STV090x_32APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, + { STV090x_32APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, + { STV090x_32APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, + { STV090x_32APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, + { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } +}; static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = { /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ @@ -566,16 +580,30 @@ static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = { { STV090x_QPSK_25, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e } }; +static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut30[] = { + /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + { STV090x_QPSK_14, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b }, + { STV090x_QPSK_13, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b }, + { STV090x_QPSK_25, 0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b } +}; -/* Cut 1.2 & 2.0 Short Frame Tracking CR Loop */ -static struct stv090x_short_frame_crloop stv090x_s2_short_crl[] = { - /* MODCOD 2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */ - { STV090x_QPSK, 0x3c, 0x2f, 0x2b, 0x2e, 0x0b, 0x0e, 0x3a, 0x0e, 0x2a, 0x3d }, - { STV090x_8PSK, 0x0b, 0x3e, 0x2a, 0x0e, 0x0a, 0x2d, 0x19, 0x0d, 0x09, 0x3c }, - { STV090x_16APSK, 0x1b, 0x1e, 0x1b, 0x1e, 0x1b, 0x1e, 0x3a, 0x3d, 0x2a, 0x2d }, - { STV090x_32APSK, 0x1b, 0x1e, 0x1b, 0x1e, 0x1b, 0x1e, 0x3a, 0x3d, 0x2a, 0x2d } +/* Cut 2.0 Short Frame Tracking CR Loop */ +static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = { + /* MODCOD 2M 5M 10M 20M 30M */ + { STV090x_QPSK, 0x2f, 0x2e, 0x0e, 0x0e, 0x3d }, + { STV090x_8PSK, 0x3e, 0x0e, 0x2d, 0x0d, 0x3c }, + { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }, + { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d } }; +/* Cut 3.0 Short Frame Tracking CR Loop */ +static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = { + /* MODCOD 2M 5M 10M 20M 30M */ + { STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A }, + { STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 }, + { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }, + { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A } +}; static inline s32 comp2(s32 __x, s32 __width) { @@ -987,74 +1015,83 @@ err: static int stv090x_activate_modcod(struct stv090x_state *state) { - u32 matype, modcod, f_mod, index; + if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0) + goto err; - if (state->dev_ver <= 0x11) { - msleep(5); - modcod = STV090x_READ_DEMOD(state, PLHMODCOD); - matype = modcod & 0x03; - modcod = (modcod & 0x7f) >> 2; - index = STV090x_ADDR_OFFST(state, MODCODLSTF) - (modcod / 2); + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + +static int stv090x_activate_modcod_single(struct stv090x_state *state) +{ + + if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0) + goto err; - switch (matype) { - default: - case 0: - f_mod = 14; - break; - case 1: - f_mod = 13; - break; - case 2: - f_mod = 11; - break; - case 3: - f_mod = 7; - break; - } - if (matype <= 1) { - if (modcod % 2) { - if (stv090x_write_reg(state, index, 0xf0 | f_mod) < 0) - goto err; - } else { - if (stv090x_write_reg(state, index, (f_mod << 4) | 0x0f) < 0) - goto err; - } - } - } else if (state->dev_ver >= 0x12) { - if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0) - goto err; - } return 0; + err: dprintk(FE_ERROR, 1, "I/O error"); return -1; @@ -1094,6 +1131,40 @@ err: return -1; } +static int stv090x_dvbs_track_crl(struct stv090x_state *state) +{ + if (state->dev_ver >= 0x30) { + /* Set ACLC BCLC optimised value vs SR */ + if (state->srate >= 15000000) { + if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0) + goto err; + } else if ((state->srate >= 7000000) && (15000000 > state->srate)) { + if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0) + goto err; + } else if (state->srate < 7000000) { + if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0) + goto err; + } + + } else { + /* Cut 2.0 */ + if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) + goto err; + } + return 0; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; +} + static int stv090x_delivery_search(struct stv090x_state *state) { u32 reg; @@ -1107,19 +1178,22 @@ static int stv090x_delivery_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) goto err; - /* Activate Viterbi decoder in legacy search, do not use FRESVIT1, might impact VITERBI2 */ + /* Activate Viterbi decoder in legacy search, + * do not use FRESVIT1, might impact VITERBI2 + */ if (stv090x_vitclk_ctl(state, 0) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) + if (stv090x_dvbs_track_crl(state) < 0) goto err; + if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */ goto err; - stv090x_set_vit_thacq(state); - stv090x_set_viterbi(state); + if (stv090x_set_vit_thacq(state) < 0) + goto err; + if (stv090x_set_viterbi(state) < 0) + goto err; break; case STV090x_SEARCH_DVBS2: @@ -1140,24 +1214,36 @@ static int stv090x_delivery_search(struct stv090x_state *state) goto err; if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) - goto err; + + if (state->dev_ver <= 0x20) { + /* enable S2 carrier loop */ + if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) + goto err; + } else { + /* > Cut 3: Stop carrier 3 */ + if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0) + goto err; + } if (state->demod_mode != STV090x_SINGLE) { - if (state->dev_ver <= 0x11) /* 900 in dual TS mode */ - stv090x_stop_modcod(state); - else - stv090x_activate_modcod(state); + /* Cut 2: enable link during search */ + if (stv090x_activate_modcod(state) < 0) + goto err; + } else { + /* Single demodulator + * Authorize SHORT and LONG frames, + * QPSK, 8PSK, 16APSK and 32APSK + */ + if (stv090x_activate_modcod_single(state) < 0) + goto err; } + break; case STV090x_SEARCH_AUTO: default: + /* enable DVB-S2 and DVB-S2 in Auto MODE */ reg = STV090x_READ_DEMOD(state, DMDCFGMD); - STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); - STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); - if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) - goto err; STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) @@ -1166,21 +1252,46 @@ static int stv090x_delivery_search(struct stv090x_state *state) if (stv090x_vitclk_ctl(state, 0) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) + if (stv090x_dvbs_track_crl(state) < 0) goto err; + if (state->dev_ver <= 0x20) { + /* enable S2 carrier loop */ + if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) + goto err; + } else { + /* > Cut 3: Stop carrier 3 */ + if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0) + goto err; + } + if (state->demod_mode != STV090x_SINGLE) { - if (state->dev_ver <= 0x11) /* 900 in dual TS mode */ - stv090x_stop_modcod(state); - else - stv090x_activate_modcod(state); + /* Cut 2: enable link during search */ + if (stv090x_activate_modcod(state) < 0) + goto err; + } else { + /* Single demodulator + * Authorize SHORT and LONG frames, + * QPSK, 8PSK, 16APSK and 32APSK + */ + if (stv090x_activate_modcod_single(state) < 0) + goto err; } - stv090x_set_vit_thacq(state); - stv090x_set_viterbi(state); + + if (state->srate >= 2000000) { + /* Srate >= 2MSPS, Viterbi threshold to acquire */ + if (stv090x_set_vit_thacq(state) < 0) + goto err; + } else { + /* Srate < 2MSPS, Reset Viterbi thresholdto track + * and then re-acquire + */ + if (stv090x_set_vit_thtracq(state) < 0) + goto err; + } + + if (stv090x_set_viterbi(state) < 0) + goto err; break; } return 0; @@ -1191,45 +1302,87 @@ err: static int stv090x_start_search(struct stv090x_state *state) { - u32 reg; + u32 reg, freq_abs; + s16 freq; + /* Reset demodulator */ reg = STV090x_READ_DEMOD(state, DMDISTATE); STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) goto err; - if (state->dev_ver == 0x10) { - if (STV090x_WRITE_DEMOD(state, CORRELEXP, 0xaa) < 0) - goto err; - } - if (state->dev_ver < 0x20) { - if (STV090x_WRITE_DEMOD(state, CARHDR, 0x55) < 0) - goto err; - } - if (state->srate <= 5000000) { - if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0) + if (state->dev_ver <= 0x20) { + if (state->srate <= 5000000) { + if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0) + goto err; + + /*enlarge the timing bandwith for Low SR*/ + if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) + goto err; + } else { + /* If the symbol rate is >5 Msps + Set The carrier search up and low to auto mode */ + if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) + goto err; + /*reduce the timing bandwith for high SR*/ + if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) + goto err; + } + } else { + /* >= Cut 3 */ + if (state->srate <= 5000000) { + /* enlarge the timing bandwith for Low SR */ + STV090x_WRITE_DEMOD(state, RTCS2, 0x68); + } else { + /* reduce timing bandwith for high SR */ + STV090x_WRITE_DEMOD(state, RTCS2, 0x44); + } + + /* Set CFR min and max to manual mode */ + STV090x_WRITE_DEMOD(state, CARCFG, 0x46); + + if (state->algo == STV090x_WARM_SEARCH) { + /* WARM Start + * CFR min = -1MHz, + * CFR max = +1MHz + */ + freq_abs = 1000 << 16; + freq_abs /= (state->mclk / 1000); + freq = (s16) freq_abs; + } else { + /* COLD Start + * CFR min =- (SearchRange / 2 + 600KHz) + * CFR max = +(SearchRange / 2 + 600KHz) + * (600KHz for the tuner step size) + */ + freq_abs = (state->search_range / 2000) + 600; + freq_abs = freq_abs << 16; + freq_abs /= (state->mclk / 1000); + freq = (s16) freq_abs; + } + + if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0) + if (STV090x_WRITE_DEMOD(state, CFRUP1, LSB(freq)) < 0) goto err; - /*enlarge the timing bandwith for Low SR*/ - if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) - goto err; - } else { - /* If the symbol rate is >5 Msps - Set The carrier search up and low to auto mode */ - if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) + freq *= -1; + + if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0) goto err; - /*reduce the timing bandwith for high SR*/ - if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) + if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0) goto err; + } + if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0) goto err; if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) @@ -1269,7 +1422,22 @@ static int stv090x_start_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0) goto err; - if (state->dev_ver >= 0x20) { /*Frequency offset detector setting*/ + if (state->dev_ver >= 0x20) { + /*Frequency offset detector setting*/ + if (state->srate < 2000000) { + if (state->dev_ver <= 0x20) { + /* Cut 2 */ + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) + goto err; + } else { + /* Cut 2 */ + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0) + goto err; + } + if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0) + goto err; + } + if (state->srate < 10000000) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0) goto err; @@ -1288,14 +1456,18 @@ static int stv090x_start_search(struct stv090x_state *state) } switch (state->algo) { - case STV090x_WARM_SEARCH:/*The symbol rate and the exact carrier Frequency are known */ + case STV090x_WARM_SEARCH: + /* The symbol rate and the exact + * carrier Frequency are known + */ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) goto err; if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) goto err; break; - case STV090x_COLD_SEARCH:/*The symbol rate is known*/ + case STV090x_COLD_SEARCH: + /* The symbol rate is known */ if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) goto err; if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) @@ -1334,7 +1506,8 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state) goto err; if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */ goto err; - stv090x_set_srate(state, 1000000); + if (stv090x_set_srate(state, 1000000) < 0) + goto err; steps = -1 + state->search_range / 1000000; steps /= 2; @@ -1441,15 +1614,16 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0) goto err; - if (state->dev_ver >= 0x20) { - if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) + if (state->dev_ver >= 0x30) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) goto err; if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) goto err; - } else { - if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) + + } else if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x73) < 0) + if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) goto err; } @@ -1503,27 +1677,39 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) freq -= cur_step * car_step; /* Setup tuner */ - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (state->config->tuner_set_frequency) - state->config->tuner_set_frequency(fe, state->frequency); + if (state->config->tuner_set_frequency) { + if (state->config->tuner_set_frequency(fe, state->frequency) < 0) + goto err; + } - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, state->tuner_bw); + if (state->config->tuner_set_bandwidth) { + if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) + goto err; + } + + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; - stv090x_i2c_gate_ctrl(fe, 0); msleep(50); - stv090x_i2c_gate_ctrl(fe, 1); - if (state->config->tuner_get_status) - state->config->tuner_get_status(fe, ®); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; + + if (state->config->tuner_get_status) { + if (state->config->tuner_get_status(fe, ®) < 0) + goto err; + } if (reg) dprintk(FE_DEBUG, 1, "Tuner phase locked"); else dprintk(FE_DEBUG, 1, "Tuner unlocked"); - stv090x_i2c_gate_ctrl(fe, 0); + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; } } @@ -1565,11 +1751,11 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) goto err; - if (state->dev_ver >= 0x20) { - if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) + if (state->dev_ver >= 0x30) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) goto err; - } else { - if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) + } else if (state->dev_ver >= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) goto err; } @@ -1674,32 +1860,27 @@ static int stv090x_blind_search(struct stv090x_state *state) u8 k_ref, k_max, k_min; int coarse_fail, lock; - if (state->dev_ver < 0x20) { - k_max = 233; - k_min = 143; - } else { - k_max = 120; - k_min = 30; - } + k_max = 120; + k_min = 30; agc2 = stv090x_get_agc2_min_level(state); - if (agc2 > STV090x_SEARCH_AGC2_TH) { + if (agc2 > STV090x_SEARCH_AGC2_TH(state->dev_ver)) { lock = 0; } else { - if (state->dev_ver == 0x10) { - if (STV090x_WRITE_DEMOD(state, CORRELEXP, 0xaa) < 0) + + if (state->dev_ver <= 0x20) { + if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) goto err; - } - if (state->dev_ver < 0x20) { - if (STV090x_WRITE_DEMOD(state, CARHDR, 0x55) < 0) + } else { + /* > Cut 3 */ + if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0) goto err; } - if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) - goto err; if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) goto err; + if (state->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) goto err; @@ -1756,7 +1937,7 @@ err: static int stv090x_chk_tmg(struct stv090x_state *state) { u32 reg; - s32 tmg_cpt, i; + s32 tmg_cpt = 0, i; u8 freq, tmg_thh, tmg_thl; int tmg_lock; @@ -1877,29 +2058,39 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) freq -= cur_step * car_step; /* Setup tuner */ - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (state->config->tuner_set_frequency) - state->config->tuner_set_frequency(fe, state->frequency); + if (state->config->tuner_set_frequency) { + if (state->config->tuner_set_frequency(fe, state->frequency) < 0) + goto err; + } - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, state->tuner_bw); + if (state->config->tuner_set_bandwidth) { + if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) + goto err; + } - stv090x_i2c_gate_ctrl(fe, 0); + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; msleep(50); - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (state->config->tuner_get_status) - state->config->tuner_get_status(fe, ®); + if (state->config->tuner_get_status) { + if (state->config->tuner_get_status(fe, ®) < 0) + goto err; + } if (reg) dprintk(FE_DEBUG, 1, "Tuner phase locked"); else dprintk(FE_DEBUG, 1, "Tuner unlocked"); - stv090x_i2c_gate_ctrl(fe, 0); + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); if (state->delsys == STV090x_DVBS2) { @@ -2031,7 +2222,7 @@ static int stv090x_chk_signal(struct stv090x_state *state) static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max) { int no_signal, lock = 0; - s32 cpt_step, offst_freq, car_max; + s32 cpt_step = 0, offst_freq, car_max; u32 reg; car_max = state->search_range / 1000; @@ -2046,7 +2237,6 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim else offst_freq = -car_max + inc; - cpt_step = 0; do { if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0) goto err; @@ -2062,16 +2252,6 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) goto err; - if (state->dev_ver == 0x12) { - reg = STV090x_READ_DEMOD(state, TSCFGH); - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x1); - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) - goto err; - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x0); - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) - goto err; - } - if (zigzag) { if (offst_freq >= 0) offst_freq = -offst_freq - 2 * inc; @@ -2111,7 +2291,8 @@ static int stv090x_sw_algo(struct stv090x_state *state) s32 dvbs2_fly_wheel; s32 inc, timeout_step, trials, steps_max; - stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max); /* get params */ + /* get params */ + stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max); switch (state->search_mode) { case STV090x_SEARCH_DVBS1: @@ -2120,10 +2301,8 @@ static int stv090x_sw_algo(struct stv090x_state *state) if (state->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) goto err; - } else { - if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0) - goto err; } + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0) goto err; zigzag = 0; @@ -2133,10 +2312,8 @@ static int stv090x_sw_algo(struct stv090x_state *state) if (state->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) goto err; - } else { - if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x68) < 0) - goto err; } + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0) goto err; zigzag = 1; @@ -2150,12 +2327,8 @@ static int stv090x_sw_algo(struct stv090x_state *state) goto err; if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) goto err; - } else { - if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x68) < 0) - goto err; } + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0) goto err; zigzag = 0; @@ -2176,11 +2349,6 @@ static int stv090x_sw_algo(struct stv090x_state *state) goto err; if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) goto err; - } else { - if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x88) < 0) - goto err; } reg = STV090x_READ_DEMOD(state, DMDSTATE); @@ -2201,10 +2369,8 @@ static int stv090x_sw_algo(struct stv090x_state *state) if (state->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) goto err; - } else { - if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x68) < 0) - goto err; } + if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0) goto err; } @@ -2325,16 +2491,23 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st } state->delsys = stv090x_get_std(state); - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (state->config->tuner_get_frequency) - state->config->tuner_get_frequency(fe, &state->frequency); + if (state->config->tuner_get_frequency) { + if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) + goto err; + } - stv090x_i2c_gate_ctrl(fe, 0); + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000; state->frequency += offst_freq; - stv090x_get_viterbi(state); + + if (stv090x_get_viterbi(state) < 0) + goto err; + reg = STV090x_READ_DEMOD(state, DMDMODCOD); state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; @@ -2346,12 +2519,16 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) { - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (state->config->tuner_get_frequency) - state->config->tuner_get_frequency(fe, &state->frequency); + if (state->config->tuner_get_frequency) { + if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) + goto err; + } - stv090x_i2c_gate_ctrl(fe, 0); + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) return STV090x_RANGEOK; @@ -2367,6 +2544,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st } return STV090x_OUTOFRANGE; +err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; } static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate) @@ -2391,19 +2571,22 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod { u8 aclc = 0x29; s32 i; - struct stv090x_long_frame_crloop *car_loop; - - if (state->dev_ver <= 0x12) - car_loop = stv090x_s2_crl; - else if (state->dev_ver == 0x20) - car_loop = stv090x_s2_crl_cut20; - else - car_loop = stv090x_s2_crl; + struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low; + if (state->dev_ver == 0x20) { + car_loop = stv090x_s2_crl_cut20; + car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20; + car_loop_apsk_low = stv090x_s2_apsk_crl_cut20; + } else { + /* >= Cut 3 */ + car_loop = stv090x_s2_crl_cut30; + car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut30; + car_loop_apsk_low = stv090x_s2_apsk_crl_cut30; + } if (modcod < STV090x_QPSK_12) { i = 0; - while ((i < 3) && (modcod != stv090x_s2_lowqpsk_crl_cut20[i].modcod)) + while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod)) i++; if (i >= 3) @@ -2416,7 +2599,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod if (i >= 14) { i = 0; - while ((i < 11) && (modcod != stv090x_s2_lowqpsk_crl_cut20[i].modcod)) + while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod)) i++; if (i >= 11) @@ -2427,26 +2610,26 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod if (modcod <= STV090x_QPSK_25) { if (pilots) { if (state->srate <= 3000000) - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_2; + aclc = car_loop_qpsk_low[i].crl_pilots_on_2; else if (state->srate <= 7000000) - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_5; + aclc = car_loop_qpsk_low[i].crl_pilots_on_5; else if (state->srate <= 15000000) - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_10; + aclc = car_loop_qpsk_low[i].crl_pilots_on_10; else if (state->srate <= 25000000) - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_20; + aclc = car_loop_qpsk_low[i].crl_pilots_on_20; else - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_on_30; + aclc = car_loop_qpsk_low[i].crl_pilots_on_30; } else { if (state->srate <= 3000000) - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_2; + aclc = car_loop_qpsk_low[i].crl_pilots_off_2; else if (state->srate <= 7000000) - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_5; + aclc = car_loop_qpsk_low[i].crl_pilots_off_5; else if (state->srate <= 15000000) - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_10; + aclc = car_loop_qpsk_low[i].crl_pilots_off_10; else if (state->srate <= 25000000) - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_20; + aclc = car_loop_qpsk_low[i].crl_pilots_off_20; else - aclc = stv090x_s2_lowqpsk_crl_cut20[i].crl_pilots_off_30; + aclc = car_loop_qpsk_low[i].crl_pilots_off_30; } } else if (modcod <= STV090x_8PSK_910) { @@ -2475,15 +2658,15 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod } } else { /* 16APSK and 32APSK */ if (state->srate <= 3000000) - aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_2; + aclc = car_loop_apsk_low[i].crl_pilots_on_2; else if (state->srate <= 7000000) - aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_5; + aclc = car_loop_apsk_low[i].crl_pilots_on_5; else if (state->srate <= 15000000) - aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_10; + aclc = car_loop_apsk_low[i].crl_pilots_on_10; else if (state->srate <= 25000000) - aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_20; + aclc = car_loop_apsk_low[i].crl_pilots_on_20; else - aclc = stv090x_s2_apsk_crl_cut20[i].crl_pilots_on_30; + aclc = car_loop_apsk_low[i].crl_pilots_on_30; } return aclc; @@ -2491,6 +2674,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) { + struct stv090x_short_frame_crloop *short_crl; s32 index = 0; u8 aclc = 0x0b; @@ -2510,34 +2694,21 @@ static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) break; } - switch (state->dev_ver) { - case 0x20: - if (state->srate <= 3000000) - aclc = stv090x_s2_short_crl[index].crl_cut20_2; - else if (state->srate <= 7000000) - aclc = stv090x_s2_short_crl[index].crl_cut20_5; - else if (state->srate <= 15000000) - aclc = stv090x_s2_short_crl[index].crl_cut20_10; - else if (state->srate <= 25000000) - aclc = stv090x_s2_short_crl[index].crl_cut20_20; - else - aclc = stv090x_s2_short_crl[index].crl_cut20_30; - break; - - case 0x12: - default: - if (state->srate <= 3000000) - aclc = stv090x_s2_short_crl[index].crl_cut12_2; - else if (state->srate <= 7000000) - aclc = stv090x_s2_short_crl[index].crl_cut12_5; - else if (state->srate <= 15000000) - aclc = stv090x_s2_short_crl[index].crl_cut12_10; - else if (state->srate <= 25000000) - aclc = stv090x_s2_short_crl[index].crl_cut12_20; - else - aclc = stv090x_s2_short_crl[index].crl_cut12_30; - break; - } + if (state->dev_ver >= 0x30) + short_crl = stv090x_s2_short_crl_cut20; + else if (state->dev_ver >= 0x20) + short_crl = stv090x_s2_short_crl_cut30; + + if (state->srate <= 3000000) + aclc = short_crl[index].crl_2; + else if (state->srate <= 7000000) + aclc = short_crl[index].crl_5; + else if (state->srate <= 15000000) + aclc = short_crl[index].crl_10; + else if (state->srate <= 25000000) + aclc = short_crl[index].crl_20; + else + aclc = short_crl[index].crl_30; return aclc; } @@ -2567,9 +2738,27 @@ static int stv090x_optimize_track(struct stv090x_state *state) } reg = STV090x_READ_DEMOD(state, DEMOD); STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff); - STV090x_SETFIELD_Px(reg, MANUAL_ROLLOFF_FIELD, 0x01); + STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01); if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) goto err; + + if (state->dev_ver >= 0x30) { + if (stv090x_get_viterbi(state) < 0) + goto err; + + if (state->fec == STV090x_PR12) { + if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0) + goto err; + } else { + if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0) + goto err; + } + } + if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0) goto err; break; @@ -2633,10 +2822,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) goto err; } } - if (state->dev_ver <= 0x11) { - if (state->demod_mode != STV090x_SINGLE) - stv090x_activate_modcod(state); /* link to LDPC after demod LOCK */ - } + STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */ break; @@ -2662,11 +2848,11 @@ static int stv090x_optimize_track(struct stv090x_state *state) STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0) + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) + goto err; + + if (stv090x_set_srate(state, srate) < 0) goto err; - stv090x_set_srate(state, srate); - stv090x_set_max_srate(state, state->mclk, srate); - stv090x_set_min_srate(state, state->mclk, srate); blind_tune = 1; } @@ -2682,20 +2868,18 @@ static int stv090x_optimize_track(struct stv090x_state *state) } } - if (state->dev_ver < 0x20) { - if (STV090x_WRITE_DEMOD(state, CARHDR, 0x08) < 0) - goto err; - } - if (state->dev_ver == 0x10) { - if (STV090x_WRITE_DEMOD(state, CORRELEXP, 0x0a) < 0) - goto err; - } - if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) goto err; - if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) { + /* AUTO tracking MODE */ + if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0) + goto err; + /* AUTO tracking MODE */ + if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0) + goto err; + if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) { + /* update initial carrier freq with the found freq offset */ if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) goto err; if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) @@ -2706,12 +2890,16 @@ static int stv090x_optimize_track(struct stv090x_state *state) if (state->algo != STV090x_WARM_SEARCH) { - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, state->tuner_bw); + if (state->config->tuner_set_bandwidth) { + if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) + goto err; + } - stv090x_i2c_gate_ctrl(fe, 0); + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; } } @@ -2754,6 +2942,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) goto err; } + if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS)) stv090x_set_vit_thtracq(state); @@ -2823,22 +3012,18 @@ static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 ti static int stv090x_set_s2rolloff(struct stv090x_state *state) { - s32 rolloff; u32 reg; - if (state->dev_ver == 0x10) { + if (state->dev_ver <= 0x20) { + /* rolloff to auto mode if DVBS2 */ reg = STV090x_READ_DEMOD(state, DEMOD); - STV090x_SETFIELD_Px(reg, MANUAL_ROLLOFF_FIELD, 0x01); - if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) - goto err; - rolloff = STV090x_READ_DEMOD(state, MATSTR1) & 0x03; - reg = STV090x_READ_DEMOD(state, DEMOD); - STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, reg); + STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00); if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) goto err; } else { + /* DVB-S2 rolloff to auto mode if DVBS2 */ reg = STV090x_READ_DEMOD(state, DEMOD); - STV090x_SETFIELD_Px(reg, MANUAL_ROLLOFF_FIELD, 0x00); + STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00); if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) goto err; } @@ -2848,84 +3033,13 @@ err: return -1; } -static enum stv090x_signal_state stv090x_acq_fixs1(struct stv090x_state *state) -{ - s32 srate, f_1, f_2; - enum stv090x_signal_state signal_state = STV090x_NODATA; - u32 reg; - int lock; - - reg = STV090x_READ_DEMOD(state, DMDSTATE); - if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) { /* DVB-S mode */ - srate = stv090x_get_srate(state, state->mclk); - srate += stv090x_get_tmgoffst(state, state->srate); - - if (state->algo == STV090x_BLIND_SEARCH) - stv090x_set_srate(state, state->srate); - - stv090x_get_lock_tmg(state); - - f_1 = STV090x_READ_DEMOD(state, CFR2); - f_2 = STV090x_READ_DEMOD(state, CFR1); - - reg = STV090x_READ_DEMOD(state, DMDCFGMD); - STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); - if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) - goto err; - - reg = STV090x_READ_DEMOD(state, DEMOD); - STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, STV090x_IQ_SWAP); - if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0) /* stop demod */ - goto err; - if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_2) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* warm start trigger */ - goto err; - - if (stv090x_get_lock(state, state->DemodTimeout, state->FecTimeout)) { - lock = 1; - stv090x_get_sig_params(state); - stv090x_optimize_track(state); - } else { - reg = STV090x_READ_DEMOD(state, DEMOD); - STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, STV090x_IQ_NORMAL); - if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_2) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* warm start trigger */ - goto err; - if (stv090x_get_lock(state, state->DemodTimeout, state->FecTimeout)) { - lock = 1; - signal_state = stv090x_get_sig_params(state); - stv090x_optimize_track(state); - } - } - } else { - lock = 0; - } - - return signal_state; - -err: - dprintk(FE_ERROR, 1, "I/O error"); - return -1; -} static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) { struct dvb_frontend *fe = &state->frontend; enum stv090x_signal_state signal_state = STV090x_NOCARRIER; u32 reg; - s32 timeout_dmd = 500, timeout_fec = 50; + s32 timeout_dmd = 500, timeout_fec = 50, agc1_power, power_iq = 0, i; int lock = 0, low_sr = 0, no_signal = 0; reg = STV090x_READ_DEMOD(state, TSCFGH); @@ -2939,18 +3053,18 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if (state->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */ goto err; - } else { - if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x88) < 0) /* cut 1.x */ - goto err; } stv090x_get_lock_tmg(state); if (state->algo == STV090x_BLIND_SEARCH) { state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */ - if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x00) < 0) /* wider srate scan */ + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */ + goto err; + if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0) + goto err; + if (stv090x_set_srate(state, 1000000) < 0) /* inital srate = 1Msps */ goto err; - stv090x_set_srate(state, 1000000); /* inital srate = 1Msps */ } else { /* known srate */ if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0) @@ -2958,14 +3072,19 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0) goto err; - if (state->srate >= 10000000) { - if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) /* High SR */ + if (state->srate < 2000000) { + /* SR < 2MSPS */ + if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0) goto err; } else { - if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0) /* Low SR */ + /* SR >= 2Msps */ + if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0) goto err; } + if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) + goto err; + if (state->dev_ver >= 0x20) { if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) goto err; @@ -2973,16 +3092,21 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10; else if (state->algo == STV090x_WARM_SEARCH) state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000; - } else { - if (STV090x_WRITE_DEMOD(state, KREFTMG, 0xc1) < 0) - goto err; - state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10; } - if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0) /* narrow srate scan */ + + /* if cold start or warm (Symbolrate is known) + * use a Narrow symbol rate scan range + */ + if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */ + goto err; + + if (stv090x_set_srate(state, state->srate) < 0) + goto err; + + if (stv090x_set_max_srate(state, state->mclk, state->srate) < 0) + goto err; + if (stv090x_set_min_srate(state, state->mclk, state->srate) < 0) goto err; - stv090x_set_srate(state, state->srate); - stv090x_set_max_srate(state, state->mclk, state->srate); - stv090x_set_min_srate(state, state->mclk, state->srate); if (state->srate >= 10000000) low_sr = 0; @@ -2991,60 +3115,97 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) } /* Setup tuner */ - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (state->config->tuner_set_bbgain) - state->config->tuner_set_bbgain(fe, 10); /* 10dB */ + if (state->config->tuner_set_bbgain) { + if (state->config->tuner_set_bbgain(fe, 10) < 0) /* 10dB */ + goto err; + } - if (state->config->tuner_set_frequency) - state->config->tuner_set_frequency(fe, state->frequency); + if (state->config->tuner_set_frequency) { + if (state->config->tuner_set_frequency(fe, state->frequency) < 0) + goto err; + } - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, state->tuner_bw); + if (state->config->tuner_set_bandwidth) { + if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) + goto err; + } - stv090x_i2c_gate_ctrl(fe, 0); + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; msleep(50); - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (state->config->tuner_get_status) - state->config->tuner_get_status(fe, ®); + if (state->config->tuner_get_status) { + if (state->config->tuner_get_status(fe, ®) < 0) + goto err; + } if (reg) dprintk(FE_DEBUG, 1, "Tuner phase locked"); else dprintk(FE_DEBUG, 1, "Tuner unlocked"); - stv090x_i2c_gate_ctrl(fe, 0); - - reg = STV090x_READ_DEMOD(state, DEMOD); - STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); - STV090x_SETFIELD_Px(reg, MANUAL_ROLLOFF_FIELD, 1); - if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) goto err; - stv090x_delivery_search(state); - if (state->algo != STV090x_BLIND_SEARCH) - stv090x_start_search(state); - if (state->dev_ver == 0x12) { - reg = STV090x_READ_DEMOD(state, TSCFGH); - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) - goto err; - msleep(3); - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */ - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + msleep(10); + agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1), + STV090x_READ_DEMOD(state, AGCIQIN0)); + + if (agc1_power == 0) { + /* If AGC1 integrator value is 0 + * then read POWERI, POWERQ + */ + for (i = 0; i < 5; i++) { + power_iq += (STV090x_READ_DEMOD(state, POWERI) + + STV090x_READ_DEMOD(state, POWERQ)) >> 1; + } + power_iq /= 5; + } + + if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) { + dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq); + lock = 0; + + } else { + reg = STV090x_READ_DEMOD(state, DEMOD); + STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); + + if (state->dev_ver <= 0x20) { + /* rolloff to auto mode if DVBS2 */ + STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1); + } else { + /* DVB-S2 rolloff to auto mode if DVBS2 */ + STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1); + } + if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) goto err; - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) + + if (stv090x_delivery_search(state) < 0) goto err; + + if (state->algo != STV090x_BLIND_SEARCH) { + if (stv090x_start_search(state) < 0) + goto err; + } } + /* need to check for AGC1 state */ + + + if (state->algo == STV090x_BLIND_SEARCH) lock = stv090x_blind_search(state); + else if (state->algo == STV090x_COLD_SEARCH) lock = stv090x_get_coldlock(state, timeout_dmd); + else if (state->algo == STV090x_WARM_SEARCH) lock = stv090x_get_dmdlock(state, timeout_dmd); @@ -3060,32 +3221,18 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ stv090x_optimize_track(state); - if (state->dev_ver <= 0x11) { /*workaround for dual DVBS1 cut 1.1 and 1.0 only*/ - if (stv090x_get_std(state) == STV090x_DVBS1) { - msleep(20); - reg = STV090x_READ_DEMOD(state, TSCFGH); - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) - goto err; - } else { - reg = STV090x_READ_DEMOD(state, TSCFGH); - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) - goto err; - msleep(3); - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */ - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) - goto err; - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ - if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) - goto err; - } - } else if (state->dev_ver == 0x20) { /*cut 2.0 :release TS reset after demod lock and TrackingOptimization*/ + + if (state->dev_ver >= 0x20) { + /* >= Cut 2.0 :release TS reset after + * demod lock and optimized Tracking + */ reg = STV090x_READ_DEMOD(state, TSCFGH); STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) goto err; + msleep(3); + STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */ if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) goto err; @@ -3099,18 +3246,27 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) lock = 1; if (state->delsys == STV090x_DVBS2) { stv090x_set_s2rolloff(state); - if (STV090x_WRITE_DEMOD(state, PDELCTRL2, 0x40) < 0) + + reg = STV090x_READ_DEMOD(state, PDELCTRL2); + STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1); + if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0) goto err; - if (STV090x_WRITE_DEMOD(state, PDELCTRL2, 0x00) < 0) /* RESET counter */ + /* Reset DVBS2 packet delinator error counter */ + reg = STV090x_READ_DEMOD(state, PDELCTRL2); + STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0); + if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0) goto err; + if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */ goto err; } else { if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0) goto err; } + /* Reset the Total packet counter */ if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0) goto err; + /* Reset the packet Error counter2 */ if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) goto err; } else { @@ -3119,13 +3275,6 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) no_signal = stv090x_chk_signal(state); } } - if ((signal_state == STV090x_NODATA) && (!no_signal)) { - if (state->dev_ver <= 0x11) { - reg = STV090x_READ_DEMOD(state, DMDSTATE); - if (((STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD)) == STV090x_DVBS1) && (state->inversion == INVERSION_AUTO)) - signal_state = stv090x_acq_fixs1(state); - } - } return signal_state; err: @@ -3578,17 +3727,18 @@ static void stv090x_release(struct dvb_frontend *fe) static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode) { - u32 reg; + u32 reg = 0; switch (ldpc_mode) { case STV090x_DUAL: default: - reg = stv090x_read_reg(state, STV090x_GENCFG); if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) { - /* follow LDPC default state */ - if (stv090x_write_reg(state, STV090x_GENCFG, reg) < 0) + /* set LDPC to dual mode */ + if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0) goto err; + state->demod_mode = STV090x_DUAL; + reg = stv090x_read_reg(state, STV090x_TSTRES0); STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1); if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) @@ -3596,10 +3746,50 @@ static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0); if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) goto err; + + if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0) + goto err; + + if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0) + goto err; } break; case STV090x_SINGLE: + if (stv090x_stop_modcod(state) < 0) + goto err; + if (stv090x_activate_modcod_single(state) < 0) + goto err; + if (state->demod == STV090x_DEMODULATOR_1) { if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */ goto err; @@ -3885,7 +4075,8 @@ static int stv090x_init(struct dvb_frontend *fe) goto err; } - stv090x_ldpc_mode(state, state->demod_mode); + if (stv090x_ldpc_mode(state, state->demod_mode) < 0) + goto err; reg = STV090x_READ_DEMOD(state, TNRCFG2); STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion); @@ -3896,16 +4087,24 @@ static int stv090x_init(struct dvb_frontend *fe) if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) goto err; - stv090x_i2c_gate_ctrl(fe, 1); + if (stv090x_i2c_gate_ctrl(fe, 1) < 0) + goto err; - if (config->tuner_set_mode) - config->tuner_set_mode(fe, TUNER_WAKE); - if (config->tuner_init) - config->tuner_init(fe); + if (config->tuner_set_mode) { + if (config->tuner_set_mode(fe, TUNER_WAKE) < 0) + goto err; + } - stv090x_i2c_gate_ctrl(fe, 0); + if (config->tuner_init) { + if (config->tuner_init(fe) < 0) + goto err; + } + + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; - stv090x_set_tspath(state); + if (stv090x_set_tspath(state) < 0) + goto err; return 0; err: @@ -3978,6 +4177,16 @@ static int stv090x_setup(struct dvb_frontend *fe) if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0) goto err; } + + } else if (state->dev_ver < 0x20) { + dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!", + state->dev_ver); + + goto err; + } else if (state->dev_ver > 0x30) { + /* we shouldn't bail out from here */ + dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!", + state->dev_ver); } if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h index 9d53622..5a4a017 100644 --- a/drivers/media/dvb/frontends/stv090x_priv.h +++ b/drivers/media/dvb/frontends/stv090x_priv.h @@ -77,7 +77,18 @@ #define MAKEWORD16(__a, __b) (((__a) << 8) | (__b)) -#define STV090x_SEARCH_AGC2_TH 700 +#define MSB(__x) ((__x >> 8) & 0xff) +#define LSB(__x) (__x & 0xff) + + +#define STV090x_IQPOWER_THRESHOLD 30 +#define STV090x_SEARCH_AGC2_TH_CUT20 700 +#define STV090x_SEARCH_AGC2_TH_CUT30 1200 + +#define STV090x_SEARCH_AGC2_TH(__ver) \ + ((__ver <= 0x20) ? \ + STV090x_SEARCH_AGC2_TH_CUT20 : \ + STV090x_SEARCH_AGC2_TH_CUT30) enum stv090x_signal_state { STV090x_NOCARRIER, @@ -201,24 +212,8 @@ struct stv090x_long_frame_crloop { struct stv090x_short_frame_crloop { enum stv090x_modulation modulation; - u8 crl_cut12_2; /* Cut 1.2, SR <= 3M */ - u8 crl_cut20_2; /* Cut 2.0, SR < 3M */ - u8 crl_cut12_5; /* Cut 1.2, 3 < SR <= 7M */ - u8 crl_cut20_5; /* Cut 2.0, 3 < SR <= 7M */ - u8 crl_cut12_10; /* Cut 1.2, 7 < SR <= 15M */ - u8 crl_cut20_10; /* Cut 2.0, 7 < SR <= 15M */ - u8 crl_cut12_20; /* Cut 1.2, 10 < SR <= 25M */ - u8 crl_cut20_20; /* Cut 2.0, 10 < SR <= 25M */ - u8 crl_cut12_30; /* Cut 1.2, 25 < SR <= 45M */ - u8 crl_cut20_30; /* Cut 2.0, 10 < SR <= 45M */ -}; - - -struct stv090x_short_frame_vsmod_crloop { - enum stv090x_modulation modulation; - - u8 crl_2; /* < 3M */ - u8 crl_5; /* 3 < SR <= 7M */ + u8 crl_2; /* SR < 3M */ + u8 crl_5; /* 3 < SR <= 7M */ u8 crl_10; /* 7 < SR <= 15M */ u8 crl_20; /* 10 < SR <= 25M */ u8 crl_30; /* 10 < SR <= 45M */ diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h index 5573707..57b6abb 100644 --- a/drivers/media/dvb/frontends/stv090x_reg.h +++ b/drivers/media/dvb/frontends/stv090x_reg.h @@ -793,10 +793,16 @@ #define STV090x_Px_DEMOD(__x) (0xF410 - (__x - 1) * 0x200) #define STV090x_P1_DEMOD STV090x_Px_DEMOD(1) #define STV090x_P2_DEMOD STV090x_Px_DEMOD(2) +#define STV090x_OFFST_Px_MANUAL_S2ROLLOFF_FIELD 7 +#define STV090x_WIDTH_Px_MANUAL_S2ROLLOFF_FIELD 1 +#define STV090x_OFFST_Px_DEMOD_STOP_FIELD 6 +#define STV090x_WIDTH_Px_DEMOD_STOP_FIELD 1 #define STV090x_OFFST_Px_SPECINV_CONTROL_FIELD 4 #define STV090x_WIDTH_Px_SPECINV_CONTROL_FIELD 2 -#define STV090x_OFFST_Px_MANUAL_ROLLOFF_FIELD 2 -#define STV090x_WIDTH_Px_MANUAL_ROLLOFF_FIELD 1 +#define STV090x_OFFST_Px_FORCE_ENASAMP_FIELD 3 +#define STV090x_WIDTH_Px_FORCE_ENASAMP_FIELD 1 +#define STV090x_OFFST_Px_MANUAL_SXROLLOFF_FIELD 2 +#define STV090x_WIDTH_Px_MANUAL_SXROLLOFF_FIELD 1 #define STV090x_OFFST_Px_ROLLOFF_CONTROL_FIELD 0 #define STV090x_WIDTH_Px_ROLLOFF_CONTROL_FIELD 2 @@ -1566,6 +1572,42 @@ #define STV090x_OFFST_Px_DIS_QP_1_4_FIELD 4 #define STV090x_WIDTH_Px_DIS_QP_1_4_FIELD 4 +#define STV090x_Px_GAUSSR0(__x) (0xf4c0 - (__x - 1) * 0x200) +#define STV090x_P1_GAUSSR0 STV090x_Px_GAUSSR0(1) +#define STV090x_P2_GAUSSR0 STV090x_Px_GAUSSR0(2) +#define STV090x_OFFST_Px_EN_CCIMODE_FIELD 7 +#define STV090x_WIDTH_Px_EN_CCIMODE_FIELD 1 +#define STV090x_OFFST_Px_R0_GAUSSIEN_FIELD 0 +#define STV090x_WIDTH_Px_R0_GAUSSIEN_FIELD 7 + +#define STV090x_Px_CCIR0(__x) (0xf4c1 - (__x - 1) * 0x200) +#define STV090x_P1_CCIR0 STV090x_Px_CCIR0(1) +#define STV090x_P2_CCIR0 STV090x_Px_CCIR0(2) +#define STV090x_OFFST_Px_CCIDETECT_PLH_FIELD 7 +#define STV090x_WIDTH_Px_CCIDETECT_PLH_FIELD 1 +#define STV090x_OFFST_Px_R0_CCI_FIELD 0 +#define STV090x_WIDTH_Px_R0_CCI_FIELD 7 + +#define STV090x_Px_CCIQUANT(__x) (0xf4c2 - (__x - 1) * 0x200) +#define STV090x_P1_CCIQUANT STV090x_Px_CCIQUANT(1) +#define STV090x_P2_CCIQUANT STV090x_Px_CCIQUANT(2) +#define STV090x_OFFST_Px_CCI_BETA_FIELD 5 +#define STV090x_WIDTH_Px_CCI_BETA_FIELD 3 +#define STV090x_OFFST_Px_CCI_QUANT_FIELD 0 +#define STV090x_WIDTH_Px_CCI_QUANT_FIELD 5 + +#define STV090x_Px_CCITHRESH(__x) (0xf4c3 - (__x - 1) * 0x200) +#define STV090x_P1_CCITHRESH STV090x_Px_CCITHRESH(1) +#define STV090x_P2_CCITHRESH STV090x_Px_CCITHRESH(2) +#define STV090x_OFFST_Px_CCI_THRESHOLD_FIELD 0 +#define STV090x_WIDTH_Px_CCI_THRESHOLD_FIELD 8 + +#define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200) +#define STV090x_P1_CCIACC STV090x_Px_CCIACC(1) +#define STV090x_P2_CCIACC STV090x_Px_CCIACC(1) +#define STV090x_OFFST_Px_CCI_VALUE_FIELD 0 +#define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8 + #define STV090x_Px_DMDRESCFG(__x) (0xF4C6 - (__x - 1) * 0x200) #define STV090x_P1_DMDRESCFG STV090x_Px_DMDRESCFG(1) #define STV090x_P2_DMDRESCFG STV090x_Px_DMDRESCFG(2) @@ -1847,16 +1889,28 @@ #define STV090x_Px_PDELCTRL2(__x) (0xf551 - (__x - 1) * 0x200) #define STV090x_P1_PDELCTRL2 STV090x_Px_PDELCTRL2(1) #define STV090x_P2_PDELCTRL2 STV090x_Px_PDELCTRL2(2) +#define STV090x_OFFST_Px_FORCE_CONTINUOUS 7 +#define STV090x_WIDTH_Px_FORCE_CONTINUOUS 1 +#define STV090x_OFFST_Px_RESET_UPKO_COUNT 6 +#define STV090x_WIDTH_Px_RESET_UPKO_COUNT 1 +#define STV090x_OFFST_Px_USER_PKTDELIN_NB 5 +#define STV090x_WIDTH_Px_USER_PKTDELIN_NB 1 +#define STV090x_OFFST_Px_FORCE_LOCKED 4 +#define STV090x_WIDTH_Px_FORCE_LOCKED 1 +#define STV090x_OFFST_Px_DATA_UNBBSCRAM 3 +#define STV090x_WIDTH_Px_DATA_UNBBSCRAM 1 +#define STV090x_OFFST_Px_FORCE_LONGPACKET 2 +#define STV090x_WIDTH_Px_FORCE_LONGPACKET 1 #define STV090x_OFFST_Px_FRAME_MODE_FIELD 1 #define STV090x_WIDTH_Px_FRAME_MODE_FIELD 1 -#define STV090x_Px_HYSTTHRESH(__x) (0xf554 - (__x - 1) * 0x200) -#define STV090x_P1_HYSTTHRESH STV090x_Px_HYSTTHRESH(1) -#define STV090x_P2_HYSTTHRESH STV090x_Px_HYSTTHRESH(2) -#define STV090x_OFFST_Px_UNLCK_THRESH_FIELD 4 -#define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD 4 -#define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD 0 -#define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD 4 +#define STV090x_Px_HYSTTHRESH(__x) (0xf554 - (__x - 1) * 0x200) +#define STV090x_P1_HYSTTHRESH STV090x_Px_HYSTTHRESH(1) +#define STV090x_P2_HYSTTHRESH STV090x_Px_HYSTTHRESH(2) +#define STV090x_OFFST_Px_UNLCK_THRESH_FIELD 4 +#define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD 4 +#define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD 0 +#define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD 4 #define STV090x_Px_ISIENTRY(__x) (0xf55e - (__x - 1) * 0x200) #define STV090x_P1_ISIENTRY STV090x_Px_ISIENTRY(1) -- cgit v1.1 From d114153816ec188b20a37583e66da33d8b2798fe Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 2 May 2009 11:07:29 -0300 Subject: V4L/DVB (11697): tda10048: Add ability to select I/F at attach time. tda10048: Add ability to select I/F at attach time. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda10048.c | 219 ++++++++++++++++++++++++++++++++- drivers/media/dvb/frontends/tda10048.h | 14 +++ 2 files changed, 232 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 2a8bbcd..28f580f 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "dvb_math.h" #include "tda10048.h" @@ -143,6 +144,15 @@ struct tda10048_state { struct dvb_frontend frontend; int fwloaded; + + u32 freq_if_hz; + u32 xtal_hz; + u32 pll_mfactor; + u32 pll_nfactor; + u32 pll_pfactor; + u32 sample_freq; + + enum fe_bandwidth bandwidth; }; static struct init_tab { @@ -271,6 +281,199 @@ error: return ret; } +static int tda10048_set_phy2(struct dvb_frontend *fe, u32 sample_freq_hz, + u32 if_hz) +{ + struct tda10048_state *state = fe->demodulator_priv; + u64 t; + + dprintk(1, "%s()\n", __func__); + + if (sample_freq_hz == 0) + return -EINVAL; + + if (if_hz < (sample_freq_hz / 2)) { + /* PHY2 = (if2/fs) * 2^15 */ + t = if_hz; + t *= 10; + t *= 32768; + do_div(t, sample_freq_hz); + t += 5; + do_div(t, 10); + } else { + /* PHY2 = ((IF1-fs)/fs) * 2^15 */ + t = sample_freq_hz - if_hz; + t *= 10; + t *= 32768; + do_div(t, sample_freq_hz); + t += 5; + do_div(t, 10); + t = ~t + 1; + } + + tda10048_writereg(state, TDA10048_FREQ_PHY2_LSB, (u8)t); + tda10048_writereg(state, TDA10048_FREQ_PHY2_MSB, (u8)(t >> 8)); + + return 0; +} + +static int tda10048_set_wref(struct dvb_frontend *fe, u32 sample_freq_hz, + u32 bw) +{ + struct tda10048_state *state = fe->demodulator_priv; + u64 t, z; + u32 b = 8000000; + + dprintk(1, "%s()\n", __func__); + + if (sample_freq_hz == 0) + return -EINVAL; + + if (bw == BANDWIDTH_6_MHZ) + b = 6000000; + else + if (bw == BANDWIDTH_7_MHZ) + b = 7000000; + + /* WREF = (B / (7 * fs)) * 2^31 */ + t = b * 10; + /* avoid warning: this decimal constant is unsigned only in ISO C90 */ + /* t *= 2147483648 on 32bit platforms */ + t *= (2048 * 1024); + t *= 1024; + z = 7 * sample_freq_hz; + do_div(t, z); + t += 5; + do_div(t, 10); + + tda10048_writereg(state, TDA10048_TIME_WREF_LSB, (u8)t); + tda10048_writereg(state, TDA10048_TIME_WREF_MID1, (u8)(t >> 8)); + tda10048_writereg(state, TDA10048_TIME_WREF_MID2, (u8)(t >> 16)); + tda10048_writereg(state, TDA10048_TIME_WREF_MSB, (u8)(t >> 24)); + + return 0; +} + +static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz, + u32 bw) +{ + struct tda10048_state *state = fe->demodulator_priv; + u64 t; + u32 b = 8000000; + + dprintk(1, "%s()\n", __func__); + + if (sample_freq_hz == 0) + return -EINVAL; + + if (bw == BANDWIDTH_6_MHZ) + b = 6000000; + else + if (bw == BANDWIDTH_7_MHZ) + b = 7000000; + + /* INVWREF = ((7 * fs) / B) * 2^5 */ + t = sample_freq_hz; + t *= 7; + t *= 32; + t *= 10; + do_div(t, b); + t += 5; + do_div(t, 10); + + tda10048_writereg(state, TDA10048_TIME_INVWREF_LSB, (u8)t); + tda10048_writereg(state, TDA10048_TIME_INVWREF_MSB, (u8)(t >> 8)); + + return 0; +} + +static int tda10048_set_bandwidth(struct dvb_frontend *fe, + enum fe_bandwidth bw) +{ + struct tda10048_state *state = fe->demodulator_priv; + dprintk(1, "%s(bw=%d)\n", __func__, bw); + + /* Bandwidth setting may need to be adjusted */ + switch (bw) { + case BANDWIDTH_6_MHZ: + case BANDWIDTH_7_MHZ: + case BANDWIDTH_8_MHZ: + tda10048_set_wref(fe, state->sample_freq, bw); + tda10048_set_invwref(fe, state->sample_freq, bw); + break; + default: + printk(KERN_ERR "%s() invalid bandwidth\n", __func__); + return -EINVAL; + } + + state->bandwidth = bw; + + return 0; +} + +static int tda10048_set_pll(struct dvb_frontend *fe) +{ + struct tda10048_state *state = fe->demodulator_priv; + int ret = 0; + + dprintk(1, "%s()\n", __func__); + + if ((state->config->clk_freq_khz == TDA10048_CLK_4000) && + (state->config->if_freq_khz == TDA10048_IF_36130)) { + state->freq_if_hz = TDA10048_IF_36130 * 1000; + state->xtal_hz = TDA10048_CLK_4000 * 1000; + state->pll_mfactor = 10; + state->pll_nfactor = 0; + state->pll_pfactor = 0; + } else + if ((state->config->clk_freq_khz == TDA10048_CLK_16000) && + (state->config->if_freq_khz == TDA10048_IF_4300)) { + state->freq_if_hz = TDA10048_IF_4300 * 1000; + state->xtal_hz = TDA10048_CLK_16000 * 1000; + state->pll_mfactor = 10; + state->pll_nfactor = 3; + state->pll_pfactor = 0; + } else + if ((state->config->clk_freq_khz == TDA10048_CLK_16000) && + (state->config->if_freq_khz == TDA10048_IF_4000)) { + state->freq_if_hz = TDA10048_IF_4000 * 1000; + state->xtal_hz = TDA10048_CLK_16000 * 1000; + state->pll_mfactor = 10; + state->pll_nfactor = 3; + state->pll_pfactor = 0; + } else + if ((state->config->clk_freq_khz == TDA10048_CLK_16000) && + (state->config->if_freq_khz == TDA10048_IF_36130)) { + state->freq_if_hz = TDA10048_IF_36130 * 1000; + state->xtal_hz = TDA10048_CLK_16000 * 1000; + state->pll_mfactor = 10; + state->pll_nfactor = 3; + state->pll_pfactor = 0; + } else { + printk(KERN_ERR "%s() Incorrect attach settings\n", __func__); + ret = -EINVAL; + } + + dprintk(1, "- freq_if_hz = %d\n", state->freq_if_hz); + dprintk(1, "- xtal_hz = %d\n", state->xtal_hz); + dprintk(1, "- pll_mfactor = %d\n", state->pll_mfactor); + dprintk(1, "- pll_nfactor = %d\n", state->pll_nfactor); + dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor); + + /* Calculate the sample frequency */ + state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45); + state->sample_freq /= (state->pll_nfactor + 1); + state->sample_freq /= (state->pll_pfactor + 4); + dprintk(1, "- sample_freq = %d\n", state->sample_freq); + + tda10048_set_phy2(fe, state->sample_freq, + state->config->if_freq_khz * 1000); + tda10048_set_wref(fe, state->sample_freq, state->bandwidth); + tda10048_set_invwref(fe, state->sample_freq, state->bandwidth); + + return ret; +} + static int tda10048_firmware_upload(struct dvb_frontend *fe) { struct tda10048_state *state = fe->demodulator_priv; @@ -523,6 +726,9 @@ static int tda10048_set_frontend(struct dvb_frontend *fe, dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); + if (p->u.ofdm.bandwidth != state->bandwidth) + tda10048_set_bandwidth(fe, p->u.ofdm.bandwidth); + if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) @@ -558,9 +764,15 @@ static int tda10048_init(struct dvb_frontend *fe) /* Set either serial or parallel */ tda10048_output_mode(fe, state->config->output_mode); - /* set inversion */ + /* Set inversion */ tda10048_set_inversion(fe, state->config->inversion); + /* Establish default PLL values */ + tda10048_set_pll(fe); + + /* Establish default bandwidth */ + tda10048_set_bandwidth(fe, BANDWIDTH_8_MHZ); + /* Ensure we leave the gate closed */ tda10048_i2c_gate_ctrl(fe, 0); @@ -830,6 +1042,7 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, state->config = config; state->i2c = i2c; state->fwloaded = 0; + state->bandwidth = BANDWIDTH_8_MHZ; /* check if the demod is present */ if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048) @@ -840,6 +1053,10 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; + /* Set the xtal and freq defaults */ + if (tda10048_set_pll(&state->frontend) != 0) + goto error; + /* Leave the gate closed */ tda10048_i2c_gate_ctrl(&state->frontend, 0); diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h index 0457b24..ab9cf5b 100644 --- a/drivers/media/dvb/frontends/tda10048.h +++ b/drivers/media/dvb/frontends/tda10048.h @@ -43,6 +43,20 @@ struct tda10048_config { #define TDA10048_INVERSION_OFF 0 #define TDA10048_INVERSION_ON 1 u8 inversion; + +#define TDA10048_IF_3300 3300 +#define TDA10048_IF_3500 3500 +#define TDA10048_IF_3800 3800 +#define TDA10048_IF_4000 4000 +#define TDA10048_IF_4300 4300 +#define TDA10048_IF_4500 4500 +#define TDA10048_IF_4750 4750 +#define TDA10048_IF_36130 36130 + u16 if_freq_khz; + +#define TDA10048_CLK_4000 4000 +#define TDA10048_CLK_16000 16000 + u16 clk_freq_khz; }; #if defined(CONFIG_DVB_TDA10048) || \ -- cgit v1.1 From e9785250ef2eead8bd5e9166679c0be0595df387 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 26 Apr 2009 05:43:59 -0300 Subject: V4L/DVB (11723): Link firmware to physical device Use the physical device rather than the i2c adapter as the reference device when loading firmwares. This will prevent the sysfs name collision with i2c-dev that has been reported many times. I may have missed other drivers which need the same fix. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/af9013.c | 2 +- drivers/media/dvb/frontends/cx24116.c | 2 +- drivers/media/dvb/frontends/drx397xD.c | 4 ++-- drivers/media/dvb/frontends/nxt200x.c | 6 ++++-- drivers/media/dvb/frontends/or51132.c | 2 +- drivers/media/dvb/frontends/tda10048.c | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index b2b50fb..136c586 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c @@ -1455,7 +1455,7 @@ static int af9013_download_firmware(struct af9013_state *state) af9013_ops.info.name); /* request the firmware, this will block and timeout */ - ret = request_firmware(&fw, fw_file, &state->i2c->dev); + ret = request_firmware(&fw, fw_file, state->i2c->dev.parent); if (ret) { err("did not find the firmware file. (%s) " "Please see linux/Documentation/dvb/ for more details" \ diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index 9b9f572..2410d8b 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c @@ -492,7 +492,7 @@ static int cx24116_firmware_ondemand(struct dvb_frontend *fe) printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE); ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, - &state->i2c->dev); + state->i2c->dev.parent); printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); if (ret) { diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index 172f1f9..0100755 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -123,10 +123,10 @@ static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix) } memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); - if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) { + rc = request_firmware(&fw[ix].file, fw[ix].name, s->i2c->dev.parent); + if (rc != 0) { printk(KERN_ERR "%s: Firmware \"%s\" not available\n", mod_name, fw[ix].name); - rc = -ENOENT; goto exit_err; } diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index a8429eb..eac2065 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c @@ -879,7 +879,8 @@ static int nxt2002_init(struct dvb_frontend* fe) /* request the firmware, this will block until someone uploads it */ printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev); + ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, + state->i2c->dev.parent); printk("nxt2002: Waiting for firmware upload(2)...\n"); if (ret) { printk("nxt2002: No firmware uploaded (timeout or file not found?)\n"); @@ -943,7 +944,8 @@ static int nxt2004_init(struct dvb_frontend* fe) /* request the firmware, this will block until someone uploads it */ printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev); + ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, + state->i2c->dev.parent); printk("nxt2004: Waiting for firmware upload(2)...\n"); if (ret) { printk("nxt2004: No firmware uploaded (timeout or file not found?)\n"); diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index 5ed3254..8133ea3 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c @@ -340,7 +340,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe, } printk("or51132: Waiting for firmware upload(%s)...\n", fwname); - ret = request_firmware(&fw, fwname, &state->i2c->dev); + ret = request_firmware(&fw, fwname, state->i2c->dev.parent); if (ret) { printk(KERN_WARNING "or51132: No firmware up" "loaded(timeout or file not found?)\n"); diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 28f580f..dfa3e2c 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -492,7 +492,7 @@ static int tda10048_firmware_upload(struct dvb_frontend *fe) TDA10048_DEFAULT_FIRMWARE); ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, - &state->i2c->dev); + state->i2c->dev.parent); if (ret) { printk(KERN_ERR "%s: Upload failed. (file not found?)\n", __func__); -- cgit v1.1 From 60c7ef3967edfb2dd59aa149fd25da4779e3261e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 26 Apr 2009 10:03:29 -0300 Subject: V4L/DVB (11724): firedtv: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Acked-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-rc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c index 46a6324..27bca2e 100644 --- a/drivers/media/dvb/firewire/firedtv-rc.c +++ b/drivers/media/dvb/firewire/firedtv-rc.c @@ -18,7 +18,7 @@ #include "firedtv.h" /* fixed table with older keycodes, geared towards MythTV */ -const static u16 oldtable[] = { +static const u16 oldtable[] = { /* code from device: 0x4501...0x451f */ @@ -62,7 +62,7 @@ const static u16 oldtable[] = { }; /* user-modifiable table for a remote as sold in 2008 */ -const static u16 keytable[] = { +static const u16 keytable[] = { /* code from device: 0x0300...0x031f */ -- cgit v1.1 From 6e9c1a2a6766df0cad1632812c6ad05eabf158e4 Mon Sep 17 00:00:00 2001 From: Wen-chien Jesse Sung Date: Tue, 28 Apr 2009 01:11:22 -0300 Subject: V4L/DVB (11730): af9015: support for KWorld MC810 Add USB ID (1b80:c810) for Kworld MC810. Signed-off-by: Wen-chien Jesse Sung Acked-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 8 +++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 965d7bd..06d54b0 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1264,6 +1264,7 @@ static struct usb_device_id af9015_usb_table[] = { /* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1534,7 +1535,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 2, /* max 9 */ + .num_device_descs = 3, /* max 9 */ .devices = { { .name = "AverMedia AVerTV Volar GPS 805 (A805)", @@ -1547,6 +1548,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { .cold_ids = {&af9015_usb_table[22], NULL}, .warm_ids = {NULL}, }, + { + .name = "KWorld Digial MC-810", + .cold_ids = {&af9015_usb_table[23], NULL}, + .warm_ids = {NULL}, + }, } }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 6a4062d..1b5e65f 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -105,6 +105,7 @@ #define USB_PID_KWORLD_395U 0xe396 #define USB_PID_KWORLD_395U_2 0xe39b #define USB_PID_KWORLD_395U_3 0xe395 +#define USB_PID_KWORLD_MC810 0xc810 #define USB_PID_KWORLD_PC160_2T 0xc160 #define USB_PID_KWORLD_VSTREAM_COLD 0x17de #define USB_PID_KWORLD_VSTREAM_WARM 0x17df -- cgit v1.1 From ca19d84295c2579229c5478db8b0f9cd7e821685 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 30 Apr 2009 19:18:08 -0300 Subject: V4L/DVB (11739): remove driver_data direct access of struct device In the near future, the driver core is going to not allow direct access to the driver_data pointer in struct device. Instead, the functions dev_get_drvdata() and dev_set_drvdata() should be used. These functions have been around since the beginning, so are backwards compatible with all older kernel versions. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-1394.c | 4 ++-- drivers/media/dvb/firewire/firedtv-dvb.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 4e20765..2b6eeea 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -225,7 +225,7 @@ fail_free: static int node_remove(struct device *dev) { - struct firedtv *fdtv = dev->driver_data; + struct firedtv *fdtv = dev_get_drvdata(dev); fdtv_dvb_unregister(fdtv); @@ -242,7 +242,7 @@ static int node_remove(struct device *dev) static int node_update(struct unit_directory *ud) { - struct firedtv *fdtv = ud->device.driver_data; + struct firedtv *fdtv = dev_get_drvdata(&ud->device); if (fdtv->isochannel >= 0) cmp_establish_pp_connection(fdtv, fdtv->subunit, diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c index 9d308dd..5742fde 100644 --- a/drivers/media/dvb/firewire/firedtv-dvb.c +++ b/drivers/media/dvb/firewire/firedtv-dvb.c @@ -268,7 +268,7 @@ struct firedtv *fdtv_alloc(struct device *dev, if (!fdtv) return NULL; - dev->driver_data = fdtv; + dev_set_drvdata(dev, fdtv); fdtv->device = dev; fdtv->isochannel = -1; fdtv->voltage = 0xff; -- cgit v1.1 From 223ffe5f8270ba9d069f1cbff9acec095a6f58b1 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 2 May 2009 16:38:47 -0300 Subject: V4L/DVB: cleanup redundant tests on unsigned Remove redundant tests on unsigned. Signed-off-by: Roel Kluin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_v4l.c | 2 +- drivers/media/dvb/ttpci/budget-av.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index 2210cff..ce64c621 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c @@ -458,7 +458,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); if (av7110->analog_tuner_flags) { - if (i->index < 0 || i->index >= 4) + if (i->index >= 4) return -EINVAL; } else { if (i->index != 0) diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 855fe74..8ea9152 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -1413,7 +1413,7 @@ static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) { dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); - if (i->index < 0 || i->index >= KNC1_INPUTS) + if (i->index >= KNC1_INPUTS) return -EINVAL; memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); return 0; -- cgit v1.1 From 8153c3b7d80a2058f91fb0b4ef49190f241ecc34 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 5 May 2009 19:30:27 -0300 Subject: V4L/DVB (11700): tda10048: Added option to block i2c gate control from other drivers. Currently, DVB-T is broken and this fixes it. The PVRUSB2 has an odd I2C bus configuration where opening the i2c gate on the digital and analog demod causes the tuner to fail. This needs to be protected against for the PVRUSB2. Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda10048.c | 3 +++ drivers/media/dvb/frontends/tda10048.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index dfa3e2c..11be469 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -689,6 +689,9 @@ static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) struct tda10048_state *state = fe->demodulator_priv; dprintk(1, "%s(%d)\n", __func__, enable); + if (state->config->disable_gate_access) + return 0; + if (enable) return tda10048_writereg(state, TDA10048_CONF_C4_1, tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02); diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h index ab9cf5b..ee07b50 100644 --- a/drivers/media/dvb/frontends/tda10048.h +++ b/drivers/media/dvb/frontends/tda10048.h @@ -57,6 +57,9 @@ struct tda10048_config { #define TDA10048_CLK_4000 4000 #define TDA10048_CLK_16000 16000 u16 clk_freq_khz; + + /* Disable I2C gate access */ + u8 disable_gate_access; }; #if defined(CONFIG_DVB_TDA10048) || \ -- cgit v1.1 From fd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bf Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Fri, 10 Apr 2009 10:20:00 -0300 Subject: V4L/DVB (11759): dvb-ttpci: Add TS replay capability Implemented TS replay capability. audio/video devices are able to process PES and TS data now. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_av.c | 95 ++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 17 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index e4d0900..2fc90e9 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -89,6 +89,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, struct dvb_demux_feed *feed); +static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len); int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) @@ -437,6 +438,45 @@ static void play_audio_cb(u8 *buf, int count, void *priv) aux_ring_buffer_write(&av7110->aout, buf, count); } + +#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096) + +static ssize_t ts_play(struct av7110 *av7110, const char __user *buf, + unsigned long count, int nonblock, int type) +{ + struct dvb_ringbuffer *rb; + u8 *kb; + unsigned long todo = count; + + dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count); + + rb = (type) ? &av7110->avout : &av7110->aout; + kb = av7110->kbuf[type]; + + if (!kb) + return -ENOBUFS; + + if (nonblock && !FREE_COND_TS) + return -EWOULDBLOCK; + + while (todo >= TS_SIZE) { + if (!FREE_COND_TS) { + if (nonblock) + return count - todo; + if (wait_event_interruptible(rb->queue, FREE_COND_TS)) + return count - todo; + } + if (copy_from_user(kb, buf, TS_SIZE)) + return -EFAULT; + write_ts_to_decoder(av7110, type, kb, TS_SIZE); + todo -= TS_SIZE; + buf += TS_SIZE; + } + + return count - todo; +} + + #define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) @@ -780,11 +820,32 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, } +static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len) +{ + struct ipack *ipack = &av7110->ipack[type]; + + if (!(buf[3] & PAYLOAD)) + return -1; + + if (buf[1] & PAY_START) + av7110_ipack_flush(ipack); + + if (buf[3] & ADAPT_FIELD) { + len -= buf[4] + 1; + buf += buf[4] + 1; + if (!len) + return 0; + } + + av7110_ipack_instant_repack(buf + 4, len - 4, ipack); + return 0; +} + + int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) { struct dvb_demux *demux = feed->demux; struct av7110 *av7110 = (struct av7110 *) demux->priv; - struct ipack *ipack = &av7110->ipack[feed->pes_type]; dprintk(2, "av7110:%p, \n", av7110); @@ -804,20 +865,7 @@ int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t l return -1; } - if (!(buf[3] & 0x10)) /* no payload? */ - return -1; - if (buf[1] & 0x40) - av7110_ipack_flush(ipack); - - if (buf[3] & 0x20) { /* adaptation field? */ - len -= buf[4] + 1; - buf += buf[4] + 1; - if (!len) - return 0; - } - - av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]); - return 0; + return write_ts_to_decoder(av7110, feed->pes_type, buf, len); } @@ -916,6 +964,7 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf, { struct dvb_device *dvbdev = file->private_data; struct av7110 *av7110 = dvbdev->priv; + unsigned char c; dprintk(2, "av7110:%p, \n", av7110); @@ -925,7 +974,12 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf, if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) return -EPERM; - return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); + if (get_user(c, buf)) + return -EFAULT; + if (c == 0x47 && count % TS_SIZE == 0) + return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); + else + return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); } static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) @@ -952,6 +1006,7 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf, { struct dvb_device *dvbdev = file->private_data; struct av7110 *av7110 = dvbdev->priv; + unsigned char c; dprintk(2, "av7110:%p, \n", av7110); @@ -959,7 +1014,13 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf, printk(KERN_ERR "not audio source memory\n"); return -EPERM; } - return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); + + if (get_user(c, buf)) + return -EFAULT; + if (c == 0x47 && count % TS_SIZE == 0) + return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); + else + return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); } static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; -- cgit v1.1 From ef226d00dd041f753163fd3b69c7790496ab8384 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 19 Apr 2009 14:47:01 -0300 Subject: V4L/DVB (11760): dvb-ttpci: Check transport error indicator flag Discard PES packet if transport error indicator flag is set. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_av.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 2fc90e9..2adcaef 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -824,6 +824,11 @@ static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, s { struct ipack *ipack = &av7110->ipack[type]; + if (buf[1] & TRANS_ERROR) { + av7110_ipack_reset(ipack); + return -1; + } + if (!(buf[3] & PAYLOAD)) return -1; -- cgit v1.1 From 452dac4550f757ef263c324d967414aa6c6122d7 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 23 Apr 2009 23:24:33 -0300 Subject: V4L/DVB (11761): dvb-ttpci: Fixed VIDEO_SLOWMOTION ioctl Fixed VIDEO_SLOWMOTION ioctl. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_av.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 2adcaef..7b93ab9 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -1249,7 +1249,8 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, case VIDEO_SLOWMOTION: if (av7110->playing&RP_VIDEO) { - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); + if (av7110->trickmode != TRICK_SLOW) + ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); if (!ret) ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); } else { -- cgit v1.1 From e76ef133522df8ad566d3e176a363ed006ff6829 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 29 Apr 2009 23:09:44 -0300 Subject: V4L/DVB (11762): dvb-ttpci: Fixed return code of av7110_av_start_play av7110_av_start_play() should return 0 on success. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_av.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 7b93ab9..a5ad9b0 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -193,8 +193,6 @@ int av7110_av_start_play(struct av7110 *av7110, int av) ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); break; } - if (!ret) - ret = av7110->playing; return ret; } -- cgit v1.1 From ea3b73dc13d87d92e805f439f3d7bfcb5865db06 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 29 Apr 2009 23:25:07 -0300 Subject: V4L/DVB (11763): dvb-ttpci: Some whitespace adjustments Some whitespace adjustments. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_av.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index a5ad9b0..5388481 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -1126,7 +1126,6 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, if (ret) break; } - if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { if (av7110->playing == RP_AV) { ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); @@ -1186,20 +1185,16 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, case VIDEO_SET_DISPLAY_FORMAT: { video_displayformat_t format = (video_displayformat_t) arg; - switch (format) { case VIDEO_PAN_SCAN: av7110->display_panscan = VID_PAN_SCAN_PREF; break; - case VIDEO_LETTER_BOX: av7110->display_panscan = VID_VC_AND_PS_PREF; break; - case VIDEO_CENTER_CUT_OUT: av7110->display_panscan = VID_CENTRE_CUT_PREF; break; - default: ret = -EINVAL; } @@ -1272,7 +1267,6 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, case VIDEO_CLEAR_BUFFER: dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); av7110_ipack_reset(&av7110->ipack[1]); - if (av7110->playing == RP_AV) { ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); @@ -1293,13 +1287,13 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, break; case VIDEO_SET_STREAMTYPE: - break; default: ret = -ENOIOCTLCMD; break; } + return ret; } @@ -1374,7 +1368,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, case AUDIO_CHANNEL_SELECT: av7110->audiostate.channel_select = (audio_channel_select_t) arg; - switch(av7110->audiostate.channel_select) { case AUDIO_STEREO: ret = audcom(av7110, AUDIO_CMD_STEREO); @@ -1385,7 +1378,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); } break; - case AUDIO_MONO_LEFT: ret = audcom(av7110, AUDIO_CMD_MONO_L); if (!ret) { @@ -1395,7 +1387,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); } break; - case AUDIO_MONO_RIGHT: ret = audcom(av7110, AUDIO_CMD_MONO_R); if (!ret) { @@ -1405,7 +1396,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); } break; - default: ret = -EINVAL; break; @@ -1431,21 +1421,24 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); break; - case AUDIO_SET_ID: + case AUDIO_SET_ID: break; + case AUDIO_SET_MIXER: { struct audio_mixer *amix = (struct audio_mixer *)parg; - ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); break; } + case AUDIO_SET_STREAMTYPE: break; + default: ret = -ENOIOCTLCMD; } + return ret; } -- cgit v1.1 From f0f4633a048128031b1a37253ab7935aca748b6b Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 4 May 2009 21:57:41 -0300 Subject: V4L/DVB (11801): dib0700: reduce xc5000 sleep time for Pinnacle 801e to 10ms According to the xc5000 spec, the reset pin only needs to be held low for 10ms. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 6251b38..dc6cae1 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1346,9 +1346,9 @@ static int dib0700_xc5000_tuner_callback(void *priv, int component, if (command == XC5000_TUNER_RESET) { /* Reset the tuner */ dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0); - msleep(330); /* from Windows USB trace */ + msleep(10); dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1); - msleep(330); /* from Windows USB trace */ + msleep(10); } else { err("xc5000: unknown tuner callback command: %d\n", command); return -EINVAL; -- cgit v1.1 From 302e8acc4137821cd30514da3d91ac109b461c7d Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Wed, 20 May 2009 04:57:10 -0300 Subject: V4L/DVB (11828): Reducing print-level of I2C error prints Reducing the print-levle of I2C error prints cleans some unwanted but unavoidable errors from default syslog-level. Signed-off-by: Matthias Schwarzott Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/b2c2/flexcop-i2c.c | 2 +- drivers/media/dvb/frontends/mt312.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index e2bed50..fd1df23 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -200,7 +200,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1); if (ret < 0) { - err("i2c master_xfer failed"); + deb_i2c("i2c master_xfer failed"); break; } } diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index 5ac9b15..a621f72 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c @@ -77,7 +77,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { - printk(KERN_ERR "%s: ret == %d\n", __func__, ret); + printk(KERN_DEBUG "%s: ret == %d\n", __func__, ret); return -EREMOTEIO; } -- cgit v1.1 From d66b94b4aa2f40e134f8c07c58ae74ef3d523ee0 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2009 05:08:26 -0300 Subject: V4L/DVB (11829): Rewrote frontend-attach mechanism to gain noise-less deactivation of submodules This patch is reorganizing the frontend-attach mechanism in order to gain noise-less (superflous prints) deactivation of submodules. Credits go to Uwe Bugla for helping to clean and test the code. Signed-off-by: Uwe Bugla Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/b2c2/flexcop-common.h | 8 +- drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 760 ++++++++++++++++-------------- 2 files changed, 413 insertions(+), 355 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index 3e1c472..9e2148a 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h @@ -1,9 +1,7 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-common.h - common header file for device-specific source files also. - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-common.h - common header file for device-specific source files + * see flexcop.c for copyright information */ #ifndef __FLEXCOP_COMMON_H__ #define __FLEXCOP_COMMON_H__ diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index f7afab5..3f485bf 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -1,34 +1,27 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-fe-tuner.c - methods for attaching a frontend and controlling DiSEqC. - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling + * see flexcop.c for copyright information */ #include - #include "flexcop.h" - -#include "stv0299.h" -#include "mt352.h" -#include "nxt200x.h" -#include "bcm3510.h" -#include "stv0297.h" #include "mt312.h" -#include "lgdt330x.h" -#include "dvb-pll.h" -#include "tuner-simple.h" - +#include "stv0299.h" #include "s5h1420.h" #include "itd1000.h" - -#include "cx24123.h" #include "cx24113.h" - +#include "cx24123.h" #include "isl6421.h" +#include "mt352.h" +#include "bcm3510.h" +#include "nxt200x.h" +#include "dvb-pll.h" +#include "lgdt330x.h" +#include "tuner-simple.h" +#include "stv0297.h" /* lnb control */ - +#if defined(CONFIG_DVB_MT312_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { struct flexcop_device *fc = fe->dvb->priv; @@ -37,65 +30,62 @@ static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage v = fc->read_ibi_reg(fc, misc_204); switch (voltage) { - case SEC_VOLTAGE_OFF: - v.misc_204.ACPI1_sig = 1; - break; - case SEC_VOLTAGE_13: - v.misc_204.ACPI1_sig = 0; - v.misc_204.LNB_L_H_sig = 0; - break; - case SEC_VOLTAGE_18: - v.misc_204.ACPI1_sig = 0; - v.misc_204.LNB_L_H_sig = 1; - break; - default: - err("unknown SEC_VOLTAGE value"); - return -EINVAL; + case SEC_VOLTAGE_OFF: + v.misc_204.ACPI1_sig = 1; + break; + case SEC_VOLTAGE_13: + v.misc_204.ACPI1_sig = 0; + v.misc_204.LNB_L_H_sig = 0; + break; + case SEC_VOLTAGE_18: + v.misc_204.ACPI1_sig = 0; + v.misc_204.LNB_L_H_sig = 1; + break; + default: + err("unknown SEC_VOLTAGE value"); + return -EINVAL; } return fc->write_ibi_reg(fc, misc_204, v); } +#endif +#if defined(CONFIG_DVB_S5H1420_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) \ + || defined(CONFIG_DVB_MT312_MODULE) static int flexcop_sleep(struct dvb_frontend* fe) { struct flexcop_device *fc = fe->dvb->priv; -/* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */ - if (fc->fe_sleep) return fc->fe_sleep(fe); - -/* v.misc_204.ACPI3_sig = 1; - fc->write_ibi_reg(fc,misc_204,v);*/ - return 0; } +#endif +/* SkyStar2 DVB-S rev 2.3 */ +#if defined(CONFIG_DVB_MT312_MODULE) static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) { - /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ +/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ struct flexcop_device *fc = fe->dvb->priv; flexcop_ibi_value v; u16 ax; v.raw = 0; - deb_tuner("tone = %u\n",tone); switch (tone) { - case SEC_TONE_ON: - ax = 0x01ff; - break; - case SEC_TONE_OFF: - ax = 0; - break; - default: - err("unknown SEC_TONE value"); - return -EINVAL; + case SEC_TONE_ON: + ax = 0x01ff; + break; + case SEC_TONE_OFF: + ax = 0; + break; + default: + err("unknown SEC_TONE value"); + return -EINVAL; } v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */ - v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax; v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax; - return fc->write_ibi_reg(fc,lnb_switch_freq_200,v); } @@ -110,17 +100,16 @@ static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data) static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data) { int i, par = 1, d; - for (i = 7; i >= 0; i--) { d = (data >> i) & 1; par ^= d; flexcop_diseqc_send_bit(fe, d); } - flexcop_diseqc_send_bit(fe, par); } -static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst) +static int flexcop_send_diseqc_msg(struct dvb_frontend *fe, + int len, u8 *msg, unsigned long burst) { int i; @@ -129,7 +118,6 @@ static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, un for (i = 0; i < len; i++) flexcop_diseqc_send_byte(fe,msg[i]); - mdelay(16); if (burst != -1) { @@ -146,50 +134,110 @@ static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, un return 0; } -static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) +static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd) { return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0); } -static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) +static int flexcop_diseqc_send_burst(struct dvb_frontend *fe, + fe_sec_mini_cmd_t minicmd) { return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd); } -/* dvb-s stv0299 */ -static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) +static struct mt312_config skystar23_samsung_tbdu18132_config = { + .demod_address = 0x0e, +}; + +static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + u8 buf[4]; + u32 div; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, + .len = sizeof(buf) }; + struct flexcop_device *fc = fe->dvb->priv; + div = (params->frequency + (125/2)) / 125; + + buf[0] = (div >> 8) & 0x7f; + buf[1] = (div >> 0) & 0xff; + buf[2] = 0x84 | ((div >> 10) & 0x60); + buf[3] = 0x80; + + if (params->frequency < 1550000) + buf[3] |= 0x02; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1) + return -EIO; + return 0; +} + +static void skystar2_rev23_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) +{ + fc->fe = dvb_attach(mt312_attach, + &skystar23_samsung_tbdu18132_config, i2c); + if (fc->fe != NULL) { + struct dvb_frontend_ops *ops = &fc->fe->ops; + ops->tuner_ops.set_params \ + = skystar23_samsung_tbdu18132_tuner_set_params; + ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; + ops->diseqc_send_burst = flexcop_diseqc_send_burst; + ops->set_tone = flexcop_set_tone; + ops->set_voltage = flexcop_set_voltage; + fc->fe_sleep = ops->sleep; + ops->sleep = flexcop_sleep; + fc->dev_type = FC_SKY_REV23; + } +} +#endif + +/* SkyStar2 DVB-S rev 2.6 */ +#if defined(CONFIG_DVB_STV0299_MODULE) +static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, + u32 srate, u32 ratio) { u8 aclk = 0; u8 bclk = 0; - if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } - else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } - else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } - else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } - else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } - else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } - - stv0299_writereg (fe, 0x13, aclk); - stv0299_writereg (fe, 0x14, bclk); - stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); + if (srate < 1500000) { + aclk = 0xb7; bclk = 0x47; + } else if (srate < 3000000) { + aclk = 0xb7; bclk = 0x4b; + } else if (srate < 7000000) { + aclk = 0xb7; bclk = 0x4f; + } else if (srate < 14000000) { + aclk = 0xb7; bclk = 0x53; + } else if (srate < 30000000) { + aclk = 0xb6; bclk = 0x53; + } else if (srate < 45000000) { + aclk = 0xb4; bclk = 0x51; + } + stv0299_writereg(fe, 0x13, aclk); + stv0299_writereg(fe, 0x14, bclk); + stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); + stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); + stv0299_writereg(fe, 0x21, ratio & 0xf0); return 0; } -static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) { u8 buf[4]; u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; + struct i2c_msg msg = { + .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; struct flexcop_device *fc = fe->dvb->priv; - div = params->frequency / 125; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; - buf[2] = 0x84; /* 0xC4 */ + buf[2] = 0x84; /* 0xC4 */ buf[3] = 0x08; if (params->frequency < 1500000) @@ -203,48 +251,48 @@ static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dv } static u8 samsung_tbmu24112_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7D, - 0x05, 0x35, - 0x06, 0x02, - 0x07, 0x00, - 0x08, 0xC3, - 0x0C, 0x00, - 0x0D, 0x81, - 0x0E, 0x23, - 0x0F, 0x12, - 0x10, 0x7E, - 0x11, 0x84, - 0x12, 0xB9, - 0x13, 0x88, - 0x14, 0x89, - 0x15, 0xC9, - 0x16, 0x00, - 0x17, 0x5C, - 0x18, 0x00, - 0x19, 0x00, - 0x1A, 0x00, - 0x1C, 0x00, - 0x1D, 0x00, - 0x1E, 0x00, - 0x1F, 0x3A, - 0x20, 0x2E, - 0x21, 0x80, - 0x22, 0xFF, - 0x23, 0xC1, - 0x28, 0x00, - 0x29, 0x1E, - 0x2A, 0x14, - 0x2B, 0x0F, - 0x2C, 0x09, - 0x2D, 0x05, - 0x31, 0x1F, - 0x32, 0x19, - 0x33, 0xFE, - 0x34, 0x93, - 0xff, 0xff, + 0x01, 0x15, + 0x02, 0x30, + 0x03, 0x00, + 0x04, 0x7D, + 0x05, 0x35, + 0x06, 0x02, + 0x07, 0x00, + 0x08, 0xC3, + 0x0C, 0x00, + 0x0D, 0x81, + 0x0E, 0x23, + 0x0F, 0x12, + 0x10, 0x7E, + 0x11, 0x84, + 0x12, 0xB9, + 0x13, 0x88, + 0x14, 0x89, + 0x15, 0xC9, + 0x16, 0x00, + 0x17, 0x5C, + 0x18, 0x00, + 0x19, 0x00, + 0x1A, 0x00, + 0x1C, 0x00, + 0x1D, 0x00, + 0x1E, 0x00, + 0x1F, 0x3A, + 0x20, 0x2E, + 0x21, 0x80, + 0x22, 0xFF, + 0x23, 0xC1, + 0x28, 0x00, + 0x29, 0x1E, + 0x2A, 0x14, + 0x2B, 0x0F, + 0x2C, 0x09, + 0x2D, 0x05, + 0x31, 0x1F, + 0x32, 0x19, + 0x33, 0xFE, + 0x34, 0x93, + 0xff, 0xff, }; static struct stv0299_config samsung_tbmu24112_config = { @@ -259,27 +307,136 @@ static struct stv0299_config samsung_tbmu24112_config = { .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, }; -/* dvb-t mt352 */ -static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) +static void skystar2_rev26_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) { - static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d }; - static u8 mt352_reset [] = { 0x50, 0x80 }; - static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; - static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 }; + fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); + if (fc->fe != NULL) { + struct dvb_frontend_ops *ops = &fc->fe->ops; + ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; + ops->set_voltage = flexcop_set_voltage; + fc->fe_sleep = ops->sleep; + ops->sleep = flexcop_sleep; + } +} +#endif + +/* SkyStar2 DVB-S rev 2.7 */ +#if defined(CONFIG_DVB_S5H1420_MODULE) +static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { + .demod_address = 0x53, + .invert = 1, + .repeated_start_workaround = 1, + .serial_mpeg = 1, +}; + +static struct itd1000_config skystar2_rev2_7_itd1000_config = { + .i2c_address = 0x61, +}; + +static void skystar2_rev27_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) +{ + /* enable no_base_addr - no repeated start when reading */ + fc->fc_i2c_adap[0].no_base_addr = 1; + fc->fe = dvb_attach(s5h1420_attach, + &skystar2_rev2_7_s5h1420_config, i2c); + if (fc->fe != NULL) { + flexcop_ibi_value r108; + struct i2c_adapter *i2c_tuner \ + = s5h1420_get_tuner_i2c_adapter(fc->fe); + struct dvb_frontend_ops *ops = &fc->fe->ops; + + fc->fe_sleep = ops->sleep; + ops->sleep = flexcop_sleep; + + /* enable no_base_addr - no repeated start when reading */ + fc->fc_i2c_adap[2].no_base_addr = 1; + if (dvb_attach(isl6421_attach, fc->fe, + &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL) + err("ISL6421 could NOT be attached"); + else + info("ISL6421 successfully attached"); + + /* the ITD1000 requires a lower i2c clock - is it a problem ? */ + r108.raw = 0x00000506; + fc->write_ibi_reg(fc, tw_sm_c_108, r108); + if (i2c_tuner) { + if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, + &skystar2_rev2_7_itd1000_config) == NULL) + err("ITD1000 could NOT be attached"); + else + info("ITD1000 successfully attached"); + } + } else + fc->fc_i2c_adap[0].no_base_addr = 0; + /* for the next devices we need it again */ +} +#endif + +/* SkyStar2 rev 2.8 */ +#if defined(CONFIG_DVB_CX24123_MODULE) +static struct cx24123_config skystar2_rev2_8_cx24123_config = { + .demod_address = 0x55, + .dont_use_pll = 1, + .agc_callback = cx24113_agc_callback, +}; + +static const struct cx24113_config skystar2_rev2_8_cx24113_config = { + .i2c_addr = 0x54, + .xtal_khz = 10111, +}; + +static void skystar2_rev28_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) +{ + fc->fe = dvb_attach(cx24123_attach, + &skystar2_rev2_8_cx24123_config, i2c); + if (fc->fe != NULL) { + struct i2c_adapter *i2c_tuner \ + = cx24123_get_tuner_i2c_adapter(fc->fe); + if (i2c_tuner != NULL) { + if (dvb_attach(cx24113_attach, fc->fe, + &skystar2_rev2_8_cx24113_config, + i2c_tuner) == NULL) + err("CX24113 could NOT be attached"); + else + info("CX24113 successfully attached"); + } + + fc->fc_i2c_adap[2].no_base_addr = 1; + if (dvb_attach(isl6421_attach, fc->fe, + &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL) + err("ISL6421 could NOT be attached"); + else + info("ISL6421 successfully attached"); + /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an + * IR-receiver (PIC16F818) - but the card has no input for that ??? */ + } +} +#endif + +/* AirStar DVB-T */ +#if defined(CONFIG_DVB_MT352_MODULE) +static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) +{ + static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d }; + static u8 mt352_reset[] = { 0x50, 0x80 }; + static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 }; + static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 }; static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); udelay(2000); mt352_write(fe, mt352_reset, sizeof(mt352_reset)); mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); - mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); - return 0; } -static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) +static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) { u32 div; unsigned char bs = 0; @@ -287,19 +444,20 @@ static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_fro if (buf_len < 5) return -EINVAL; - #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ +#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - - if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09; - if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; - if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; + if (params->frequency >= 48000000 && params->frequency <= 154000000) \ + bs = 0x09; + if (params->frequency >= 161000000 && params->frequency <= 439000000) \ + bs = 0x0a; + if (params->frequency >= 447000000 && params->frequency <= 863000000) \ + bs = 0x08; pllbuf[0] = 0x61; pllbuf[1] = div >> 8; pllbuf[2] = div & 0xff; pllbuf[3] = 0xcc; pllbuf[4] = bs; - return 5; } @@ -308,70 +466,88 @@ static struct mt352_config samsung_tdtc9251dh0_config = { .demod_init = samsung_tdtc9251dh0_demod_init, }; -static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) +static void airstar_dvbt_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) +{ + fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); + if (fc->fe != NULL) + fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; +} +#endif + +/* AirStar ATSC 1st generation */ +#if defined(CONFIG_DVB_BCM3510_MODULE) +static int flexcop_fe_request_firmware(struct dvb_frontend *fe, + const struct firmware **fw, char* name) { struct flexcop_device *fc = fe->dvb->priv; return request_firmware(fw, name, fc->dev); } -static struct lgdt330x_config air2pc_atsc_hd5000_config = { - .demod_address = 0x59, - .demod_chip = LGDT3303, - .serial_mpeg = 0x04, - .clock_polarity_flip = 1, -}; - -static struct nxt200x_config samsung_tbmv_config = { - .demod_address = 0x0a, -}; - static struct bcm3510_config air2pc_atsc_first_gen_config = { .demod_address = 0x0f, .request_firmware = flexcop_fe_request_firmware, }; -static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static void airstar_atsc1_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) { - u8 buf[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - struct flexcop_device *fc = fe->dvb->priv; - - div = (params->frequency + (125/2)) / 125; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = (div >> 0) & 0xff; - buf[2] = 0x84 | ((div >> 10) & 0x60); - buf[3] = 0x80; + fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); +} +#endif - if (params->frequency < 1550000) - buf[3] |= 0x02; +/* AirStar ATSC 2nd generation */ +#if defined(CONFIG_DVB_NXT200X_MODULE) +static struct nxt200x_config samsung_tbmv_config = { + .demod_address = 0x0a, +}; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; +static void airstar_atsc2_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) +{ + fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c); + if (fc->fe != NULL) + dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, + DVB_PLL_SAMSUNG_TBMV); } +#endif -static struct mt312_config skystar23_samsung_tbdu18132_config = { - - .demod_address = 0x0e, +/* AirStar ATSC 3rd generation */ +#if defined(CONFIG_DVB_LGDT330X_MODULE) +static struct lgdt330x_config air2pc_atsc_hd5000_config = { + .demod_address = 0x59, + .demod_chip = LGDT3303, + .serial_mpeg = 0x04, + .clock_polarity_flip = 1, }; +static void airstar_atsc3_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) +{ + fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c); + if (fc->fe != NULL) { + dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, + TUNER_LG_TDVS_H06XF); + } +} +#endif + +/* CableStar2 DVB-C */ +#if defined(CONFIG_DVB_STV0297_MODULE) static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) + struct dvb_frontend_parameters *fep) { struct flexcop_device *fc = fe->dvb->priv; u8 buf[4]; u16 div; int ret; -/* 62.5 kHz * 10 */ +/* 62.5 kHz * 10 */ #define REF_FREQ 625 #define FREQ_OFFSET 36125 - div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz + div = ((fep->frequency/1000 + FREQ_OFFSET) * 10) / REF_FREQ; +/* 4 MHz = 4000 KHz */ buf[0] = (u8)( div >> 8) & 0x7f; buf[1] = (u8) div & 0xff; @@ -384,11 +560,11 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */ buf[2] = 0x95; -// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 -// 47 - 153 0 * 0 0 0 0 0 1 0x01 -// 153 - 430 0 * 0 0 0 0 1 0 0x02 -// 430 - 822 0 * 0 0 1 0 0 0 0x08 -// 822 - 862 1 * 0 0 1 0 0 0 0x88 +/* Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 + * 47 - 153 0 * 0 0 0 0 0 1 0x01 + * 153 - 430 0 * 0 0 0 0 1 0 0x02 + * 430 - 822 0 * 0 0 1 0 0 0 0x08 + * 822 - 862 1 * 0 0 1 0 0 0 0x88 */ if (fep->frequency <= 153000000) buf[3] = 0x01; else if (fep->frequency <= 430000000) buf[3] = 0x02; @@ -397,11 +573,11 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); + deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n", fep->frequency, + buf[0], buf[1], buf[2], buf[3]); ret = fc->i2c_request(&fc->fc_i2c_adap[2], - FC_WRITE, 0x61, buf[0], &buf[1], 3); + FC_WRITE, 0x61, buf[0], &buf[1], 3); deb_tuner("tuner write returned: %d\n",ret); - return ret; } @@ -481,190 +657,75 @@ static u8 alps_tdee4_stv0297_inittab[] = { static struct stv0297_config alps_tdee4_stv0297_config = { .demod_address = 0x1c, .inittab = alps_tdee4_stv0297_inittab, -// .invert = 1, -// .pll_set = alps_tdee4_stv0297_pll_set, }; - -/* SkyStar2 rev2.7 (a/u) */ -static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { - .demod_address = 0x53, - .invert = 1, - .repeated_start_workaround = 1, - .serial_mpeg = 1, -}; - -static struct itd1000_config skystar2_rev2_7_itd1000_config = { - .i2c_address = 0x61, -}; - -/* SkyStar2 rev2.8 */ -static struct cx24123_config skystar2_rev2_8_cx24123_config = { - .demod_address = 0x55, - .dont_use_pll = 1, - .agc_callback = cx24113_agc_callback, -}; - -static const struct cx24113_config skystar2_rev2_8_cx24113_config = { - .i2c_addr = 0x54, - .xtal_khz = 10111, -}; - -/* try to figure out the frontend, each card/box can have on of the following list */ -int flexcop_frontend_init(struct flexcop_device *fc) +static void cablestar2_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) { - struct dvb_frontend_ops *ops; - struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap; - struct i2c_adapter *i2c_tuner; - - /* enable no_base_addr - no repeated start when reading */ - fc->fc_i2c_adap[0].no_base_addr = 1; - fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, i2c); - if (fc->fe != NULL) { - flexcop_ibi_value r108; - i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe); - ops = &fc->fe->ops; - - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; - - fc->dev_type = FC_SKY_REV27; - - /* enable no_base_addr - no repeated start when reading */ - fc->fc_i2c_adap[2].no_base_addr = 1; - if (dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL) - err("ISL6421 could NOT be attached"); - else - info("ISL6421 successfully attached"); - - /* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */ - r108.raw = 0x00000506; - fc->write_ibi_reg(fc, tw_sm_c_108, r108); - if (i2c_tuner) { - if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, &skystar2_rev2_7_itd1000_config) == NULL) - err("ITD1000 could NOT be attached"); - else - info("ITD1000 successfully attached"); - } - goto fe_found; - } - fc->fc_i2c_adap[0].no_base_addr = 0; /* for the next devices we need it again */ - - /* try the sky v2.8 (cx24123, isl6421) */ - fc->fe = dvb_attach(cx24123_attach, - &skystar2_rev2_8_cx24123_config, i2c); - if (fc->fe != NULL) { - i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe); - if (i2c_tuner != NULL) { - if (dvb_attach(cx24113_attach, fc->fe, - &skystar2_rev2_8_cx24113_config, - i2c_tuner) == NULL) - err("CX24113 could NOT be attached"); - else - info("CX24113 successfully attached"); - } - - fc->dev_type = FC_SKY_REV28; - - fc->fc_i2c_adap[2].no_base_addr = 1; - if (dvb_attach(isl6421_attach, fc->fe, - &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL) - err("ISL6421 could NOT be attached"); - else - info("ISL6421 successfully attached"); - - /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an - * IR-receiver (PIC16F818) - but the card has no input for - * that ??? */ - - goto fe_found; - } - - /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ - fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); - if (fc->fe != NULL) { - ops = &fc->fe->ops; - - ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; - - ops->set_voltage = flexcop_set_voltage; - - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; - - fc->dev_type = FC_SKY_REV26; - goto fe_found; - } - - /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ - fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_AIR_DVBT; - fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; - goto fe_found; - } - - /* try the air atsc 2nd generation (nxt2002) */ - fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_AIR_ATSC2; - dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV); - goto fe_found; - } - - fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_AIR_ATSC3; - dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, - TUNER_LG_TDVS_H06XF); - goto fe_found; - } - - /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ - fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_AIR_ATSC1; - goto fe_found; - } - - /* try the cable dvb (stv0297) */ fc->fc_i2c_adap[0].no_base_addr = 1; fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_CABLE; - fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; - goto fe_found; - } - fc->fc_i2c_adap[0].no_base_addr = 0; - - /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ - fc->fe = dvb_attach(mt312_attach, - &skystar23_samsung_tbdu18132_config, i2c); - if (fc->fe != NULL) { - ops = &fc->fe->ops; - - ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; - - ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; - ops->diseqc_send_burst = flexcop_diseqc_send_burst; - ops->set_tone = flexcop_set_tone; - ops->set_voltage = flexcop_set_voltage; - - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; + if (fc->fe != NULL) + fc->fe->ops.tuner_ops.set_params \ + = alps_tdee4_stv0297_tuner_set_params; + else + fc->fc_i2c_adap[0].no_base_addr = 0; +} +#endif + +static struct { + flexcop_device_type_t type; + void (*attach)(struct flexcop_device *, struct i2c_adapter *); +} flexcop_frontends[] = { +#if defined(CONFIG_DVB_S5H1420_MODULE) + { FC_SKY_REV27, skystar2_rev27_attach }, +#endif +#if defined(CONFIG_DVB_CX24123_MODULE) + { FC_SKY_REV28, skystar2_rev28_attach }, +#endif +#if defined(CONFIG_DVB_STV0299_MODULE) + { FC_SKY_REV26, skystar2_rev26_attach }, +#endif +#if defined(CONFIG_DVB_MT352_MODULE) + { FC_AIR_DVBT, airstar_dvbt_attach }, +#endif +#if defined(CONFIG_DVB_NXT200X_MODULE) + { FC_AIR_ATSC2, airstar_atsc2_attach }, +#endif +#if defined(CONFIG_DVB_LGDT330X_MODULE) + { FC_AIR_ATSC3, airstar_atsc3_attach }, +#endif +#if defined(CONFIG_DVB_BCM3510_MODULE) + { FC_AIR_ATSC1, airstar_atsc1_attach }, +#endif +#if defined(CONFIG_DVB_STV0297_MODULE) + { FC_CABLE, cablestar2_attach }, +#endif +#if defined(CONFIG_DVB_MT312_MODULE) + { FC_SKY_REV23, skystar2_rev23_attach }, +#endif +}; - fc->dev_type = FC_SKY_REV23; - goto fe_found; +/* try to figure out the frontend */ +int flexcop_frontend_init(struct flexcop_device *fc) +{ + int i; + for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) { + /* type needs to be set before, because of some workarounds + * done based on the probed card type */ + fc->dev_type = flexcop_frontends[i].type; + flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap); + if (fc->fe != NULL) + goto fe_found; } - + fc->dev_type = FC_UNK; err("no frontend driver found for this B2C2/FlexCop adapter"); return -ENODEV; fe_found: info("found '%s' .", fc->fe->ops.info.name); if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { + struct dvb_frontend_ops *ops = &fc->fe->ops; err("frontend registration failed!"); - ops = &fc->fe->ops; if (ops->release != NULL) ops->release(fc->fe); fc->fe = NULL; @@ -680,6 +741,5 @@ void flexcop_frontend_exit(struct flexcop_device *fc) dvb_unregister_frontend(fc->fe); dvb_frontend_detach(fc->fe); } - fc->init_state &= ~FC_STATE_FE_INIT; } -- cgit v1.1 From f0f4ae763b3dc04de3745a75c3518925d1b8325e Mon Sep 17 00:00:00 2001 From: tomas petr Date: Wed, 20 May 2009 05:28:05 -0300 Subject: V4L/DVB (11830): dib0700: add support for Leadtek WinFast DTV Dongle H "Leadtek WinFast DTV Dongle H" is a hybrid digital/analog USB-stick TV receiver. The code below allows the digital part to work with dvb_usb in linux. Signed-off-by: tomas petr Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 8 +++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index dc6cae1..b208f24 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1494,6 +1494,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) }, { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) }, /* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) }, + { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1817,7 +1818,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 7, + .num_device_descs = 8, .devices = { { "Terratec Cinergy HT USB XE", { &dib0700_usb_id_table[27], NULL }, @@ -1847,6 +1848,11 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[48], NULL }, { NULL }, }, + { "Leadtek WinFast DTV Dongle H", + { &dib0700_usb_id_table[51], NULL }, + { NULL }, + }, + }, .rc_interval = DEFAULT_RC_INTERVAL, .rc_key_map = dib0700_rc_keys, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 1b5e65f..0722797 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -225,6 +225,7 @@ #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 +#define USB_PID_WINFAST_DTV_DONGLE_H 0x60f6 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 #define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029 #define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 -- cgit v1.1 From a9b8fe30a6d2a49749327ff18c4daa488ef73ab3 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2009 05:35:02 -0300 Subject: V4L/DVB (11831): dib0700: added USB IDs for Terratec T3 and T5 This patch adds the USB IDs for the Terratec devices T3 and T5. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 12 ++++++++---- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index b208f24..818b2ab 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1495,6 +1495,8 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) }, /* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) }, { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) }, + { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) }, + { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1728,8 +1730,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[30], NULL }, { NULL }, }, - { "Terratec Cinergy T USB XXS", - { &dib0700_usb_id_table[33], NULL }, + { "Terratec Cinergy T USB XXS/ T3", + { &dib0700_usb_id_table[33], + &dib0700_usb_id_table[52], NULL }, { NULL }, }, { "Elgato EyeTV DTT", @@ -1790,8 +1793,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[36], NULL }, { NULL }, }, - { "Terratec Cinergy DT USB XS Diversity", - { &dib0700_usb_id_table[43], NULL }, + { "Terratec Cinergy DT USB XS Diversity/ T5", + { &dib0700_usb_id_table[43], + &dib0700_usb_id_table[53], NULL}, { NULL }, }, { "Sony PlayTV", diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 0722797..7340ef4 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -181,6 +181,8 @@ #define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 #define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 #define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 +#define USB_PID_TERRATEC_T3 0x10a0 +#define USB_PID_TERRATEC_T5 0x10a1 #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e #define USB_PID_PINNACLE_PCTV2000E 0x022c #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 -- cgit v1.1 From 81dae6716f13e801cfe2035514e7aeb971b57492 Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Wed, 20 May 2009 05:42:33 -0300 Subject: V4L/DVB (11832): dibusb_mc: fix i2c to not corrupt eeprom in case of strange read pattern dibusb_i2c_xfer seems to do things very dangerous : it assumes that it get only write/read request or write request. That means that read can be understood as write. For example a program doing file = open("/dev/i2c-x", O_RDWR); ioctl(file, I2C_SLAVE, 0x50) read(file, data, 10) will corrupt the eeprom as it will be understood as a write. Signed-off-by: Matthieu CASTET Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dibusb-common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 8ee6cd4..8dbad1e 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -133,14 +133,17 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num for (i = 0; i < num; i++) { /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0 + && (msg[i+1].flags & I2C_M_RD)) { if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len, msg[i+1].buf,msg[i+1].len) < 0) break; i++; - } else + } else if ((msg[i].flags & I2C_M_RD) == 0) { if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) break; + } else + break; } mutex_unlock(&d->i2c_mutex); -- cgit v1.1 From 86cf5f84e60fe32e3e665fdc69325f8993970189 Mon Sep 17 00:00:00 2001 From: Alan Nisota Date: Wed, 20 May 2009 05:52:13 -0300 Subject: V4L/DVB (11833): dvb-usb: Remove support for Genpix-CW3K (damages hardware) I have been informed by the manufacturer that the patch currently in the v4l tree to support the Genpix-CW3K version of the hardware will actually damage the firmware on recent units. As he seems to not want this hardware supported in Linux, and I do not know how to detect the difference between affected and not-affected units, I am requesting the immediate removal of support for this device. This patch removes a portion of the changeset dce7e08ed2b1 applied 2007-08-18 relating to this specific device. Adapted patch to not remove code, but to only to comment it out. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/gp8psk.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index 3dd6843..afb444d 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/drivers/media/dvb/dvb-usb/gp8psk.c @@ -223,7 +223,7 @@ static struct usb_device_id gp8psk_usb_table [] = { { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) }, { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) }, { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) }, - { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, +/* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */ { 0 }, }; MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); @@ -254,7 +254,7 @@ static struct dvb_usb_device_properties gp8psk_properties = { .generic_bulk_ctrl_endpoint = 0x01, - .num_device_descs = 4, + .num_device_descs = 3, .devices = { { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver", .cold_ids = { &gp8psk_usb_table[0], NULL }, @@ -268,10 +268,6 @@ static struct dvb_usb_device_properties gp8psk_properties = { .cold_ids = { NULL }, .warm_ids = { &gp8psk_usb_table[3], NULL }, }, - { .name = "Genpix SkyWalker-CW3K DVB-S receiver", - .cold_ids = { NULL }, - .warm_ids = { &gp8psk_usb_table[4], NULL }, - }, { NULL }, } }; -- cgit v1.1 From eda9f7523b6760bdfc3b9c5001214467b5ecd618 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Tue, 12 May 2009 17:39:28 -0300 Subject: V4L/DVB (11841): core: fix potential mutex_unlock without mutex_lock in dvb_dvr_read dvb_dvr_read may unlock the dmxdev mutex and return -ENODEV, except this function is a file op and will never be called with the mutex held. There's existing mutex_lock and mutex_unlock around the actual read but it's commented out. These should probably be uncommented but the read blocks and this could block another non-blocking reader on the mutex instead. This change comments out the extra mutex_unlock. [akpm@linux-foundation.org: cleanups, simplification] Signed-off-by: Simon Arlott Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dmxdev.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index c35fbb8..6d6121e 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -244,19 +244,13 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; - int ret; - if (dmxdev->exit) { - mutex_unlock(&dmxdev->mutex); + if (dmxdev->exit) return -ENODEV; - } - //mutex_lock(&dmxdev->mutex); - ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, - file->f_flags & O_NONBLOCK, - buf, count, ppos); - //mutex_unlock(&dmxdev->mutex); - return ret; + return dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, + file->f_flags & O_NONBLOCK, + buf, count, ppos); } static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev, -- cgit v1.1 From 9e08199770f28b92e5a85052e8c16cde94f9a2c9 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 15 May 2009 21:01:57 -0300 Subject: V4L/DVB (11854): TDA10048: Ensure the I/F changes during DVB-T 6/7/8 bandwidth changes. TDA10048: Ensure the I/F changes during DVB-T 6/7/8 bandwidth changes. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda10048.c | 184 ++++++++++++++++++++++----------- drivers/media/dvb/frontends/tda10048.h | 6 +- 2 files changed, 127 insertions(+), 63 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 11be469..6707832 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -1,7 +1,7 @@ /* NXP TDA10048HN DVB OFDM demodulator driver - Copyright (C) 2008 Steven Toth + Copyright (C) 2009 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 @@ -139,8 +139,8 @@ struct tda10048_state { struct i2c_adapter *i2c; - /* configuration settings */ - const struct tda10048_config *config; + /* We'll cache and update the attach config settings */ + struct tda10048_config config; struct dvb_frontend frontend; int fwloaded; @@ -202,12 +202,24 @@ static struct init_tab { { TDA10048_CONF_C4_2, 0x04 }, }; +static struct pll_tab { + u32 clk_freq_khz; + u32 if_freq_khz; + u8 m, n, p; +} pll_tab[] = { + { TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 }, + { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 }, + { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 }, + { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 }, +}; + static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) { + struct tda10048_config *config = &state->config; int ret; u8 buf[] = { reg, data }; struct i2c_msg msg = { - .addr = state->config->demod_address, + .addr = config->demod_address, .flags = 0, .buf = buf, .len = 2 }; dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data); @@ -222,13 +234,14 @@ static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) { + struct tda10048_config *config = &state->config; int ret; u8 b0[] = { reg }; u8 b1[] = { 0 }; struct i2c_msg msg[] = { - { .addr = state->config->demod_address, + { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, + { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg); @@ -245,6 +258,7 @@ static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, const u8 *data, u16 len) { + struct tda10048_config *config = &state->config; int ret = -EREMOTEIO; struct i2c_msg msg; u8 *buf; @@ -260,7 +274,7 @@ static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, *buf = reg; memcpy(buf + 1, data, len); - msg.addr = state->config->demod_address; + msg.addr = config->demod_address; msg.flags = 0; msg.buf = buf; msg.len = len + 1; @@ -411,47 +425,47 @@ static int tda10048_set_bandwidth(struct dvb_frontend *fe, return 0; } -static int tda10048_set_pll(struct dvb_frontend *fe) +static int tda10048_set_if(struct dvb_frontend *fe, enum fe_bandwidth bw) { struct tda10048_state *state = fe->demodulator_priv; - int ret = 0; + struct tda10048_config *config = &state->config; + int i; + u32 if_freq_khz; - dprintk(1, "%s()\n", __func__); + dprintk(1, "%s(bw = %d)\n", __func__, bw); - if ((state->config->clk_freq_khz == TDA10048_CLK_4000) && - (state->config->if_freq_khz == TDA10048_IF_36130)) { - state->freq_if_hz = TDA10048_IF_36130 * 1000; - state->xtal_hz = TDA10048_CLK_4000 * 1000; - state->pll_mfactor = 10; - state->pll_nfactor = 0; - state->pll_pfactor = 0; - } else - if ((state->config->clk_freq_khz == TDA10048_CLK_16000) && - (state->config->if_freq_khz == TDA10048_IF_4300)) { - state->freq_if_hz = TDA10048_IF_4300 * 1000; - state->xtal_hz = TDA10048_CLK_16000 * 1000; - state->pll_mfactor = 10; - state->pll_nfactor = 3; - state->pll_pfactor = 0; - } else - if ((state->config->clk_freq_khz == TDA10048_CLK_16000) && - (state->config->if_freq_khz == TDA10048_IF_4000)) { - state->freq_if_hz = TDA10048_IF_4000 * 1000; - state->xtal_hz = TDA10048_CLK_16000 * 1000; - state->pll_mfactor = 10; - state->pll_nfactor = 3; - state->pll_pfactor = 0; - } else - if ((state->config->clk_freq_khz == TDA10048_CLK_16000) && - (state->config->if_freq_khz == TDA10048_IF_36130)) { - state->freq_if_hz = TDA10048_IF_36130 * 1000; - state->xtal_hz = TDA10048_CLK_16000 * 1000; - state->pll_mfactor = 10; - state->pll_nfactor = 3; - state->pll_pfactor = 0; - } else { - printk(KERN_ERR "%s() Incorrect attach settings\n", __func__); - ret = -EINVAL; + /* based on target bandwidth and clk we calculate pll factors */ + switch (bw) { + case BANDWIDTH_6_MHZ: + if_freq_khz = config->dtv6_if_freq_khz; + break; + case BANDWIDTH_7_MHZ: + if_freq_khz = config->dtv7_if_freq_khz; + break; + case BANDWIDTH_8_MHZ: + if_freq_khz = config->dtv8_if_freq_khz; + break; + default: + printk(KERN_ERR "%s() no default\n", __func__); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(pll_tab); i++) { + if ((pll_tab[i].clk_freq_khz == config->clk_freq_khz) && + (pll_tab[i].if_freq_khz == if_freq_khz)) { + + state->freq_if_hz = pll_tab[i].if_freq_khz * 1000; + state->xtal_hz = pll_tab[i].clk_freq_khz * 1000; + state->pll_mfactor = pll_tab[i].m; + state->pll_nfactor = pll_tab[i].n; + state->pll_pfactor = pll_tab[i].p; + break; + } + } + if (i == ARRAY_SIZE(pll_tab)) { + printk(KERN_ERR "%s() Incorrect attach settings\n", + __func__); + return -EINVAL; } dprintk(1, "- freq_if_hz = %d\n", state->freq_if_hz); @@ -466,22 +480,21 @@ static int tda10048_set_pll(struct dvb_frontend *fe) state->sample_freq /= (state->pll_pfactor + 4); dprintk(1, "- sample_freq = %d\n", state->sample_freq); - tda10048_set_phy2(fe, state->sample_freq, - state->config->if_freq_khz * 1000); - tda10048_set_wref(fe, state->sample_freq, state->bandwidth); - tda10048_set_invwref(fe, state->sample_freq, state->bandwidth); + /* Update the I/F */ + tda10048_set_phy2(fe, state->sample_freq, state->freq_if_hz); - return ret; + return 0; } static int tda10048_firmware_upload(struct dvb_frontend *fe) { struct tda10048_state *state = fe->demodulator_priv; + struct tda10048_config *config = &state->config; const struct firmware *fw; int ret; int pos = 0; int cnt; - u8 wlen = state->config->fwbulkwritelen; + u8 wlen = config->fwbulkwritelen; if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50)) wlen = TDA10048_BULKWRITE_200; @@ -687,9 +700,10 @@ static int tda10048_get_tps(struct tda10048_state *state, static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { struct tda10048_state *state = fe->demodulator_priv; + struct tda10048_config *config = &state->config; dprintk(1, "%s(%d)\n", __func__, enable); - if (state->config->disable_gate_access) + if (config->disable_gate_access) return 0; if (enable) @@ -729,8 +743,11 @@ static int tda10048_set_frontend(struct dvb_frontend *fe, dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); - if (p->u.ofdm.bandwidth != state->bandwidth) + /* Update the I/F pll's if the bandwidth changes */ + if (p->u.ofdm.bandwidth != state->bandwidth) { + tda10048_set_if(fe, p->u.ofdm.bandwidth); tda10048_set_bandwidth(fe, p->u.ofdm.bandwidth); + } if (fe->ops.tuner_ops.set_params) { @@ -753,6 +770,7 @@ static int tda10048_set_frontend(struct dvb_frontend *fe, static int tda10048_init(struct dvb_frontend *fe) { struct tda10048_state *state = fe->demodulator_priv; + struct tda10048_config *config = &state->config; int ret = 0, i; dprintk(1, "%s()\n", __func__); @@ -765,15 +783,13 @@ static int tda10048_init(struct dvb_frontend *fe) ret = tda10048_firmware_upload(fe); /* Set either serial or parallel */ - tda10048_output_mode(fe, state->config->output_mode); + tda10048_output_mode(fe, config->output_mode); /* Set inversion */ - tda10048_set_inversion(fe, state->config->inversion); + tda10048_set_inversion(fe, config->inversion); - /* Establish default PLL values */ - tda10048_set_pll(fe); - - /* Establish default bandwidth */ + /* Establish default RF values */ + tda10048_set_if(fe, BANDWIDTH_8_MHZ); tda10048_set_bandwidth(fe, BANDWIDTH_8_MHZ); /* Ensure we leave the gate closed */ @@ -1027,6 +1043,45 @@ static void tda10048_release(struct dvb_frontend *fe) kfree(state); } +static void tda10048_establish_defaults(struct dvb_frontend *fe) +{ + struct tda10048_state *state = fe->demodulator_priv; + struct tda10048_config *config = &state->config; + + /* Validate/default the config */ + if (config->dtv6_if_freq_khz == 0) { + config->dtv6_if_freq_khz = TDA10048_IF_4300; + printk(KERN_WARNING "%s() tda10048_config.dtv6_if_freq_khz " + "is not set (defaulting to %d)\n", + __func__, + config->dtv6_if_freq_khz); + } + + if (config->dtv7_if_freq_khz == 0) { + config->dtv7_if_freq_khz = TDA10048_IF_4300; + printk(KERN_WARNING "%s() tda10048_config.dtv7_if_freq_khz " + "is not set (defaulting to %d)\n", + __func__, + config->dtv7_if_freq_khz); + } + + if (config->dtv8_if_freq_khz == 0) { + config->dtv8_if_freq_khz = TDA10048_IF_4300; + printk(KERN_WARNING "%s() tda10048_config.dtv8_if_freq_khz " + "is not set (defaulting to %d)\n", + __func__, + config->dtv8_if_freq_khz); + } + + if (config->clk_freq_khz == 0) { + config->clk_freq_khz = TDA10048_CLK_16000; + printk(KERN_WARNING "%s() tda10048_config.clk_freq_khz " + "is not set (defaulting to %d)\n", + __func__, + config->clk_freq_khz); + } +} + static struct dvb_frontend_ops tda10048_ops; struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, @@ -1041,8 +1096,8 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, if (state == NULL) goto error; - /* setup the state */ - state->config = config; + /* setup the state and clone the config */ + memcpy(&state->config, config, sizeof(*config)); state->i2c = i2c; state->fwloaded = 0; state->bandwidth = BANDWIDTH_8_MHZ; @@ -1056,8 +1111,15 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; + /* Establish any defaults the the user didn't pass */ + tda10048_establish_defaults(&state->frontend); + /* Set the xtal and freq defaults */ - if (tda10048_set_pll(&state->frontend) != 0) + if (tda10048_set_if(&state->frontend, BANDWIDTH_8_MHZ) != 0) + goto error; + + /* Default bandwidth */ + if (tda10048_set_bandwidth(&state->frontend, BANDWIDTH_8_MHZ) != 0) goto error; /* Leave the gate closed */ diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h index ee07b50..8828cea 100644 --- a/drivers/media/dvb/frontends/tda10048.h +++ b/drivers/media/dvb/frontends/tda10048.h @@ -1,7 +1,7 @@ /* NXP TDA10048HN DVB OFDM demodulator driver - Copyright (C) 2008 Steven Toth + Copyright (C) 2009 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 @@ -52,7 +52,9 @@ struct tda10048_config { #define TDA10048_IF_4500 4500 #define TDA10048_IF_4750 4750 #define TDA10048_IF_36130 36130 - u16 if_freq_khz; + u16 dtv6_if_freq_khz; + u16 dtv7_if_freq_khz; + u16 dtv8_if_freq_khz; #define TDA10048_CLK_4000 4000 #define TDA10048_CLK_16000 16000 -- cgit v1.1 From a884c63cae986cadb6d604f3599a5cf54444f7d2 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 16 May 2009 14:43:51 -0300 Subject: V4L/DVB (11857): TDA10048: Missing two I/F's / Pll combinations from the PLL table This was causing a lock failure in Australia. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda10048.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 6707832..4302c56 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -208,8 +208,10 @@ static struct pll_tab { u8 m, n, p; } pll_tab[] = { { TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 }, - { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 }, + { TDA10048_CLK_16000, TDA10048_IF_3300, 10, 3, 0 }, + { TDA10048_CLK_16000, TDA10048_IF_3500, 10, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 }, + { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 }, }; -- cgit v1.1 From 22d4645311689cd20967813775e492c786f2d3c6 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 31 May 2009 17:07:01 -0300 Subject: V4L/DVB (11915): af9015: support for Genius TVGo DVB-T03 Add USB ID (0458:4012) for Genius TVGo DVB-T03. Thanks to Petr Vodicka for reporting and testing. Tested-by: Petr Vodicka Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 8 +++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 06d54b0..9155a79 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1265,6 +1265,7 @@ static struct usb_device_id af9015_usb_table[] = { {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, + {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1535,7 +1536,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 3, /* max 9 */ + .num_device_descs = 4, /* max 9 */ .devices = { { .name = "AverMedia AVerTV Volar GPS 805 (A805)", @@ -1553,6 +1554,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { .cold_ids = {&af9015_usb_table[23], NULL}, .warm_ids = {NULL}, }, + { + .name = "Genius TVGo DVB-T03", + .cold_ids = {&af9015_usb_table[24], NULL}, + .warm_ids = {NULL}, + }, } }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 7340ef4..9593b72 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -98,6 +98,7 @@ #define USB_PID_DPOSH_M9206_COLD 0x9206 #define USB_PID_DPOSH_M9206_WARM 0xa090 #define USB_PID_UNIWILL_STK7700P 0x6003 +#define USB_PID_GENIUS_TVGO_DVB_T03 0x4012 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 #define USB_PID_INTEL_CE9500 0x9500 -- cgit v1.1 From 0d834635a35a98d0dced54da7695ccab4464854d Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Sat, 6 Jun 2009 09:31:34 -0300 Subject: V4L/DVB (11930): TS continuity check: show error message when discontinuity detected or TEI flag detected in header Signed-off-by: Abylay Ospan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_demux.c | 42 ++++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-core/dvb_demux.h | 4 ++++ 2 files changed, 46 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index e2eca0b..cfe2768 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -38,6 +38,16 @@ */ // #define DVB_DEMUX_SECTION_LOSS_LOG +static int dvb_demux_tscheck; +module_param(dvb_demux_tscheck, int, 0644); +MODULE_PARM_DESC(dvb_demux_tscheck, + "enable transport stream continuity and TEI check"); + +#define dprintk_tscheck(x...) do { \ + if (dvb_demux_tscheck && printk_ratelimit()) \ + printk(x); \ + } while (0) + /****************************************************************************** * static inlined helper functions ******************************************************************************/ @@ -376,6 +386,36 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) u16 pid = ts_pid(buf); int dvr_done = 0; + if (dvb_demux_tscheck) { + if (!demux->cnt_storage) + demux->cnt_storage = vmalloc(MAX_PID + 1); + + if (!demux->cnt_storage) { + printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n"); + dvb_demux_tscheck = 0; + goto no_dvb_demux_tscheck; + } + + /* check pkt counter */ + if (pid < MAX_PID) { + if (buf[1] & 0x80) + dprintk_tscheck("TEI detected. " + "PID=0x%x data1=0x%x\n", + pid, buf[1]); + + if ((buf[3] & 0xf) != demux->cnt_storage[pid]) + dprintk_tscheck("TS packet counter mismatch. " + "PID=0x%x expected 0x%x " + "got 0x%x\n", + pid, demux->cnt_storage[pid], + buf[3] & 0xf); + + demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf; + }; + /* end check */ + }; +no_dvb_demux_tscheck: + list_for_each_entry(feed, &demux->feed_list, list_head) { if ((feed->pid != pid) && (feed->pid != 0x2000)) continue; @@ -1160,6 +1200,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) int i; struct dmx_demux *dmx = &dvbdemux->dmx; + dvbdemux->cnt_storage = NULL; dvbdemux->users = 0; dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter)); @@ -1226,6 +1267,7 @@ EXPORT_SYMBOL(dvb_dmx_init); void dvb_dmx_release(struct dvb_demux *dvbdemux) { + vfree(dvbdemux->cnt_storage); vfree(dvbdemux->filter); vfree(dvbdemux->feed); } diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h index 2c5f915..2fe05d0 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/drivers/media/dvb/dvb-core/dvb_demux.h @@ -42,6 +42,8 @@ #define DVB_DEMUX_MASK_MAX 18 +#define MAX_PID 0x1fff + struct dvb_demux_filter { struct dmx_section_filter filter; u8 maskandmode[DMX_MAX_FILTER_SIZE]; @@ -127,6 +129,8 @@ struct dvb_demux { struct mutex mutex; spinlock_t lock; + + uint8_t *cnt_storage; /* for TS continuity check */ }; int dvb_dmx_init(struct dvb_demux *dvbdemux); -- cgit v1.1 From 3cd5270c411538329ccc135189c68d2b4544c49a Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 22 May 2009 21:07:46 -0300 Subject: V4L/DVB (11931): lnbp21: Add missing newline Reported-by: VDR User Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lnbp21.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c index 1dcc56f..71f607f 100644 --- a/drivers/media/dvb/frontends/lnbp21.c +++ b/drivers/media/dvb/frontends/lnbp21.c @@ -133,7 +133,7 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, /* override frontend ops */ fe->ops.set_voltage = lnbp21_set_voltage; fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; - printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr); + printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr); return fe; } -- cgit v1.1 From eccd15aad72f774b2059f708bc422dbb8493bb30 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Thu, 11 Jun 2009 05:33:00 -0300 Subject: V4L/DVB (11964): b2c2: Fix problems with frontend attachment The frontend attachment code didn't handle cases where the frontend partially failed to attach. For instance, when the demod was attached successfully but the tuner driver wasn't compiled or fails to init for some reason. In these cases we try to clean up the partial attachment and fail instead of proceeding with a broken frontend. If frontend registration fails, clean up with dvb_frontend_detach() rather than just calling the frontend's main release method. The former does some additional stuff, like release an attached tuner and take care of putting symbols when dynamic binding is used. In skystar2_rev23_attach() it's not necessary to set fc->dev_type, that gets set before skystar2_rev23_attach() is called. Signed-off-by: Trent Piepho Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 196 +++++++++++++++++------------- 1 file changed, 113 insertions(+), 83 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 3f485bf..efb4a6c 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -175,23 +175,23 @@ static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe, return 0; } -static void skystar2_rev23_attach(struct flexcop_device *fc, +static int skystar2_rev23_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { - fc->fe = dvb_attach(mt312_attach, - &skystar23_samsung_tbdu18132_config, i2c); + fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c); if (fc->fe != NULL) { struct dvb_frontend_ops *ops = &fc->fe->ops; - ops->tuner_ops.set_params \ - = skystar23_samsung_tbdu18132_tuner_set_params; + ops->tuner_ops.set_params = + skystar23_samsung_tbdu18132_tuner_set_params; ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; ops->diseqc_send_burst = flexcop_diseqc_send_burst; ops->set_tone = flexcop_set_tone; ops->set_voltage = flexcop_set_voltage; fc->fe_sleep = ops->sleep; ops->sleep = flexcop_sleep; - fc->dev_type = FC_SKY_REV23; + return 1; } + return 0; } #endif @@ -307,7 +307,7 @@ static struct stv0299_config samsung_tbmu24112_config = { .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, }; -static void skystar2_rev26_attach(struct flexcop_device *fc, +static int skystar2_rev26_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); @@ -317,7 +317,9 @@ static void skystar2_rev26_attach(struct flexcop_device *fc, ops->set_voltage = flexcop_set_voltage; fc->fe_sleep = ops->sleep; ops->sleep = flexcop_sleep; + return 1; } + return 0; } #endif @@ -334,43 +336,54 @@ static struct itd1000_config skystar2_rev2_7_itd1000_config = { .i2c_address = 0x61, }; -static void skystar2_rev27_attach(struct flexcop_device *fc, +static int skystar2_rev27_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { + flexcop_ibi_value r108; + struct i2c_adapter *i2c_tuner; + /* enable no_base_addr - no repeated start when reading */ fc->fc_i2c_adap[0].no_base_addr = 1; - fc->fe = dvb_attach(s5h1420_attach, - &skystar2_rev2_7_s5h1420_config, i2c); - if (fc->fe != NULL) { - flexcop_ibi_value r108; - struct i2c_adapter *i2c_tuner \ - = s5h1420_get_tuner_i2c_adapter(fc->fe); - struct dvb_frontend_ops *ops = &fc->fe->ops; + fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, + i2c); + if (!fc->fe) + goto fail; - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; - - /* enable no_base_addr - no repeated start when reading */ - fc->fc_i2c_adap[2].no_base_addr = 1; - if (dvb_attach(isl6421_attach, fc->fe, - &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL) - err("ISL6421 could NOT be attached"); - else - info("ISL6421 successfully attached"); - - /* the ITD1000 requires a lower i2c clock - is it a problem ? */ - r108.raw = 0x00000506; - fc->write_ibi_reg(fc, tw_sm_c_108, r108); - if (i2c_tuner) { - if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, - &skystar2_rev2_7_itd1000_config) == NULL) - err("ITD1000 could NOT be attached"); - else - info("ITD1000 successfully attached"); - } - } else - fc->fc_i2c_adap[0].no_base_addr = 0; - /* for the next devices we need it again */ + i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe); + if (!i2c_tuner) + goto fail; + + fc->fe_sleep = fc->fe->ops.sleep; + fc->fe->ops.sleep = flexcop_sleep; + + /* enable no_base_addr - no repeated start when reading */ + fc->fc_i2c_adap[2].no_base_addr = 1; + if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, + 0x08, 1, 1)) { + err("ISL6421 could NOT be attached"); + goto fail_isl; + } + info("ISL6421 successfully attached"); + + /* the ITD1000 requires a lower i2c clock - is it a problem ? */ + r108.raw = 0x00000506; + fc->write_ibi_reg(fc, tw_sm_c_108, r108); + if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner, + &skystar2_rev2_7_itd1000_config)) { + err("ITD1000 could NOT be attached"); + /* Should i2c clock be restored? */ + goto fail_isl; + } + info("ITD1000 successfully attached"); + + return 1; + +fail_isl: + fc->fc_i2c_adap[2].no_base_addr = 0; +fail: + /* for the next devices we need it again */ + fc->fc_i2c_adap[0].no_base_addr = 0; + return 0; } #endif @@ -387,32 +400,38 @@ static const struct cx24113_config skystar2_rev2_8_cx24113_config = { .xtal_khz = 10111, }; -static void skystar2_rev28_attach(struct flexcop_device *fc, +static int skystar2_rev28_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { - fc->fe = dvb_attach(cx24123_attach, - &skystar2_rev2_8_cx24123_config, i2c); - if (fc->fe != NULL) { - struct i2c_adapter *i2c_tuner \ - = cx24123_get_tuner_i2c_adapter(fc->fe); - if (i2c_tuner != NULL) { - if (dvb_attach(cx24113_attach, fc->fe, - &skystar2_rev2_8_cx24113_config, - i2c_tuner) == NULL) - err("CX24113 could NOT be attached"); - else - info("CX24113 successfully attached"); - } + struct i2c_adapter *i2c_tuner; + + fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config, + i2c); + if (!fc->fe) + return 0; + + i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);; + if (!i2c_tuner) + return 0; - fc->fc_i2c_adap[2].no_base_addr = 1; - if (dvb_attach(isl6421_attach, fc->fe, - &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL) - err("ISL6421 could NOT be attached"); - else - info("ISL6421 successfully attached"); + if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config, + i2c_tuner)) { + err("CX24113 could NOT be attached"); + return 0; + } + info("CX24113 successfully attached"); + + fc->fc_i2c_adap[2].no_base_addr = 1; + if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, + 0x08, 0, 0)) { + err("ISL6421 could NOT be attached"); + fc->fc_i2c_adap[2].no_base_addr = 0; + return 0; + } + info("ISL6421 successfully attached"); /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an * IR-receiver (PIC16F818) - but the card has no input for that ??? */ - } + return 1; } #endif @@ -466,12 +485,15 @@ static struct mt352_config samsung_tdtc9251dh0_config = { .demod_init = samsung_tdtc9251dh0_demod_init, }; -static void airstar_dvbt_attach(struct flexcop_device *fc, +static int airstar_dvbt_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); - if (fc->fe != NULL) + if (fc->fe != NULL) { fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; + return 1; + } + return 0; } #endif @@ -489,10 +511,11 @@ static struct bcm3510_config air2pc_atsc_first_gen_config = { .request_firmware = flexcop_fe_request_firmware, }; -static void airstar_atsc1_attach(struct flexcop_device *fc, +static int airstar_atsc1_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); + return fc->fe != NULL; } #endif @@ -502,13 +525,15 @@ static struct nxt200x_config samsung_tbmv_config = { .demod_address = 0x0a, }; -static void airstar_atsc2_attach(struct flexcop_device *fc, +static int airstar_atsc2_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c); - if (fc->fe != NULL) - dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, - DVB_PLL_SAMSUNG_TBMV); + if (!fc->fe) + return 0; + + return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, + DVB_PLL_SAMSUNG_TBMV); } #endif @@ -521,14 +546,15 @@ static struct lgdt330x_config air2pc_atsc_hd5000_config = { .clock_polarity_flip = 1, }; -static void airstar_atsc3_attach(struct flexcop_device *fc, +static int airstar_atsc3_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c); - if (fc->fe != NULL) { - dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, - TUNER_LG_TDVS_H06XF); - } + if (!fc->fe) + return 0; + + return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, + TUNER_LG_TDVS_H06XF); } #endif @@ -659,22 +685,24 @@ static struct stv0297_config alps_tdee4_stv0297_config = { .inittab = alps_tdee4_stv0297_inittab, }; -static void cablestar2_attach(struct flexcop_device *fc, +static int cablestar2_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { fc->fc_i2c_adap[0].no_base_addr = 1; fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); - if (fc->fe != NULL) - fc->fe->ops.tuner_ops.set_params \ - = alps_tdee4_stv0297_tuner_set_params; - else + if (!fc->fe) { + /* Reset for next frontend to try */ fc->fc_i2c_adap[0].no_base_addr = 0; + return 0; + } + fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; + return 1; } #endif static struct { flexcop_device_type_t type; - void (*attach)(struct flexcop_device *, struct i2c_adapter *); + int (*attach)(struct flexcop_device *, struct i2c_adapter *); } flexcop_frontends[] = { #if defined(CONFIG_DVB_S5H1420_MODULE) { FC_SKY_REV27, skystar2_rev27_attach }, @@ -713,9 +741,13 @@ int flexcop_frontend_init(struct flexcop_device *fc) /* type needs to be set before, because of some workarounds * done based on the probed card type */ fc->dev_type = flexcop_frontends[i].type; - flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap); - if (fc->fe != NULL) + if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap)) goto fe_found; + /* Clean up partially attached frontend */ + if (fc->fe) { + dvb_frontend_detach(fc->fe); + fc->fe = NULL; + } } fc->dev_type = FC_UNK; err("no frontend driver found for this B2C2/FlexCop adapter"); @@ -724,10 +756,8 @@ int flexcop_frontend_init(struct flexcop_device *fc) fe_found: info("found '%s' .", fc->fe->ops.info.name); if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { - struct dvb_frontend_ops *ops = &fc->fe->ops; err("frontend registration failed!"); - if (ops->release != NULL) - ops->release(fc->fe); + dvb_frontend_detach(fc->fe); fc->fe = NULL; return -EINVAL; } -- cgit v1.1 From 8a8dad71485cbfc21ddc0e93f4ae4338b68b82b1 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sat, 13 Jun 2009 08:10:24 -0300 Subject: V4L/DVB (11981): Remote control debugging for dw2102 driver based USB cards Remote control debugging for dw2102 driver based USB cards It includes DVBWorld, TeVii, Terratec and others. Type 'modprobe dvb-usb-dw2102 debug=4', then look at dmesg output. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 27 ++++++++++++++++++++------- drivers/media/dvb/dvb-usb/dw2102.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index c65f273..dee9399 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -51,7 +51,9 @@ struct dw210x_rc_keys { /* debug */ static int dvb_usb_dw2102_debug; module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); +MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." + DVB_USB_DEBUG_STATUS); + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -553,26 +555,37 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { struct dw210x_state *st = d->priv; u8 key[2]; - struct i2c_msg msg[] = { - {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, - .len = 2}, + struct i2c_msg msg = { + .addr = DW2102_RC_QUERY, + .flags = I2C_M_RD, + .buf = key, + .len = 2 }; int i; *state = REMOTE_NO_KEY_PRESSED; - if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { + if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) { for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) { - if (dw210x_rc_keys[i].data == msg[0].buf[0]) { + if (dw210x_rc_keys[i].data == msg.buf[0]) { *state = REMOTE_KEY_PRESSED; *event = dw210x_rc_keys[i].event; st->last_key_pressed = dw210x_rc_keys[i].event; break; } + st->last_key_pressed = 0; } + + if ((*state) == REMOTE_KEY_PRESSED) + deb_rc("%s: found rc key: %x, %x, event: %x\n", + __func__, key[0], key[1], (*event)); + else if (key[0] != 0xff) + deb_rc("%s: unknown rc key: %x, %x\n", + __func__, key[0], key[1]); + } - /* info("key: %x %x\n",key[0],key[1]); */ + return 0; } diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h index e337073..5cd0b0e 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.h +++ b/drivers/media/dvb/dvb-usb/dw2102.h @@ -5,4 +5,5 @@ #include "dvb-usb.h" #define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) +#define deb_rc(args...) dprintk(dvb_usb_dw2102_debug, 0x04, args) #endif -- cgit v1.1 From b42e1d71f52995f0a25f2b593fdb166326db3fd4 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 14 Jun 2009 19:41:22 -0300 Subject: V4L/DVB (11982): Add keymaps for TeVii and TBS USB DVB-S/S2 cards Add keymaps for TeVii and TBS USB DVB-S/S2 cards Also module parameter named keymap inserted for override default keymap. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 126 ++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 16 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index dee9399..06a0aa1 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -40,12 +40,9 @@ #define DW2102_VOLTAGE_CTRL (0x1800) #define DW2102_RC_QUERY (0x1a00) -struct dw210x_state { - u32 last_key_pressed; -}; -struct dw210x_rc_keys { - u32 keycode; - u32 event; +struct dvb_usb_rc_keys_table { + struct dvb_usb_rc_key *rc_keys; + int rc_keys_size; }; /* debug */ @@ -54,6 +51,10 @@ module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." DVB_USB_DEBUG_STATUS); +/* keymaps */ +static int ir_keymap; +module_param_named(keymap, ir_keymap, int, 0644); +MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -462,6 +463,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) } static struct dvb_usb_device_properties dw2102_properties; +static struct dvb_usb_device_properties dw2104_properties; static int dw2102_frontend_attach(struct dvb_usb_adapter *d) { @@ -546,14 +548,103 @@ static struct dvb_usb_rc_key dw210x_rc_keys[] = { { 0xf8, 0x40, KEY_F }, /*full*/ { 0xf8, 0x1e, KEY_W }, /*tvmode*/ { 0xf8, 0x1b, KEY_B }, /*recall*/ +}; +static struct dvb_usb_rc_key tevii_rc_keys[] = { + { 0xf8, 0x0a, KEY_POWER }, + { 0xf8, 0x0c, KEY_MUTE }, + { 0xf8, 0x11, KEY_1 }, + { 0xf8, 0x12, KEY_2 }, + { 0xf8, 0x13, KEY_3 }, + { 0xf8, 0x14, KEY_4 }, + { 0xf8, 0x15, KEY_5 }, + { 0xf8, 0x16, KEY_6 }, + { 0xf8, 0x17, KEY_7 }, + { 0xf8, 0x18, KEY_8 }, + { 0xf8, 0x19, KEY_9 }, + { 0xf8, 0x10, KEY_0 }, + { 0xf8, 0x1c, KEY_MENU }, + { 0xf8, 0x0f, KEY_VOLUMEDOWN }, + { 0xf8, 0x1a, KEY_LAST }, + { 0xf8, 0x0e, KEY_OPEN }, + { 0xf8, 0x04, KEY_RECORD }, + { 0xf8, 0x09, KEY_VOLUMEUP }, + { 0xf8, 0x08, KEY_CHANNELUP }, + { 0xf8, 0x07, KEY_PVR }, + { 0xf8, 0x0b, KEY_TIME }, + { 0xf8, 0x02, KEY_RIGHT }, + { 0xf8, 0x03, KEY_LEFT }, + { 0xf8, 0x00, KEY_UP }, + { 0xf8, 0x1f, KEY_OK }, + { 0xf8, 0x01, KEY_DOWN }, + { 0xf8, 0x05, KEY_TUNER }, + { 0xf8, 0x06, KEY_CHANNELDOWN }, + { 0xf8, 0x40, KEY_PLAYPAUSE }, + { 0xf8, 0x1e, KEY_REWIND }, + { 0xf8, 0x1b, KEY_FAVORITES }, + { 0xf8, 0x1d, KEY_BACK }, + { 0xf8, 0x4d, KEY_FASTFORWARD }, + { 0xf8, 0x44, KEY_EPG }, + { 0xf8, 0x4c, KEY_INFO }, + { 0xf8, 0x41, KEY_AB }, + { 0xf8, 0x43, KEY_AUDIO }, + { 0xf8, 0x45, KEY_SUBTITLE }, + { 0xf8, 0x4a, KEY_LIST }, + { 0xf8, 0x46, KEY_F1 }, + { 0xf8, 0x47, KEY_F2 }, + { 0xf8, 0x5e, KEY_F3 }, + { 0xf8, 0x5c, KEY_F4 }, + { 0xf8, 0x52, KEY_F5 }, + { 0xf8, 0x5a, KEY_F6 }, + { 0xf8, 0x56, KEY_MODE }, + { 0xf8, 0x58, KEY_SWITCHVIDEOMODE }, }; +static struct dvb_usb_rc_key tbs_rc_keys[] = { + { 0xf8, 0x84, KEY_POWER }, + { 0xf8, 0x94, KEY_MUTE }, + { 0xf8, 0x87, KEY_1 }, + { 0xf8, 0x86, KEY_2 }, + { 0xf8, 0x85, KEY_3 }, + { 0xf8, 0x8b, KEY_4 }, + { 0xf8, 0x8a, KEY_5 }, + { 0xf8, 0x89, KEY_6 }, + { 0xf8, 0x8f, KEY_7 }, + { 0xf8, 0x8e, KEY_8 }, + { 0xf8, 0x8d, KEY_9 }, + { 0xf8, 0x92, KEY_0 }, + { 0xf8, 0x96, KEY_CHANNELUP }, + { 0xf8, 0x91, KEY_CHANNELDOWN }, + { 0xf8, 0x93, KEY_VOLUMEUP }, + { 0xf8, 0x8c, KEY_VOLUMEDOWN }, + { 0xf8, 0x83, KEY_RECORD }, + { 0xf8, 0x98, KEY_PAUSE }, + { 0xf8, 0x99, KEY_OK }, + { 0xf8, 0x9a, KEY_SHUFFLE }, + { 0xf8, 0x81, KEY_UP }, + { 0xf8, 0x90, KEY_LEFT }, + { 0xf8, 0x82, KEY_RIGHT }, + { 0xf8, 0x88, KEY_DOWN }, + { 0xf8, 0x95, KEY_FAVORITES }, + { 0xf8, 0x97, KEY_SUBTITLE }, + { 0xf8, 0x9d, KEY_ZOOM }, + { 0xf8, 0x9f, KEY_EXIT }, + { 0xf8, 0x9e, KEY_MENU }, + { 0xf8, 0x9c, KEY_EPG }, + { 0xf8, 0x80, KEY_PREVIOUS }, + { 0xf8, 0x9b, KEY_MODE } +}; +static struct dvb_usb_rc_keys_table keys_tables[] = { + { dw210x_rc_keys, ARRAY_SIZE(dw210x_rc_keys) }, + { tevii_rc_keys, ARRAY_SIZE(tevii_rc_keys) }, + { tbs_rc_keys, ARRAY_SIZE(tbs_rc_keys) }, +}; static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - struct dw210x_state *st = d->priv; + struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + int keymap_size = d->props.rc_key_map_size; u8 key[2]; struct i2c_msg msg = { .addr = DW2102_RC_QUERY, @@ -562,19 +653,21 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) .len = 2 }; int i; + /* override keymap */ + if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { + keymap = keys_tables[ir_keymap - 1].rc_keys ; + keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; + } *state = REMOTE_NO_KEY_PRESSED; if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) { - for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) { - if (dw210x_rc_keys[i].data == msg.buf[0]) { + for (i = 0; i < keymap_size ; i++) { + if (keymap[i].data == msg.buf[0]) { *state = REMOTE_KEY_PRESSED; - *event = dw210x_rc_keys[i].event; - st->last_key_pressed = - dw210x_rc_keys[i].event; + *event = keymap[i].event; break; } - st->last_key_pressed = 0; } if ((*state) == REMOTE_KEY_PRESSED) @@ -655,8 +748,11 @@ static int dw2102_load_firmware(struct usb_device *dev, } /* init registers */ switch (dev->descriptor.idProduct) { - case USB_PID_DW2104: case 0xd650: + dw2104_properties.rc_key_map = tevii_rc_keys; + dw2104_properties.rc_key_map_size = + ARRAY_SIZE(tevii_rc_keys); + case USB_PID_DW2104: reset = 1; dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, DW210X_WRITE_MSG); @@ -713,7 +809,6 @@ static struct dvb_usb_device_properties dw2102_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-dw2102.fw", - .size_of_priv = sizeof(struct dw210x_state), .no_reconnect = 1, .i2c_algo = &dw2102_serit_i2c_algo, @@ -765,7 +860,6 @@ static struct dvb_usb_device_properties dw2104_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-dw2104.fw", - .size_of_priv = sizeof(struct dw210x_state), .no_reconnect = 1, .i2c_algo = &dw2104_i2c_algo, -- cgit v1.1 From 1dac77c9d82f344b21c1d962d79875ec331f83cc Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 14 Jun 2009 20:51:45 -0300 Subject: V4L/DVB (11983): Add support for DVBWorld DVB-C USB Cable card. DVBWorld DVB-C USB Cable card contains TUA6034 tuner, TDA10023 demod and Cypress FX-2 controller. http://www.worlddvb.com/product/htm/usbc.htm Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.c | 176 ++++++++++++++++++++++++++++++++++--- 1 file changed, 165 insertions(+), 11 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 06a0aa1..75de49c 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1,7 +1,7 @@ /* DVB USB framework compliant Linux driver for the -* DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) +* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, +* TeVii S600, S650 Cards +* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) * * 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 @@ -17,6 +17,7 @@ #include "stb6000.h" #include "eds1547.h" #include "cx24116.h" +#include "tda1002x.h" #ifndef USB_PID_DW2102 #define USB_PID_DW2102 0x2102 @@ -26,10 +27,18 @@ #define USB_PID_DW2104 0x2104 #endif +#ifndef USB_PID_DW3101 +#define USB_PID_DW3101 0x3101 +#endif + #ifndef USB_PID_CINERGY_S #define USB_PID_CINERGY_S 0x0064 #endif +#ifndef USB_PID_TEVII_S650 +#define USB_PID_TEVII_S650 0xd650 +#endif + #define DW210X_READ_MSG 0 #define DW210X_WRITE_MSG 1 @@ -82,7 +91,7 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { -struct dvb_usb_device *d = i2c_get_adapdata(adap); + struct dvb_usb_device *d = i2c_get_adapdata(adap); int i = 0, ret = 0; u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; u16 value; @@ -208,6 +217,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, mutex_unlock(&d->i2c_mutex); return num; } + static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); @@ -222,7 +232,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms case 2: { /* read */ /* first write first register number */ - u8 ibuf [msg[1].len + 2], obuf[3]; + u8 ibuf[msg[1].len + 2], obuf[3]; obuf[0] = 0xd0; obuf[1] = msg[0].len; obuf[2] = msg[0].buf[0]; @@ -296,7 +306,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i case 2: { /* read */ /* first write first register number */ - u8 ibuf [msg[1].len + 2], obuf[3]; + u8 ibuf[msg[1].len + 2], obuf[3]; obuf[0] = 0xaa; obuf[1] = msg[0].len; obuf[2] = msg[0].buf[0]; @@ -363,6 +373,69 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i return num; } +static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int ret = 0, i; + + if (!d) + return -ENODEV; + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + switch (num) { + case 2: { + /* read */ + /* first write first register number */ + u8 ibuf[msg[1].len + 2], obuf[3]; + obuf[0] = msg[0].addr << 1; + obuf[1] = msg[0].len; + obuf[2] = msg[0].buf[0]; + ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, + obuf, msg[0].len + 2, DW210X_WRITE_MSG); + /* second read registers */ + ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0, + ibuf, msg[1].len + 2, DW210X_READ_MSG); + memcpy(msg[1].buf, ibuf + 2, msg[1].len); + + break; + } + case 1: + switch (msg[0].addr) { + case 0x60: + case 0x0c: { + /* write to register */ + u8 obuf[msg[0].len + 2]; + obuf[0] = msg[0].addr << 1; + obuf[1] = msg[0].len; + memcpy(obuf + 2, msg[0].buf, msg[0].len); + ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, + obuf, msg[0].len + 2, DW210X_WRITE_MSG); + break; + } + case(DW2102_RC_QUERY): { + u8 ibuf[2]; + ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, + ibuf, 2, DW210X_READ_MSG); + memcpy(msg[0].buf, ibuf , 2); + break; + } + } + + break; + } + + for (i = 0; i < num; i++) { + deb_xfer("%02x:%02x: %s ", i, msg[i].addr, + msg[i].flags == 0 ? ">>>" : "<<<"); + debug_dump(msg[i].buf, msg[i].len, deb_xfer); + } + + mutex_unlock(&d->i2c_mutex); + return num; +} + static u32 dw210x_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C; @@ -388,6 +461,11 @@ static struct i2c_algorithm dw2104_i2c_algo = { .functionality = dw210x_i2c_func, }; +static struct i2c_algorithm dw3101_i2c_algo = { + .master_xfer = dw3101_i2c_transfer, + .functionality = dw210x_i2c_func, +}; + static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) { int i; @@ -407,6 +485,7 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) debug_dump(eepromline, 16, deb_xfer); } } + memcpy(mac, eeprom + 8, 6); return 0; }; @@ -451,6 +530,11 @@ static struct si21xx_config serit_sp1511lhb_config = { }; +static struct tda10023_config dw3101_tda10023_config = { + .demod_address = 0x0c, + .invert = 1, +}; + static int dw2104_frontend_attach(struct dvb_usb_adapter *d) { if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, @@ -501,6 +585,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) return -EIO; } +static int dw3101_frontend_attach(struct dvb_usb_adapter *d) +{ + d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config, + &d->dev->i2c_adap, 0x48); + if (d->fe != NULL) { + info("Attached tda10023!\n"); + return 0; + } + return -EIO; +} + static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) { dvb_attach(dvb_pll_attach, adap->fe, 0x60, @@ -516,6 +611,14 @@ static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap) return 0; } +static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) +{ + dvb_attach(dvb_pll_attach, adap->fe, 0x60, + &adap->dev->i2c_adap, DVB_PLL_TUA6034); + + return 0; +} + static struct dvb_usb_rc_key dw210x_rc_keys[] = { { 0xf8, 0x0a, KEY_Q }, /*power*/ { 0xf8, 0x0c, KEY_M }, /*mute*/ @@ -685,9 +788,10 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) static struct usb_device_id dw2102_table[] = { {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, - {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, - {USB_DEVICE(0x9022, 0xd650)}, + {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)}, + {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, + {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, { } }; @@ -748,7 +852,7 @@ static int dw2102_load_firmware(struct usb_device *dev, } /* init registers */ switch (dev->descriptor.idProduct) { - case 0xd650: + case USB_PID_TEVII_S650: dw2104_properties.rc_key_map = tevii_rc_keys; dw2104_properties.rc_key_map_size = ARRAY_SIZE(tevii_rc_keys); @@ -756,6 +860,8 @@ static int dw2102_load_firmware(struct usb_device *dev, reset = 1; dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, DW210X_WRITE_MSG); + /* break omitted intentionally */ + case USB_PID_DW3101: reset = 0; dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, DW210X_WRITE_MSG); @@ -799,6 +905,7 @@ static int dw2102_load_firmware(struct usb_device *dev, DW210X_READ_MSG); break; } + msleep(100); kfree(p); } @@ -822,7 +929,7 @@ static struct dvb_usb_device_properties dw2102_properties = { .num_adapters = 1, .download_firmware = dw2102_load_firmware, .read_mac_address = dw210x_read_mac_address, - .adapter = { + .adapter = { { .frontend_attach = dw2102_frontend_attach, .streaming_ctrl = NULL, @@ -903,12 +1010,57 @@ static struct dvb_usb_device_properties dw2104_properties = { } }; +static struct dvb_usb_device_properties dw3101_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .firmware = "dvb-usb-dw3101.fw", + .no_reconnect = 1, + + .i2c_algo = &dw3101_i2c_algo, + .rc_key_map = dw210x_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), + .rc_interval = 150, + .rc_query = dw2102_rc_query, + + .generic_bulk_ctrl_endpoint = 0x81, + /* parameter for the MPEG2-data transfer */ + .num_adapters = 1, + .download_firmware = dw2102_load_firmware, + .read_mac_address = dw210x_read_mac_address, + .adapter = { + { + .frontend_attach = dw3101_frontend_attach, + .streaming_ctrl = NULL, + .tuner_attach = dw3101_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + } + }, + .num_device_descs = 1, + .devices = { + { "DVBWorld DVB-C 3101 USB2.0", + {&dw2102_table[5], NULL}, + {NULL}, + }, + } +}; + static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { if (0 == dvb_usb_device_init(intf, &dw2102_properties, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &dw2104_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &dw3101_properties, THIS_MODULE, NULL, adapter_nr)) { return 0; } @@ -940,6 +1092,8 @@ module_init(dw2102_module_init); module_exit(dw2102_module_exit); MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); -MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device"); +MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," + " DVB-C 3101 USB2.0," + " TeVii S600, S650 USB2.0 devices"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); -- cgit v1.1 From 519a4bdcf8221c6b2d129b3c720761b7cab7f2c1 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 14 Jun 2009 21:34:12 -0300 Subject: V4L/DVB (11984): Add support for yet another SDMC DM1105 based DVB-S card. Add support for SDMC DM1105 based DVB-S cards with PCI ID 195d:1105 Also create separate workqueue for demuxing. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dm1105/dm1105.c | 121 +++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 41 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 971a8b1..4dbd7d4 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -51,6 +51,9 @@ #ifndef PCI_VENDOR_ID_TRIGEM #define PCI_VENDOR_ID_TRIGEM 0x109f #endif +#ifndef PCI_VENDOR_ID_AXESS +#define PCI_VENDOR_ID_AXESS 0x195d +#endif #ifndef PCI_DEVICE_ID_DM1105 #define PCI_DEVICE_ID_DM1105 0x036f #endif @@ -60,6 +63,9 @@ #ifndef PCI_DEVICE_ID_DW2004 #define PCI_DEVICE_ID_DW2004 0x2004 #endif +#ifndef PCI_DEVICE_ID_DM05 +#define PCI_DEVICE_ID_DM05 0x1105 +#endif /* ----------------------------------------------- */ /* sdmc dm1105 registers */ @@ -150,6 +156,11 @@ #define DM1105_LNB_13V 0x00010100 #define DM1105_LNB_18V 0x00000100 +/* GPIO's for LNB power control for Axess DM05 */ +#define DM05_LNB_MASK 0x00000000 +#define DM05_LNB_13V 0x00020000 +#define DM05_LNB_18V 0x00030000 + static int ir_debug; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); @@ -188,6 +199,8 @@ struct dm1105dvb { /* irq */ struct work_struct work; + struct workqueue_struct *wq; + char wqn[16]; /* dma */ dma_addr_t dma_addr; @@ -313,15 +326,25 @@ static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe) static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); + u32 lnb_mask, lnb_13v, lnb_18v; - if (voltage == SEC_VOLTAGE_18) { - outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); - outl(DM1105_LNB_18V, dm_io_mem(DM1105_GPIOVAL)); - } else { - /*LNB ON-13V by default!*/ - outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); - outl(DM1105_LNB_13V, dm_io_mem(DM1105_GPIOVAL)); - } + switch (dm1105dvb->pdev->subsystem_device) { + case PCI_DEVICE_ID_DM05: + lnb_mask = DM05_LNB_MASK; + lnb_13v = DM05_LNB_13V; + lnb_18v = DM05_LNB_18V; + break; + default: + lnb_mask = DM1105_LNB_MASK; + lnb_13v = DM1105_LNB_13V; + lnb_18v = DM1105_LNB_18V; + } + + outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR)); + if (voltage == SEC_VOLTAGE_18) + outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL)); + else + outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL)); return 0; } @@ -440,7 +463,7 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) case (INTSTS_TSIRQ | INTSTS_IR): dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) - inl(dm_io_mem(DM1105_STADR)); - schedule_work(&dm1105dvb->work); + queue_work(dm1105dvb->wq, &dm1105dvb->work); break; case INTSTS_IR: dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); @@ -567,46 +590,44 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb) int ret; switch (dm1105dvb->pdev->subsystem_device) { - case PCI_DEVICE_ID_DW2002: + case PCI_DEVICE_ID_DW2004: dm1105dvb->fe = dvb_attach( - stv0299_attach, &sharp_z0194a_config, + cx24116_attach, &serit_sp2633_config, &dm1105dvb->i2c_adap); + if (dm1105dvb->fe) + dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; + break; + default: + dm1105dvb->fe = dvb_attach( + stv0299_attach, &sharp_z0194a_config, + &dm1105dvb->i2c_adap); if (dm1105dvb->fe) { dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60, &dm1105dvb->i2c_adap, DVB_PLL_OPERA1); + break; } - if (!dm1105dvb->fe) { - dm1105dvb->fe = dvb_attach( - stv0288_attach, &earda_config, - &dm1105dvb->i2c_adap); - if (dm1105dvb->fe) { - dm1105dvb->fe->ops.set_voltage = - dm1105dvb_set_voltage; - dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, - &dm1105dvb->i2c_adap); - } + dm1105dvb->fe = dvb_attach( + stv0288_attach, &earda_config, + &dm1105dvb->i2c_adap); + if (dm1105dvb->fe) { + dm1105dvb->fe->ops.set_voltage = + dm1105dvb_set_voltage; + dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, + &dm1105dvb->i2c_adap); + break; } - if (!dm1105dvb->fe) { - dm1105dvb->fe = dvb_attach( - si21xx_attach, &serit_config, - &dm1105dvb->i2c_adap); - if (dm1105dvb->fe) - dm1105dvb->fe->ops.set_voltage = - dm1105dvb_set_voltage; - } - break; - case PCI_DEVICE_ID_DW2004: dm1105dvb->fe = dvb_attach( - cx24116_attach, &serit_sp2633_config, + si21xx_attach, &serit_config, &dm1105dvb->i2c_adap); if (dm1105dvb->fe) - dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; - break; + dm1105dvb->fe->ops.set_voltage = + dm1105dvb_set_voltage; + } if (!dm1105dvb->fe) { @@ -630,10 +651,17 @@ static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac) static u8 command[1] = { 0x28 }; struct i2c_msg msg[] = { - { .addr = IIC_24C01_addr >> 1, .flags = 0, - .buf = command, .len = 1 }, - { .addr = IIC_24C01_addr >> 1, .flags = I2C_M_RD, - .buf = mac, .len = 6 }, + { + .addr = IIC_24C01_addr >> 1, + .flags = 0, + .buf = command, + .len = 1 + }, { + .addr = IIC_24C01_addr >> 1, + .flags = I2C_M_RD, + .buf = mac, + .len = 6 + }, }; dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2); @@ -752,14 +780,22 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, dm1105_ir_init(dm1105dvb); INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); + sprintf(dm1105dvb->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num); + dm1105dvb->wq = create_singlethread_workqueue(dm1105dvb->wqn); + if (!dm1105dvb->wq) + goto err_dvb_net; ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb); if (ret < 0) - goto err_free_irq; + goto err_workqueue; return 0; +err_workqueue: + destroy_workqueue(dm1105dvb->wq); +err_dvb_net: + dvb_net_release(&dm1105dvb->dvbnet); err_disconnect_frontend: dmx->disconnect_frontend(dmx); err_remove_mem_frontend: @@ -776,8 +812,6 @@ err_i2c_del_adapter: i2c_del_adapter(&dm1105dvb->i2c_adap); err_dm1105dvb_hw_exit: dm1105dvb_hw_exit(dm1105dvb); -err_free_irq: - free_irq(pdev->irq, dm1105dvb); err_pci_iounmap: pci_iounmap(pdev, dm1105dvb->io_mem); err_pci_release_regions: @@ -834,6 +868,11 @@ static struct pci_device_id dm1105_id_table[] __devinitdata = { .subvendor = PCI_ANY_ID, .subdevice = PCI_DEVICE_ID_DW2004, }, { + .vendor = PCI_VENDOR_ID_AXESS, + .device = PCI_DEVICE_ID_DM05, + .subvendor = PCI_VENDOR_ID_AXESS, + .subdevice = PCI_DEVICE_ID_DM05, + }, { /* empty */ }, }; -- cgit v1.1 From 24dff657e725fe63b3514b7ee57e4ac51210d3fc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 16 Jun 2009 00:46:40 -0300 Subject: V4L/DVB (11986): Kconfig: DVBWorld DVB-C USB Cable card needs tda1002x frontend Auto-selects tda1002x if !DVB_FE_CUSTOMISE Cc: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 1bb66e1..496c1a3 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -261,6 +261,7 @@ config DVB_USB_DW2102 select DVB_STB6000 if !DVB_FE_CUSTOMISE select DVB_CX24116 if !DVB_FE_CUSTOMISE select DVB_SI21XX if !DVB_FE_CUSTOMISE + select DVB_TDA10021 if !DVB_FE_CUSTOMISE help Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers and the TeVii S650. -- cgit v1.1 From 040d4cbfb3df7db8cb661a64d0d65f7e753f43d3 Mon Sep 17 00:00:00 2001 From: Frank Dischner Date: Sun, 14 Jun 2009 23:05:20 -0300 Subject: V4L/DVB (11987): au8522: add support for QAM-64 modulation type Add support for QAM64 modulation type to the au8522 demod driver. Signed-off-by: Frank Dischner Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_dig.c | 98 ++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 6 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 3573125..956b80f 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -367,11 +367,90 @@ static struct { { 0x8231, 0x13 }, }; -/* QAM Modulation table */ +/* QAM64 Modulation table */ static struct { u16 reg; u16 data; -} QAM_mod_tab[] = { +} QAM64_mod_tab[] = { + { 0x00a3, 0x09 }, + { 0x00a4, 0x00 }, + { 0x0081, 0xc4 }, + { 0x00a5, 0x40 }, + { 0x00aa, 0x77 }, + { 0x00ad, 0x77 }, + { 0x00a6, 0x67 }, + { 0x0262, 0x20 }, + { 0x021c, 0x30 }, + { 0x00b8, 0x3e }, + { 0x00b9, 0xf0 }, + { 0x00ba, 0x01 }, + { 0x00bb, 0x18 }, + { 0x00bc, 0x50 }, + { 0x00bd, 0x00 }, + { 0x00be, 0xea }, + { 0x00bf, 0xef }, + { 0x00c0, 0xfc }, + { 0x00c1, 0xbd }, + { 0x00c2, 0x1f }, + { 0x00c3, 0xfc }, + { 0x00c4, 0xdd }, + { 0x00c5, 0xaf }, + { 0x00c6, 0x00 }, + { 0x00c7, 0x38 }, + { 0x00c8, 0x30 }, + { 0x00c9, 0x05 }, + { 0x00ca, 0x4a }, + { 0x00cb, 0xd0 }, + { 0x00cc, 0x01 }, + { 0x00cd, 0xd9 }, + { 0x00ce, 0x6f }, + { 0x00cf, 0xf9 }, + { 0x00d0, 0x70 }, + { 0x00d1, 0xdf }, + { 0x00d2, 0xf7 }, + { 0x00d3, 0xc2 }, + { 0x00d4, 0xdf }, + { 0x00d5, 0x02 }, + { 0x00d6, 0x9a }, + { 0x00d7, 0xd0 }, + { 0x0250, 0x0d }, + { 0x0251, 0xcd }, + { 0x0252, 0xe0 }, + { 0x0253, 0x05 }, + { 0x0254, 0xa7 }, + { 0x0255, 0xff }, + { 0x0256, 0xed }, + { 0x0257, 0x5b }, + { 0x0258, 0xae }, + { 0x0259, 0xe6 }, + { 0x025a, 0x3d }, + { 0x025b, 0x0f }, + { 0x025c, 0x0d }, + { 0x025d, 0xea }, + { 0x025e, 0xf2 }, + { 0x025f, 0x51 }, + { 0x0260, 0xf5 }, + { 0x0261, 0x06 }, + { 0x021a, 0x00 }, + { 0x0546, 0x40 }, + { 0x0210, 0xc7 }, + { 0x0211, 0xaa }, + { 0x0212, 0xab }, + { 0x0213, 0x02 }, + { 0x0502, 0x00 }, + { 0x0121, 0x04 }, + { 0x0122, 0x04 }, + { 0x052e, 0x10 }, + { 0x00a4, 0xca }, + { 0x00a7, 0x40 }, + { 0x0526, 0x01 }, +}; + +/* QAM256 Modulation table */ +static struct { + u16 reg; + u16 data; +} QAM256_mod_tab[] = { { 0x80a3, 0x09 }, { 0x80a4, 0x00 }, { 0x8081, 0xc4 }, @@ -464,12 +543,19 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, au8522_set_if(fe, state->config->vsb_if); break; case QAM_64: + dprintk("%s() QAM 64\n", __func__); + for (i = 0; i < ARRAY_SIZE(QAM64_mod_tab); i++) + au8522_writereg(state, + QAM64_mod_tab[i].reg, + QAM64_mod_tab[i].data); + au8522_set_if(fe, state->config->qam_if); + break; case QAM_256: - dprintk("%s() QAM 64/256\n", __func__); - for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) + dprintk("%s() QAM 256\n", __func__); + for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++) au8522_writereg(state, - QAM_mod_tab[i].reg, - QAM_mod_tab[i].data); + QAM256_mod_tab[i].reg, + QAM256_mod_tab[i].data); au8522_set_if(fe, state->config->qam_if); break; default: -- cgit v1.1 From e36bc31f823d6089bedc935fea82b6d36793412a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 4 Jun 2009 11:07:16 -0300 Subject: V4L/DVB (11992): Add missing __devexit_p() Add missing __devexit_p() to several drivers. Also add a few missing __init, __devinit and __exit markers. These errors could result in build failures depending on the kernel configuration. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/bt8xx/bt878.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 56d8fab..a24c125 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c @@ -508,12 +508,6 @@ static int __devinit bt878_probe(struct pci_dev *dev, pci_set_master(dev); pci_set_drvdata(dev, bt); -/* if(init_bt878(btv) < 0) { - bt878_remove(dev); - return -EIO; - } -*/ - if ((result = bt878_mem_alloc(bt))) { printk(KERN_ERR "bt878: failed to allocate memory!\n"); goto fail2; @@ -579,7 +573,7 @@ static struct pci_driver bt878_pci_driver = { .name = "bt878", .id_table = bt878_pci_tbl, .probe = bt878_probe, - .remove = bt878_remove, + .remove = __devexit_p(bt878_remove), }; static int bt878_pci_driver_registered; -- cgit v1.1 From 1e7439388a5aa6decf76ac1d73d5312fe713e6af Mon Sep 17 00:00:00 2001 From: Jan Nikitenko Date: Tue, 9 Jun 2009 19:31:55 -0300 Subject: V4L/DVB (11999): af9015: fix stack corruption bug This patch fixes stack corruption bug present in af9015_eeprom_dump(): the buffer buf is one byte smaller than required - there is 4 chars for address prefix, 16*3 chars for dump of 16 eeprom bytes per line and 1 byte for zero ending the string required, i.e. 53 bytes, but only 52 are provided. The one byte missing in stack based buffer buf causes following oops on MIPS little endian platform, because i2c_adap pointer in af9015_af9013_frontend_attach() is corrupted by inlined function af9015_eeprom_dump(): CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 803a4488, ra == c049a1c8 Oops[#1]: Cpu 0 $ 0 : 00000000 10003c00 00000000 803a4468 $ 4 : 8f17c600 8f067b30 00000002 00000038 $ 8 : 00000001 8faf3e98 11da000d 09010002 $12 : 00000000 00000000 00000000 0000000a $16 : 8f17c600 8f067b68 8faf3c00 8f067c04 $20 : 8f067b9c 00000100 8f067bf0 80104100 $24 : 00000000 2aba9fb0 $28 : 8f066000 8f067af0 802cbc48 c049a1c8 Hi : 00000000 Lo : 00000000 epc : 803a4488 i2c_transfer+0x20/0x104 Not tainted ra : c049a1c8 af9013_read_reg+0x78/0xc4 [af9013] Status: 10003c03 KERNEL EXL IE Cause : 00808008 BadVA : 00000000 PrId : 03030200 (Au1550) Modules linked in: af9013 dvb_usb_af9015(+) dvb_usb dvb_core firmware_class i2c_au1550 au1550_spi Process modprobe (pid: 2757, threadinfo=8f066000, task=8fade098, tls=2aad6470) Stack : c049f5e0 80163090 805ba880 00000100 8f067bf0 0000d733 8f067b68 8faf3c00 8f067c04 c049a1c8 80163bc0 8056a630 8f067b40 80163224 80569fc8 8f0033d7 00000038 80140003 8f067b2c 00010038 c0420001 8f067b28 c049f5e0 00000004 00000004 c049a524 c049d5a8 c049d5a8 00000000 803a6700 00000000 8f17c600 c042a7a4 8f17c600 c042a7a4 c049c924 00000000 00000000 00000002 613a6c00 ... Call Trace: [<803a4488>] i2c_transfer+0x20/0x104 [] af9013_read_reg+0x78/0xc4 [af9013] [] af9013_read_reg_bits+0x2c/0x70 [af9013] [] af9013_attach+0x98/0x65c [af9013] [] af9015_af9013_frontend_attach+0x214/0x67c [dvb_usb_af9015] [] dvb_usb_adapter_frontend_init+0x20/0x12c [dvb_usb] [] dvb_usb_device_init+0x374/0x6b0 [dvb_usb] [] af9015_usb_probe+0x4fc/0xfcc [dvb_usb_af9015] [<80381024>] usb_probe_interface+0xbc/0x218 [<803227fc>] driver_probe_device+0x12c/0x30c [<80322a80>] __driver_attach+0xa4/0xac [<80321ed0>] bus_for_each_dev+0x60/0xd0 [<8032162c>] bus_add_driver+0x1e8/0x2a8 [<80322cdc>] driver_register+0x7c/0x17c [<80380d30>] usb_register_driver+0xa0/0x12c [] af9015_usb_module_init+0x30/0x6c [dvb_usb_af9015] [<8010d2a4>] __kprobes_text_end+0x3c/0x1f4 [<80167150>] sys_init_module+0xb8/0x1cc [<80102370>] stack_done+0x20/0x3c Code: afb10018 7000003f 00808021 <8c430000> 7000003f 1060002d 00c09021 8f830014 3c02efff Signed-off-by: Jan Nikitenko Acked-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 9155a79..4cb31e7 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -538,7 +538,7 @@ exit: /* dump eeprom */ static int af9015_eeprom_dump(struct dvb_usb_device *d) { - char buf[52], buf2[4]; + char buf[4+3*16+1], buf2[4]; u8 reg, val; for (reg = 0; ; reg++) { -- cgit v1.1 From ba7d457dd352fdc598d9dae733f8d53ace34c9da Mon Sep 17 00:00:00 2001 From: David Wong Date: Thu, 11 Jun 2009 09:38:54 -0300 Subject: V4L/DVB (12000): lgs8gxx: lgs8913 fake signal strength option default on lgs8gxx: lgs8913 fake signal strength option default on. Original calculation is too slow. Signed-off-by: David T.L. Wong gmail.com> Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lgs8gxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index f9785df..da689ce 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c @@ -37,14 +37,14 @@ } while (0) static int debug; -static int fake_signal_str; +static int fake_signal_str = 1; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); module_param(fake_signal_str, int, 0644); MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." -"Signal strength calculation is slow.(default:off)."); +"Signal strength calculation is slow.(default:on)."); /* LGS8GXX internal helper functions */ -- cgit v1.1 From 6762d953a36833c8b94090781c791c67cb546080 Mon Sep 17 00:00:00 2001 From: David Wong Date: Thu, 11 Jun 2009 09:39:04 -0300 Subject: V4L/DVB (12001): lgs8gxx: update signal strength scale lgs8gxx: update signal strength scale Signed-off-by: David T.L. Wong Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lgs8gxx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index da689ce..fde2764 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c @@ -610,7 +610,7 @@ static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal) else cat = 0; - *signal = cat; + *signal = cat * 65535 / 5; return 0; } @@ -630,8 +630,8 @@ static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal) if (fake_signal_str) { if ((t & 0xC0) == 0xC0) { - dprintk("Fake signal strength as 50\n"); - *signal = 0x32; + dprintk("Fake signal strength\n"); + *signal = 0x7FFF; } else *signal = 0; return 0; -- cgit v1.1 From 57594a586f3353286d64c30f397494a834cac238 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 4 May 2009 21:43:02 -0300 Subject: V4L/DVB (11785): dvb_frontend: fix race condition resulting in dropped tuning commands A race condition was detected in the case that putting the tuner to sleep takes an unusually long period of time, combined with applications that quickly close/open the dvb frontend. The kaffeine channel scanner closes and reopens the dvb frontend between each tuning attempt. If it takes an unusually longer period of time to put the tuner to sleep (for example, the Pinnacle 801e takes 660 ms), the dvb_frontend thread will still be in a running state (and hence fepriv->thread is still set) but the fepriv->exit field will still be zero. As a result, if a dvb_frontend_start() call arrives while the frontend thread is in the process of terminating, the call will return 0 without actually starting a new thread. This results in the tuning request being dropped. To address this, mark fepriv->exit as soon as we know the thread is going to be terminated, so that dvb_frontend_start() knows to start a new instance. Problem encountered with Kaffeine 0.8.7 doing ATSC scanning against the Pinnacle 801e tuner, in conjunction with new code to power down the xc5000 when not in use. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_frontend.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index ebc7815..1f38dd8 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -543,6 +543,7 @@ restart: if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { /* got signal or quitting */ + fepriv->exit = 1; break; } -- cgit v1.1 From 9c9c68a8c06623b1f1b68652b1a3bf6d8ef415df Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Thu, 14 May 2009 16:27:16 -0300 Subject: V4L/DVB (11812): Siano: smsusb - add big endian support Add support for big endien target hosts, which use USB interface. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 71c65f5..5cda938 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -73,6 +73,7 @@ static void smsusb_onresponse(struct urb *urb) if (urb->actual_length > 0) { struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) surb->cb->p; + smsendian_handle_message_header(phdr); if (urb->actual_length >= phdr->msgLength) { surb->cb->size = phdr->msgLength; -- cgit v1.1 From a5beb7b32364a236e833631c3ee5c910cbbfa5bb Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 20 May 2009 23:58:16 -0300 Subject: V4L/DVB (11875): dvb_frontend: fix case where fepriv->exit not reset The fact that we now explicitly set fepriv->exit = 1 when the thread is shutting down exposed an edge case where it was not being reset back to zero once the thread went away in some cases. This resulted in failures in cases where the frontend was closed, and then opened O_RDONLY, since in that case the thread is not being restarted but it was checking the fepriv->exit flag. Thanks to Thierry Lelegard, who and encountered and debugged a large portion of the issue in the same twelve hours that I did (as well as testing my patch). Cc: Thierry Lelegard Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_frontend.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 1f38dd8..f50ca72 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -657,6 +657,7 @@ restart: } fepriv->thread = NULL; + fepriv->exit = 0; mb(); dvb_frontend_wakeup(fe); -- cgit v1.1 From 511da457340d3b30336f7a6731bad9bbe3ffaf08 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 28 May 2009 13:50:36 -0300 Subject: V4L/DVB (11877): lgdt3305: fix 64bit division in function lgdt3305_set_if Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lgdt3305.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index d92d055..fde8c59 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -19,6 +19,7 @@ * */ +#include #include #include "dvb_math.h" #include "lgdt3305.h" @@ -496,27 +497,15 @@ static int lgdt3305_set_if(struct lgdt3305_state *state, nco = if_freq_khz / 10; -#define LGDT3305_64BIT_DIVISION_ENABLED 0 - /* FIXME: 64bit division disabled to avoid linking error: - * WARNING: "__udivdi3" [lgdt3305.ko] undefined! - */ switch (param->u.vsb.modulation) { case VSB_8: -#if LGDT3305_64BIT_DIVISION_ENABLED nco <<= 24; - nco /= 625; -#else - nco *= ((1 << 24) / 625); -#endif + do_div(nco, 625); break; case QAM_64: case QAM_256: -#if LGDT3305_64BIT_DIVISION_ENABLED nco <<= 28; - nco /= 625; -#else - nco *= ((1 << 28) / 625); -#endif + do_div(nco, 625); break; default: return -EINVAL; -- cgit v1.1 From 319afbf97f209e3a907981f76e382c02ea3ecff3 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Fri, 27 Mar 2009 14:16:57 -0300 Subject: V4L/DVB (11240): siano: add high level SDIO interface driver for SMS based cards This patch provides SDIO interface driver for SMS (Siano Mobile Silicon) based devices. The patch includes SMS high level SDIO driver and requires patching the kernel SDIO stack, those stack patches had been provided previously. I would like to thank Pierre Ossman, MMC maintainer, who wrote this driver. Signed-off-by: Pierre Ossman Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smssdio.c | 356 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 drivers/media/dvb/siano/smssdio.c (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c new file mode 100644 index 0000000..31ba8c5 --- /dev/null +++ b/drivers/media/dvb/siano/smssdio.c @@ -0,0 +1,356 @@ +/* + * smssdio.c - Siano 1xxx SDIO interface driver + * + * Copyright 2008 Pierre Ossman + * + * Based on code by Siano Mobile Silicon, Inc., + * Copyright (C) 2006-2008, Uri Shkolnik + * + * 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 hardware is a bit odd in that all transfers should be done + * to/from the SMSSDIO_DATA register, yet the "increase address" bit + * always needs to be set. + * + * Also, buffers from the card are always aligned to 128 byte + * boundaries. + */ + +/* + * General cleanup notes: + * + * - only typedefs should be name *_t + * + * - use ERR_PTR and friends for smscore_register_device() + * + * - smscore_getbuffer should zero fields + * + * Fix stop command + */ + +#include +#include +#include +#include +#include +#include + +#include "smscoreapi.h" +#include "sms-cards.h" + +/* Registers */ + +#define SMSSDIO_DATA 0x00 +#define SMSSDIO_INT 0x04 + +static const struct sdio_device_id smssdio_ids[] = { + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR), + .driver_data = SMS1XXX_BOARD_SIANO_STELLAR}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0), + .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0), + .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0), + .driver_data = SMS1XXX_BOARD_SIANO_VEGA}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE), + .driver_data = SMS1XXX_BOARD_SIANO_VEGA}, + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(sdio, smssdio_ids); + +struct smssdio_device { + struct sdio_func *func; + + struct smscore_device_t *coredev; + + struct smscore_buffer_t *split_cb; +}; + +/*******************************************************************/ +/* Siano core callbacks */ +/*******************************************************************/ + +static int smssdio_sendrequest(void *context, void *buffer, size_t size) +{ + int ret; + struct smssdio_device *smsdev; + + smsdev = context; + + sdio_claim_host(smsdev->func); + + while (size >= smsdev->func->cur_blksize) { + ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1); + if (ret) + goto out; + + buffer += smsdev->func->cur_blksize; + size -= smsdev->func->cur_blksize; + } + + if (size) { + ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA, + buffer, size); + if (ret) + goto out; + } + +out: + sdio_release_host(smsdev->func); + + return ret; +} + +/*******************************************************************/ +/* SDIO callbacks */ +/*******************************************************************/ + +static void smssdio_interrupt(struct sdio_func *func) +{ + int ret, isr; + + struct smssdio_device *smsdev; + struct smscore_buffer_t *cb; + struct SmsMsgHdr_ST *hdr; + size_t size; + + smsdev = sdio_get_drvdata(func); + + /* + * The interrupt register has no defined meaning. It is just + * a way of turning of the level triggered interrupt. + */ + isr = sdio_readb(func, SMSSDIO_INT, &ret); + if (ret) { + dev_err(&smsdev->func->dev, + "Unable to read interrupt register!\n"); + return; + } + + if (smsdev->split_cb == NULL) { + cb = smscore_getbuffer(smsdev->coredev); + if (!cb) { + dev_err(&smsdev->func->dev, + "Unable to allocate data buffer!\n"); + return; + } + + ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1); + if (ret) { + dev_err(&smsdev->func->dev, + "Error %d reading initial block!\n", ret); + return; + } + + hdr = cb->p; + + if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) { + smsdev->split_cb = cb; + return; + } + + size = hdr->msgLength - smsdev->func->cur_blksize; + } else { + cb = smsdev->split_cb; + hdr = cb->p; + + size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST); + + smsdev->split_cb = NULL; + } + + if (hdr->msgLength > smsdev->func->cur_blksize) { + void *buffer; + + size = ALIGN(size, 128); + buffer = cb->p + hdr->msgLength; + + BUG_ON(smsdev->func->cur_blksize != 128); + + /* + * First attempt to transfer all of it in one go... + */ + ret = sdio_read_blocks(smsdev->func, buffer, + SMSSDIO_DATA, size / 128); + if (ret && ret != -EINVAL) { + smscore_putbuffer(smsdev->coredev, cb); + dev_err(&smsdev->func->dev, + "Error %d reading data from card!\n", ret); + return; + } + + /* + * ..then fall back to one block at a time if that is + * not possible... + * + * (we have to do this manually because of the + * problem with the "increase address" bit) + */ + if (ret == -EINVAL) { + while (size) { + ret = sdio_read_blocks(smsdev->func, + buffer, SMSSDIO_DATA, 1); + if (ret) { + smscore_putbuffer(smsdev->coredev, cb); + dev_err(&smsdev->func->dev, + "Error %d reading " + "data from card!\n", ret); + return; + } + + buffer += smsdev->func->cur_blksize; + if (size > smsdev->func->cur_blksize) + size -= smsdev->func->cur_blksize; + else + size = 0; + } + } + } + + cb->size = hdr->msgLength; + cb->offset = 0; + + smscore_onresponse(smsdev->coredev, cb); +} + +static int smssdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + int ret; + + int board_id; + struct smssdio_device *smsdev; + struct smsdevice_params_t params; + + board_id = id->driver_data; + + smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL); + if (!smsdev) + return -ENOMEM; + + smsdev->func = func; + + memset(¶ms, 0, sizeof(struct smsdevice_params_t)); + + params.device = &func->dev; + params.buffer_size = 0x5000; /* ?? */ + params.num_buffers = 22; /* ?? */ + params.context = smsdev; + + snprintf(params.devpath, sizeof(params.devpath), + "sdio\\%s", sdio_func_id(func)); + + params.sendrequest_handler = smssdio_sendrequest; + + params.device_type = sms_get_board(board_id)->type; + + if (params.device_type != SMS_STELLAR) + params.flags |= SMS_DEVICE_FAMILY2; + else { + /* + * FIXME: Stellar needs special handling... + */ + ret = -ENODEV; + goto free; + } + + ret = smscore_register_device(¶ms, &smsdev->coredev); + if (ret < 0) + goto free; + + smscore_set_board_id(smsdev->coredev, board_id); + + sdio_claim_host(func); + + ret = sdio_enable_func(func); + if (ret) + goto release; + + ret = sdio_set_block_size(func, 128); + if (ret) + goto disable; + + ret = sdio_claim_irq(func, smssdio_interrupt); + if (ret) + goto disable; + + sdio_set_drvdata(func, smsdev); + + sdio_release_host(func); + + ret = smscore_start_device(smsdev->coredev); + if (ret < 0) + goto reclaim; + + return 0; + +reclaim: + sdio_claim_host(func); + sdio_release_irq(func); +disable: + sdio_disable_func(func); +release: + sdio_release_host(func); + smscore_unregister_device(smsdev->coredev); +free: + kfree(smsdev); + + return ret; +} + +static void smssdio_remove(struct sdio_func *func) +{ + struct smssdio_device *smsdev; + + smsdev = sdio_get_drvdata(func); + + /* FIXME: racy! */ + if (smsdev->split_cb) + smscore_putbuffer(smsdev->coredev, smsdev->split_cb); + + smscore_unregister_device(smsdev->coredev); + + sdio_claim_host(func); + sdio_release_irq(func); + sdio_disable_func(func); + sdio_release_host(func); + + kfree(smsdev); +} + +static struct sdio_driver smssdio_driver = { + .name = "smssdio", + .id_table = smssdio_ids, + .probe = smssdio_probe, + .remove = smssdio_remove, +}; + +/*******************************************************************/ +/* Module functions */ +/*******************************************************************/ + +int smssdio_register(void) +{ + int ret = 0; + + printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n"); + printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n"); + + ret = sdio_register_driver(&smssdio_driver); + + return ret; +} + +void smssdio_unregister(void) +{ + sdio_unregister_driver(&smssdio_driver); +} + +MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver"); +MODULE_AUTHOR("Pierre Ossman"); +MODULE_LICENSE("GPL"); -- cgit v1.1 From f762ee1a0d07d1fdbbc3fa13b39d46d74687a23a Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Mon, 20 Apr 2009 11:35:06 -0300 Subject: V4L/DVB (11552): Siano: SDIO interface driver - remove two redundant lines Remove two redundant lines, based on Klimov Alexey code review. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smssdio.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c index 31ba8c5..4f8fa59 100644 --- a/drivers/media/dvb/siano/smssdio.c +++ b/drivers/media/dvb/siano/smssdio.c @@ -96,8 +96,6 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size) if (size) { ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA, buffer, size); - if (ret) - goto out; } out: -- cgit v1.1 From a6f231a88cb75324ce812a827077943e23d11448 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 5 Apr 2009 05:12:51 -0300 Subject: V4L/DVB (11554): Siano: core header - add definitions and structures Add new definitions (of Siano's protocol messages), and protocol structures (for future commits usage) Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 548de905..26749b0 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -46,6 +46,7 @@ #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif +#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000) #define SMS_ALLOC_ALIGNMENT 128 #define SMS_DMA_ALIGNMENT 16 #define SMS_ALIGN_ADDRESS(addr) \ @@ -161,6 +162,7 @@ struct smsclient_params_t { #define MSG_SMS_GET_PID_FILTER_LIST_RES 609 #define MSG_SMS_GET_STATISTICS_REQ 615 #define MSG_SMS_GET_STATISTICS_RES 616 +#define MSG_SMS_HO_PER_SLICES_IND 630 #define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 #define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 #define MSG_SMS_GET_STATISTICS_EX_REQ 653 @@ -190,6 +192,13 @@ struct smsclient_params_t { #define MSG_SMS_GPIO_CONFIG_EX_RES 713 #define MSG_SMS_ISDBT_TUNE_REQ 776 #define MSG_SMS_ISDBT_TUNE_RES 777 +#define MSG_SMS_TRANSMISSION_IND 782 +#define MSG_SMS_START_IR_REQ 800 +#define MSG_SMS_START_IR_RES 801 +#define MSG_SMS_IR_SAMPLES_IND 802 +#define MSG_SMS_SIGNAL_DETECTED_IND 827 +#define MSG_SMS_NO_SIGNAL_IND 828 + #define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ @@ -197,6 +206,15 @@ struct smsclient_params_t { } while (0) #define SMS_INIT_MSG(ptr, type, len) \ SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) +enum SMS_DVB3_EVENTS { + DVB3_EVENT_INIT = 0, + DVB3_EVENT_SLEEP, + DVB3_EVENT_HOTPLUG, + DVB3_EVENT_FE_LOCK, + DVB3_EVENT_FE_UNLOCK, + DVB3_EVENT_UNC_OK, + DVB3_EVENT_UNC_ERR +}; enum SMS_DEVICE_MODE { DEVICE_MODE_NONE = -1, @@ -221,8 +239,13 @@ struct SmsMsgHdr_ST { }; struct SmsMsgData_ST { - struct SmsMsgHdr_ST xMsgHeader; - u32 msgData[1]; + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[1]; +}; + +struct SmsMsgData_ST2 { + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[2]; }; struct SmsDataDownload_ST { -- cgit v1.1 From 7c57333dcc95b38827a78ef1660c453077bf63f8 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 5 Apr 2009 05:21:23 -0300 Subject: V4L/DVB (11555): Siano: core - move and update the main core structure declaration smscoreapi - move the main core structure declaration to the header, in order to enable other components (such as IR) to use it. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 36 ------------------------ drivers/media/dvb/siano/smscoreapi.h | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 36 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 7bd4d1d..f3e1cc7 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -58,42 +58,6 @@ struct smscore_client_t { onremove_t onremove_handler; }; -struct smscore_device_t { - struct list_head entry; - - struct list_head clients; - struct list_head subclients; - spinlock_t clientslock; - - struct list_head buffers; - spinlock_t bufferslock; - int num_buffers; - - void *common_buffer; - int common_buffer_size; - dma_addr_t common_buffer_phys; - - void *context; - struct device *device; - - char devpath[32]; - unsigned long device_flags; - - setmode_t setmode_handler; - detectmode_t detectmode_handler; - sendrequest_t sendrequest_handler; - preload_t preload_handler; - postload_t postload_handler; - - int mode, modes_supported; - - struct completion version_ex_done, data_download_done, trigger_done; - struct completion init_device_done, reload_start_done, resume_done; - - int board_id; - int led_state; -}; - void smscore_set_board_id(struct smscore_device_t *core, int id) { core->board_id = id; diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 26749b0..bb52d87 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -121,6 +121,60 @@ struct smsclient_params_t { void *context; }; +struct smscore_device_t { + struct list_head entry; + + struct list_head clients; + struct list_head subclients; + spinlock_t clientslock; + + struct list_head buffers; + spinlock_t bufferslock; + int num_buffers; + + void *common_buffer; + int common_buffer_size; + dma_addr_t common_buffer_phys; + + void *context; + struct device *device; + + char devpath[32]; + unsigned long device_flags; + + setmode_t setmode_handler; + detectmode_t detectmode_handler; + sendrequest_t sendrequest_handler; + preload_t preload_handler; + postload_t postload_handler; + + int mode, modes_supported; + + /* host <--> device messages */ + struct completion version_ex_done, data_download_done, trigger_done; + struct completion init_device_done, reload_start_done, resume_done; + struct completion gpio_configuration_done, gpio_set_level_done; + struct completion gpio_get_level_done, ir_init_done; + + /* Buffer management */ + wait_queue_head_t buffer_mng_waitq; + + /* GPIO */ + int gpio_get_res; + + /* Target hardware board */ + int board_id; + + /* Firmware */ + u8 *fw_buf; + u32 fw_buf_size; + + /* Infrared (IR) */ + /* struct ir_t ir; */ + + int led_state; +}; + /* GPIO definitions for antenna frequency domain control (SMS8021) */ #define SMS_ANTENNA_GPIO_0 1 #define SMS_ANTENNA_GPIO_1 0 -- cgit v1.1 From 53838e4b6126b225d2705a00614bd1de42e15f1d Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 5 Apr 2009 05:26:50 -0300 Subject: V4L/DVB (11556): Siano: core header - indentation Some more indentation for the smscoreapi.h There are no implementation changes in this patch. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 42 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index bb52d87..d728448 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -46,14 +46,14 @@ #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif -#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000) -#define SMS_ALLOC_ALIGNMENT 128 -#define SMS_DMA_ALIGNMENT 16 +#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000) +#define SMS_ALLOC_ALIGNMENT 128 +#define SMS_DMA_ALIGNMENT 16 #define SMS_ALIGN_ADDRESS(addr) \ ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) -#define SMS_DEVICE_FAMILY2 1 -#define SMS_ROM_NO_RESPONSE 2 +#define SMS_DEVICE_FAMILY2 1 +#define SMS_ROM_NO_RESPONSE 2 #define SMS_DEVICE_NOT_READY 0x8000000 enum sms_device_type_st { @@ -84,13 +84,13 @@ typedef void (*onremove_t)(void *context); struct smscore_buffer_t { /* public members, once passed to clients can be changed freely */ struct list_head entry; - int size; - int offset; + int size; + int offset; /* private members, read-only for clients */ - void *p; - dma_addr_t phys; - unsigned long offset_in_common; + void *p; + dma_addr_t phys; + unsigned long offset_in_common; }; struct smsdevice_params_t { @@ -117,7 +117,6 @@ struct smsclient_params_t { int data_type; onresponse_t onresponse_handler; onremove_t onremove_handler; - void *context; }; @@ -253,13 +252,14 @@ struct smscore_device_t { #define MSG_SMS_SIGNAL_DETECTED_IND 827 #define MSG_SMS_NO_SIGNAL_IND 828 - #define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ } while (0) + #define SMS_INIT_MSG(ptr, type, len) \ SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) + enum SMS_DVB3_EVENTS { DVB3_EVENT_INIT = 0, DVB3_EVENT_SLEEP, @@ -315,11 +315,12 @@ struct SmsVersionRes_ST { u8 Step; /* 0 - Step A */ u8 MetalFix; /* 0 - Metal 0 */ - u8 FirmwareId; /* 0xFF � ROM, otherwise the - * value indicated by - * SMSHOSTLIB_DEVICE_MODES_E */ - u8 SupportedProtocols; /* Bitwise OR combination of + /* FirmwareId 0xFF if ROM, otherwise the + * value indicated by SMSHOSTLIB_DEVICE_MODES_E */ + u8 FirmwareId; + /* SupportedProtocols Bitwise OR combination of * supported protocols */ + u8 SupportedProtocols; u8 VersionMajor; u8 VersionMinor; @@ -353,10 +354,12 @@ struct SMSHOSTLIB_STATISTICS_ST { s32 SNR; /* dB */ u32 BER; /* Post Viterbi BER [1E-5] */ u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ - u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, + /* Transport stream PER, 0xFFFFFFFF indicate N/A, * valid only for DVB-T/H */ - u32 MFER; /* DVB-H frame error rate in percentage, + u32 TS_PER; + /* DVB-H frame error rate in percentage, * 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + u32 MFER; s32 RSSI; /* dBm */ s32 InBandPwr; /* In band power in dBM */ s32 CarrierOffset; /* Carrier Offset in bin/1024 */ @@ -364,8 +367,9 @@ struct SMSHOSTLIB_STATISTICS_ST { /* Transmission parameters, valid only for DVB-T/H */ u32 Frequency; /* Frequency in Hz */ u32 Bandwidth; /* Bandwidth in MHz */ - u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, + /* Transmission Mode, for DAB modes 1-4, * for DVB-T/H FFT mode carriers in Kilos */ + u32 TransmissionMode; u32 ModemState; /* from SMS_DvbModemState_ET */ u32 GuardInterval; /* Guard Interval, 1 divided by value */ u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */ -- cgit v1.1 From ebb6c22e80ccb2889b9c459df36d686d223911f5 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 5 Apr 2009 06:01:37 -0300 Subject: V4L/DVB (11559): Siano: add support for infra-red (IR) controllers This patch add support for IR (infra-red) remote controllers. Further commits are needed in order to enable the activation of the IR components. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsir.c | 301 ++++++++++++++++++++++++++++++++++++++++ drivers/media/dvb/siano/smsir.h | 93 +++++++++++++ 2 files changed, 394 insertions(+) create mode 100644 drivers/media/dvb/siano/smsir.c create mode 100644 drivers/media/dvb/siano/smsir.h (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c new file mode 100644 index 0000000..a5f302c --- /dev/null +++ b/drivers/media/dvb/siano/smsir.c @@ -0,0 +1,301 @@ +/**************************************************************** + + Siano Mobile Silicon, Inc. + MDTV receiver kernel modules. + Copyright (C) 2006-2009, Uri Shkolnik + + 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, see . + + ****************************************************************/ + + +#include +#include + +#include "smscoreapi.h" +#include "smsir.h" +#include "sms-cards.h" + +/* In order to add new IR remote control - + * 1) Add it to the @ smsir,h, + * 2) Add its map to keyboard_layout_maps below + * 3) Set your board (sms-cards sub-module) to use it + */ + +static struct keyboard_layout_map_t keyboard_layout_maps[] = { + [SMS_IR_KB_DEFAULT_TV] = { + .ir_protocol = IR_RC5, + .rc5_kbd_address = KEYBOARD_ADDRESS_TV1, + .keyboard_layout_map = { + KEY_0, KEY_1, KEY_2, + KEY_3, KEY_4, KEY_5, + KEY_6, KEY_7, KEY_8, + KEY_9, 0, 0, KEY_POWER, + KEY_MUTE, 0, 0, + KEY_VOLUMEUP, KEY_VOLUMEDOWN, + KEY_BRIGHTNESSUP, + KEY_BRIGHTNESSDOWN, KEY_CHANNELUP, + KEY_CHANNELDOWN, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + [SMS_IR_KB_HCW_SILVER] = { + .ir_protocol = IR_RC5, + .rc5_kbd_address = KEYBOARD_ADDRESS_LIGHTING1, + .keyboard_layout_map = { + KEY_0, KEY_1, KEY_2, + KEY_3, KEY_4, KEY_5, + KEY_6, KEY_7, KEY_8, + KEY_9, KEY_TEXT, KEY_RED, + KEY_RADIO, KEY_MENU, + KEY_SUBTITLE, + KEY_MUTE, KEY_VOLUMEUP, + KEY_VOLUMEDOWN, KEY_PREVIOUS, 0, + KEY_UP, KEY_DOWN, KEY_LEFT, + KEY_RIGHT, KEY_VIDEO, KEY_AUDIO, + KEY_MHP, KEY_EPG, KEY_TV, + 0, KEY_NEXTSONG, KEY_EXIT, + KEY_CHANNELUP, KEY_CHANNELDOWN, + KEY_CHANNEL, 0, + KEY_PREVIOUSSONG, KEY_ENTER, + KEY_SLEEP, 0, 0, KEY_BLUE, + 0, 0, 0, 0, KEY_GREEN, 0, + KEY_PAUSE, 0, KEY_REWIND, + 0, KEY_FASTFORWARD, KEY_PLAY, + KEY_STOP, KEY_RECORD, + KEY_YELLOW, 0, 0, KEY_SELECT, + KEY_ZOOM, KEY_POWER, 0, 0 + } + }, + { } /* Terminating entry */ +}; + +u32 ir_pos; +u32 ir_word; +u32 ir_toggle; + +#define RC5_PUSH_BIT(dst, bit, pos) \ + { dst <<= 1; dst |= bit; pos++; } + + +static void sms_ir_rc5_event(struct smscore_device_t *coredev, + u32 toggle, u32 addr, u32 cmd) +{ + bool toggle_changed; + u16 keycode; + + sms_info("IR RC5 word: address %d, command %d, toggle %d", + addr, cmd, toggle); + + toggle_changed = ir_toggle != toggle; + /* keep toggle */ + ir_toggle = toggle; + + if (addr != + keyboard_layout_maps[coredev->ir.ir_kb_type].rc5_kbd_address) + return; /* Check for valid address */ + + keycode = + keyboard_layout_maps + [coredev->ir.ir_kb_type].keyboard_layout_map[cmd]; + + if (!toggle_changed && + (keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN)) + return; /* accept only repeated volume, reject other keys */ + + sms_info("kernel input keycode (from ir) %d", keycode); + input_report_key(coredev->ir.input_dev, keycode, 1); + input_sync(coredev->ir.input_dev); + +} + +/* decode raw bit pattern to RC5 code */ +/* taken from ir-functions.c */ +static u32 ir_rc5_decode(unsigned int code) +{ +/* unsigned int org_code = code;*/ + unsigned int pair; + unsigned int rc5 = 0; + int i; + + for (i = 0; i < 14; ++i) { + pair = code & 0x3; + code >>= 2; + + rc5 <<= 1; + switch (pair) { + case 0: + case 2: + break; + case 1: + rc5 |= 1; + break; + case 3: +/* dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/ + sms_info("bad code"); + return 0; + } + } +/* + dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, + toggle=%x, address=%x, " + "instr=%x\n", rc5, org_code, RC5_START(rc5), + RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); +*/ + return rc5; +} + +static void sms_rc5_parse_word(struct smscore_device_t *coredev) +{ + #define RC5_START(x) (((x)>>12)&3) + #define RC5_TOGGLE(x) (((x)>>11)&1) + #define RC5_ADDR(x) (((x)>>6)&0x1F) + #define RC5_INSTR(x) ((x)&0x3F) + + int i, j; + u32 rc5_word = 0; + + /* Reverse the IR word direction */ + for (i = 0 ; i < 28 ; i++) + RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j) + + rc5_word = ir_rc5_decode(rc5_word); + /* sms_info("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */ + + sms_ir_rc5_event(coredev, + RC5_TOGGLE(rc5_word), + RC5_ADDR(rc5_word), + RC5_INSTR(rc5_word)); +} + + +static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev, + s32 ir_sample) +{ + #define RC5_TIME_GRANULARITY 200 + #define RC5_DEF_BIT_TIME 889 + #define RC5_MAX_SAME_BIT_CONT 4 + #define RC5_WORD_LEN 27 /* 28 bit */ + + u32 i, j; + s32 delta_time; + u32 time = (ir_sample > 0) ? ir_sample : (0-ir_sample); + u32 level = (ir_sample < 0) ? 0 : 1; + + for (i = RC5_MAX_SAME_BIT_CONT; i > 0; i--) { + delta_time = time - (i*RC5_DEF_BIT_TIME) + RC5_TIME_GRANULARITY; + if (delta_time < 0) + continue; /* not so many consecutive bits */ + if (delta_time > (2 * RC5_TIME_GRANULARITY)) { + /* timeout */ + if (ir_pos == (RC5_WORD_LEN-1)) + /* complete last bit */ + RC5_PUSH_BIT(ir_word, level, ir_pos) + + if (ir_pos == RC5_WORD_LEN) + sms_rc5_parse_word(coredev); + else if (ir_pos) /* timeout within a word */ + sms_info("IR error parsing a word"); + + ir_pos = 0; + ir_word = 0; + /* sms_info("timeout %d", time); */ + break; + } + /* The time is within the range of this number of bits */ + for (j = 0 ; j < i ; j++) + RC5_PUSH_BIT(ir_word, level, ir_pos) + + break; + } +} + +void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) +{ + #define IR_DATA_RECEIVE_MAX_LEN 520 /* 128*4 + 4 + 4 */ + u32 i; + enum ir_protocol ir_protocol = + keyboard_layout_maps[coredev->ir.ir_kb_type] + .ir_protocol; + s32 *samples; + int count = len>>2; + + samples = (s32 *)buf; +/* sms_info("IR buffer received, length = %d", count);*/ + + for (i = 0; i < count; i++) + if (ir_protocol == IR_RC5) + sms_rc5_accumulate_bits(coredev, samples[i]); + /* IR_RCMM not implemented */ +} + +int sms_ir_init(struct smscore_device_t *coredev) +{ + struct input_dev *input_dev; + + sms_info("Allocating input device"); + input_dev = input_allocate_device(); + if (!input_dev) { + sms_err("Not enough memory"); + return -ENOMEM; + } + + coredev->ir.input_dev = input_dev; + coredev->ir.ir_kb_type = + sms_get_board(smscore_get_board_id(coredev))->ir_kb_type; + coredev->ir.keyboard_layout_map = + keyboard_layout_maps[coredev->ir.ir_kb_type]. + keyboard_layout_map; + sms_info("IR remote keyboard type is %d", coredev->ir.ir_kb_type); + + coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ + coredev->ir.timeout = IR_DEFAULT_TIMEOUT; + sms_info("IR port %d, timeout %d ms", + coredev->ir.controller, coredev->ir.timeout); + + snprintf(coredev->ir.name, + IR_DEV_NAME_MAX_LEN, + "SMS IR w/kbd type %d", + coredev->ir.ir_kb_type); + input_dev->name = coredev->ir.name; + input_dev->phys = coredev->ir.name; + input_dev->dev.parent = coredev->device; + + /* Key press events only */ + input_dev->evbit[0] = BIT_MASK(EV_KEY); + input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); + + sms_info("Input device (IR) %s is set for key events", input_dev->name); + + if (input_register_device(input_dev)) { + sms_err("Failed to register device"); + input_free_device(input_dev); + return -EACCES; + } + + return 0; +} + +void sms_ir_exit(struct smscore_device_t *coredev) +{ + if (coredev->ir.input_dev) + input_unregister_device(coredev->ir.input_dev); + + sms_info(""); +} + diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h new file mode 100644 index 0000000..b7d703e --- /dev/null +++ b/drivers/media/dvb/siano/smsir.h @@ -0,0 +1,93 @@ +/**************************************************************** + +Siano Mobile Silicon, Inc. +MDTV receiver kernel modules. +Copyright (C) 2006-2009, Uri Shkolnik + +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, see . + +****************************************************************/ + +#ifndef __SMS_IR_H__ +#define __SMS_IR_H__ + +#include + +#define IR_DEV_NAME_MAX_LEN 23 /* "SMS IR kbd type nn\0" */ +#define IR_KEYBOARD_LAYOUT_SIZE 64 +#define IR_DEFAULT_TIMEOUT 100 + +enum ir_kb_type { + SMS_IR_KB_DEFAULT_TV, + SMS_IR_KB_HCW_SILVER +}; + +enum rc5_keyboard_address { + KEYBOARD_ADDRESS_TV1 = 0, + KEYBOARD_ADDRESS_TV2 = 1, + KEYBOARD_ADDRESS_TELETEXT = 2, + KEYBOARD_ADDRESS_VIDEO = 3, + KEYBOARD_ADDRESS_LV1 = 4, + KEYBOARD_ADDRESS_VCR1 = 5, + KEYBOARD_ADDRESS_VCR2 = 6, + KEYBOARD_ADDRESS_EXPERIMENTAL = 7, + KEYBOARD_ADDRESS_SAT1 = 8, + KEYBOARD_ADDRESS_CAMERA = 9, + KEYBOARD_ADDRESS_SAT2 = 10, + KEYBOARD_ADDRESS_CDV = 12, + KEYBOARD_ADDRESS_CAMCORDER = 13, + KEYBOARD_ADDRESS_PRE_AMP = 16, + KEYBOARD_ADDRESS_TUNER = 17, + KEYBOARD_ADDRESS_RECORDER1 = 18, + KEYBOARD_ADDRESS_PRE_AMP1 = 19, + KEYBOARD_ADDRESS_CD_PLAYER = 20, + KEYBOARD_ADDRESS_PHONO = 21, + KEYBOARD_ADDRESS_SATA = 22, + KEYBOARD_ADDRESS_RECORDER2 = 23, + KEYBOARD_ADDRESS_CDR = 26, + KEYBOARD_ADDRESS_LIGHTING = 29, + KEYBOARD_ADDRESS_LIGHTING1 = 30, /* KEYBOARD_ADDRESS_HCW_SILVER */ + KEYBOARD_ADDRESS_PHONE = 31, + KEYBOARD_ADDRESS_NOT_RC5 = 0xFFFF +}; + +enum ir_protocol { + IR_RC5, + IR_RCMM +}; + +struct keyboard_layout_map_t { + enum ir_protocol ir_protocol; + enum rc5_keyboard_address rc5_kbd_address; + u16 keyboard_layout_map[IR_KEYBOARD_LAYOUT_SIZE]; +}; + +struct smscore_device_t; + +struct ir_t { + struct input_dev *input_dev; + enum ir_kb_type ir_kb_type; + char name[IR_DEV_NAME_MAX_LEN+1]; + u16 *keyboard_layout_map; + u32 timeout; + u32 controller; +}; + +int sms_ir_init(struct smscore_device_t *coredev); +void sms_ir_exit(struct smscore_device_t *coredev); +void sms_ir_event(struct smscore_device_t *coredev, + const char *buf, int len); + +#endif /* __SMS_IR_H__ */ + -- cgit v1.1 From cb17f9047d2c6f248f2f87f4783ca90db7b3f445 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Mon, 20 Apr 2009 13:00:52 -0300 Subject: V4L/DVB (11561): Siano: add messages handling for big-endian target Add code that modify the content of Siano's protocol messages when running with big-endian target. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsendian.c | 100 ++++++++++++++++++++++++++++++++++++ drivers/media/dvb/siano/smsendian.h | 32 ++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 drivers/media/dvb/siano/smsendian.c create mode 100644 drivers/media/dvb/siano/smsendian.h (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsendian.c b/drivers/media/dvb/siano/smsendian.c new file mode 100644 index 0000000..d79aa05 --- /dev/null +++ b/drivers/media/dvb/siano/smsendian.c @@ -0,0 +1,100 @@ +/**************************************************************** + + Siano Mobile Silicon, Inc. + MDTV receiver kernel modules. + Copyright (C) 2006-2009, Uri Shkolnik + + 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, see . + + ****************************************************************/ + +#include + +#include "smsendian.h" +#include "smscoreapi.h" + +void smsendian_handle_tx_message(void *buffer) +{ +#ifdef __BIG_ENDIAN + struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer; + int i; + int msgWords; + + switch (msg->xMsgHeader.msgType) { + case MSG_SMS_DATA_DOWNLOAD_REQ: + { + msg->msgData[0] = le32_to_cpu(msg->msgData[0]); + break; + } + + default: + msgWords = (msg->xMsgHeader.msgLength - + sizeof(struct SmsMsgHdr_ST))/4; + + for (i = 0; i < msgWords; i++) + msg->msgData[i] = le32_to_cpu(msg->msgData[i]); + + break; + } +#endif /* __BIG_ENDIAN */ +} + +void smsendian_handle_rx_message(void *buffer) +{ +#ifdef __BIG_ENDIAN + struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer; + int i; + int msgWords; + + switch (msg->xMsgHeader.msgType) { + case MSG_SMS_GET_VERSION_EX_RES: + { + struct SmsVersionRes_ST *ver = + (struct SmsVersionRes_ST *) msg; + ver->ChipModel = le16_to_cpu(ver->ChipModel); + break; + } + + case MSG_SMS_DVBT_BDA_DATA: + case MSG_SMS_DAB_CHANNEL: + case MSG_SMS_DATA_MSG: + { + break; + } + + default: + { + msgWords = (msg->xMsgHeader.msgLength - + sizeof(struct SmsMsgHdr_ST))/4; + + for (i = 0; i < msgWords; i++) + msg->msgData[i] = le32_to_cpu(msg->msgData[i]); + + break; + } + } +#endif /* __BIG_ENDIAN */ +} + +void smsendian_handle_message_header(void *msg) +{ +#ifdef __BIG_ENDIAN + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg; + + phdr->msgType = le16_to_cpu(phdr->msgType); + phdr->msgLength = le16_to_cpu(phdr->msgLength); + phdr->msgFlags = le16_to_cpu(phdr->msgFlags); +#endif /* __BIG_ENDIAN */ +} + diff --git a/drivers/media/dvb/siano/smsendian.h b/drivers/media/dvb/siano/smsendian.h new file mode 100644 index 0000000..7fbedc6 --- /dev/null +++ b/drivers/media/dvb/siano/smsendian.h @@ -0,0 +1,32 @@ +/**************************************************************** + +Siano Mobile Silicon, Inc. +MDTV receiver kernel modules. +Copyright (C) 2006-2009, Uri Shkolnik + +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, see . + +****************************************************************/ + +#ifndef __SMS_ENDIAN_H__ +#define __SMS_ENDIAN_H__ + +#include + +void smsendian_handle_tx_message(void *buffer); +void smsendian_handle_rx_message(void *buffer); +void smsendian_handle_message_header(void *msg); + +#endif /* __SMS_ENDIAN_H__ */ + -- cgit v1.1 From 1339f9108a84710969903e892dcf1849ae1215cf Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Mon, 27 Apr 2009 07:50:42 -0300 Subject: V4L/DVB (11726): Modify the file license to match all other Siano's files Modify the file license to match all other Siano's files Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 48 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index d728448..fcd2bde 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -1,26 +1,26 @@ -/* - * Driver for the Siano SMS1xxx USB dongle - * - * author: Anatoly Greenblat - * - * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * 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 __smscoreapi_h__ -#define __smscoreapi_h__ +/**************************************************************** + +Siano Mobile Silicon, Inc. +MDTV receiver kernel modules. +Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat + +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, see . + +****************************************************************/ + +#ifndef __SMS_CORE_API_H__ +#define __SMS_CORE_API_H__ #include #include @@ -523,4 +523,4 @@ int smscore_led_state(struct smscore_device_t *core, int led); dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) -#endif /* __smscoreapi_h__ */ +#endif /* __SMS_CORE_API_H__ */ -- cgit v1.1 From f95e82c2e5f0dbb9b6e9c7d03b0311c21b6b05b8 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Mon, 11 May 2009 06:36:27 -0300 Subject: V4L/DVB (11727): Siano: core header - update include files Re-order the include files list Re-order the include files list, put the DVB-API v3 within its own section, within a define container. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index fcd2bde..d826ded 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -28,14 +28,19 @@ along with this program. If not, see . #include #include #include -#include #include +#include +#include + +#include +#define SMS_DVB3_SUBSYS +#ifdef SMS_DVB3_SUBSYS #include "dmxdev.h" #include "dvbdev.h" #include "dvb_demux.h" #include "dvb_frontend.h" - +#endif #define kmutex_init(_p_) mutex_init(_p_) #define kmutex_lock(_p_) mutex_lock(_p_) -- cgit v1.1 From e527579373ab3be045de16a627e43a193fcfacc0 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Mon, 27 Apr 2009 09:09:47 -0300 Subject: V4L/DVB (11728): Siano: smsdvb - modify license Siano: smsdvb - Fix license to match all other Siano's files Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsdvb.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index ba080b9..db3346d 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -1,23 +1,23 @@ -/* - * Driver for the Siano SMS1xxx USB dongle - * - * Author: Uri Shkolni - * - * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * 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. - */ +/**************************************************************** + +Siano Mobile Silicon, Inc. +MDTV receiver kernel modules. +Copyright (C) 2006-2008, Uri Shkolnik + +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, see . + +****************************************************************/ #include #include -- cgit v1.1 From 2e25d1428ae1a166954fb2cd0de422094a93fef1 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Mon, 27 Apr 2009 09:12:37 -0300 Subject: V4L/DVB (11729): Siano: smsdvb - remove redundent complete instruction Remove redundant complete instruction from smsdvb, in the past this was used by the statistics state machine, but no longer. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsdvb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index db3346d..9d6aab5 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -485,7 +485,6 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, client->coredev = coredev; init_completion(&client->tune_done); - init_completion(&client->stat_done); kmutex_lock(&g_smsdvb_clientslock); -- cgit v1.1 From 6d4e6972bb9545f968359379aa5adff863aa4d7c Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 12 May 2009 07:57:54 -0300 Subject: V4L/DVB (11776): Siano: smsusb - update license This patch updates the license of the USB interface driver Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 5cda938..ad80366 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -1,23 +1,23 @@ -/* - * Driver for the Siano SMS1xxx USB dongle - * - * author: Anatoly Greenblat - * - * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * 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. - */ +/**************************************************************** + +Siano Mobile Silicon, Inc. +MDTV receiver kernel modules. +Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat + +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, see . + +****************************************************************/ #include #include -- cgit v1.1 From c7ce8d37a738b64cafae07db4de021edf1feaa70 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 12 May 2009 08:24:07 -0300 Subject: V4L/DVB (11777): Siano: smsusb - handle byte ordering and big endianity This patch adds support for byte ordering and big endianity handling for the USB interface driver Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index ad80366..1bcd0ef 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -26,6 +26,7 @@ along with this program. If not, see . #include "smscoreapi.h" #include "sms-cards.h" +#include "smsendian.h" static int sms_dbg; module_param_named(debug, sms_dbg, int, 0644); @@ -177,6 +178,7 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size) struct smsusb_device_t *dev = (struct smsusb_device_t *) context; int dummy; + smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); } @@ -334,8 +336,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) case SMS_VEGA: dev->buffer_size = USB2_BUFFER_SIZE; dev->response_alignment = - dev->udev->ep_in[1]->desc.wMaxPacketSize - - sizeof(struct SmsMsgHdr_ST); + le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - + sizeof(struct SmsMsgHdr_ST); params.flags |= SMS_DEVICE_FAMILY2; break; -- cgit v1.1 From 8f12d0a4eb7c55837f0104c95c60933dc9c593db Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 12 May 2009 11:28:41 -0300 Subject: V4L/DVB (11778): Siano: smsusb - lost buffers bug fix This patch fixes a problem were protocol buffers have been lost during USB disconnect events. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 1bcd0ef..4fa38bd 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -65,14 +65,14 @@ static void smsusb_onresponse(struct urb *urb) struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; struct smsusb_device_t *dev = surb->dev; - if (urb->status < 0) { - sms_err("error, urb status %d, %d bytes", + if (urb->status == -ESHUTDOWN) { + sms_err("error, urb status %d (-ESHUTDOWN), %d bytes", urb->status, urb->actual_length); return; } - if (urb->actual_length > 0) { - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) surb->cb->p; + if ((urb->actual_length > 0) && (urb->status == 0)) { + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)surb->cb->p; smsendian_handle_message_header(phdr); if (urb->actual_length >= phdr->msgLength) { @@ -111,7 +111,10 @@ static void smsusb_onresponse(struct urb *urb) "msglen %d actual %d", phdr->msgLength, urb->actual_length); } - } + } else + sms_err("error, urb status %d, %d bytes", + urb->status, urb->actual_length); + exit_and_resubmit: smsusb_submit_urb(dev, surb); -- cgit v1.1 From 51819f6493f434598e89e8a66d6aa2c31bde494d Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 12 May 2009 10:38:58 -0300 Subject: V4L/DVB (11779): Siano: Makefile - add smsendian to build Add smsendian component to the module build Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile index bcf93f4..6354a471 100644 --- a/drivers/media/dvb/siano/Makefile +++ b/drivers/media/dvb/siano/Makefile @@ -1,4 +1,4 @@ -sms1xxx-objs := smscoreapi.o sms-cards.o +sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o -- cgit v1.1 From 2c5582e58ce2982fd64da21907dfad4061fc1f71 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2009 09:35:26 -0300 Subject: V4L/DVB (11780): Siano: fix compilation error due to the lack of EXTERNAL_SYMBOL Cc: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsendian.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsendian.c b/drivers/media/dvb/siano/smsendian.c index d79aa05..457b6d0 100644 --- a/drivers/media/dvb/siano/smsendian.c +++ b/drivers/media/dvb/siano/smsendian.c @@ -49,6 +49,7 @@ void smsendian_handle_tx_message(void *buffer) } #endif /* __BIG_ENDIAN */ } +EXPORT_SYMBOL_GPL(smsendian_handle_tx_message); void smsendian_handle_rx_message(void *buffer) { @@ -86,6 +87,7 @@ void smsendian_handle_rx_message(void *buffer) } #endif /* __BIG_ENDIAN */ } +EXPORT_SYMBOL_GPL(smsendian_handle_rx_message); void smsendian_handle_message_header(void *msg) { @@ -97,4 +99,4 @@ void smsendian_handle_message_header(void *msg) phdr->msgFlags = le16_to_cpu(phdr->msgFlags); #endif /* __BIG_ENDIAN */ } - +EXPORT_SYMBOL_GPL(smsendian_handle_message_header); -- cgit v1.1 From ba79bb2c381f01224786270d0914d46f31667cf0 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 12 May 2009 11:37:09 -0300 Subject: V4L/DVB (11781): Siano: smsdvb - add big endian support Add support for Siano protocol messages with big endian systems. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsdvb.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 9d6aab5..8fb283b 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -23,6 +23,7 @@ along with this program. If not, see . #include #include "smscoreapi.h" +#include "smsendian.h" #include "sms-cards.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -60,6 +61,8 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); + smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr); + switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), @@ -149,6 +152,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); PidMsg.msgData[0] = feed->pid; + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg); return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); } @@ -169,6 +173,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); PidMsg.msgData[0] = feed->pid; + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg); return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); } @@ -177,7 +182,10 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, void *buffer, size_t size, struct completion *completion) { - int rc = smsclient_sendrequest(client->smsclient, buffer, size); + int rc; + + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer); + rc = smsclient_sendrequest(client->smsclient, buffer, size); if (rc < 0) return rc; -- cgit v1.1 From 793786d19a35c59a9379cb75da5b5d6bd052820d Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 12 May 2009 12:28:46 -0300 Subject: V4L/DVB (11782): Siano: smsdvb - use 'push' status mechanism This patch replace the old method of pulling the device status by sending "get_statistics" request, to push mode. This make status update much faster, and reduce various operation time (UHF scan now takes 15s instead of 2m). In order to make the change the following modification have been applied: 1) core header - update statistics headers. 2) dvb adapter - omit the statistics request, add handling of status indications. 3) core 'onresponse' - re-route messages addressed to other adapter to the dvb adapter. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 21 ++- drivers/media/dvb/siano/smscoreapi.h | 270 +++++++++++++++++++++++++---------- drivers/media/dvb/siano/smsdvb.c | 266 +++++++++++++++++++--------------- 3 files changed, 366 insertions(+), 191 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index f3e1cc7..398e219 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -904,14 +904,11 @@ smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, * */ void smscore_onresponse(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb) -{ - struct SmsMsgHdr_ST *phdr = - (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); - struct smscore_client_t *client = - smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); + struct smscore_buffer_t *cb) { + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p + + cb->offset); + struct smscore_client_t *client; int rc = -EBUSY; - static unsigned long last_sample_time; /* = 0; */ static int data_total; /* = 0; */ unsigned long time_now = jiffies_to_msecs(jiffies); @@ -929,6 +926,16 @@ void smscore_onresponse(struct smscore_device_t *coredev, } data_total += cb->size; + /* Do we need to re-route? */ + if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) || + (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) { + if (coredev->mode == DEVICE_MODE_DVBT_BDA) + phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID; + } + + + client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); + /* If no client registered for type & id, * check for control client where type is not registered */ if (client) diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index d826ded..ca08f61 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -213,19 +213,15 @@ struct smscore_device_t { #define MSG_SMS_INIT_DEVICE_RES 579 #define MSG_SMS_ADD_PID_FILTER_REQ 601 #define MSG_SMS_ADD_PID_FILTER_RES 602 -#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 -#define MSG_SMS_REMOVE_PID_FILTER_RES 604 -#define MSG_SMS_DAB_CHANNEL 607 -#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 -#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 -#define MSG_SMS_GET_STATISTICS_REQ 615 -#define MSG_SMS_GET_STATISTICS_RES 616 +#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 +#define MSG_SMS_REMOVE_PID_FILTER_RES 604 +#define MSG_SMS_DAB_CHANNEL 607 +#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 +#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 #define MSG_SMS_HO_PER_SLICES_IND 630 -#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 -#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 -#define MSG_SMS_GET_STATISTICS_EX_REQ 653 -#define MSG_SMS_GET_STATISTICS_EX_RES 654 -#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 +#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 +#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 +#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 #define MSG_SMS_DATA_DOWNLOAD_REQ 660 #define MSG_SMS_DATA_DOWNLOAD_RES 661 #define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 @@ -347,85 +343,215 @@ struct SmsFirmware_ST { u8 Payload[1]; }; -struct SMSHOSTLIB_STATISTICS_ST { - u32 Reserved; /* Reserved */ +/* Statistics information returned as response for + * SmsHostApiGetStatistics_Req */ +struct SMSHOSTLIB_STATISTICS_S { + u32 Reserved; /* Reserved */ /* Common parameters */ - u32 IsRfLocked; /* 0 - not locked, 1 - locked */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ /* Reception quality */ - s32 SNR; /* dB */ - u32 BER; /* Post Viterbi BER [1E-5] */ - u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ - /* Transport stream PER, 0xFFFFFFFF indicate N/A, - * valid only for DVB-T/H */ - u32 TS_PER; - /* DVB-H frame error rate in percentage, - * 0xFFFFFFFF indicate N/A, valid only for DVB-H */ - u32 MFER; - s32 RSSI; /* dBm */ - s32 InBandPwr; /* In band power in dBM */ - s32 CarrierOffset; /* Carrier Offset in bin/1024 */ - - /* Transmission parameters, valid only for DVB-T/H */ - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz */ - /* Transmission Mode, for DAB modes 1-4, - * for DVB-T/H FFT mode carriers in Kilos */ - u32 TransmissionMode; - u32 ModemState; /* from SMS_DvbModemState_ET */ - u32 GuardInterval; /* Guard Interval, 1 divided by value */ - u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */ - u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET */ - u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET */ - u32 Constellation; /* Constellation from SMS_Constellation_ET */ + s32 SNR; /* dB */ + u32 BER; /* Post Viterbi BER [1E-5] */ + u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ + u32 TS_PER; /* Transport stream PER, + 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */ + u32 MFER; /* DVB-H frame error rate in percentage, + 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + s32 RSSI; /* dBm */ + s32 InBandPwr; /* In band power in dBM */ + s32 CarrierOffset; /* Carrier Offset in bin/1024 */ + + /* Transmission parameters */ + u32 Frequency; /* Frequency in Hz */ + u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */ + u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, + for DVB-T/H FFT mode carriers in Kilos */ + u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET, + valid only for DVB-T/H */ + u32 GuardInterval; /* Guard Interval from + SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */ + u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, + valid only for DVB-T/H */ + u32 LPCodeRate; /* Low Priority Code Rate from + SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */ + u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET, + valid only for DVB-T/H */ + u32 Constellation; /* Constellation from + SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */ /* Burst parameters, valid only for DVB-H */ - u32 BurstSize; /* Current burst size in bytes */ - u32 BurstDuration; /* Current burst duration in mSec */ - u32 BurstCycleTime; /* Current burst cycle time in mSec */ - u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, - * as calculated by demodulator */ - u32 NumOfRows; /* Number of rows in MPE table */ - u32 NumOfPaddCols; /* Number of padding columns in MPE table */ - u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */ - /* Burst parameters */ - u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include - * errors after MPE RS decoding */ - u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors - * after MPE RS decoding */ - u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected - * by MPE RS decoding */ - + u32 BurstSize; /* Current burst size in bytes, + valid only for DVB-H */ + u32 BurstDuration; /* Current burst duration in mSec, + valid only for DVB-H */ + u32 BurstCycleTime; /* Current burst cycle time in mSec, + valid only for DVB-H */ + u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec, + as calculated by demodulator, valid only for DVB-H */ + u32 NumOfRows; /* Number of rows in MPE table, + valid only for DVB-H */ + u32 NumOfPaddCols; /* Number of padding columns in MPE table, + valid only for DVB-H */ + u32 NumOfPunctCols; /* Number of puncturing columns in MPE table, + valid only for DVB-H */ + u32 ErrorTSPackets; /* Number of erroneous + transport-stream packets */ + u32 TotalTSPackets; /* Total number of transport-stream packets */ + u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include + errors after MPE RS decoding */ + u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors + after MPE RS decoding */ + u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were + corrected by MPE RS decoding */ /* Common params */ - u32 BERErrorCount; /* Number of errornous SYNC bits. */ - u32 BERBitCount; /* Total number of SYNC bits. */ + u32 BERErrorCount; /* Number of errornous SYNC bits. */ + u32 BERBitCount; /* Total number of SYNC bits. */ /* Interface information */ - u32 SmsToHostTxErrors; /* Total number of transmission errors. */ + u32 SmsToHostTxErrors; /* Total number of transmission errors. */ /* DAB/T-DMB */ - u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ + u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ /* DVB-H TPS parameters */ - u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; - * if set to 0xFFFFFFFF cell_id not yet recovered */ + u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; + if set to 0xFFFFFFFF cell_id not yet recovered */ + u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - + Time Slicing indicator, bit 0 - MPE-FEC indicator */ + u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - + Time Slicing indicator, bit 0 - MPE-FEC indicator */ + + u32 NumMPEReceived; /* DVB-H, Num MPE section received */ + + u32 ReservedFields[10]; /* Reserved */ +}; + +struct PID_STATISTICS_DATA_S { + struct PID_BURST_S { + u32 size; + u32 padding_cols; + u32 punct_cols; + u32 duration; + u32 cycle; + u32 calc_cycle; + } burst; + + u32 tot_tbl_cnt; + u32 invalid_tbl_cnt; + u32 tot_cor_tbl; +}; +struct PID_DATA_S { + u32 pid; + u32 num_rows; + struct PID_STATISTICS_DATA_S pid_statistics; }; -struct SmsMsgStatisticsInfo_ST { - u32 RequestResult; +#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1) +#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth) +#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \ + if (_stat.TransmissionMode == 0) \ + _stat.TransmissionMode = 2; \ + else if (_stat.TransmissionMode == 1) \ + _stat.TransmissionMode = 8; \ + else \ + _stat.TransmissionMode = 4; + +struct TRANSMISSION_STATISTICS_S { + u32 Frequency; /* Frequency in Hz */ + u32 Bandwidth; /* Bandwidth in MHz */ + u32 TransmissionMode; /* FFT mode carriers in Kilos */ + u32 GuardInterval; /* Guard Interval from + SMSHOSTLIB_GUARD_INTERVALS_ET */ + u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ + u32 LPCodeRate; /* Low Priority Code Rate from + SMSHOSTLIB_CODE_RATE_ET */ + u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ + u32 Constellation; /* Constellation from + SMSHOSTLIB_CONSTELLATION_ET */ - struct SMSHOSTLIB_STATISTICS_ST Stat; + /* DVB-H TPS parameters */ + u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; + if set to 0xFFFFFFFF cell_id not yet recovered */ + u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - + Time Slicing indicator, bit 0 - MPE-FEC indicator */ + u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - + Time Slicing indicator, bit 0 - MPE-FEC indicator */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ +}; + +struct RECEPTION_STATISTICS_S { + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + + u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ + s32 SNR; /* dB */ + u32 BER; /* Post Viterbi BER [1E-5] */ + u32 BERErrorCount; /* Number of erronous SYNC bits. */ + u32 BERBitCount; /* Total number of SYNC bits. */ + u32 TS_PER; /* Transport stream PER, + 0xFFFFFFFF indicate N/A */ + u32 MFER; /* DVB-H frame error rate in percentage, + 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + s32 RSSI; /* dBm */ + s32 InBandPwr; /* In band power in dBM */ + s32 CarrierOffset; /* Carrier Offset in bin/1024 */ + u32 ErrorTSPackets; /* Number of erroneous + transport-stream packets */ + u32 TotalTSPackets; /* Total number of transport-stream packets */ + + s32 MRC_SNR; /* dB */ + s32 MRC_RSSI; /* dBm */ + s32 MRC_InBandPwr; /* In band power in dBM */ +}; - /* Split the calc of the SNR in DAB */ - u32 Signal; /* dB */ - u32 Noise; /* dB */ +/* Statistics information returned as response for + * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */ +struct SMSHOSTLIB_STATISTICS_DVB_S { + /* Reception */ + struct RECEPTION_STATISTICS_S ReceptionData; + + /* Transmission parameters */ + struct TRANSMISSION_STATISTICS_S TransmissionData; + + /* Burst parameters, valid only for DVB-H */ +#define SRVM_MAX_PID_FILTERS 8 + struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS]; +}; + +struct SRVM_SIGNAL_STATUS_S { + u32 result; + u32 snr; + u32 tsPackets; + u32 etsPackets; + u32 constellation; + u32 hpCode; + u32 tpsSrvIndLP; + u32 tpsSrvIndHP; + u32 cellId; + u32 reason; + + s32 inBandPower; + u32 requestId; +}; + +struct SMSHOSTLIB_I2C_REQ_ST { + u32 DeviceAddress; /* I2c device address */ + u32 WriteCount; /* number of bytes to write */ + u32 ReadCount; /* number of bytes to read */ + u8 Data[1]; +}; + +struct SMSHOSTLIB_I2C_RES_ST { + u32 Status; /* non-zero value in case of failure */ + u32 ReadCount; /* number of bytes read */ + u8 Data[1]; }; diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 8fb283b..881f5c5 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -40,12 +40,15 @@ struct smsdvb_client_t { struct dvb_frontend frontend; fe_status_t fe_status; - int fe_ber, fe_snr, fe_unc, fe_signal_strength; - struct completion tune_done, stat_done; + struct completion tune_done; /* todo: save freq/band instead whole struct */ struct dvb_frontend_parameters fe_params; + + struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; + int event_fe_state; + int event_unc_state; }; static struct list_head g_smsdvb_clients; @@ -55,11 +58,19 @@ static int sms_dbg; module_param_named(debug, sms_dbg, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); +/* Events that may come from DVB v3 adapter */ +static void sms_board_dvb3_event(struct smsdvb_client_t *client, + enum SMS_DVB3_EVENTS event) { +} + static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; - struct SmsMsgHdr_ST *phdr = - (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) + + cb->offset); + u32 *pMsgData = (u32 *) phdr + 1; + /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/ + bool is_status_update = false; smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr); @@ -73,43 +84,110 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) complete(&client->tune_done); break; - case MSG_SMS_GET_STATISTICS_RES: - { - struct SmsMsgStatisticsInfo_ST *p = - (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); - - if (p->Stat.IsDemodLocked) { - client->fe_status = FE_HAS_SIGNAL | - FE_HAS_CARRIER | - FE_HAS_VITERBI | - FE_HAS_SYNC | - FE_HAS_LOCK; - - client->fe_snr = p->Stat.SNR; - client->fe_ber = p->Stat.BER; - client->fe_unc = p->Stat.BERErrorCount; - - if (p->Stat.InBandPwr < -95) - client->fe_signal_strength = 0; - else if (p->Stat.InBandPwr > -29) - client->fe_signal_strength = 100; - else - client->fe_signal_strength = - (p->Stat.InBandPwr + 95) * 3 / 2; + case MSG_SMS_SIGNAL_DETECTED_IND: + sms_info("MSG_SMS_SIGNAL_DETECTED_IND"); + client->sms_stat_dvb.TransmissionData.IsDemodLocked = true; + is_status_update = true; + break; + + case MSG_SMS_NO_SIGNAL_IND: + sms_info("MSG_SMS_NO_SIGNAL_IND"); + client->sms_stat_dvb.TransmissionData.IsDemodLocked = false; + is_status_update = true; + break; + + case MSG_SMS_TRANSMISSION_IND: { + sms_info("MSG_SMS_TRANSMISSION_IND"); + + pMsgData++; + memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData, + sizeof(struct TRANSMISSION_STATISTICS_S)); + + /* Mo need to correct guard interval + * (as opposed to old statistics message). + */ + CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData); + CORRECT_STAT_TRANSMISSON_MODE( + client->sms_stat_dvb.TransmissionData); + is_status_update = true; + break; + } + case MSG_SMS_HO_PER_SLICES_IND: { + struct RECEPTION_STATISTICS_S *pReceptionData = + &client->sms_stat_dvb.ReceptionData; + struct SRVM_SIGNAL_STATUS_S SignalStatusData; + + /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/ + pMsgData++; + SignalStatusData.result = pMsgData[0]; + SignalStatusData.snr = pMsgData[1]; + SignalStatusData.inBandPower = (s32) pMsgData[2]; + SignalStatusData.tsPackets = pMsgData[3]; + SignalStatusData.etsPackets = pMsgData[4]; + SignalStatusData.constellation = pMsgData[5]; + SignalStatusData.hpCode = pMsgData[6]; + SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03; + SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03; + SignalStatusData.cellId = pMsgData[9] & 0xFFFF; + SignalStatusData.reason = pMsgData[10]; + SignalStatusData.requestId = pMsgData[11]; + pReceptionData->IsRfLocked = pMsgData[16]; + pReceptionData->IsDemodLocked = pMsgData[17]; + pReceptionData->ModemState = pMsgData[12]; + pReceptionData->SNR = pMsgData[1]; + pReceptionData->BER = pMsgData[13]; + pReceptionData->RSSI = pMsgData[14]; + CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData); + + pReceptionData->InBandPwr = (s32) pMsgData[2]; + pReceptionData->CarrierOffset = (s32) pMsgData[15]; + pReceptionData->TotalTSPackets = pMsgData[3]; + pReceptionData->ErrorTSPackets = pMsgData[4]; + + /* TS PER */ + if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets) + > 0) { + pReceptionData->TS_PER = (SignalStatusData.etsPackets + * 100) / (SignalStatusData.tsPackets + + SignalStatusData.etsPackets); } else { - client->fe_status = 0; - client->fe_snr = - client->fe_ber = - client->fe_unc = - client->fe_signal_strength = 0; + pReceptionData->TS_PER = 0; } - complete(&client->stat_done); - break; - } } + pReceptionData->BERBitCount = pMsgData[18]; + pReceptionData->BERErrorCount = pMsgData[19]; + pReceptionData->MRC_SNR = pMsgData[20]; + pReceptionData->MRC_InBandPwr = pMsgData[21]; + pReceptionData->MRC_RSSI = pMsgData[22]; + + is_status_update = true; + break; + } + } smscore_putbuffer(client->coredev, cb); + if (is_status_update) { + if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) { + client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER + | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); + if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets + == 0) + sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); + else + sms_board_dvb3_event(client, + DVB3_EVENT_UNC_ERR); + + } else { + /*client->fe_status = + (phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ? + 0 : FE_HAS_SIGNAL;*/ + client->fe_status = 0; + sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); + } + } + return 0; } @@ -194,83 +272,61 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, 0 : -ETIME; } -static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) -{ - struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, - DVBT_BDA_CONTROL_MSG_ID, - HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 }; - int ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->stat_done); - if (ret < 0) - return ret; - - if (client->fe_status & FE_HAS_LOCK) - sms_board_led_feedback(client->coredev, - (client->fe_unc == 0) ? - SMS_LED_HI : SMS_LED_LO); - else - sms_board_led_feedback(client->coredev, SMS_LED_OFF); - return ret; -} - static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) { - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); + struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); - if (!rc) - *stat = client->fe_status; + *stat = client->fe_status; - return rc; + return 0; } static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) { - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); + struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); - if (!rc) - *ber = client->fe_ber; + *ber = client->sms_stat_dvb.ReceptionData.BER; - return rc; + return 0; } static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); + struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); - if (!rc) - *strength = client->fe_signal_strength; + if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95) + *strength = 0; + else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29) + *strength = 100; + else + *strength = + (client->sms_stat_dvb.ReceptionData.InBandPwr + + 95) * 3 / 2; - return rc; + return 0; } static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) { - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); + struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); - if (!rc) - *snr = client->fe_snr; + *snr = client->sms_stat_dvb.ReceptionData.SNR; - return rc; + return 0; } static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); + struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); - if (!rc) - *ucblocks = client->fe_unc; + *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; - return rc; + return 0; } static int smsdvb_get_tune_settings(struct dvb_frontend *fe, @@ -294,12 +350,15 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, struct SmsMsgHdr_ST Msg; u32 Data[3]; } Msg; - int ret; - Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - Msg.Msg.msgDstId = HIF_TASK; - Msg.Msg.msgFlags = 0; - Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; + client->fe_status = FE_HAS_SIGNAL; + client->event_fe_state = -1; + client->event_unc_state = -1; + + Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + Msg.Msg.msgDstId = HIF_TASK; + Msg.Msg.msgFlags = 0; + Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; Msg.Msg.msgLength = sizeof(Msg); Msg.Data[0] = fep->frequency; Msg.Data[2] = 12000000; @@ -315,24 +374,6 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, default: return -EINVAL; } - /* Disable LNA, if any. An error is returned if no LNA is present */ - ret = sms_board_lna_control(client->coredev, 0); - if (ret == 0) { - fe_status_t status; - - /* tune with LNA off at first */ - ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); - - smsdvb_read_status(fe, &status); - - if (status & FE_HAS_LOCK) - return ret; - - /* previous tune didnt lock - enable LNA and tune again */ - sms_board_lna_control(client->coredev, 1); - } - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); } @@ -357,8 +398,7 @@ static int smsdvb_init(struct dvb_frontend *fe) struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); - sms_board_power(client->coredev, 1); - + sms_board_dvb3_event(client, DVB3_EVENT_INIT); return 0; } @@ -367,8 +407,7 @@ static int smsdvb_sleep(struct dvb_frontend *fe) struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); - sms_board_led_feedback(client->coredev, SMS_LED_OFF); - sms_board_power(client->coredev, 0); + sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); return 0; } @@ -500,8 +539,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, kmutex_unlock(&g_smsdvb_clientslock); - sms_info("success"); + client->event_fe_state = -1; + client->event_unc_state = -1; + sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); + sms_info("success"); sms_board_setup(coredev); return 0; -- cgit v1.1 From 843d0605efa58f6e087cae074b22a2fb77506f6a Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 12 May 2009 13:13:13 -0300 Subject: V4L/DVB (11783): Siano: smsdvb - small typo fix ad module author Fix type at the module description Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsdvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 881f5c5..92a4dbb 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -596,5 +596,5 @@ module_init(smsdvb_module_init); module_exit(smsdvb_module_exit); MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); -MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); +MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); MODULE_LICENSE("GPL"); -- cgit v1.1 From c9679e3b0c329fa090798d658e185ee788540353 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Thu, 14 May 2009 16:28:17 -0300 Subject: V4L/DVB (11813): Siano: move dvb-api headers' includes to dvb adapter Move the DVB-API v3 headers' include list from the core component to the smsdvb (DVB adapter) which is the only one that uses them. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 7 ------- drivers/media/dvb/siano/smsdvb.c | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index ca08f61..942baae 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -34,13 +34,6 @@ along with this program. If not, see . #include -#define SMS_DVB3_SUBSYS -#ifdef SMS_DVB3_SUBSYS -#include "dmxdev.h" -#include "dvbdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" -#endif #define kmutex_init(_p_) mutex_init(_p_) #define kmutex_lock(_p_) mutex_lock(_p_) diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 92a4dbb..c845b79 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -22,6 +22,11 @@ along with this program. If not, see . #include #include +#include "dmxdev.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" + #include "smscoreapi.h" #include "smsendian.h" #include "sms-cards.h" -- cgit v1.1 From 3b2d18efd16d444ffd1ec50547ee6f1d66e3b57b Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Thu, 14 May 2009 16:31:23 -0300 Subject: V4L/DVB (11814): Siano: smscards - add gpio look-up table Add gpio look-up table for various requirements, any target may select any gpio and assign it to a function Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 64d74c5..5bd4fb4 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -35,9 +35,43 @@ #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9 #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 +struct sms_board_gpio_cfg { + int lna_vhf_exist; + int lna_vhf_ctrl; + int lna_uhf_exist; + int lna_uhf_ctrl; + int lna_uhf_d_ctrl; + int lna_sband_exist; + int lna_sband_ctrl; + int lna_sband_d_ctrl; + int foreign_lna0_ctrl; + int foreign_lna1_ctrl; + int foreign_lna2_ctrl; + int rf_switch_vhf; + int rf_switch_uhf; + int rf_switch_sband; + int leds_power; + int led0; + int led1; + int led2; + int led3; + int led4; + int ir; + int eeprom_wp; + int mrc_sense; + int mrc_pdn_resetn; + int mrc_gp0; /* mrcs spi int */ + int mrc_gp1; + int mrc_gp2; + int mrc_gp3; + int mrc_gp4; + int host_spi_gsp_ts_int; +}; + struct sms_board { enum sms_device_type_st type; char *name, *fw[DEVICE_MODE_MAX]; + struct sms_board_gpio_cfg board_cfg; /* gpios */ int led_power, led_hi, led_lo, lna_ctrl, rf_switch; -- cgit v1.1 From 90f944a38c4eb8432b6381fd0b9789f1f4600786 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Thu, 14 May 2009 16:32:12 -0300 Subject: V4L/DVB (11815): Siano: bind infra-red component Add the infra-red to the makefile and declare the assignment in the cards components. [mchehab@redhat.com: Fixed a few trivial merge conflicts] Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/Makefile | 2 +- drivers/media/dvb/siano/sms-cards.c | 1 + drivers/media/dvb/siano/sms-cards.h | 4 ++++ drivers/media/dvb/siano/smscoreapi.h | 3 ++- drivers/media/dvb/siano/smsir.c | 24 ++++++++++++------------ 5 files changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile index 6354a471..c6644d9 100644 --- a/drivers/media/dvb/siano/Makefile +++ b/drivers/media/dvb/siano/Makefile @@ -1,4 +1,4 @@ -sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o +sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 63e4d0e..c35ff1f 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -18,6 +18,7 @@ */ #include "sms-cards.h" +#include "smsir.h" static int sms_dbg; module_param_named(cards_dbg, sms_dbg, int, 0644); diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 5bd4fb4..447481a 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -22,6 +22,7 @@ #include #include "smscoreapi.h" +#include "smsir.h" #define SMS_BOARD_UNKNOWN 0 #define SMS1XXX_BOARD_SIANO_STELLAR 1 @@ -72,6 +73,7 @@ struct sms_board { enum sms_device_type_st type; char *name, *fw[DEVICE_MODE_MAX]; struct sms_board_gpio_cfg board_cfg; + enum ir_kb_type ir_kb_type; /* gpios */ int led_power, led_hi, led_lo, lna_ctrl, rf_switch; @@ -79,6 +81,8 @@ struct sms_board { struct sms_board *sms_get_board(int id); +extern struct smscore_device_t *coredev; + int sms_board_setup(struct smscore_device_t *coredev); #define SMS_LED_OFF 0 diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 942baae..6e23c5f 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -34,6 +34,7 @@ along with this program. If not, see . #include +#include "smsir.h" #define kmutex_init(_p_) mutex_init(_p_) #define kmutex_lock(_p_) mutex_lock(_p_) @@ -167,7 +168,7 @@ struct smscore_device_t { u32 fw_buf_size; /* Infrared (IR) */ - /* struct ir_t ir; */ + struct ir_t ir; int led_state; }; diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c index a5f302c..e3d776f 100644 --- a/drivers/media/dvb/siano/smsir.c +++ b/drivers/media/dvb/siano/smsir.c @@ -99,7 +99,7 @@ static void sms_ir_rc5_event(struct smscore_device_t *coredev, bool toggle_changed; u16 keycode; - sms_info("IR RC5 word: address %d, command %d, toggle %d", + sms_log("IR RC5 word: address %d, command %d, toggle %d", addr, cmd, toggle); toggle_changed = ir_toggle != toggle; @@ -118,7 +118,7 @@ static void sms_ir_rc5_event(struct smscore_device_t *coredev, (keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN)) return; /* accept only repeated volume, reject other keys */ - sms_info("kernel input keycode (from ir) %d", keycode); + sms_log("kernel input keycode (from ir) %d", keycode); input_report_key(coredev->ir.input_dev, keycode, 1); input_sync(coredev->ir.input_dev); @@ -147,7 +147,7 @@ static u32 ir_rc5_decode(unsigned int code) break; case 3: /* dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/ - sms_info("bad code"); + sms_log("bad code"); return 0; } } @@ -175,7 +175,7 @@ static void sms_rc5_parse_word(struct smscore_device_t *coredev) RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j) rc5_word = ir_rc5_decode(rc5_word); - /* sms_info("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */ + /* sms_log("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */ sms_ir_rc5_event(coredev, RC5_TOGGLE(rc5_word), @@ -210,11 +210,11 @@ static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev, if (ir_pos == RC5_WORD_LEN) sms_rc5_parse_word(coredev); else if (ir_pos) /* timeout within a word */ - sms_info("IR error parsing a word"); + sms_log("IR error parsing a word"); ir_pos = 0; ir_word = 0; - /* sms_info("timeout %d", time); */ + /* sms_log("timeout %d", time); */ break; } /* The time is within the range of this number of bits */ @@ -236,7 +236,7 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) int count = len>>2; samples = (s32 *)buf; -/* sms_info("IR buffer received, length = %d", count);*/ +/* sms_log("IR buffer received, length = %d", count);*/ for (i = 0; i < count; i++) if (ir_protocol == IR_RC5) @@ -248,7 +248,7 @@ int sms_ir_init(struct smscore_device_t *coredev) { struct input_dev *input_dev; - sms_info("Allocating input device"); + sms_log("Allocating input device"); input_dev = input_allocate_device(); if (!input_dev) { sms_err("Not enough memory"); @@ -261,11 +261,11 @@ int sms_ir_init(struct smscore_device_t *coredev) coredev->ir.keyboard_layout_map = keyboard_layout_maps[coredev->ir.ir_kb_type]. keyboard_layout_map; - sms_info("IR remote keyboard type is %d", coredev->ir.ir_kb_type); + sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type); coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ coredev->ir.timeout = IR_DEFAULT_TIMEOUT; - sms_info("IR port %d, timeout %d ms", + sms_log("IR port %d, timeout %d ms", coredev->ir.controller, coredev->ir.timeout); snprintf(coredev->ir.name, @@ -280,7 +280,7 @@ int sms_ir_init(struct smscore_device_t *coredev) input_dev->evbit[0] = BIT_MASK(EV_KEY); input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); - sms_info("Input device (IR) %s is set for key events", input_dev->name); + sms_log("Input device (IR) %s is set for key events", input_dev->name); if (input_register_device(input_dev)) { sms_err("Failed to register device"); @@ -296,6 +296,6 @@ void sms_ir_exit(struct smscore_device_t *coredev) if (coredev->ir.input_dev) input_unregister_device(coredev->ir.input_dev); - sms_info(""); + sms_log(""); } -- cgit v1.1 From a804800a29cbbe2881107df0a016b0b98a21cbbf Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Thu, 14 May 2009 16:29:35 -0300 Subject: V4L/DVB (11816): Siano: USB - move the device id table to the cards module The card modules is the component which handles various targets, so the IDs table should reside within it. [mchehab@redhat.com: add missing smsendian.h include at smscoreapi.c] Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 98 ++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 14 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 398e219..040a3ff 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -33,6 +33,8 @@ #include "smscoreapi.h" #include "sms-cards.h" +#include "smsir.h" +#include "smsendian.h" static int sms_dbg; module_param_named(debug, sms_dbg, int, 0644); @@ -348,6 +350,7 @@ int smscore_register_device(struct smsdevice_params_t *params, init_completion(&dev->init_device_done); init_completion(&dev->reload_start_done); init_completion(&dev->resume_done); + init_completion(&dev->ir_init_done); /* alloc common buffer */ dev->common_buffer_size = params->buffer_size * params->num_buffers; @@ -403,6 +406,71 @@ int smscore_register_device(struct smsdevice_params_t *params, } EXPORT_SYMBOL_GPL(smscore_register_device); + +static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, + void *buffer, size_t size, struct completion *completion) { + int rc = coredev->sendrequest_handler(coredev->context, buffer, size); + if (rc < 0) { + sms_info("sendrequest returned error %d", rc); + return rc; + } + + return wait_for_completion_timeout(completion, + msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ? + 0 : -ETIME; +} + +/** + * Starts & enables IR operations + * + * @return 0 on success, < 0 on error. + */ +static int smscore_init_ir(struct smscore_device_t *coredev) +{ + int ir_io; + int rc; + void *buffer; + + coredev->ir.input_dev = NULL; + ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir; + if (ir_io) {/* only if IR port exist we use IR sub-module */ + sms_info("IR loading"); + rc = sms_ir_init(coredev); + + if (rc != 0) + sms_err("Error initialization DTV IR sub-module"); + else { + buffer = kmalloc(sizeof(struct SmsMsgData_ST2) + + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + if (buffer) { + struct SmsMsgData_ST2 *msg = + (struct SmsMsgData_ST2 *) + SMS_ALIGN_ADDRESS(buffer); + + SMS_INIT_MSG(&msg->xMsgHeader, + MSG_SMS_START_IR_REQ, + sizeof(struct SmsMsgData_ST2)); + msg->msgData[0] = coredev->ir.controller; + msg->msgData[1] = coredev->ir.timeout; + + smsendian_handle_tx_message( + (struct SmsMsgHdr_ST2 *)msg); + rc = smscore_sendrequest_and_wait(coredev, msg, + msg->xMsgHeader. msgLength, + &coredev->ir_init_done); + + kfree(buffer); + } else + sms_err + ("Sending IR initialization message failed"); + } + } else + sms_info("IR port has not been detected"); + + return 0; +} + /** * sets initial device mode and notifies client hotplugs that device is ready * @@ -423,6 +491,7 @@ int smscore_start_device(struct smscore_device_t *coredev) kmutex_lock(&g_smscore_deviceslock); rc = smscore_notify_callbacks(coredev, coredev->device, 1); + smscore_init_ir(coredev); sms_info("device %p started, rc %d", coredev, rc); @@ -432,20 +501,6 @@ int smscore_start_device(struct smscore_device_t *coredev) } EXPORT_SYMBOL_GPL(smscore_start_device); -static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, - void *buffer, size_t size, - struct completion *completion) -{ - int rc = coredev->sendrequest_handler(coredev->context, buffer, size); - if (rc < 0) { - sms_info("sendrequest returned error %d", rc); - return rc; - } - - return wait_for_completion_timeout(completion, - msecs_to_jiffies(10000)) ? - 0 : -ETIME; -} static int smscore_load_firmware_family2(struct smscore_device_t *coredev, void *buffer, size_t size) @@ -621,6 +676,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev) kmutex_lock(&g_smscore_deviceslock); + /* Release input device (IR) resources */ + sms_ir_exit(coredev); + smscore_notify_clients(coredev); smscore_notify_callbacks(coredev, NULL, 0); @@ -980,6 +1038,18 @@ void smscore_onresponse(struct smscore_device_t *coredev, case MSG_SMS_SLEEP_RESUME_COMP_IND: complete(&coredev->resume_done); break; + case MSG_SMS_START_IR_RES: + complete(&coredev->ir_init_done); + break; + case MSG_SMS_IR_SAMPLES_IND: + sms_ir_event(coredev, + (const char *) + ((char *)phdr + + sizeof(struct SmsMsgHdr_ST)), + (int)phdr->msgLength + - sizeof(struct SmsMsgHdr_ST)); + break; + default: break; } -- cgit v1.1 From 266b95a548c6707eac43ac8caac515348aa44efe Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Thu, 14 May 2009 16:33:37 -0300 Subject: V4L/DVB (11817): Siano: smscards - fix wrong firmware assignment Remove wrong firmware assignments for Nova, Stellar Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index c35ff1f..b5dc36d 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -31,17 +31,14 @@ static struct sms_board sms_boards[] = { [SMS1XXX_BOARD_SIANO_STELLAR] = { .name = "Siano Stellar Digital Receiver", .type = SMS_STELLAR, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", }, [SMS1XXX_BOARD_SIANO_NOVA_A] = { .name = "Siano Nova A Digital Receiver", .type = SMS_NOVA_A0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", }, [SMS1XXX_BOARD_SIANO_NOVA_B] = { .name = "Siano Nova B Digital Receiver", .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", }, [SMS1XXX_BOARD_SIANO_VEGA] = { .name = "Siano Vega Digital Receiver", -- cgit v1.1 From 9504ccacd749ad98e1990c35acd94f7fceaa992e Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Thu, 14 May 2009 16:34:59 -0300 Subject: V4L/DVB (11818): Siano: smscards - assign gpio to HPG targets Assign using the new gpio structures, i/o for exist HPG targets, without removing the old implementation. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index b5dc36d..fda483f 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -63,6 +63,9 @@ static struct sms_board sms_boards[] = { .name = "Hauppauge WinTV MiniStick", .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", + .board_cfg.leds_power = 26, + .board_cfg.led0 = 27, + .board_cfg.led1 = 28, .led_power = 26, .led_lo = 27, .led_hi = 28, @@ -72,7 +75,9 @@ static struct sms_board sms_boards[] = { .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", .lna_ctrl = 29, + .board_cfg.foreign_lna0_ctrl = 29, .rf_switch = 17, + .board_cfg.rf_switch_uhf = 17, }, [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { .name = "Hauppauge WinTV MiniCard", -- cgit v1.1 From a9349315f65cd6a16e8fab1f6cf0fd40f379c4db Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 17 May 2009 05:59:37 -0300 Subject: V4L/DVB (11819): Siano: smscore - fix get_common_buffer bug get common buffers() should block operation until valid buffer is avaliable. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 38 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 040a3ff..9a5358c 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -30,6 +30,7 @@ #include #include +#include #include "smscoreapi.h" #include "sms-cards.h" @@ -352,6 +353,9 @@ int smscore_register_device(struct smsdevice_params_t *params, init_completion(&dev->resume_done); init_completion(&dev->ir_init_done); + /* Buffer management */ + init_waitqueue_head(&dev->buffer_mng_waitq); + /* alloc common buffer */ dev->common_buffer_size = params->buffer_size * params->num_buffers; dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, @@ -686,7 +690,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev) * onresponse must no longer be called */ while (1) { - while ((cb = smscore_getbuffer(coredev))) { + while (!list_empty(&coredev->buffers)) { + cb = (struct smscore_buffer_t *) coredev->buffers.next; + list_del(&cb->entry); kfree(cb); num_buffers++; } @@ -707,8 +713,10 @@ void smscore_unregister_device(struct smscore_device_t *coredev) if (coredev->common_buffer) dma_free_coherent(NULL, coredev->common_buffer_size, - coredev->common_buffer, - coredev->common_buffer_phys); + coredev->common_buffer, coredev->common_buffer_phys); + + if (coredev->fw_buf != NULL) + kfree(coredev->fw_buf); list_del(&coredev->entry); kfree(coredev); @@ -1071,12 +1079,24 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) struct smscore_buffer_t *cb = NULL; unsigned long flags; + DEFINE_WAIT(wait); + spin_lock_irqsave(&coredev->bufferslock, flags); - if (!list_empty(&coredev->buffers)) { - cb = (struct smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); - } + /* This function must return a valid buffer, since the buffer list is + * finite, we check that there is an available buffer, if not, we wait + * until such buffer become available. + */ + + prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE); + + if (list_empty(&coredev->buffers)) + schedule(); + + finish_wait(&coredev->buffer_mng_waitq, &wait); + + cb = (struct smscore_buffer_t *) coredev->buffers.next; + list_del(&cb->entry); spin_unlock_irqrestore(&coredev->bufferslock, flags); @@ -1093,8 +1113,8 @@ EXPORT_SYMBOL_GPL(smscore_getbuffer); * */ void smscore_putbuffer(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb) -{ + struct smscore_buffer_t *cb) { + wake_up_interruptible(&coredev->buffer_mng_waitq); list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } EXPORT_SYMBOL_GPL(smscore_putbuffer); -- cgit v1.1 From 01abc0b07685137765ec36441adf66f7cfcaf654 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 17 May 2009 06:01:03 -0300 Subject: V4L/DVB (11820): Siano: smscore - fix byte ordering bug Fix byte ordering bug. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 9a5358c..e80641a 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -31,6 +31,7 @@ #include #include +#include #include "smscoreapi.h" #include "sms-cards.h" @@ -511,9 +512,13 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, { struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; struct SmsMsgHdr_ST *msg; - u32 mem_address = firmware->StartAddress; + u32 mem_address; u8 *payload = firmware->Payload; int rc = 0; + firmware->StartAddress = le32_to_cpu(firmware->StartAddress); + firmware->Length = le32_to_cpu(firmware->Length); + + mem_address = firmware->StartAddress; sms_info("loading FW to addr 0x%x size %d", mem_address, firmware->Length); -- cgit v1.1 From 8cc8ef265015cee192fddad3801f09c9c750821b Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 17 May 2009 06:01:55 -0300 Subject: V4L/DVB (11821): Siano: smscore - fix isdb-t firmware name Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index e80641a..d400a82 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -781,7 +781,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { /*BDA*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, /*ISDBT*/ - {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, + {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, /*ISDBTBDA*/ {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, /*CMMB*/ -- cgit v1.1 From 5d2387e3cae1e70febc1bd805f248d6e13cb254f Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 17 May 2009 06:02:46 -0300 Subject: V4L/DVB (11822): Siano: smscore - bug fix at get_device_mode Fix bug that cause error log to echo also if success Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index d400a82..00a1053 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -905,7 +905,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) coredev->device_flags &= ~SMS_DEVICE_NOT_READY; } - if (rc != 0) + if (rc < 0) sms_err("return error code %d.", rc); return rc; } -- cgit v1.1 From 05a073769dbc5f4440d40880a26b76bc8e568c78 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 17 May 2009 09:17:51 -0300 Subject: V4L/DVB (11823): Siano: smsusb - fix typo in module description Fix small typo in the module description Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 4fa38bd..81fc85c 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -562,6 +562,6 @@ void smsusb_module_exit(void) module_init(smsusb_module_init); module_exit(smsusb_module_exit); -MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); +MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle"); MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); MODULE_LICENSE("GPL"); -- cgit v1.1 From bebfa762b171ffcfeeec08f3e677fa9076db6d4c Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Sun, 17 May 2009 09:28:55 -0300 Subject: V4L/DVB (11824): Siano: smsusb - change exit func debug msg Change the debug message of the USB interface driver exit function. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 81fc85c..37a00e9 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -554,9 +554,9 @@ int smsusb_module_init(void) void smsusb_module_exit(void) { - sms_debug(""); /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); + sms_info("end"); } module_init(smsusb_module_init); -- cgit v1.1 From d0b66180c3b288678853e31ec4330b2b5d01e2db Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 09:51:41 -0300 Subject: V4L/DVB (11883): Siano: cards - add two additional (USB) devices Add two additional USB targets, add these to the 'cards' modules and to the 'smsusb' module. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 10 ++++++++++ drivers/media/dvb/siano/sms-cards.h | 2 ++ drivers/media/dvb/siano/smsusb.c | 9 +++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index fda483f..1a18906 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -85,6 +85,16 @@ static struct sms_board sms_boards[] = { .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", .lna_ctrl = -1, }, + [SMS1XXX_BOARD_SIANO_NICE] = { + /* 11 */ + .name = "Siano Nice Digital Receiver", + .type = SMS_NOVA_B0, + }, + [SMS1XXX_BOARD_SIANO_VENICE] = { + /* 12 */ + .name = "Siano Venice Digital Receiver", + .type = SMS_VEGA, + }, }; struct sms_board *sms_get_board(int id) diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 447481a..e183f94 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -35,6 +35,8 @@ #define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9 #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 +#define SMS1XXX_BOARD_SIANO_NICE 11 +#define SMS1XXX_BOARD_SIANO_VENICE 12 struct sms_board_gpio_cfg { int lna_vhf_exist; diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 37a00e9..a4325d9 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -527,8 +527,13 @@ struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0x5590), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { } /* Terminating entry */ -}; + { USB_DEVICE(0x187f, 0x0202), + .driver_info = SMS1XXX_BOARD_SIANO_NICE }, + { USB_DEVICE(0x187f, 0x0301), + .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, smsusb_id_table); static struct usb_driver smsusb_driver = { -- cgit v1.1 From db9582a1e447daffec54a7172f6f824cfaed0a8e Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 11:15:01 -0300 Subject: V4L/DVB (11884): Siano: smssdio - revert to stand alone module Make the SDIO interface driver a stand alone module. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smssdio.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c index 4f8fa59..dfaa49a 100644 --- a/drivers/media/dvb/siano/smssdio.c +++ b/drivers/media/dvb/siano/smssdio.c @@ -332,7 +332,7 @@ static struct sdio_driver smssdio_driver = { /* Module functions */ /*******************************************************************/ -int smssdio_register(void) +int smssdio_module_init(void) { int ret = 0; @@ -344,11 +344,14 @@ int smssdio_register(void) return ret; } -void smssdio_unregister(void) +void smssdio_module_exit(void) { sdio_unregister_driver(&smssdio_driver); } +module_init(smssdio_module_init); +module_exit(smssdio_module_exit); + MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver"); MODULE_AUTHOR("Pierre Ossman"); MODULE_LICENSE("GPL"); -- cgit v1.1 From 7c4ca79f4969a5c5ffcf31a3ba01453821669ced Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 11:49:19 -0300 Subject: V4L/DVB (11885): Siano: Add new GPIO management interface Add new GPIO management interface to replace old (buggy) one. Keeping old interface intact for now. Signed-off-by: Uri Shkolnik Acked-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 2 +- drivers/media/dvb/siano/smscoreapi.c | 235 ++++++++++++++++++++++++++++++++++- drivers/media/dvb/siano/smscoreapi.h | 55 +++++++- 3 files changed, 288 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 1a18906..370cf51 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -109,7 +109,7 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) { int lvl, ret; u32 gpio; - struct smscore_gpio_config gpioconfig = { + struct smscore_config_gpio gpioconfig = { .direction = SMS_GPIO_DIRECTION_OUTPUT, .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 00a1053..043368a 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1276,8 +1276,9 @@ int smsclient_sendrequest(struct smscore_client_t *client, EXPORT_SYMBOL_GPL(smsclient_sendrequest); +/* old GPIO managments implementation */ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, - struct smscore_gpio_config *pinconfig) + struct smscore_config_gpio *pinconfig) { struct { struct SmsMsgHdr_ST hdr; @@ -1346,6 +1347,238 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level) &msg, sizeof(msg)); } +/* new GPIO managment implementation */ +static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum, + u32 *pGroupNum, u32 *pGroupCfg) { + + *pGroupCfg = 1; + + if (PinNum >= 0 && PinNum <= 1) { + *pTranslatedPinNum = 0; + *pGroupNum = 9; + *pGroupCfg = 2; + } else if (PinNum >= 2 && PinNum <= 6) { + *pTranslatedPinNum = 2; + *pGroupNum = 0; + *pGroupCfg = 2; + } else if (PinNum >= 7 && PinNum <= 11) { + *pTranslatedPinNum = 7; + *pGroupNum = 1; + } else if (PinNum >= 12 && PinNum <= 15) { + *pTranslatedPinNum = 12; + *pGroupNum = 2; + *pGroupCfg = 3; + } else if (PinNum == 16) { + *pTranslatedPinNum = 16; + *pGroupNum = 23; + } else if (PinNum >= 17 && PinNum <= 24) { + *pTranslatedPinNum = 17; + *pGroupNum = 3; + } else if (PinNum == 25) { + *pTranslatedPinNum = 25; + *pGroupNum = 6; + } else if (PinNum >= 26 && PinNum <= 28) { + *pTranslatedPinNum = 26; + *pGroupNum = 4; + } else if (PinNum == 29) { + *pTranslatedPinNum = 29; + *pGroupNum = 5; + *pGroupCfg = 2; + } else if (PinNum == 30) { + *pTranslatedPinNum = 30; + *pGroupNum = 8; + } else if (PinNum == 31) { + *pTranslatedPinNum = 31; + *pGroupNum = 17; + } else + return -1; + + *pGroupCfg <<= 24; + + return 0; +} + +int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, + struct smscore_gpio_config *pGpioConfig) { + + u32 totalLen; + u32 TranslatedPinNum; + u32 GroupNum; + u32 ElectricChar; + u32 groupCfg; + void *buffer; + int rc; + + struct SetGpioMsg { + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[6]; + } *pMsg; + + + if (PinNum > MAX_GPIO_PIN_NUMBER) + return -EINVAL; + + if (pGpioConfig == NULL) + return -EINVAL; + + totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6); + + buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + if (!buffer) + return -ENOMEM; + + pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); + + pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + pMsg->xMsgHeader.msgDstId = HIF_TASK; + pMsg->xMsgHeader.msgFlags = 0; + pMsg->xMsgHeader.msgLength = (u16) totalLen; + pMsg->msgData[0] = PinNum; + + if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { + pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; + if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, + &groupCfg) != 0) + return -EINVAL; + + pMsg->msgData[1] = TranslatedPinNum; + pMsg->msgData[2] = GroupNum; + ElectricChar = (pGpioConfig->PullUpDown) + | (pGpioConfig->InputCharacteristics << 2) + | (pGpioConfig->OutputSlewRate << 3) + | (pGpioConfig->OutputDriving << 4); + pMsg->msgData[3] = ElectricChar; + pMsg->msgData[4] = pGpioConfig->Direction; + pMsg->msgData[5] = groupCfg; + } else { + pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; + pMsg->msgData[1] = pGpioConfig->PullUpDown; + pMsg->msgData[2] = pGpioConfig->OutputSlewRate; + pMsg->msgData[3] = pGpioConfig->OutputDriving; + pMsg->msgData[4] = pGpioConfig->Direction; + pMsg->msgData[5] = 0; + } + + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); + rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, + &coredev->gpio_configuration_done); + + if (rc != 0) { + if (rc == -ETIME) + sms_err("smscore_gpio_configure timeout"); + else + sms_err("smscore_gpio_configure error"); + } + kfree(buffer); + + return rc; +} + +int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, + u8 NewLevel) { + + u32 totalLen; + int rc; + void *buffer; + + struct SetGpioMsg { + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[3]; /* keep it 3 ! */ + } *pMsg; + + if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) || + (PinNum > MAX_GPIO_PIN_NUMBER)) + return -EINVAL; + + totalLen = sizeof(struct SmsMsgHdr_ST) + + (3 * sizeof(u32)); /* keep it 3 ! */ + + buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + if (!buffer) + return -ENOMEM; + + pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); + + pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + pMsg->xMsgHeader.msgDstId = HIF_TASK; + pMsg->xMsgHeader.msgFlags = 0; + pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; + pMsg->xMsgHeader.msgLength = (u16) totalLen; + pMsg->msgData[0] = PinNum; + pMsg->msgData[1] = NewLevel; + + /* Send message to SMS */ + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); + rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, + &coredev->gpio_set_level_done); + + if (rc != 0) { + if (rc == -ETIME) + sms_err("smscore_gpio_set_level timeout"); + else + sms_err("smscore_gpio_set_level error"); + } + kfree(buffer); + + return rc; +} + +int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, + u8 *level) { + + u32 totalLen; + int rc; + void *buffer; + + struct SetGpioMsg { + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[2]; + } *pMsg; + + + if (PinNum > MAX_GPIO_PIN_NUMBER) + return -EINVAL; + + totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32)); + + buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + if (!buffer) + return -ENOMEM; + + pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); + + pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + pMsg->xMsgHeader.msgDstId = HIF_TASK; + pMsg->xMsgHeader.msgFlags = 0; + pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ; + pMsg->xMsgHeader.msgLength = (u16) totalLen; + pMsg->msgData[0] = PinNum; + pMsg->msgData[1] = 0; + + /* Send message to SMS */ + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); + rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, + &coredev->gpio_get_level_done); + + if (rc != 0) { + if (rc == -ETIME) + sms_err("smscore_gpio_get_level timeout"); + else + sms_err("smscore_gpio_get_level error"); + } + kfree(buffer); + + /* Its a race between other gpio_get_level() and the copy of the single + * global 'coredev->gpio_get_res' to the function's variable 'level' + */ + *level = coredev->gpio_get_res; + + return rc; +} + static int __init smscore_module_init(void) { int rc = 0; diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 6e23c5f..03bdc94 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -549,7 +549,7 @@ struct SMSHOSTLIB_I2C_RES_ST { }; -struct smscore_gpio_config { +struct smscore_config_gpio { #define SMS_GPIO_DIRECTION_INPUT 0 #define SMS_GPIO_DIRECTION_OUTPUT 1 u8 direction; @@ -575,6 +575,48 @@ struct smscore_gpio_config { u8 outputdriving; }; +struct smscore_gpio_config { +#define SMS_GPIO_DIRECTION_INPUT 0 +#define SMS_GPIO_DIRECTION_OUTPUT 1 + u8 Direction; + +#define SMS_GPIO_PULLUPDOWN_NONE 0 +#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1 +#define SMS_GPIO_PULLUPDOWN_PULLUP 2 +#define SMS_GPIO_PULLUPDOWN_KEEPER 3 + u8 PullUpDown; + +#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0 +#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1 + u8 InputCharacteristics; + +#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */ + + +#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */ + u8 OutputSlewRate; + +#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */ +#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */ +#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */ +#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */ + +#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ +#undef SMS_GPIO_OUTPUT_DRIVING_16mA +#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ + u8 OutputDriving; +}; + extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); @@ -616,10 +658,19 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); extern void smscore_putbuffer(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); +/* old GPIO managment */ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, - struct smscore_gpio_config *pinconfig); + struct smscore_config_gpio *pinconfig); int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); +/* new GPIO managment */ +extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, + struct smscore_gpio_config *pGpioConfig); +extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, + u8 NewLevel); +extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, + u8 *level); + void smscore_set_board_id(struct smscore_device_t *core, int id); int smscore_get_board_id(struct smscore_device_t *core); -- cgit v1.1 From 4887f7b4ef8926fd8eb79a928d5f3c4ea25263b8 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 12:10:36 -0300 Subject: V4L/DVB (11886): Siano: smscore - fix some new GPIO definitions names Fix some definitions' names, in order to emphasize the names Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 03bdc94..f1108c6 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -580,10 +580,10 @@ struct smscore_gpio_config { #define SMS_GPIO_DIRECTION_OUTPUT 1 u8 Direction; -#define SMS_GPIO_PULLUPDOWN_NONE 0 -#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1 -#define SMS_GPIO_PULLUPDOWN_PULLUP 2 -#define SMS_GPIO_PULLUPDOWN_KEEPER 3 +#define SMS_GPIO_PULL_UP_DOWN_NONE 0 +#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1 +#define SMS_GPIO_PULL_UP_DOWN_PULLUP 2 +#define SMS_GPIO_PULL_UP_DOWN_KEEPER 3 u8 PullUpDown; #define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0 @@ -607,13 +607,12 @@ struct smscore_gpio_config { #define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */ #define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ -#undef SMS_GPIO_OUTPUT_DRIVING_16mA -#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ u8 OutputDriving; }; -- cgit v1.1 From 5b8db8978379be5e715803f89c03a2733fe8c8e8 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 12:18:40 -0300 Subject: V4L/DVB (11887): Siano: smscards - add board (target) events Add events handling for targets. All board-specific (target specific) should reside here. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 167 ++++++++++++++++++++++++++++++++++++ drivers/media/dvb/siano/sms-cards.h | 24 ++++++ 2 files changed, 191 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 370cf51..d8b15d5 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -104,6 +104,173 @@ struct sms_board *sms_get_board(int id) return &sms_boards[id]; } EXPORT_SYMBOL_GPL(sms_get_board); +static inline void sms_gpio_assign_11xx_default_led_config( + struct smscore_gpio_config *pGpioConfig) { + pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT; + pGpioConfig->InputCharacteristics = + SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL; + pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA; + pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS; + pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE; +} + +int sms_board_event(struct smscore_device_t *coredev, + enum SMS_BOARD_EVENTS gevent) { + int board_id = smscore_get_board_id(coredev); + struct sms_board *board = sms_get_board(board_id); + struct smscore_gpio_config MyGpioConfig; + + sms_gpio_assign_11xx_default_led_config(&MyGpioConfig); + + switch (gevent) { + case BOARD_EVENT_POWER_INIT: /* including hotplug */ + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + /* set I/O and turn off all LEDs */ + smscore_gpio_configure(coredev, + board->board_cfg.leds_power, + &MyGpioConfig); + smscore_gpio_set_level(coredev, + board->board_cfg.leds_power, 0); + smscore_gpio_configure(coredev, board->board_cfg.led0, + &MyGpioConfig); + smscore_gpio_set_level(coredev, + board->board_cfg.led0, 0); + smscore_gpio_configure(coredev, board->board_cfg.led1, + &MyGpioConfig); + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + /* set I/O and turn off LNA */ + smscore_gpio_configure(coredev, + board->board_cfg.foreign_lna0_ctrl, + &MyGpioConfig); + smscore_gpio_set_level(coredev, + board->board_cfg.foreign_lna0_ctrl, + 0); + break; + } + break; /* BOARD_EVENT_BIND */ + + case BOARD_EVENT_POWER_SUSPEND: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.leds_power, 0); + smscore_gpio_set_level(coredev, + board->board_cfg.led0, 0); + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + smscore_gpio_set_level(coredev, + board->board_cfg.foreign_lna0_ctrl, + 0); + break; + } + break; /* BOARD_EVENT_POWER_SUSPEND */ + + case BOARD_EVENT_POWER_RESUME: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.leds_power, 1); + smscore_gpio_set_level(coredev, + board->board_cfg.led0, 1); + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + smscore_gpio_set_level(coredev, + board->board_cfg.foreign_lna0_ctrl, + 1); + break; + } + break; /* BOARD_EVENT_POWER_RESUME */ + + case BOARD_EVENT_BIND: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.leds_power, 1); + smscore_gpio_set_level(coredev, + board->board_cfg.led0, 1); + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + smscore_gpio_set_level(coredev, + board->board_cfg.foreign_lna0_ctrl, + 1); + break; + } + break; /* BOARD_EVENT_BIND */ + + case BOARD_EVENT_SCAN_PROG: + break; /* BOARD_EVENT_SCAN_PROG */ + case BOARD_EVENT_SCAN_COMP: + break; /* BOARD_EVENT_SCAN_COMP */ + case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL: + break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */ + case BOARD_EVENT_FE_LOCK: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 1); + break; + } + break; /* BOARD_EVENT_FE_LOCK */ + case BOARD_EVENT_FE_UNLOCK: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + } + break; /* BOARD_EVENT_FE_UNLOCK */ + case BOARD_EVENT_DEMOD_LOCK: + break; /* BOARD_EVENT_DEMOD_LOCK */ + case BOARD_EVENT_DEMOD_UNLOCK: + break; /* BOARD_EVENT_DEMOD_UNLOCK */ + case BOARD_EVENT_RECEPTION_MAX_4: + break; /* BOARD_EVENT_RECEPTION_MAX_4 */ + case BOARD_EVENT_RECEPTION_3: + break; /* BOARD_EVENT_RECEPTION_3 */ + case BOARD_EVENT_RECEPTION_2: + break; /* BOARD_EVENT_RECEPTION_2 */ + case BOARD_EVENT_RECEPTION_1: + break; /* BOARD_EVENT_RECEPTION_1 */ + case BOARD_EVENT_RECEPTION_LOST_0: + break; /* BOARD_EVENT_RECEPTION_LOST_0 */ + case BOARD_EVENT_MULTIPLEX_OK: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 1); + break; + } + break; /* BOARD_EVENT_MULTIPLEX_OK */ + case BOARD_EVENT_MULTIPLEX_ERRORS: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + } + break; /* BOARD_EVENT_MULTIPLEX_ERRORS */ + + default: + sms_err("Unknown SMS board event"); + break; + } + return 0; +} +EXPORT_SYMBOL_GPL(sms_board_event); static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) { diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index e183f94..38f062f 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -85,6 +85,30 @@ struct sms_board *sms_get_board(int id); extern struct smscore_device_t *coredev; +enum SMS_BOARD_EVENTS { + BOARD_EVENT_POWER_INIT, + BOARD_EVENT_POWER_SUSPEND, + BOARD_EVENT_POWER_RESUME, + BOARD_EVENT_BIND, + BOARD_EVENT_SCAN_PROG, + BOARD_EVENT_SCAN_COMP, + BOARD_EVENT_EMERGENCY_WARNING_SIGNAL, + BOARD_EVENT_FE_LOCK, + BOARD_EVENT_FE_UNLOCK, + BOARD_EVENT_DEMOD_LOCK, + BOARD_EVENT_DEMOD_UNLOCK, + BOARD_EVENT_RECEPTION_MAX_4, + BOARD_EVENT_RECEPTION_3, + BOARD_EVENT_RECEPTION_2, + BOARD_EVENT_RECEPTION_1, + BOARD_EVENT_RECEPTION_LOST_0, + BOARD_EVENT_MULTIPLEX_OK, + BOARD_EVENT_MULTIPLEX_ERRORS +}; + +int sms_board_event(struct smscore_device_t *coredev, + enum SMS_BOARD_EVENTS gevent); + int sms_board_setup(struct smscore_device_t *coredev); #define SMS_LED_OFF 0 -- cgit v1.1 From 07f56002c11897d663f6b1e74a564d821d4086a2 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 12:24:03 -0300 Subject: V4L/DVB (11888): Siano: smsusb - remove redundant ifdef Remove a redundant ifdef Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index a4325d9..cb8a358 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -485,7 +485,6 @@ static int smsusb_resume(struct usb_interface *intf) } struct usb_device_id smsusb_id_table[] = { -#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS { USB_DEVICE(0x187f, 0x0010), .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, { USB_DEVICE(0x187f, 0x0100), @@ -496,7 +495,6 @@ struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, { USB_DEVICE(0x187f, 0x0300), .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, -#endif { USB_DEVICE(0x2040, 0x1700), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, { USB_DEVICE(0x2040, 0x1800), -- cgit v1.1 From 4db989f7745778f9f0a4f823bd5932f108dd76ba Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 12:28:02 -0300 Subject: V4L/DVB (11889): Siano: smsdvb - add DVB v3 events Add various DVB-API v3 events, those events will trig target (card) events. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsdvb.c | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index c845b79..3ee1c39 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -66,6 +66,54 @@ MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); /* Events that may come from DVB v3 adapter */ static void sms_board_dvb3_event(struct smsdvb_client_t *client, enum SMS_DVB3_EVENTS event) { + + struct smscore_device_t *coredev = client->coredev; + switch (event) { + case DVB3_EVENT_INIT: + sms_debug("DVB3_EVENT_INIT"); + sms_board_event(coredev, BOARD_EVENT_BIND); + break; + case DVB3_EVENT_SLEEP: + sms_debug("DVB3_EVENT_SLEEP"); + sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); + break; + case DVB3_EVENT_HOTPLUG: + sms_debug("DVB3_EVENT_HOTPLUG"); + sms_board_event(coredev, BOARD_EVENT_POWER_INIT); + break; + case DVB3_EVENT_FE_LOCK: + if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { + client->event_fe_state = DVB3_EVENT_FE_LOCK; + sms_debug("DVB3_EVENT_FE_LOCK"); + sms_board_event(coredev, BOARD_EVENT_FE_LOCK); + } + break; + case DVB3_EVENT_FE_UNLOCK: + if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { + client->event_fe_state = DVB3_EVENT_FE_UNLOCK; + sms_debug("DVB3_EVENT_FE_UNLOCK"); + sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); + } + break; + case DVB3_EVENT_UNC_OK: + if (client->event_unc_state != DVB3_EVENT_UNC_OK) { + client->event_unc_state = DVB3_EVENT_UNC_OK; + sms_debug("DVB3_EVENT_UNC_OK"); + sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); + } + break; + case DVB3_EVENT_UNC_ERR: + if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { + client->event_unc_state = DVB3_EVENT_UNC_ERR; + sms_debug("DVB3_EVENT_UNC_ERR"); + sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); + } + break; + + default: + sms_err("Unknown dvb3 api event"); + break; + } } static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) -- cgit v1.1 From 6675167cab92906a7b1d29faa3901716925d3af8 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 12:34:09 -0300 Subject: V4L/DVB (11890): Siano: smscore - remove redundant code remove redundant code, which in the past handled the various components (now independent modules) registrations. Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 043368a..b2127c1 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1590,24 +1590,11 @@ static int __init smscore_module_init(void) INIT_LIST_HEAD(&g_smscore_registry); kmutex_init(&g_smscore_registrylock); - - - - - - return rc; - sms_debug("rc %d", rc); - return rc; } static void __exit smscore_module_exit(void) { - - - - - kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { struct smscore_device_notifyee_t *notifyee = -- cgit v1.1 From 34601caa64e11b8fa5e9a03d74cc1df0af32e2ca Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 12:52:58 -0300 Subject: V4L/DVB (11891): Siano: smscore - bind the GPIO SMS protocol Bind SMS protocol commands to the GPIO commands Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index b2127c1..32be382 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -352,6 +352,9 @@ int smscore_register_device(struct smsdevice_params_t *params, init_completion(&dev->init_device_done); init_completion(&dev->reload_start_done); init_completion(&dev->resume_done); + init_completion(&dev->gpio_configuration_done); + init_completion(&dev->gpio_set_level_done); + init_completion(&dev->gpio_get_level_done); init_completion(&dev->ir_init_done); /* Buffer management */ @@ -1051,6 +1054,23 @@ void smscore_onresponse(struct smscore_device_t *coredev, case MSG_SMS_SLEEP_RESUME_COMP_IND: complete(&coredev->resume_done); break; + case MSG_SMS_GPIO_CONFIG_EX_RES: + sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES"); + complete(&coredev->gpio_configuration_done); + break; + case MSG_SMS_GPIO_SET_LEVEL_RES: + sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES"); + complete(&coredev->gpio_set_level_done); + break; + case MSG_SMS_GPIO_GET_LEVEL_RES: + { + u32 *msgdata = (u32 *) phdr; + coredev->gpio_get_res = msgdata[1]; + sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d", + coredev->gpio_get_res); + complete(&coredev->gpio_get_level_done); + break; + } case MSG_SMS_START_IR_RES: complete(&coredev->ir_init_done); break; -- cgit v1.1 From d95e9883ce28c23cb852d599bf0a0889527c1d09 Mon Sep 17 00:00:00 2001 From: Uri Shkolnik Date: Tue, 19 May 2009 12:56:16 -0300 Subject: V4L/DVB (11892): Siano: smsendian - declare function as extern Declare the object function as 'extern' Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsendian.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/siano/smsendian.h b/drivers/media/dvb/siano/smsendian.h index 7fbedc6..1624d6f 100644 --- a/drivers/media/dvb/siano/smsendian.h +++ b/drivers/media/dvb/siano/smsendian.h @@ -24,9 +24,9 @@ along with this program. If not, see . #include -void smsendian_handle_tx_message(void *buffer); -void smsendian_handle_rx_message(void *buffer); -void smsendian_handle_message_header(void *msg); +extern void smsendian_handle_tx_message(void *buffer); +extern void smsendian_handle_rx_message(void *buffer); +extern void smsendian_handle_message_header(void *msg); #endif /* __SMS_ENDIAN_H__ */ -- cgit v1.1 From 1c905a4522a3913cf321365c5bb62eb2f70d55d9 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Fri, 22 May 2009 07:19:14 -0300 Subject: V4L/DVB (11894): flexcop-pci: dmesg visible names broken Changeset 1589a993f074124c3edfff03656e910bb472eeaa broke user visible names of flexcop-pci devices, as it did reorder the enum of card types, but did not adjust the array containing the card names. Reorder the names, and uses [FC_AIR_DVBT] = "Air2PC/AirStar 2 DVB-T" assignment style for more clarity. It also adds the revision Number to the name for SkyStar rev. 2.3 and rev 2.6 as I think it is useful to see in log output. Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/b2c2/flexcop-misc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/media/dvb') diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c index e56627d..f06f3a9 100644 --- a/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/drivers/media/dvb/b2c2/flexcop-misc.c @@ -46,16 +46,16 @@ static const char *flexcop_revision_names[] = { }; static const char *flexcop_device_names[] = { - "Unknown device", - "Air2PC/AirStar 2 DVB-T", - "Air2PC/AirStar 2 ATSC 1st generation", - "Air2PC/AirStar 2 ATSC 2nd generation", - "Sky2PC/SkyStar 2 DVB-S", - "Sky2PC/SkyStar 2 DVB-S (old version)", - "Cable2PC/CableStar 2 DVB-C", - "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", - "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", - "Sky2PC/SkyStar 2 DVB-S rev 2.8", + [FC_UNK] = "Unknown device", + [FC_CABLE] = "Cable2PC/CableStar 2 DVB-C", + [FC_AIR_DVBT] = "Air2PC/AirStar 2 DVB-T", + [FC_AIR_ATSC1] = "Air2PC/AirStar 2 ATSC 1st generation", + [FC_AIR_ATSC2] = "Air2PC/AirStar 2 ATSC 2nd generation", + [FC_AIR_ATSC3] = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", + [FC_SKY_REV23] = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)", + [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6", + [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", + [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8", }; static const char *flexcop_bus_names[] = { -- cgit v1.1