From 056fc916b20459b2954fff78f3f99b2df7f11950 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 27 Jan 2009 02:08:48 +0400 Subject: Use Diseqc 3/3 mode to send data From: Sigmund Augdal Signed-off-by: Sigmund Augdal Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stb0899_drv.c b/linux/drivers/media/dvb/frontends/stb0899_drv.c index 1e38abee5..32841ade0 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c @@ -794,7 +794,7 @@ static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t reg = stb0899_read_reg(state, STB0899_DISCNTRL1); old_state = reg; /* set to burst mode */ - STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02); + STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x03); STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01); stb0899_write_reg(state, STB0899_DISCNTRL1, reg); switch (burst) { -- cgit v1.2.3 From a4d14c1b200f333fb3b27517bd31d7f31445dbf8 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 27 Jan 2009 18:03:16 +0400 Subject: Bug: Use signed types, Offsets and range can be negative Code simplification: use in kernel macros From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb0899_algo.c | 14 +++++++------- linux/drivers/media/dvb/frontends/stb0899_priv.h | 12 ++++-------- 2 files changed, 11 insertions(+), 15 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stb0899_algo.c b/linux/drivers/media/dvb/frontends/stb0899_algo.c index 3d13968a7..72012ce11 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_algo.c +++ b/linux/drivers/media/dvb/frontends/stb0899_algo.c @@ -156,7 +156,7 @@ static void stb0899_first_subrange(struct stb0899_state *state) } if (range > 0) - internal->sub_range = MIN(internal->srch_range, range); + internal->sub_range = min(internal->srch_range, range); else internal->sub_range = 0; @@ -185,7 +185,7 @@ static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state) timing = stb0899_read_reg(state, STB0899_RTF); if (lock >= 42) { - if ((lock > 48) && (ABS(timing) >= 110)) { + if ((lock > 48) && (abs(timing) >= 110)) { internal->status = ANALOGCARRIER; dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !"); } else { @@ -222,7 +222,7 @@ static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state) index++; derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */ - if (ABS(derot_freq) > derot_limit) + if (abs(derot_freq) > derot_limit) next_loop--; if (next_loop) { @@ -298,7 +298,7 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state) last_derot_freq = derot_freq; derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */ - if(ABS(derot_freq) > derot_limit) + if(abs(derot_freq) > derot_limit) next_loop--; if (next_loop) { @@ -400,7 +400,7 @@ static enum stb0899_status stb0899_search_data(struct stb0899_state *state) if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) { derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ - if (ABS(derot_freq) > derot_limit) + if (abs(derot_freq) > derot_limit) next_loop--; if (next_loop) { @@ -467,7 +467,7 @@ static void next_sub_range(struct stb0899_state *state) if (internal->sub_dir > 0) { old_sub_range = internal->sub_range; - internal->sub_range = MIN((internal->srch_range / 2) - + internal->sub_range = min((internal->srch_range / 2) - (internal->tuner_offst + internal->sub_range / 2), internal->sub_range); @@ -771,7 +771,7 @@ static long Log2Int(int number) int i; i = 0; - while ((1 << i) <= ABS(number)) + while ((1 << i) <= abs(number)) i++; if (number == 0) diff --git a/linux/drivers/media/dvb/frontends/stb0899_priv.h b/linux/drivers/media/dvb/frontends/stb0899_priv.h index e57ff227b..d2a69d0a3 100644 --- a/linux/drivers/media/dvb/frontends/stb0899_priv.h +++ b/linux/drivers/media/dvb/frontends/stb0899_priv.h @@ -59,10 +59,6 @@ #define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) #define MAKEWORD16(a, b) (((a) << 8) | (b)) -#define MIN(x, y) ((x) <= (y) ? (x) : (y)) -#define MAX(x, y) ((x) >= (y) ? (x) : (y)) -#define ABS(x) ((x) >= 0 ? (x) : -(x)) - #define LSB(x) ((x & 0xff)) #define MSB(y) ((y >> 8) & 0xff) @@ -168,10 +164,10 @@ struct stb0899_internal { u32 freq; /* Demod internal Frequency */ u32 srate; /* Demod internal Symbol rate */ enum stb0899_fec fecrate; /* Demod internal FEC rate */ - u32 srch_range; /* Demod internal Search Range */ - u32 sub_range; /* Demod current sub range (Hz) */ - u32 tuner_step; /* Tuner step (Hz) */ - u32 tuner_offst; /* Relative offset to carrier (Hz) */ + s32 srch_range; /* Demod internal Search Range */ + s32 sub_range; /* Demod current sub range (Hz) */ + s32 tuner_step; /* Tuner step (Hz) */ + s32 tuner_offst; /* Relative offset to carrier (Hz) */ u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */ s32 mclk; /* Masterclock Divider factor (binary) */ -- cgit v1.2.3 From b7deb66fda3accee36c079e200d1773c5e0fcc67 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 9 Nov 2008 16:35:13 +0200 Subject: Bug fix: For legacy applications stv0899 performs search only first time after insmod. From: Igor M. Liplianin For legacy applications stv0899 performs search only first time after insmod due to not set DVBFE_ALGO_SEARCH_AGAIN bit Signed-off-by: Igor M. Liplianin Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 01a9ceb37..60a9c80a1 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1396,9 +1396,6 @@ static int dtv_property_process_set(struct dvb_frontend *fe, dprintk("%s() Finalised property cache\n", __func__); dtv_property_cache_submit(fe); - /* Request the search algorithm to search */ - fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; - r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, &fepriv->parameters); break; @@ -1832,6 +1829,10 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000; fepriv->state = FESTATE_RETUNE; + + /* Request the search algorithm to search */ + fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; + dvb_frontend_wakeup(fe); dvb_frontend_add_event(fe, 0); fepriv->status = 0; -- cgit v1.2.3 From 3165ca2068855d7118d78396adce4c49a4e7f636 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 4 May 2009 20:43:02 -0400 Subject: dvb_frontend: fix race condition resulting in dropped tuning commands From: Devin Heitmueller 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. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index da2890b22..d359f6841 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -554,6 +554,7 @@ restart: if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { /* got signal or quitting */ + fepriv->exit = 1; break; } -- cgit v1.2.3 From 711a3b562c4751c854fd271f44c6e5f432bc09d6 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 27 Jan 2009 23:09:12 +0400 Subject: STB6100 init fix, the call to stb6100_set_bandwidth needs an argument in Hz not kHz, and a comment incorrectly says MHz instead of Hz. I don't know if this caused real problems anywhere From: Hans Werner Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stb6100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stb6100.c b/linux/drivers/media/dvb/frontends/stb6100.c index 29bc07b86..2b1af36b8 100644 --- a/linux/drivers/media/dvb/frontends/stb6100.c +++ b/linux/drivers/media/dvb/frontends/stb6100.c @@ -434,11 +434,11 @@ static int stb6100_init(struct dvb_frontend *fe) status->refclock = 27000000; /* Hz */ status->iqsense = 1; status->bandwidth = 36000; /* kHz */ - state->bandwidth = status->bandwidth * 1000; /* MHz */ + state->bandwidth = status->bandwidth * 1000; /* Hz */ state->reference = status->refclock / 1000; /* kHz */ /* Set default bandwidth. */ - return stb6100_set_bandwidth(fe, status->bandwidth); + return stb6100_set_bandwidth(fe, state->bandwidth); } static int stb6100_get_state(struct dvb_frontend *fe, -- cgit v1.2.3 From 84c19b03d182a3ad1a04fa4be0772ef587225fe6 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 27 Jan 2009 23:29:44 +0400 Subject: Report tuning algorith correctly From: Matthias Schwarzzot Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/bt8xx/dst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/bt8xx/dst.c b/linux/drivers/media/dvb/bt8xx/dst.c index 29e8f1546..fec1d77fa 100644 --- a/linux/drivers/media/dvb/bt8xx/dst.c +++ b/linux/drivers/media/dvb/bt8xx/dst.c @@ -1683,7 +1683,7 @@ static int dst_tune_frontend(struct dvb_frontend* fe, static int dst_get_tuning_algo(struct dvb_frontend *fe) { - return dst_algo; + return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW; } static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -- cgit v1.2.3 From 6c7ed65e3ea76c36aec18b3c7d7fc97af216bf05 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 28 Feb 2009 14:19:30 +0100 Subject: Fix i2c code of flexcop-driver for rare revisions From: Patrick Boettcher This patch adds a workaround in the i2c-code of the flexcop-driver to fix support for SkyStar2 rev 2.7. There are not many devices out there, that's why this bug was not revealed earlier. Priority: high Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/flexcop-i2c.c | 12 ++++++++++++ linux/drivers/media/dvb/frontends/itd1000_priv.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c index 01d27613f..1c07eeafc 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -47,6 +47,18 @@ static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c, int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */ ret; + /* work-around to have CableStar2 and SkyStar2 rev 2.7 work + * correctly: + * + * the ITD1000 is behind an i2c-gate which closes automatically + * after an i2c-transaction the STV0297 needs 2 consecutive reads + * one with no_base_addr = 0 and one with 1 + * + * those two work-arounds are conflictin: we check for the card + * type, it is set when probing the ITD1000 */ + if (i2c->fc->dev_type == FC_SKY_REV27) + r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr; + ret = flexcop_i2c_operation(i2c->fc, &r100); if (ret != 0) { deb_i2c("Retrying operation\n"); diff --git a/linux/drivers/media/dvb/frontends/itd1000_priv.h b/linux/drivers/media/dvb/frontends/itd1000_priv.h index 8cdc54e57..08ca85122 100644 --- a/linux/drivers/media/dvb/frontends/itd1000_priv.h +++ b/linux/drivers/media/dvb/frontends/itd1000_priv.h @@ -31,7 +31,7 @@ struct itd1000_state { /* ugly workaround for flexcop's incapable i2c-controller * FIXME, if possible */ - u8 shadow[255]; + u8 shadow[256]; }; enum itd1000_register { -- cgit v1.2.3 From 299a56025d357c1156cbe3b69689f37e5ac19eef Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 28 Feb 2009 14:30:20 +0100 Subject: Remove unecessary udelay From: Patrick Boettcher When resetting the PID-filter block a safety msleep(1) was injected. Now that the function is called from interrupt context, it was replaced with a udelay. It seems that this delay is not necessary at all, let's remove it for now and test a while. Priority: normal Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/flexcop.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop.c b/linux/drivers/media/dvb/b2c2/flexcop.c index 91068952b..e836caece 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop.c +++ b/linux/drivers/media/dvb/b2c2/flexcop.c @@ -212,7 +212,6 @@ void flexcop_reset_block_300(struct flexcop_device *fc) v210.sw_reset_210.Block_reset_enable = 0xb2; fc->write_ibi_reg(fc,sw_reset_210,v210); - udelay(1000); fc->write_ibi_reg(fc,ctrl_208,v208_save); } -- cgit v1.2.3 From 11fac5cc5ec5cdba94e722f55d09a91dfc0df95a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 10 Mar 2009 18:06:40 +0200 Subject: zl10353: i2c_gate_ctrl bug fix From: Antti Palosaari zl10353 i2c-gate was always closed and due to that devices having tuner behind i2c-gate were broken. Add module configuration which allows disabling i2c-gate only when really needed. Priority: high Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/frontends/zl10353.c | 2 +- linux/drivers/media/dvb/frontends/zl10353.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index be5d7ef7c..96ccc1720 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -601,7 +601,7 @@ static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) struct zl10353_state *state = fe->demodulator_priv; u8 val = 0x0a; - if (state->config.no_tuner) { + if (state->config.disable_i2c_gate_ctrl) { /* No tuner attached to the internal I2C bus */ /* If set enable I2C bridge, the main I2C bus stopped hardly */ return 0; diff --git a/linux/drivers/media/dvb/frontends/zl10353.h b/linux/drivers/media/dvb/frontends/zl10353.h index fdbb88ff7..2287bac46 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.h +++ b/linux/drivers/media/dvb/frontends/zl10353.h @@ -38,6 +38,9 @@ struct zl10353_config /* set if parallel ts output is required */ int parallel_ts; + + /* set if i2c_gate_ctrl disable is required */ + u8 disable_i2c_gate_ctrl:1; }; #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) -- cgit v1.2.3 From 170f8d4937939b9a0252e62983e0a508b3954897 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 10 Mar 2009 16:55:14 +0000 Subject: flexcop-pci: Print a message in case the new stream watchdog detects a problem From: Matthias Schwarzott Print a message in case the new software IRQ watchdog detects a problem. I choose the info message category, this can be changed if not appropriate. Signed-off-by: Matthias Schwarzott CC: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/b2c2/flexcop-pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop-pci.c b/linux/drivers/media/dvb/b2c2/flexcop-pci.c index 2905ffccf..72710fee2 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-pci.c @@ -133,6 +133,7 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) deb_chk("no IRQ since the last check\n"); if (fc_pci->stream_problem++ == 3) { struct dvb_demux_feed *feed; + deb_info("flexcop-pci: stream problem, resetting pid filter\n"); spin_lock_irq(&fc->demux.lock); list_for_each_entry(feed, &fc->demux.feed_list, -- cgit v1.2.3 From a5efdf6be9cdb58a3990d6981228bc2abcc53619 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Mar 2009 00:45:44 -0400 Subject: lgdt3305: add email address to MODULE_AUTHOR From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/lgdt3305.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgdt3305.c b/linux/drivers/media/dvb/frontends/lgdt3305.c index aeb34e924..780981557 100644 --- a/linux/drivers/media/dvb/frontends/lgdt3305.c +++ b/linux/drivers/media/dvb/frontends/lgdt3305.c @@ -1105,7 +1105,7 @@ static struct dvb_frontend_ops lgdt3305_ops = { }; MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver"); -MODULE_AUTHOR("Michael Krufky"); +MODULE_AUTHOR("Michael Krufky "); MODULE_LICENSE("GPL"); /* -- cgit v1.2.3 From 128ef238ca1c652004419d9183144e4c6e492a99 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Mar 2009 00:47:53 -0400 Subject: lgdt3305: add missing space in comment From: Michael Krufky small whitespace cleanup - space missing after the * Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/lgdt3305.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgdt3305.c b/linux/drivers/media/dvb/frontends/lgdt3305.c index 780981557..85a40fe1e 100644 --- a/linux/drivers/media/dvb/frontends/lgdt3305.c +++ b/linux/drivers/media/dvb/frontends/lgdt3305.c @@ -936,7 +936,7 @@ static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr) /* convert from 8.24 fixed-point to 8.8 */ *snr = (state->snr) >> 16; #else - /*report SNR in dB * 10 */ + /* report SNR in dB * 10 */ *snr = (state->snr / ((1 << 24) / 10)); #endif lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise, -- cgit v1.2.3 From 3c00de0d74330e4761f5592f873d1a2b7553e8b3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Mar 2009 00:46:44 -0400 Subject: lgdt3305: add MODULE_VERSION From: Michael Krufky We'll start off with MODULE_VERSION("0.1") Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/lgdt3305.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgdt3305.c b/linux/drivers/media/dvb/frontends/lgdt3305.c index 85a40fe1e..8d62d1257 100644 --- a/linux/drivers/media/dvb/frontends/lgdt3305.c +++ b/linux/drivers/media/dvb/frontends/lgdt3305.c @@ -1107,6 +1107,7 @@ static struct dvb_frontend_ops lgdt3305_ops = { MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver"); MODULE_AUTHOR("Michael Krufky "); MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); /* * Local variables: -- cgit v1.2.3 From 5553d1020de15eea0f217aed78847db3c976ed4d Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 01:59:30 -0400 Subject: au8522: rename the au8522.c source file From: Devin Heitmueller Rename the au8522.c file to au8522_dig.c so that more source files can be added to the driver while preserving the original name of au8522.ko Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/Makefile | 1 + linux/drivers/media/dvb/frontends/au8522.c | 880 ------------------------- linux/drivers/media/dvb/frontends/au8522_dig.c | 880 +++++++++++++++++++++++++ 3 files changed, 881 insertions(+), 880 deletions(-) delete mode 100644 linux/drivers/media/dvb/frontends/au8522.c create mode 100644 linux/drivers/media/dvb/frontends/au8522_dig.c (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 1e3866b2f..fa3ab69f7 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -8,6 +8,7 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/ s921-objs := s921_module.o s921_core.o stb0899-objs = stb0899_drv.o stb0899_algo.o stv0900-objs = stv0900_core.o stv0900_sw.o +au8522-objs = au8522_dig.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o diff --git a/linux/drivers/media/dvb/frontends/au8522.c b/linux/drivers/media/dvb/frontends/au8522.c deleted file mode 100644 index 1e3ad2302..000000000 --- a/linux/drivers/media/dvb/frontends/au8522.c +++ /dev/null @@ -1,880 +0,0 @@ -/* - Auvitek AU8522 QAM/8VSB demodulator driver - - Copyright (C) 2008 Steven Toth - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include -#include -#include -#include "dvb_frontend.h" -#include "au8522.h" - -struct au8522_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct au8522_config *config; - - struct dvb_frontend frontend; - - u32 current_frequency; - fe_modulation_t current_modulation; - - u32 fe_status; - unsigned int led_state; -}; - -static int debug; - -#define dprintk(arg...) do { \ - if (debug) \ - printk(arg); \ - } while (0) - -/* 16 bit registers, 8 bit values */ -static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) -{ - int ret; - u8 buf [] = { reg >> 8, reg & 0xff, data }; - - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 3 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u8 au8522_readreg(struct au8522_state *state, u16 reg) -{ - int ret; - u8 b0 [] = { reg >> 8, reg & 0xff }; - u8 b1 [] = { 0 }; - - struct i2c_msg msg [] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 2 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); - return b1[0]; -} - -static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct au8522_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return au8522_writereg(state, 0x106, 1); - else - return au8522_writereg(state, 0x106, 0); -} - -struct mse2snr_tab { - u16 val; - u16 data; -}; - -/* VSB SNR lookup table */ -static struct mse2snr_tab vsb_mse2snr_tab[] = { - { 0, 270 }, - { 2, 250 }, - { 3, 240 }, - { 5, 230 }, - { 7, 220 }, - { 9, 210 }, - { 12, 200 }, - { 13, 195 }, - { 15, 190 }, - { 17, 185 }, - { 19, 180 }, - { 21, 175 }, - { 24, 170 }, - { 27, 165 }, - { 31, 160 }, - { 32, 158 }, - { 33, 156 }, - { 36, 152 }, - { 37, 150 }, - { 39, 148 }, - { 40, 146 }, - { 41, 144 }, - { 43, 142 }, - { 44, 140 }, - { 48, 135 }, - { 50, 130 }, - { 43, 142 }, - { 53, 125 }, - { 56, 120 }, - { 256, 115 }, -}; - -/* QAM64 SNR lookup table */ -static struct mse2snr_tab qam64_mse2snr_tab[] = { - { 15, 0 }, - { 16, 290 }, - { 17, 288 }, - { 18, 286 }, - { 19, 284 }, - { 20, 282 }, - { 21, 281 }, - { 22, 279 }, - { 23, 277 }, - { 24, 275 }, - { 25, 273 }, - { 26, 271 }, - { 27, 269 }, - { 28, 268 }, - { 29, 266 }, - { 30, 264 }, - { 31, 262 }, - { 32, 260 }, - { 33, 259 }, - { 34, 258 }, - { 35, 256 }, - { 36, 255 }, - { 37, 254 }, - { 38, 252 }, - { 39, 251 }, - { 40, 250 }, - { 41, 249 }, - { 42, 248 }, - { 43, 246 }, - { 44, 245 }, - { 45, 244 }, - { 46, 242 }, - { 47, 241 }, - { 48, 240 }, - { 50, 239 }, - { 51, 238 }, - { 53, 237 }, - { 54, 236 }, - { 56, 235 }, - { 57, 234 }, - { 59, 233 }, - { 60, 232 }, - { 62, 231 }, - { 63, 230 }, - { 65, 229 }, - { 67, 228 }, - { 68, 227 }, - { 70, 226 }, - { 71, 225 }, - { 73, 224 }, - { 74, 223 }, - { 76, 222 }, - { 78, 221 }, - { 80, 220 }, - { 82, 219 }, - { 85, 218 }, - { 88, 217 }, - { 90, 216 }, - { 92, 215 }, - { 93, 214 }, - { 94, 212 }, - { 95, 211 }, - { 97, 210 }, - { 99, 209 }, - { 101, 208 }, - { 102, 207 }, - { 104, 206 }, - { 107, 205 }, - { 111, 204 }, - { 114, 203 }, - { 118, 202 }, - { 122, 201 }, - { 125, 200 }, - { 128, 199 }, - { 130, 198 }, - { 132, 197 }, - { 256, 190 }, -}; - -/* QAM256 SNR lookup table */ -static struct mse2snr_tab qam256_mse2snr_tab[] = { - { 16, 0 }, - { 17, 400 }, - { 18, 398 }, - { 19, 396 }, - { 20, 394 }, - { 21, 392 }, - { 22, 390 }, - { 23, 388 }, - { 24, 386 }, - { 25, 384 }, - { 26, 382 }, - { 27, 380 }, - { 28, 379 }, - { 29, 378 }, - { 30, 377 }, - { 31, 376 }, - { 32, 375 }, - { 33, 374 }, - { 34, 373 }, - { 35, 372 }, - { 36, 371 }, - { 37, 370 }, - { 38, 362 }, - { 39, 354 }, - { 40, 346 }, - { 41, 338 }, - { 42, 330 }, - { 43, 328 }, - { 44, 326 }, - { 45, 324 }, - { 46, 322 }, - { 47, 320 }, - { 48, 319 }, - { 49, 318 }, - { 50, 317 }, - { 51, 316 }, - { 52, 315 }, - { 53, 314 }, - { 54, 313 }, - { 55, 312 }, - { 56, 311 }, - { 57, 310 }, - { 58, 308 }, - { 59, 306 }, - { 60, 304 }, - { 61, 302 }, - { 62, 300 }, - { 63, 298 }, - { 65, 295 }, - { 68, 294 }, - { 70, 293 }, - { 73, 292 }, - { 76, 291 }, - { 78, 290 }, - { 79, 289 }, - { 81, 288 }, - { 82, 287 }, - { 83, 286 }, - { 84, 285 }, - { 85, 284 }, - { 86, 283 }, - { 88, 282 }, - { 89, 281 }, - { 256, 280 }, -}; - -static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, - u16 *snr) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < sz; i++) { - if (mse < tab[i].val) { - *snr = tab[i].data; - ret = 0; - break; - } - } - dprintk("%s() snr=%d\n", __func__, *snr); - return ret; -} - -static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq) -{ - struct au8522_state *state = fe->demodulator_priv; - u8 r0b5, r0b6, r0b7; - char *ifmhz; - - switch (if_freq) { - case AU8522_IF_3_25MHZ: - ifmhz = "3.25"; - r0b5 = 0x00; - r0b6 = 0x3d; - r0b7 = 0xa0; - break; - case AU8522_IF_4MHZ: - ifmhz = "4.00"; - r0b5 = 0x00; - r0b6 = 0x4b; - r0b7 = 0xd9; - break; - case AU8522_IF_6MHZ: - ifmhz = "6.00"; - r0b5 = 0xfb; - r0b6 = 0x8e; - r0b7 = 0x39; - break; - default: - dprintk("%s() IF Frequency not supported\n", __func__); - return -EINVAL; - } - dprintk("%s() %s MHz\n", __func__, ifmhz); - au8522_writereg(state, 0x80b5, r0b5); - au8522_writereg(state, 0x80b6, r0b6); - au8522_writereg(state, 0x80b7, r0b7); - - return 0; -} - -/* VSB Modulation table */ -static struct { - u16 reg; - u16 data; -} VSB_mod_tab[] = { - { 0x8090, 0x84 }, - { 0x4092, 0x11 }, - { 0x2005, 0x00 }, - { 0x8091, 0x80 }, - { 0x80a3, 0x0c }, - { 0x80a4, 0xe8 }, - { 0x8081, 0xc4 }, - { 0x80a5, 0x40 }, - { 0x80a7, 0x40 }, - { 0x80a6, 0x67 }, - { 0x8262, 0x20 }, - { 0x821c, 0x30 }, - { 0x80d8, 0x1a }, - { 0x8227, 0xa0 }, - { 0x8121, 0xff }, - { 0x80a8, 0xf0 }, - { 0x80a9, 0x05 }, - { 0x80aa, 0x77 }, - { 0x80ab, 0xf0 }, - { 0x80ac, 0x05 }, - { 0x80ad, 0x77 }, - { 0x80ae, 0x41 }, - { 0x80af, 0x66 }, - { 0x821b, 0xcc }, - { 0x821d, 0x80 }, - { 0x80a4, 0xe8 }, - { 0x8231, 0x13 }, -}; - -/* QAM Modulation table */ -static struct { - u16 reg; - u16 data; -} QAM_mod_tab[] = { - { 0x80a3, 0x09 }, - { 0x80a4, 0x00 }, - { 0x8081, 0xc4 }, - { 0x80a5, 0x40 }, - { 0x80aa, 0x77 }, - { 0x80ad, 0x77 }, - { 0x80a6, 0x67 }, - { 0x8262, 0x20 }, - { 0x821c, 0x30 }, - { 0x80b8, 0x3e }, - { 0x80b9, 0xf0 }, - { 0x80ba, 0x01 }, - { 0x80bb, 0x18 }, - { 0x80bc, 0x50 }, - { 0x80bd, 0x00 }, - { 0x80be, 0xea }, - { 0x80bf, 0xef }, - { 0x80c0, 0xfc }, - { 0x80c1, 0xbd }, - { 0x80c2, 0x1f }, - { 0x80c3, 0xfc }, - { 0x80c4, 0xdd }, - { 0x80c5, 0xaf }, - { 0x80c6, 0x00 }, - { 0x80c7, 0x38 }, - { 0x80c8, 0x30 }, - { 0x80c9, 0x05 }, - { 0x80ca, 0x4a }, - { 0x80cb, 0xd0 }, - { 0x80cc, 0x01 }, - { 0x80cd, 0xd9 }, - { 0x80ce, 0x6f }, - { 0x80cf, 0xf9 }, - { 0x80d0, 0x70 }, - { 0x80d1, 0xdf }, - { 0x80d2, 0xf7 }, - { 0x80d3, 0xc2 }, - { 0x80d4, 0xdf }, - { 0x80d5, 0x02 }, - { 0x80d6, 0x9a }, - { 0x80d7, 0xd0 }, - { 0x8250, 0x0d }, - { 0x8251, 0xcd }, - { 0x8252, 0xe0 }, - { 0x8253, 0x05 }, - { 0x8254, 0xa7 }, - { 0x8255, 0xff }, - { 0x8256, 0xed }, - { 0x8257, 0x5b }, - { 0x8258, 0xae }, - { 0x8259, 0xe6 }, - { 0x825a, 0x3d }, - { 0x825b, 0x0f }, - { 0x825c, 0x0d }, - { 0x825d, 0xea }, - { 0x825e, 0xf2 }, - { 0x825f, 0x51 }, - { 0x8260, 0xf5 }, - { 0x8261, 0x06 }, - { 0x821a, 0x00 }, - { 0x8546, 0x40 }, - { 0x8210, 0x26 }, - { 0x8211, 0xf6 }, - { 0x8212, 0x84 }, - { 0x8213, 0x02 }, - { 0x8502, 0x01 }, - { 0x8121, 0x04 }, - { 0x8122, 0x04 }, - { 0x852e, 0x10 }, - { 0x80a4, 0xca }, - { 0x80a7, 0x40 }, - { 0x8526, 0x01 }, -}; - -static int au8522_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) -{ - struct au8522_state *state = fe->demodulator_priv; - int i; - - dprintk("%s(0x%08x)\n", __func__, m); - - switch (m) { - case VSB_8: - dprintk("%s() VSB_8\n", __func__); - for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++) - au8522_writereg(state, - VSB_mod_tab[i].reg, - VSB_mod_tab[i].data); - au8522_set_if(fe, state->config->vsb_if); - break; - case QAM_64: - case QAM_256: - dprintk("%s() QAM 64/256\n", __func__); - for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) - au8522_writereg(state, - QAM_mod_tab[i].reg, - QAM_mod_tab[i].data); - au8522_set_if(fe, state->config->qam_if); - break; - default: - dprintk("%s() Invalid modulation\n", __func__); - return -EINVAL; - } - - state->current_modulation = m; - - return 0; -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int au8522_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct au8522_state *state = fe->demodulator_priv; - int ret = -EINVAL; - - dprintk("%s(frequency=%d)\n", __func__, p->frequency); - - if ((state->current_frequency == p->frequency) && - (state->current_modulation == p->u.vsb.modulation)) - return 0; - - au8522_enable_modulation(fe, p->u.vsb.modulation); - - /* Allow the demod to settle */ - msleep(100); - - if (fe->ops.tuner_ops.set_params) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - if (ret < 0) - return ret; - - state->current_frequency = p->frequency; - - return 0; -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int au8522_init(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - au8522_writereg(state, 0xa4, 1 << 5); - - au8522_i2c_gate_ctrl(fe, 1); - - return 0; -} - -static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - u8 val; - - /* bail out if we cant control an LED */ - if (!led_config || !led_config->gpio_output || - !led_config->gpio_output_enable || !led_config->gpio_output_disable) - return 0; - - val = au8522_readreg(state, 0x4000 | - (led_config->gpio_output & ~0xc000)); - if (onoff) { - /* enable GPIO output */ - val &= ~((led_config->gpio_output_enable >> 8) & 0xff); - val |= (led_config->gpio_output_enable & 0xff); - } else { - /* disable GPIO output */ - val &= ~((led_config->gpio_output_disable >> 8) & 0xff); - val |= (led_config->gpio_output_disable & 0xff); - } - return au8522_writereg(state, 0x8000 | - (led_config->gpio_output & ~0xc000), val); -} - -/* led = 0 | off - * led = 1 | signal ok - * led = 2 | signal strong - * led < 0 | only light led if leds are currently off - */ -static int au8522_led_ctrl(struct au8522_state *state, int led) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - int i, ret = 0; - - /* bail out if we cant control an LED */ - if (!led_config || !led_config->gpio_leds || - !led_config->num_led_states || !led_config->led_states) - return 0; - - if (led < 0) { - /* if LED is already lit, then leave it as-is */ - if (state->led_state) - return 0; - else - led *= -1; - } - - /* toggle LED if changing state */ - if (state->led_state != led) { - u8 val; - - dprintk("%s: %d\n", __func__, led); - - au8522_led_gpio_enable(state, 1); - - val = au8522_readreg(state, 0x4000 | - (led_config->gpio_leds & ~0xc000)); - - /* start with all leds off */ - for (i = 0; i < led_config->num_led_states; i++) - val &= ~led_config->led_states[i]; - - /* set selected LED state */ - if (led < led_config->num_led_states) - val |= led_config->led_states[led]; - else if (led_config->num_led_states) - val |= - led_config->led_states[led_config->num_led_states - 1]; - - ret = au8522_writereg(state, 0x8000 | - (led_config->gpio_leds & ~0xc000), val); - if (ret < 0) - return ret; - - state->led_state = led; - - if (led == 0) - au8522_led_gpio_enable(state, 0); - } - - return 0; -} - -static int au8522_sleep(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - /* turn off led */ - au8522_led_ctrl(state, 0); - - state->current_frequency = 0; - - return 0; -} - -static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct au8522_state *state = fe->demodulator_priv; - u8 reg; - u32 tuner_status = 0; - - *status = 0; - - if (state->current_modulation == VSB_8) { - dprintk("%s() Checking VSB_8\n", __func__); - reg = au8522_readreg(state, 0x4088); - if ((reg & 0x03) == 0x03) - *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; - } else { - dprintk("%s() Checking QAM\n", __func__); - reg = au8522_readreg(state, 0x4541); - if (reg & 0x80) - *status |= FE_HAS_VITERBI; - if (reg & 0x20) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; - } - - switch (state->config->status_mode) { - case AU8522_DEMODLOCKING: - dprintk("%s() DEMODLOCKING\n", __func__); - if (*status & FE_HAS_VITERBI) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - case AU8522_TUNERLOCKING: - /* Get the tuner status */ - dprintk("%s() TUNERLOCKING\n", __func__); - if (fe->ops.tuner_ops.get_status) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.get_status(fe, &tuner_status); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (tuner_status) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - } - state->fe_status = *status; - - if (*status & FE_HAS_LOCK) - /* turn on LED, if it isn't on already */ - au8522_led_ctrl(state, -1); - else - /* turn off LED */ - au8522_led_ctrl(state, 0); - - dprintk("%s() status 0x%08x\n", __func__, *status); - - return 0; -} - -static int au8522_led_status(struct au8522_state *state, const u16 *snr) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - int led; - u16 strong; - - /* bail out if we cant control an LED */ - if (!led_config) - return 0; - - if (0 == (state->fe_status & FE_HAS_LOCK)) - return au8522_led_ctrl(state, 0); - else if (state->current_modulation == QAM_256) - strong = led_config->qam256_strong; - else if (state->current_modulation == QAM_64) - strong = led_config->qam64_strong; - else /* (state->current_modulation == VSB_8) */ - strong = led_config->vsb8_strong; - - if (*snr >= strong) - led = 2; - else - led = 1; - - if ((state->led_state) && - (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10)) - /* snr didn't change enough to bother - * changing the color of the led */ - return 0; - - return au8522_led_ctrl(state, led); -} - -static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct au8522_state *state = fe->demodulator_priv; - int ret = -EINVAL; - - dprintk("%s()\n", __func__); - - if (state->current_modulation == QAM_256) - ret = au8522_mse2snr_lookup(qam256_mse2snr_tab, - ARRAY_SIZE(qam256_mse2snr_tab), - au8522_readreg(state, 0x4522), - snr); - else if (state->current_modulation == QAM_64) - ret = au8522_mse2snr_lookup(qam64_mse2snr_tab, - ARRAY_SIZE(qam64_mse2snr_tab), - au8522_readreg(state, 0x4522), - snr); - else /* VSB_8 */ - ret = au8522_mse2snr_lookup(vsb_mse2snr_tab, - ARRAY_SIZE(vsb_mse2snr_tab), - au8522_readreg(state, 0x4311), - snr); - - if (state->config->led_cfg) - au8522_led_status(state, snr); - - return ret; -} - -static int au8522_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - return au8522_read_snr(fe, signal_strength); -} - -static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct au8522_state *state = fe->demodulator_priv; - - if (state->current_modulation == VSB_8) - *ucblocks = au8522_readreg(state, 0x4087); - else - *ucblocks = au8522_readreg(state, 0x4543); - - return 0; -} - -static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - return au8522_read_ucblocks(fe, ber); -} - -static int au8522_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct au8522_state *state = fe->demodulator_priv; - - p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; - - return 0; -} - -static int au8522_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void au8522_release(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops au8522_ops; - -struct dvb_frontend *au8522_attach(const struct au8522_config *config, - struct i2c_adapter *i2c) -{ - struct au8522_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; -#if 0 - /* check if the demod exists */ - reg = au8522_readreg(state, 0x04); - if ((reg != 0x0066) && (reg != 0x007f)) - goto error; -#endif - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &au8522_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - if (au8522_init(&state->frontend) != 0) { - printk(KERN_ERR "%s: Failed to initialize correctly\n", - __func__); - goto error; - } - - /* Note: Leaving the I2C gate open here. */ - au8522_i2c_gate_ctrl(&state->frontend, 1); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(au8522_attach); - -static struct dvb_frontend_ops au8522_ops = { - - .info = { - .name = "Auvitek AU8522 QAM/8VSB Frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - - .init = au8522_init, - .sleep = au8522_sleep, - .i2c_gate_ctrl = au8522_i2c_gate_ctrl, - .set_frontend = au8522_set_frontend, - .get_frontend = au8522_get_frontend, - .get_tune_settings = au8522_get_tune_settings, - .read_status = au8522_read_status, - .read_ber = au8522_read_ber, - .read_signal_strength = au8522_read_signal_strength, - .read_snr = au8522_read_snr, - .read_ucblocks = au8522_read_ucblocks, - .release = au8522_release, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c new file mode 100644 index 000000000..1e3ad2302 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/au8522_dig.c @@ -0,0 +1,880 @@ +/* + Auvitek AU8522 QAM/8VSB demodulator driver + + Copyright (C) 2008 Steven Toth + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include +#include +#include "dvb_frontend.h" +#include "au8522.h" + +struct au8522_state { + + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct au8522_config *config; + + struct dvb_frontend frontend; + + u32 current_frequency; + fe_modulation_t current_modulation; + + u32 fe_status; + unsigned int led_state; +}; + +static int debug; + +#define dprintk(arg...) do { \ + if (debug) \ + printk(arg); \ + } while (0) + +/* 16 bit registers, 8 bit values */ +static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) +{ + int ret; + u8 buf [] = { reg >> 8, reg & 0xff, data }; + + struct i2c_msg msg = { .addr = state->config->demod_address, + .flags = 0, .buf = buf, .len = 3 }; + + ret = i2c_transfer(state->i2c, &msg, 1); + + if (ret != 1) + printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " + "ret == %i)\n", __func__, reg, data, ret); + + return (ret != 1) ? -1 : 0; +} + +static u8 au8522_readreg(struct au8522_state *state, u16 reg) +{ + int ret; + u8 b0 [] = { reg >> 8, reg & 0xff }; + u8 b1 [] = { 0 }; + + struct i2c_msg msg [] = { + { .addr = state->config->demod_address, .flags = 0, + .buf = b0, .len = 2 }, + { .addr = state->config->demod_address, .flags = I2C_M_RD, + .buf = b1, .len = 1 } }; + + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) + printk(KERN_ERR "%s: readreg error (ret == %i)\n", + __func__, ret); + return b1[0]; +} + +static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct au8522_state *state = fe->demodulator_priv; + + dprintk("%s(%d)\n", __func__, enable); + + if (enable) + return au8522_writereg(state, 0x106, 1); + else + return au8522_writereg(state, 0x106, 0); +} + +struct mse2snr_tab { + u16 val; + u16 data; +}; + +/* VSB SNR lookup table */ +static struct mse2snr_tab vsb_mse2snr_tab[] = { + { 0, 270 }, + { 2, 250 }, + { 3, 240 }, + { 5, 230 }, + { 7, 220 }, + { 9, 210 }, + { 12, 200 }, + { 13, 195 }, + { 15, 190 }, + { 17, 185 }, + { 19, 180 }, + { 21, 175 }, + { 24, 170 }, + { 27, 165 }, + { 31, 160 }, + { 32, 158 }, + { 33, 156 }, + { 36, 152 }, + { 37, 150 }, + { 39, 148 }, + { 40, 146 }, + { 41, 144 }, + { 43, 142 }, + { 44, 140 }, + { 48, 135 }, + { 50, 130 }, + { 43, 142 }, + { 53, 125 }, + { 56, 120 }, + { 256, 115 }, +}; + +/* QAM64 SNR lookup table */ +static struct mse2snr_tab qam64_mse2snr_tab[] = { + { 15, 0 }, + { 16, 290 }, + { 17, 288 }, + { 18, 286 }, + { 19, 284 }, + { 20, 282 }, + { 21, 281 }, + { 22, 279 }, + { 23, 277 }, + { 24, 275 }, + { 25, 273 }, + { 26, 271 }, + { 27, 269 }, + { 28, 268 }, + { 29, 266 }, + { 30, 264 }, + { 31, 262 }, + { 32, 260 }, + { 33, 259 }, + { 34, 258 }, + { 35, 256 }, + { 36, 255 }, + { 37, 254 }, + { 38, 252 }, + { 39, 251 }, + { 40, 250 }, + { 41, 249 }, + { 42, 248 }, + { 43, 246 }, + { 44, 245 }, + { 45, 244 }, + { 46, 242 }, + { 47, 241 }, + { 48, 240 }, + { 50, 239 }, + { 51, 238 }, + { 53, 237 }, + { 54, 236 }, + { 56, 235 }, + { 57, 234 }, + { 59, 233 }, + { 60, 232 }, + { 62, 231 }, + { 63, 230 }, + { 65, 229 }, + { 67, 228 }, + { 68, 227 }, + { 70, 226 }, + { 71, 225 }, + { 73, 224 }, + { 74, 223 }, + { 76, 222 }, + { 78, 221 }, + { 80, 220 }, + { 82, 219 }, + { 85, 218 }, + { 88, 217 }, + { 90, 216 }, + { 92, 215 }, + { 93, 214 }, + { 94, 212 }, + { 95, 211 }, + { 97, 210 }, + { 99, 209 }, + { 101, 208 }, + { 102, 207 }, + { 104, 206 }, + { 107, 205 }, + { 111, 204 }, + { 114, 203 }, + { 118, 202 }, + { 122, 201 }, + { 125, 200 }, + { 128, 199 }, + { 130, 198 }, + { 132, 197 }, + { 256, 190 }, +}; + +/* QAM256 SNR lookup table */ +static struct mse2snr_tab qam256_mse2snr_tab[] = { + { 16, 0 }, + { 17, 400 }, + { 18, 398 }, + { 19, 396 }, + { 20, 394 }, + { 21, 392 }, + { 22, 390 }, + { 23, 388 }, + { 24, 386 }, + { 25, 384 }, + { 26, 382 }, + { 27, 380 }, + { 28, 379 }, + { 29, 378 }, + { 30, 377 }, + { 31, 376 }, + { 32, 375 }, + { 33, 374 }, + { 34, 373 }, + { 35, 372 }, + { 36, 371 }, + { 37, 370 }, + { 38, 362 }, + { 39, 354 }, + { 40, 346 }, + { 41, 338 }, + { 42, 330 }, + { 43, 328 }, + { 44, 326 }, + { 45, 324 }, + { 46, 322 }, + { 47, 320 }, + { 48, 319 }, + { 49, 318 }, + { 50, 317 }, + { 51, 316 }, + { 52, 315 }, + { 53, 314 }, + { 54, 313 }, + { 55, 312 }, + { 56, 311 }, + { 57, 310 }, + { 58, 308 }, + { 59, 306 }, + { 60, 304 }, + { 61, 302 }, + { 62, 300 }, + { 63, 298 }, + { 65, 295 }, + { 68, 294 }, + { 70, 293 }, + { 73, 292 }, + { 76, 291 }, + { 78, 290 }, + { 79, 289 }, + { 81, 288 }, + { 82, 287 }, + { 83, 286 }, + { 84, 285 }, + { 85, 284 }, + { 86, 283 }, + { 88, 282 }, + { 89, 281 }, + { 256, 280 }, +}; + +static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, + u16 *snr) +{ + int i, ret = -EINVAL; + dprintk("%s()\n", __func__); + + for (i = 0; i < sz; i++) { + if (mse < tab[i].val) { + *snr = tab[i].data; + ret = 0; + break; + } + } + dprintk("%s() snr=%d\n", __func__, *snr); + return ret; +} + +static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq) +{ + struct au8522_state *state = fe->demodulator_priv; + u8 r0b5, r0b6, r0b7; + char *ifmhz; + + switch (if_freq) { + case AU8522_IF_3_25MHZ: + ifmhz = "3.25"; + r0b5 = 0x00; + r0b6 = 0x3d; + r0b7 = 0xa0; + break; + case AU8522_IF_4MHZ: + ifmhz = "4.00"; + r0b5 = 0x00; + r0b6 = 0x4b; + r0b7 = 0xd9; + break; + case AU8522_IF_6MHZ: + ifmhz = "6.00"; + r0b5 = 0xfb; + r0b6 = 0x8e; + r0b7 = 0x39; + break; + default: + dprintk("%s() IF Frequency not supported\n", __func__); + return -EINVAL; + } + dprintk("%s() %s MHz\n", __func__, ifmhz); + au8522_writereg(state, 0x80b5, r0b5); + au8522_writereg(state, 0x80b6, r0b6); + au8522_writereg(state, 0x80b7, r0b7); + + return 0; +} + +/* VSB Modulation table */ +static struct { + u16 reg; + u16 data; +} VSB_mod_tab[] = { + { 0x8090, 0x84 }, + { 0x4092, 0x11 }, + { 0x2005, 0x00 }, + { 0x8091, 0x80 }, + { 0x80a3, 0x0c }, + { 0x80a4, 0xe8 }, + { 0x8081, 0xc4 }, + { 0x80a5, 0x40 }, + { 0x80a7, 0x40 }, + { 0x80a6, 0x67 }, + { 0x8262, 0x20 }, + { 0x821c, 0x30 }, + { 0x80d8, 0x1a }, + { 0x8227, 0xa0 }, + { 0x8121, 0xff }, + { 0x80a8, 0xf0 }, + { 0x80a9, 0x05 }, + { 0x80aa, 0x77 }, + { 0x80ab, 0xf0 }, + { 0x80ac, 0x05 }, + { 0x80ad, 0x77 }, + { 0x80ae, 0x41 }, + { 0x80af, 0x66 }, + { 0x821b, 0xcc }, + { 0x821d, 0x80 }, + { 0x80a4, 0xe8 }, + { 0x8231, 0x13 }, +}; + +/* QAM Modulation table */ +static struct { + u16 reg; + u16 data; +} QAM_mod_tab[] = { + { 0x80a3, 0x09 }, + { 0x80a4, 0x00 }, + { 0x8081, 0xc4 }, + { 0x80a5, 0x40 }, + { 0x80aa, 0x77 }, + { 0x80ad, 0x77 }, + { 0x80a6, 0x67 }, + { 0x8262, 0x20 }, + { 0x821c, 0x30 }, + { 0x80b8, 0x3e }, + { 0x80b9, 0xf0 }, + { 0x80ba, 0x01 }, + { 0x80bb, 0x18 }, + { 0x80bc, 0x50 }, + { 0x80bd, 0x00 }, + { 0x80be, 0xea }, + { 0x80bf, 0xef }, + { 0x80c0, 0xfc }, + { 0x80c1, 0xbd }, + { 0x80c2, 0x1f }, + { 0x80c3, 0xfc }, + { 0x80c4, 0xdd }, + { 0x80c5, 0xaf }, + { 0x80c6, 0x00 }, + { 0x80c7, 0x38 }, + { 0x80c8, 0x30 }, + { 0x80c9, 0x05 }, + { 0x80ca, 0x4a }, + { 0x80cb, 0xd0 }, + { 0x80cc, 0x01 }, + { 0x80cd, 0xd9 }, + { 0x80ce, 0x6f }, + { 0x80cf, 0xf9 }, + { 0x80d0, 0x70 }, + { 0x80d1, 0xdf }, + { 0x80d2, 0xf7 }, + { 0x80d3, 0xc2 }, + { 0x80d4, 0xdf }, + { 0x80d5, 0x02 }, + { 0x80d6, 0x9a }, + { 0x80d7, 0xd0 }, + { 0x8250, 0x0d }, + { 0x8251, 0xcd }, + { 0x8252, 0xe0 }, + { 0x8253, 0x05 }, + { 0x8254, 0xa7 }, + { 0x8255, 0xff }, + { 0x8256, 0xed }, + { 0x8257, 0x5b }, + { 0x8258, 0xae }, + { 0x8259, 0xe6 }, + { 0x825a, 0x3d }, + { 0x825b, 0x0f }, + { 0x825c, 0x0d }, + { 0x825d, 0xea }, + { 0x825e, 0xf2 }, + { 0x825f, 0x51 }, + { 0x8260, 0xf5 }, + { 0x8261, 0x06 }, + { 0x821a, 0x00 }, + { 0x8546, 0x40 }, + { 0x8210, 0x26 }, + { 0x8211, 0xf6 }, + { 0x8212, 0x84 }, + { 0x8213, 0x02 }, + { 0x8502, 0x01 }, + { 0x8121, 0x04 }, + { 0x8122, 0x04 }, + { 0x852e, 0x10 }, + { 0x80a4, 0xca }, + { 0x80a7, 0x40 }, + { 0x8526, 0x01 }, +}; + +static int au8522_enable_modulation(struct dvb_frontend *fe, + fe_modulation_t m) +{ + struct au8522_state *state = fe->demodulator_priv; + int i; + + dprintk("%s(0x%08x)\n", __func__, m); + + switch (m) { + case VSB_8: + dprintk("%s() VSB_8\n", __func__); + for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++) + au8522_writereg(state, + VSB_mod_tab[i].reg, + VSB_mod_tab[i].data); + au8522_set_if(fe, state->config->vsb_if); + break; + case QAM_64: + case QAM_256: + dprintk("%s() QAM 64/256\n", __func__); + for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) + au8522_writereg(state, + QAM_mod_tab[i].reg, + QAM_mod_tab[i].data); + au8522_set_if(fe, state->config->qam_if); + break; + default: + dprintk("%s() Invalid modulation\n", __func__); + return -EINVAL; + } + + state->current_modulation = m; + + return 0; +} + +/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ +static int au8522_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct au8522_state *state = fe->demodulator_priv; + int ret = -EINVAL; + + dprintk("%s(frequency=%d)\n", __func__, p->frequency); + + if ((state->current_frequency == p->frequency) && + (state->current_modulation == p->u.vsb.modulation)) + return 0; + + au8522_enable_modulation(fe, p->u.vsb.modulation); + + /* Allow the demod to settle */ + msleep(100); + + if (fe->ops.tuner_ops.set_params) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + ret = fe->ops.tuner_ops.set_params(fe, p); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + if (ret < 0) + return ret; + + state->current_frequency = p->frequency; + + return 0; +} + +/* Reset the demod hardware and reset all of the configuration registers + to a default state. */ +static int au8522_init(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + dprintk("%s()\n", __func__); + + au8522_writereg(state, 0xa4, 1 << 5); + + au8522_i2c_gate_ctrl(fe, 1); + + return 0; +} + +static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) +{ + struct au8522_led_config *led_config = state->config->led_cfg; + u8 val; + + /* bail out if we cant control an LED */ + if (!led_config || !led_config->gpio_output || + !led_config->gpio_output_enable || !led_config->gpio_output_disable) + return 0; + + val = au8522_readreg(state, 0x4000 | + (led_config->gpio_output & ~0xc000)); + if (onoff) { + /* enable GPIO output */ + val &= ~((led_config->gpio_output_enable >> 8) & 0xff); + val |= (led_config->gpio_output_enable & 0xff); + } else { + /* disable GPIO output */ + val &= ~((led_config->gpio_output_disable >> 8) & 0xff); + val |= (led_config->gpio_output_disable & 0xff); + } + return au8522_writereg(state, 0x8000 | + (led_config->gpio_output & ~0xc000), val); +} + +/* led = 0 | off + * led = 1 | signal ok + * led = 2 | signal strong + * led < 0 | only light led if leds are currently off + */ +static int au8522_led_ctrl(struct au8522_state *state, int led) +{ + struct au8522_led_config *led_config = state->config->led_cfg; + int i, ret = 0; + + /* bail out if we cant control an LED */ + if (!led_config || !led_config->gpio_leds || + !led_config->num_led_states || !led_config->led_states) + return 0; + + if (led < 0) { + /* if LED is already lit, then leave it as-is */ + if (state->led_state) + return 0; + else + led *= -1; + } + + /* toggle LED if changing state */ + if (state->led_state != led) { + u8 val; + + dprintk("%s: %d\n", __func__, led); + + au8522_led_gpio_enable(state, 1); + + val = au8522_readreg(state, 0x4000 | + (led_config->gpio_leds & ~0xc000)); + + /* start with all leds off */ + for (i = 0; i < led_config->num_led_states; i++) + val &= ~led_config->led_states[i]; + + /* set selected LED state */ + if (led < led_config->num_led_states) + val |= led_config->led_states[led]; + else if (led_config->num_led_states) + val |= + led_config->led_states[led_config->num_led_states - 1]; + + ret = au8522_writereg(state, 0x8000 | + (led_config->gpio_leds & ~0xc000), val); + if (ret < 0) + return ret; + + state->led_state = led; + + if (led == 0) + au8522_led_gpio_enable(state, 0); + } + + return 0; +} + +static int au8522_sleep(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + dprintk("%s()\n", __func__); + + /* turn off led */ + au8522_led_ctrl(state, 0); + + state->current_frequency = 0; + + return 0; +} + +static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct au8522_state *state = fe->demodulator_priv; + u8 reg; + u32 tuner_status = 0; + + *status = 0; + + if (state->current_modulation == VSB_8) { + dprintk("%s() Checking VSB_8\n", __func__); + reg = au8522_readreg(state, 0x4088); + if ((reg & 0x03) == 0x03) + *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; + } else { + dprintk("%s() Checking QAM\n", __func__); + reg = au8522_readreg(state, 0x4541); + if (reg & 0x80) + *status |= FE_HAS_VITERBI; + if (reg & 0x20) + *status |= FE_HAS_LOCK | FE_HAS_SYNC; + } + + switch (state->config->status_mode) { + case AU8522_DEMODLOCKING: + dprintk("%s() DEMODLOCKING\n", __func__); + if (*status & FE_HAS_VITERBI) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + case AU8522_TUNERLOCKING: + /* Get the tuner status */ + dprintk("%s() TUNERLOCKING\n", __func__); + if (fe->ops.tuner_ops.get_status) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + fe->ops.tuner_ops.get_status(fe, &tuner_status); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + if (tuner_status) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + } + state->fe_status = *status; + + if (*status & FE_HAS_LOCK) + /* turn on LED, if it isn't on already */ + au8522_led_ctrl(state, -1); + else + /* turn off LED */ + au8522_led_ctrl(state, 0); + + dprintk("%s() status 0x%08x\n", __func__, *status); + + return 0; +} + +static int au8522_led_status(struct au8522_state *state, const u16 *snr) +{ + struct au8522_led_config *led_config = state->config->led_cfg; + int led; + u16 strong; + + /* bail out if we cant control an LED */ + if (!led_config) + return 0; + + if (0 == (state->fe_status & FE_HAS_LOCK)) + return au8522_led_ctrl(state, 0); + else if (state->current_modulation == QAM_256) + strong = led_config->qam256_strong; + else if (state->current_modulation == QAM_64) + strong = led_config->qam64_strong; + else /* (state->current_modulation == VSB_8) */ + strong = led_config->vsb8_strong; + + if (*snr >= strong) + led = 2; + else + led = 1; + + if ((state->led_state) && + (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10)) + /* snr didn't change enough to bother + * changing the color of the led */ + return 0; + + return au8522_led_ctrl(state, led); +} + +static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct au8522_state *state = fe->demodulator_priv; + int ret = -EINVAL; + + dprintk("%s()\n", __func__); + + if (state->current_modulation == QAM_256) + ret = au8522_mse2snr_lookup(qam256_mse2snr_tab, + ARRAY_SIZE(qam256_mse2snr_tab), + au8522_readreg(state, 0x4522), + snr); + else if (state->current_modulation == QAM_64) + ret = au8522_mse2snr_lookup(qam64_mse2snr_tab, + ARRAY_SIZE(qam64_mse2snr_tab), + au8522_readreg(state, 0x4522), + snr); + else /* VSB_8 */ + ret = au8522_mse2snr_lookup(vsb_mse2snr_tab, + ARRAY_SIZE(vsb_mse2snr_tab), + au8522_readreg(state, 0x4311), + snr); + + if (state->config->led_cfg) + au8522_led_status(state, snr); + + return ret; +} + +static int au8522_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + return au8522_read_snr(fe, signal_strength); +} + +static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct au8522_state *state = fe->demodulator_priv; + + if (state->current_modulation == VSB_8) + *ucblocks = au8522_readreg(state, 0x4087); + else + *ucblocks = au8522_readreg(state, 0x4543); + + return 0; +} + +static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + return au8522_read_ucblocks(fe, ber); +} + +static int au8522_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct au8522_state *state = fe->demodulator_priv; + + p->frequency = state->current_frequency; + p->u.vsb.modulation = state->current_modulation; + + return 0; +} + +static int au8522_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 1000; + return 0; +} + +static void au8522_release(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops au8522_ops; + +struct dvb_frontend *au8522_attach(const struct au8522_config *config, + struct i2c_adapter *i2c) +{ + struct au8522_state *state = NULL; + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* setup the state */ + state->config = config; + state->i2c = i2c; +#if 0 + /* check if the demod exists */ + reg = au8522_readreg(state, 0x04); + if ((reg != 0x0066) && (reg != 0x007f)) + goto error; +#endif + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &au8522_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + if (au8522_init(&state->frontend) != 0) { + printk(KERN_ERR "%s: Failed to initialize correctly\n", + __func__); + goto error; + } + + /* Note: Leaving the I2C gate open here. */ + au8522_i2c_gate_ctrl(&state->frontend, 1); + + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(au8522_attach); + +static struct dvb_frontend_ops au8522_ops = { + + .info = { + .name = "Auvitek AU8522 QAM/8VSB Frontend", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + + .init = au8522_init, + .sleep = au8522_sleep, + .i2c_gate_ctrl = au8522_i2c_gate_ctrl, + .set_frontend = au8522_set_frontend, + .get_frontend = au8522_get_frontend, + .get_tune_settings = au8522_get_tune_settings, + .read_status = au8522_read_status, + .read_ber = au8522_read_ber, + .read_signal_strength = au8522_read_signal_strength, + .read_snr = au8522_read_snr, + .read_ucblocks = au8522_read_ucblocks, + .release = au8522_release, +}; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Enable verbose debug messages"); + +MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver"); +MODULE_AUTHOR("Steven Toth"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 442d082f75069d464542421d3e3d6da68c2ddbc4 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 01:59:56 -0400 Subject: au8522: move shared state and common functions into a separate header files From: Devin Heitmueller Move the au8522 state structure, as well as exposing functions needed by the analog side of the demodulator into a common header file. Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/au8522_dig.c | 25 +++-------- linux/drivers/media/dvb/frontends/au8522_priv.h | 57 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 linux/drivers/media/dvb/frontends/au8522_priv.h (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c index 1e3ad2302..cd8f1ec3e 100644 --- a/linux/drivers/media/dvb/frontends/au8522_dig.c +++ b/linux/drivers/media/dvb/frontends/au8522_dig.c @@ -27,22 +27,7 @@ #include #include "dvb_frontend.h" #include "au8522.h" - -struct au8522_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct au8522_config *config; - - struct dvb_frontend frontend; - - u32 current_frequency; - fe_modulation_t current_modulation; - - u32 fe_status; - unsigned int led_state; -}; +#include "au8522_priv.h" static int debug; @@ -52,7 +37,7 @@ static int debug; } while (0) /* 16 bit registers, 8 bit values */ -static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) +int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) { int ret; u8 buf [] = { reg >> 8, reg & 0xff, data }; @@ -69,7 +54,7 @@ static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) return (ret != 1) ? -1 : 0; } -static u8 au8522_readreg(struct au8522_state *state, u16 reg) +u8 au8522_readreg(struct au8522_state *state, u16 reg) { int ret; u8 b0 [] = { reg >> 8, reg & 0xff }; @@ -528,7 +513,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe, /* Reset the demod hardware and reset all of the configuration registers to a default state. */ -static int au8522_init(struct dvb_frontend *fe) +int au8522_init(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); @@ -624,7 +609,7 @@ static int au8522_led_ctrl(struct au8522_state *state, int led) return 0; } -static int au8522_sleep(struct dvb_frontend *fe) +int au8522_sleep(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); diff --git a/linux/drivers/media/dvb/frontends/au8522_priv.h b/linux/drivers/media/dvb/frontends/au8522_priv.h new file mode 100644 index 000000000..569675d29 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/au8522_priv.h @@ -0,0 +1,57 @@ +/* + Auvitek AU8522 QAM/8VSB demodulator driver + + Copyright (C) 2008 Steven Toth + Copyright (C) 2008 Devin Heitmueller + Copyright (C) 2005-2008 Auvitek International, Ltd. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dvb_frontend.h" +#include "au8522.h" +#include "tuner-i2c.h" + +struct au8522_state { + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct au8522_config *config; + + struct dvb_frontend frontend; + + u32 current_frequency; + fe_modulation_t current_modulation; + + u32 fe_status; + unsigned int led_state; +}; + +/* These are routines shared by both the VSB/QAM demodulator and the analog + decoder */ +int au8522_writereg(struct au8522_state *state, u16 reg, u8 data); +u8 au8522_readreg(struct au8522_state *state, u16 reg); +int au8522_init(struct dvb_frontend *fe); +int au8522_sleep(struct dvb_frontend *fe); -- cgit v1.2.3 From fe041f64faf5fecd2b6a9edecf7c74bb7cf71c95 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:00:19 -0400 Subject: au8522: fix register read/write high bits From: Devin Heitmueller For the i2c messages to read and write registers, the two high order bits of the first byte dictates whether it is a read or a write operation. Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/au8522_dig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c index cd8f1ec3e..e63e17827 100644 --- a/linux/drivers/media/dvb/frontends/au8522_dig.c +++ b/linux/drivers/media/dvb/frontends/au8522_dig.c @@ -40,7 +40,7 @@ static int debug; int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) { int ret; - u8 buf [] = { reg >> 8, reg & 0xff, data }; + u8 buf [] = { (reg >> 8) | 0x80, reg & 0xff, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; @@ -57,7 +57,7 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) u8 au8522_readreg(struct au8522_state *state, u16 reg) { int ret; - u8 b0 [] = { reg >> 8, reg & 0xff }; + u8 b0 [] = { (reg >> 8) | 0x40, reg & 0xff }; u8 b1 [] = { 0 }; struct i2c_msg msg [] = { -- cgit v1.2.3 From c55d671ee9eb267b04c218863cd9a577fa036dbc Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:00:34 -0400 Subject: au8522: power down the digital demod when not in use From: Devin Heitmueller When the au8522 is idle, put the chip into a low power mode (reduces power consumption from 450ma to 346ma) Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/au8522_dig.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c index e63e17827..a78636286 100644 --- a/linux/drivers/media/dvb/frontends/au8522_dig.c +++ b/linux/drivers/media/dvb/frontends/au8522_dig.c @@ -617,6 +617,9 @@ int au8522_sleep(struct dvb_frontend *fe) /* turn off led */ au8522_led_ctrl(state, 0); + /* Power down the chip */ + au8522_writereg(state, 0xa4, 1 << 5); + state->current_frequency = 0; return 0; -- cgit v1.2.3 From 552d2a4fdce766a81187b285e8114ee089b7a721 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:00:36 -0400 Subject: au8522: make use of hybrid framework so analog/digital demod can share state From: Devin Heitmueller Make use of the hybrid tuner framework so the analog and digital parts of the au8522 demodulator can make use of the same shared state. Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/au8522_dig.c | 45 +++++++++++++++++++++---- linux/drivers/media/dvb/frontends/au8522_priv.h | 8 +++++ 2 files changed, 46 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c index a78636286..00d783ce2 100644 --- a/linux/drivers/media/dvb/frontends/au8522_dig.c +++ b/linux/drivers/media/dvb/frontends/au8522_dig.c @@ -31,6 +31,10 @@ static int debug; +/* Despite the name "hybrid_tuner", the framework works just as well for + hybrid demodulators as well... */ +static LIST_HEAD(hybrid_tuner_instance_list); + #define dprintk(arg...) do { \ if (debug) \ printk(arg); \ @@ -786,23 +790,50 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe, return 0; } +static struct dvb_frontend_ops au8522_ops; + +int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, + u8 client_address) +{ + return hybrid_tuner_request_state(struct au8522_state, (*state), + hybrid_tuner_instance_list, + i2c, client_address, "au8522"); +} + +void au8522_release_state(struct au8522_state *state) +{ + if (state != NULL) + hybrid_tuner_release_state(state); +} + + static void au8522_release(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; - kfree(state); + au8522_release_state(state); } -static struct dvb_frontend_ops au8522_ops; - struct dvb_frontend *au8522_attach(const struct au8522_config *config, struct i2c_adapter *i2c) { struct au8522_state *state = NULL; + int instance; /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); - if (state == NULL) - goto error; + instance = au8522_get_state(&state, i2c, config->demod_address); + switch (instance) { + case 0: + dprintk("%s state allocation failed\n", __func__); + break; + case 1: + /* new demod instance */ + dprintk("%s using new instance\n", __func__); + break; + default: + /* existing demod instance */ + dprintk("%s using existing instance\n", __func__); + break; + } /* setup the state */ state->config = config; @@ -830,7 +861,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config, return &state->frontend; error: - kfree(state); + au8522_release_state(state); return NULL; } EXPORT_SYMBOL(au8522_attach); diff --git a/linux/drivers/media/dvb/frontends/au8522_priv.h b/linux/drivers/media/dvb/frontends/au8522_priv.h index 569675d29..98b09caa2 100644 --- a/linux/drivers/media/dvb/frontends/au8522_priv.h +++ b/linux/drivers/media/dvb/frontends/au8522_priv.h @@ -37,6 +37,10 @@ struct au8522_state { struct i2c_adapter *i2c; + /* Used for sharing of the state between analog and digital mode */ + struct tuner_i2c_props i2c_props; + struct list_head hybrid_tuner_instance_list; + /* configuration settings */ const struct au8522_config *config; @@ -55,3 +59,7 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data); u8 au8522_readreg(struct au8522_state *state, u16 reg); int au8522_init(struct dvb_frontend *fe); int au8522_sleep(struct dvb_frontend *fe); + +int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, + u8 client_address); +void au8522_release_state(struct au8522_state *state); -- cgit v1.2.3 From 23e405c74fb529c9afc894ebc22d2b289a78628f Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:00:38 -0400 Subject: au8522: add support for analog side of demodulator From: Devin Heitmueller Add support for the analog functionality in the au8522 analog/digital demodulator Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/Makefile | 2 +- linux/drivers/media/dvb/frontends/au8522.h | 16 ++ linux/drivers/media/dvb/frontends/au8522_priv.h | 347 ++++++++++++++++++++++++ 3 files changed, 364 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index fa3ab69f7..cffe25e2a 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -8,7 +8,7 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/ s921-objs := s921_module.o s921_core.o stb0899-objs = stb0899_drv.o stb0899_algo.o stv0900-objs = stv0900_core.o stv0900_sw.o -au8522-objs = au8522_dig.o +au8522-objs = au8522_dig.o au8522_decoder.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o diff --git a/linux/drivers/media/dvb/frontends/au8522.h b/linux/drivers/media/dvb/frontends/au8522.h index 7b94f554a..565dcf31a 100644 --- a/linux/drivers/media/dvb/frontends/au8522.h +++ b/linux/drivers/media/dvb/frontends/au8522.h @@ -74,6 +74,22 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config, } #endif /* CONFIG_DVB_AU8522 */ +/* Other modes may need to be added later */ +enum au8522_video_input { + AU8522_COMPOSITE_CH1 = 1, + AU8522_COMPOSITE_CH2, + AU8522_COMPOSITE_CH3, + AU8522_COMPOSITE_CH4, + AU8522_COMPOSITE_CH4_SIF, + AU8522_SVIDEO_CH13, + AU8522_SVIDEO_CH24, +}; + +enum au8522_audio_input { + AU8522_AUDIO_NONE, + AU8522_AUDIO_SIF, +}; + #endif /* __AU8522_H__ */ /* diff --git a/linux/drivers/media/dvb/frontends/au8522_priv.h b/linux/drivers/media/dvb/frontends/au8522_priv.h index 98b09caa2..f328f2b3a 100644 --- a/linux/drivers/media/dvb/frontends/au8522_priv.h +++ b/linux/drivers/media/dvb/frontends/au8522_priv.h @@ -35,6 +35,7 @@ #include "tuner-i2c.h" struct au8522_state { + struct i2c_client *c; struct i2c_adapter *i2c; /* Used for sharing of the state between analog and digital mode */ @@ -51,6 +52,16 @@ struct au8522_state { u32 fe_status; unsigned int led_state; + + /* Analog settings */ + struct v4l2_subdev sd; + v4l2_std_id std; + int vid_input; + int aud_input; + u32 id; + u32 rev; + u8 brightness; + u8 contrast; }; /* These are routines shared by both the VSB/QAM demodulator and the analog @@ -63,3 +74,339 @@ int au8522_sleep(struct dvb_frontend *fe); int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, u8 client_address); void au8522_release_state(struct au8522_state *state); + +/* REGISTERS */ +#define AU8522_INPUT_CONTROL_REG081H 0x081 +#define AU8522_PGA_CONTROL_REG082H 0x082 +#define AU8522_CLAMPING_CONTROL_REG083H 0x083 + +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H 0x0A3 +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H 0x0A4 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5 +#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6 +#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7 +#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8 +#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9 +#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA +#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB +#define AU8522_TUNER_AGC_IF_START_REG0ACH 0x0AC +#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH 0x0AD +#define AU8522_TUNER_AGC_STEP_REG0AEH 0x0AE +#define AU8522_TUNER_GAIN_STEP_REG0AFH 0x0AF + +/* Receiver registers */ +#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0 +#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1 +#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2 +#define AU8522_TOREGAGC1_REG0B3H 0x0B3 +#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4 +#define AU8522_FRMREGBBH_REG0B5H 0x0B5 +#define AU8522_FRMREGBBM_REG0B6H 0x0B6 +#define AU8522_FRMREGBBL_REG0B7H 0x0B7 +/* 0xB8 TO 0xD7 are the filter coefficients */ +#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8 +#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9 +#define AU8522_TOREGAGC2_REG0DAH 0x0DA +#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB +#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC +#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD +#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE +#define AU8522_TOREGFREQ_REG0DFH 0x0DF + +#define AU8522_RX_PGA_RFOUT_REG0EBH 0x0EB +#define AU8522_RX_PGA_IFOUT_REG0ECH 0x0EC +#define AU8522_RX_PGA_PGAOUT_REG0EDH 0x0ED + +#define AU8522_CHIP_MODE_REG0FEH 0x0FE + +/* I2C bus control registers */ +#define AU8522_I2C_CONTROL_REG0_REG090H 0x090 +#define AU8522_I2C_CONTROL_REG1_REG091H 0x091 +#define AU8522_I2C_STATUS_REG092H 0x092 +#define AU8522_I2C_WR_DATA0_REG093H 0x093 +#define AU8522_I2C_WR_DATA1_REG094H 0x094 +#define AU8522_I2C_WR_DATA2_REG095H 0x095 +#define AU8522_I2C_WR_DATA3_REG096H 0x096 +#define AU8522_I2C_WR_DATA4_REG097H 0x097 +#define AU8522_I2C_WR_DATA5_REG098H 0x098 +#define AU8522_I2C_WR_DATA6_REG099H 0x099 +#define AU8522_I2C_WR_DATA7_REG09AH 0x09A +#define AU8522_I2C_RD_DATA0_REG09BH 0x09B +#define AU8522_I2C_RD_DATA1_REG09CH 0x09C +#define AU8522_I2C_RD_DATA2_REG09DH 0x09D +#define AU8522_I2C_RD_DATA3_REG09EH 0x09E +#define AU8522_I2C_RD_DATA4_REG09FH 0x09F +#define AU8522_I2C_RD_DATA5_REG0A0H 0x0A0 +#define AU8522_I2C_RD_DATA6_REG0A1H 0x0A1 +#define AU8522_I2C_RD_DATA7_REG0A2H 0x0A2 + +#define AU8522_ENA_USB_REG101H 0x101 + +#define AU8522_I2S_CTRL_0_REG110H 0x110 +#define AU8522_I2S_CTRL_1_REG111H 0x111 +#define AU8522_I2S_CTRL_2_REG112H 0x112 + +#define AU8522_FRMREGFFECONTROL_REG121H 0x121 +#define AU8522_FRMREGDFECONTROL_REG122H 0x122 + +#define AU8522_CARRFREQOFFSET0_REG201H 0x201 +#define AU8522_CARRFREQOFFSET1_REG202H 0x202 + +#define AU8522_DECIMATION_GAIN_REG21AH 0x21A +#define AU8522_FRMREGIFSLP_REG21BH 0x21B +#define AU8522_FRMREGTHRDL2_REG21CH 0x21C +#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D +#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E +#define AU8522_FRMREGPLLMODE_REG21FH 0x21F +#define AU8522_FRMREGCSTHRD_REG220H 0x220 +#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221 +#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222 +#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223 +#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224 +#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225 +#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226 +#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227 +#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228 + +/* Analog TV Decoder */ +#define AU8522_TVDEC_STATUS_REG000H 0x000 +#define AU8522_TVDEC_INT_STATUS_REG001H 0x001 +#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002 +#define AU8522_TVDEC_SHARPNESSREG009H 0x009 +#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A +#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B +#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C +#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D +#define AU8522_TVDEC_HUE_H_REG00EH 0x00E +#define AU8522_TVDEC_HUE_L_REG00FH 0x00F +#define AU8522_TVDEC_INT_MASK_REG010H 0x010 +#define AU8522_VIDEO_MODE_REG011H 0x011 +#define AU8522_TVDEC_PGA_REG012H 0x012 +#define AU8522_TVDEC_COMB_MODE_REG015H 0x015 +#define AU8522_REG016H 0x016 +#define AU8522_TVDED_DBG_MODE_REG060H 0x060 +#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061 +#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062 +#define AU8522_TVDEC_VCR_DET_LLIM_REG063H 0x063 +#define AU8522_TVDEC_VCR_DET_HLIM_REG064H 0x064 +#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H 0x065 +#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066 +#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067 +#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068 +#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069 +#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A +#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B +#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C +#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D +#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E +#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F +#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070 +#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073 +#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077 +#define AU8522_TVDEC_PIC_START_ADJ_REG078H 0x078 +#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H 0x079 +#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH 0x07A +#define AU8522_TVDEC_INTRP_CTRL_REG07BH 0x07B +#define AU8522_TVDEC_PLL_STATUS_REG07EH 0x07E +#define AU8522_TVDEC_FSC_FREQ_REG07FH 0x07F + +#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H 0x0E4 +#define AU8522_TOREGAAGC_REG0E5H 0x0E5 + +#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401 +#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402 +#define AU8522_FILTER_COEF_R410 0x410 +#define AU8522_FILTER_COEF_R411 0x411 +#define AU8522_FILTER_COEF_R412 0x412 +#define AU8522_FILTER_COEF_R413 0x413 +#define AU8522_FILTER_COEF_R414 0x414 +#define AU8522_FILTER_COEF_R415 0x415 +#define AU8522_FILTER_COEF_R416 0x416 +#define AU8522_FILTER_COEF_R417 0x417 +#define AU8522_FILTER_COEF_R418 0x418 +#define AU8522_FILTER_COEF_R419 0x419 +#define AU8522_FILTER_COEF_R41A 0x41A +#define AU8522_FILTER_COEF_R41B 0x41B +#define AU8522_FILTER_COEF_R41C 0x41C +#define AU8522_FILTER_COEF_R41D 0x41D +#define AU8522_FILTER_COEF_R41E 0x41E +#define AU8522_FILTER_COEF_R41F 0x41F +#define AU8522_FILTER_COEF_R420 0x420 +#define AU8522_FILTER_COEF_R421 0x421 +#define AU8522_FILTER_COEF_R422 0x422 +#define AU8522_FILTER_COEF_R423 0x423 +#define AU8522_FILTER_COEF_R424 0x424 +#define AU8522_FILTER_COEF_R425 0x425 +#define AU8522_FILTER_COEF_R426 0x426 +#define AU8522_FILTER_COEF_R427 0x427 +#define AU8522_FILTER_COEF_R428 0x428 +#define AU8522_FILTER_COEF_R429 0x429 +#define AU8522_FILTER_COEF_R42A 0x42A +#define AU8522_FILTER_COEF_R42B 0x42B +#define AU8522_FILTER_COEF_R42C 0x42C +#define AU8522_FILTER_COEF_R42D 0x42D + +/* VBI Control Registers */ +#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004 +#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005 +#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006 +#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007 +#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017 +#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018 +#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019 +#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH 0x01A +#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B +#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C +#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E +#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F +#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020 +#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021 +#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022 +#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023 + +#define AU8522_REG071H 0x071 +#define AU8522_REG072H 0x072 +#define AU8522_REG074H 0x074 +#define AU8522_REG075H 0x075 + +/* Digital Demodulator Registers */ +#define AU8522_FRAME_COUNT0_REG084H 0x084 +#define AU8522_RS_STATUS_G0_REG085H 0x085 +#define AU8522_RS_STATUS_B0_REG086H 0x086 +#define AU8522_RS_STATUS_E_REG087H 0x087 +#define AU8522_DEMODULATION_STATUS_REG088H 0x088 +#define AU8522_TOREGTRESTATUS_REG0E6H 0x0E6 +#define AU8522_TSPORT_CONTROL_REG10BH 0x10B +#define AU8522_TSTHES_REG10CH 0x10C +#define AU8522_FRMREGDFEKEEP_REG301H 0x301 +#define AU8522_DFE_AVERAGE_REG302H 0x302 +#define AU8522_FRMREGEQLERRWIN_REG303H 0x303 +#define AU8522_FRMREGFFEKEEP_REG304H 0x304 +#define AU8522_FRMREGDFECONTROL1_REG305H 0x305 +#define AU8522_FRMREGEQLERRLOW_REG306H 0x306 + +#define AU8522_REG42EH 0x42E +#define AU8522_REG42FH 0x42F +#define AU8522_REG430H 0x430 +#define AU8522_REG431H 0x431 +#define AU8522_REG432H 0x432 +#define AU8522_REG433H 0x433 +#define AU8522_REG434H 0x434 +#define AU8522_REG435H 0x435 +#define AU8522_REG436H 0x436 + +/* GPIO Registers */ +#define AU8522_GPIO_CONTROL_REG0E0H 0x0E0 +#define AU8522_GPIO_STATUS_REG0E1H 0x0E1 +#define AU8522_GPIO_DATA_REG0E2H 0x0E2 + +/* Audio Control Registers */ +#define AU8522_AUDIOAGC_REG0EEH 0x0EE +#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0 +#define AU8522_AUDIO_MODE_REG0F1H 0x0F1 +#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2 +#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3 +#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4 +#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7 +#define AU8522_REG0F9H 0x0F9 + +#define AU8522_AUDIOAGC2_REG605H 0x605 +#define AU8522_AUDIOFREQ_REG606H 0x606 + + +/**************************************************************/ + +#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28 +/* CH1 AS Y,CH3 AS C */ +#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23 +/* CH2 AS Y,CH4 AS C */ +#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02 + +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00 +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8 +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD + +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01 + +/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */ +#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS 0x79 +#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS 0x80 +#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS 0x80 +#define AU8522_TVDEC_HUE_H_REG00EH_CVBS 0x00 +#define AU8522_TVDEC_HUE_L_REG00FH_CVBS 0x00 +#define AU8522_TVDEC_PGA_REG012H_CVBS 0x0F +#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00 +#define AU8522_REG016H_CVBS 0x00 +#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00 +#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B +#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03 +#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00 +#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19 +#define AU8522_REG0F9H_AUDIO 0x20 +#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7 +#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS 0x0A +#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS 0x32 +#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS 0x19 +#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS 0x23 +#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS 0x41 +#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A +#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32 +#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34 +#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05 +#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E +#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F +#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80 +#define AU8522_REG071H_CVBS 0x18 +#define AU8522_REG072H_CVBS 0x30 +#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS 0xF0 +#define AU8522_REG074H_CVBS 0x80 +#define AU8522_REG075H_CVBS 0xF0 +#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS 0xFB +#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS 0x04 +#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS 0x00 +#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS 0x00 +#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS 0xEE +#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS 0xFE +#define AU8522_TOREGAAGC_REG0E5H_CVBS 0x00 +#define AU8522_TVDEC_VBI6A_REG035H_CVBS 0x40 + +/* Enables Closed captioning */ +#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON 0x21 -- cgit v1.2.3 From 7f62cf2d7360ac3b7f2fac64950706a588db8977 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:00:45 -0400 Subject: au8522: add mutex protecting use of hybrid state From: Devin Heitmueller Access using the hybrid state framework requires the list to be protected by a mutex. Thanks to Michael Krufky for reporting this during a code review. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/au8522_dig.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c index 00d783ce2..27e2e0730 100644 --- a/linux/drivers/media/dvb/frontends/au8522_dig.c +++ b/linux/drivers/media/dvb/frontends/au8522_dig.c @@ -34,6 +34,7 @@ static int debug; /* Despite the name "hybrid_tuner", the framework works just as well for hybrid demodulators as well... */ static LIST_HEAD(hybrid_tuner_instance_list); +static DEFINE_MUTEX(au8522_list_mutex); #define dprintk(arg...) do { \ if (debug) \ @@ -795,15 +796,23 @@ static struct dvb_frontend_ops au8522_ops; int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, u8 client_address) { - return hybrid_tuner_request_state(struct au8522_state, (*state), - hybrid_tuner_instance_list, - i2c, client_address, "au8522"); + int ret; + + mutex_lock(&au8522_list_mutex); + ret = hybrid_tuner_request_state(struct au8522_state, (*state), + hybrid_tuner_instance_list, + i2c, client_address, "au8522"); + mutex_unlock(&au8522_list_mutex); + + return ret; } void au8522_release_state(struct au8522_state *state) { + mutex_lock(&au8522_list_mutex); if (state != NULL) hybrid_tuner_release_state(state); + mutex_unlock(&au8522_list_mutex); } -- cgit v1.2.3 From 60202da763db2446be57359a18882470715e68f8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 11 Mar 2009 22:29:19 +0100 Subject: fired-avc: fix printk formatting warning. From: Hans Verkuil size_t should be printed with %zu. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/firewire/firedtv-avc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/firewire/firedtv-avc.c b/linux/drivers/media/dvb/firewire/firedtv-avc.c index b55d9ccaf..af8fdf706 100644 --- a/linux/drivers/media/dvb/firewire/firedtv-avc.c +++ b/linux/drivers/media/dvb/firewire/firedtv-avc.c @@ -150,7 +150,7 @@ static void debug_fcp(const u8 *data, size_t length) subunit_type = data[1] >> 3; subunit_id = data[1] & 7; op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2]; - printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n", + printk(KERN_INFO "%ssu=%x.%x l=%zu: %-8s - %s\n", prefix, subunit_type, subunit_id, length, debug_fcp_ctype(data[0]), debug_fcp_opcode(op, data, length)); -- cgit v1.2.3 From a9f7a944fa810879c33504a9081eaaafd3fe305e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 11 Mar 2009 22:48:33 +0100 Subject: fired-avc: fix print_hex_dump warning on 2.6.22. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/firewire/firedtv-avc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/firewire/firedtv-avc.c b/linux/drivers/media/dvb/firewire/firedtv-avc.c index af8fdf706..d8dae2599 100644 --- a/linux/drivers/media/dvb/firewire/firedtv-avc.c +++ b/linux/drivers/media/dvb/firewire/firedtv-avc.c @@ -157,8 +157,13 @@ static void debug_fcp(const u8 *data, size_t length) } if (avc_debug & AVC_DEBUG_FCP_PAYLOADS) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22) print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1, data, length, false); +#else + print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1, + (void *)data, length, false); +#endif } static int __avc_write(struct firedtv *fdtv, -- cgit v1.2.3 From 9731acdee8858e02b65a411ba6bd7050540b4c27 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 26 Mar 2009 12:26:48 -0300 Subject: ce6230: avoid using unitialized var MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Mauro Carvalho Chehab drivers/media/dvb/dvb-usb/ce6230.c: In function ‘ce6230_i2c_xfer’: drivers/media/dvb/dvb-usb/ce6230.c:107: warning: ‘ret’ may be used uninitialized in this function Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/ce6230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/ce6230.c b/linux/drivers/media/dvb/dvb-usb/ce6230.c index 2a959c4bd..1682af62f 100644 --- a/linux/drivers/media/dvb/dvb-usb/ce6230.c +++ b/linux/drivers/media/dvb/dvb-usb/ce6230.c @@ -104,7 +104,7 @@ static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], struct dvb_usb_device *d = i2c_get_adapdata(adap); int i = 0; struct req_t req; - int ret; + int ret = 0; memset(&req, 0, sizeof(&req)); if (num > 2) -- cgit v1.2.3 From 9a161310d7fbbc285576a6d822bbcdf93744e836 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 24 Mar 2009 21:12:47 +0000 Subject: changed ioctls to unlocked From: Stoyan Gaydarov Signed-off-by: Stoyan Gaydarov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/bt8xx/dst_ca.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/bt8xx/dst_ca.c b/linux/drivers/media/dvb/bt8xx/dst_ca.c index 68aef6786..e71c269c1 100644 --- a/linux/drivers/media/dvb/bt8xx/dst_ca.c +++ b/linux/drivers/media/dvb/bt8xx/dst_ca.c @@ -648,8 +648,10 @@ free_mem_and_exit: return result; } -static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg) +static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg) { + lock_kernel(); + struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; struct dst_state* state = (struct dst_state*) dvbdev->priv; struct ca_slot_info *p_ca_slot_info; @@ -743,6 +745,7 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd kfree (p_ca_slot_info); kfree (p_ca_caps); + unlock_kernel(); return result; } @@ -780,7 +783,7 @@ static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t static const struct file_operations dst_ca_fops = { .owner = THIS_MODULE, - .ioctl = dst_ca_ioctl, + .unlocked_ioctl = dst_ca_ioctl, .open = dst_ca_open, .release = dst_ca_release, .read = dst_ca_read, -- cgit v1.2.3 From 86948a72d224082ef87b1a46b9bc7ce3292e1003 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 25 Mar 2009 20:53:02 +0000 Subject: tda827x: fix locking issues with DVB-C From: klaas de waal Separate tuning table for DVB-C solves tuning problem at 388MHz TechnoTrend C-1501 DVB-C card does not lock on 388MHz. I assume that existing frequency table is valid for DVB-T. This is suggested by the name of the table: tda827xa_dvbt. Added a table for DVB-C with the name tda827xa_dvbc. Added runtime selection of the DVB-C table when the tuner is type FE_QAM. This should leave the behaviour of this driver with with DVB_T tuners unchanged. This modification is in file tda827x.c The tda827x.c gives the following warning message when debug=1: tda827x: tda827x_config not defined, cannot set LNA gain! Solved this by adding a tda827x_config struct in budget-ci.c. Priority: normal Signed-off-by: Klaas de Waal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/ttpci/budget-ci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 99fcb55d5..1b564eb79 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -1084,6 +1084,10 @@ static struct tda10023_config tda10023_config = { .deltaf = 0xa511, }; +static struct tda827x_config tda827x_config = { + .config = 0, +}; + /* TT S2-3200 DVB-S (STB0899) Inittab */ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { @@ -1422,7 +1426,7 @@ static void frontend_init(struct budget_ci *budget_ci) case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */ budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48); if (budget_ci->budget.dvb_frontend) { - if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) { + if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) { printk(KERN_ERR "%s: No tda827x found!\n", __func__); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; -- cgit v1.2.3 From 6716df924ee6f2791b1939b04028f01dd37a9e9e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 12 Mar 2009 09:12:16 -0400 Subject: lgdt3305: avoid OOPS in error path of lgdt3305_attach From: Michael Krufky Setting state->frontend.demodulator_priv to NULL in the event of a kzalloc error will result in an OOPS. Just remove that line. Thanks to Matthias Schwarzott for pointing this out. Priority: normal Signed-off-by: Michael Krufky Cc: Matthias Schwarzott --- linux/drivers/media/dvb/frontends/lgdt3305.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgdt3305.c b/linux/drivers/media/dvb/frontends/lgdt3305.c index 8d62d1257..f0c0c8199 100644 --- a/linux/drivers/media/dvb/frontends/lgdt3305.c +++ b/linux/drivers/media/dvb/frontends/lgdt3305.c @@ -1075,7 +1075,6 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, return &state->frontend; fail: lg_warn("unable to detect LGDT3305 hardware\n"); - state->frontend.demodulator_priv = NULL; kfree(state); return NULL; } -- cgit v1.2.3 From c5b41e23cfa080a22b48bdf0e6e2a8028f340a70 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Mar 2009 16:36:54 +0100 Subject: bttv: convert to v4l2_device. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c index c4b8b0677..08c63014c 100644 --- a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -815,7 +815,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) mutex_init(&card->lock); card->bttv_nr = sub->core->nr; - strncpy(card->card_name, sub->core->name, sizeof(sub->core->name)); + strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name)); card->i2c_adapter = &sub->core->i2c_adap; switch(sub->core->type) { -- cgit v1.2.3 From 69bcabeaf801c5c21c31e534501c8b77769944b7 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 15 Mar 2009 13:28:45 +0300 Subject: Shorten some lines in stv0900 to less then 81 characters From: Igor M. Liplianin Signed-off-by: Igor M. Liplianin --- linux/drivers/media/dvb/frontends/stv0900_core.c | 41 ++++++++++++++++-------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv0900_core.c b/linux/drivers/media/dvb/frontends/stv0900_core.c index 1fde0e255..0cd313cd0 100644 --- a/linux/drivers/media/dvb/frontends/stv0900_core.c +++ b/linux/drivers/media/dvb/frontends/stv0900_core.c @@ -660,13 +660,18 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, dprintk(KERN_INFO "%s\n", __func__); - dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); + dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF, + F0900_P2_LOCK_DEFINITIF); if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { - dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1, F0900_P2_NOSPLHT_NORMED1); - dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0, F0900_P2_NOSPLHT_NORMED0); + dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1, + F0900_P2_NOSPLHT_NORMED1); + dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0, + F0900_P2_NOSPLHT_NORMED0); } else { - dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, F0900_P2_NOSDATAT_NORMED1); - dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, F0900_P1_NOSDATAT_NORMED0); + dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, + F0900_P2_NOSDATAT_NORMED1); + dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, + F0900_P1_NOSDATAT_NORMED0); } if (stv0900_get_bits(i_params, lock_flag_field)) { @@ -674,27 +679,34 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, regval = 0; msleep(5); for (i = 0; i < 16; i++) { - regval += MAKEWORD(stv0900_get_bits(i_params, noise_field1), - stv0900_get_bits(i_params, noise_field0)); + regval += MAKEWORD(stv0900_get_bits(i_params, + noise_field1), + stv0900_get_bits(i_params, + noise_field0)); msleep(1); } regval /= 16; imin = 0; imax = lookup->size - 1; - if (INRANGE(lookup->table[imin].regval, regval, lookup->table[imax].regval)) { + if (INRANGE(lookup->table[imin].regval, + regval, + lookup->table[imax].regval)) { while ((imax - imin) > 1) { i = (imax + imin) >> 1; - - if (INRANGE(lookup->table[imin].regval, regval, lookup->table[i].regval)) + if (INRANGE(lookup->table[imin].regval, + regval, + lookup->table[i].regval)) imax = i; else imin = i; } c_n = ((regval - lookup->table[imin].regval) - * (lookup->table[imax].realval - lookup->table[imin].realval) - / (lookup->table[imax].regval - lookup->table[imin].regval)) + * (lookup->table[imax].realval + - lookup->table[imin].realval) + / (lookup->table[imax].regval + - lookup->table[imin].regval)) + lookup->table[imin].realval; } else if (regval < lookup->table[imin].regval) c_n = 1000; @@ -706,7 +718,10 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) { - *snr = (16383 / 1030) * (30 + stv0900_carr_get_quality(fe, (const struct stv0900_table *)&stv0900_s2_cn)); + *snr = stv0900_carr_get_quality(fe, + (const struct stv0900_table *)&stv0900_s2_cn); + *snr += 30; + *snr *= (16383 / 1030); return 0; } -- cgit v1.2.3 From aebdd9e3f65e084f513eea41a8b37444f4e99cc6 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 15 Mar 2009 13:31:45 +0300 Subject: Fix typo in stv0900 From: Igor M. Liplianin Signed-off-by: Igor M. Liplianin --- linux/drivers/media/dvb/frontends/stv0900_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv0900_core.c b/linux/drivers/media/dvb/frontends/stv0900_core.c index 0cd313cd0..67cce764f 100644 --- a/linux/drivers/media/dvb/frontends/stv0900_core.c +++ b/linux/drivers/media/dvb/frontends/stv0900_core.c @@ -671,7 +671,7 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, F0900_P2_NOSDATAT_NORMED1); dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, - F0900_P1_NOSDATAT_NORMED0); + F0900_P2_NOSDATAT_NORMED0); } if (stv0900_get_bits(i_params, lock_flag_field)) { -- cgit v1.2.3 From 3381b31112a4b0a5321384bf4e339bc12a103731 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 15 Mar 2009 17:48:52 -0400 Subject: au0828/au8522: Codingstyle fixes From: Devin Heitmueller Take a pass over all of the au0828/au8522 files and cleanup all the codingstyle issues. This patch does not make *any* functional change to the code. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/frontends/au8522_dig.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c index 27e2e0730..41aedcc99 100644 --- a/linux/drivers/media/dvb/frontends/au8522_dig.c +++ b/linux/drivers/media/dvb/frontends/au8522_dig.c @@ -36,16 +36,16 @@ static int debug; static LIST_HEAD(hybrid_tuner_instance_list); static DEFINE_MUTEX(au8522_list_mutex); -#define dprintk(arg...) do { \ - if (debug) \ - printk(arg); \ +#define dprintk(arg...)\ + do { if (debug)\ + printk(arg);\ } while (0) /* 16 bit registers, 8 bit values */ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) { int ret; - u8 buf [] = { (reg >> 8) | 0x80, reg & 0xff, data }; + u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; @@ -62,10 +62,10 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) u8 au8522_readreg(struct au8522_state *state, u16 reg) { int ret; - u8 b0 [] = { (reg >> 8) | 0x40, reg & 0xff }; - u8 b1 [] = { 0 }; + u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff }; + u8 b1[] = { 0 }; - struct i2c_msg msg [] = { + struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, { .addr = state->config->demod_address, .flags = I2C_M_RD, -- cgit v1.2.3 From e349a2e984faf451597ceea0fc7e1ffb077314d8 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 15 Mar 2009 18:04:45 -0400 Subject: au8522: move the analog decoder source file From: Devin Heitmueller As Mauro pointed out, for a given driver you cannot have one file in media/video and another in dvb/frontends. Until we have a better scheme for managing the source tree in terms of a single chip that has both a digital demod and an analog demod, make sure both files reside in the dvb/frontends dir. This patch is strictly a file move - there are no changes to the file itself. This change was required so that the code works in the mainline kernel (without it the code only compiles in the out-of-tree v4l-dvb branch). Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/frontends/au8522_decoder.c | 850 +++++++++++++++++++++ 1 file changed, 850 insertions(+) create mode 100644 linux/drivers/media/dvb/frontends/au8522_decoder.c (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_decoder.c b/linux/drivers/media/dvb/frontends/au8522_decoder.c new file mode 100644 index 000000000..b4a205809 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/au8522_decoder.c @@ -0,0 +1,850 @@ +/* + * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder + * + * Copyright (C) 2009 Devin Heitmueller + * Copyright (C) 2005-2008 Auvitek International, Ltd. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/* Developer notes: + * + * VBI support is not yet working + * Saturation and hue setting are not yet working + * Enough is implemented here for CVBS and S-Video inputs, but the actual + * analog demodulator code isn't implemented (not needed for xc5000 since it + * has its own demodulator and outputs CVBS) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "compat.h" +#include "au8522.h" +#include "au8522_priv.h" + +MODULE_AUTHOR("Devin Heitmueller"); +MODULE_LICENSE("GPL"); + +static int au8522_analog_debug; + +static unsigned short normal_i2c[] = { 0x8e >> 1, I2C_CLIENT_END }; + +module_param_named(analog_debug, au8522_analog_debug, int, 0644); + +MODULE_PARM_DESC(analog_debug, + "Analog debugging messages [0=Off (default) 1=On]"); + +I2C_CLIENT_INSMOD; + +struct au8522_register_config { + u16 reg_name; + u8 reg_val[8]; +}; + + +/* Video Decoder Filter Coefficients + The values are as follows from left to right + 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13" +*/ +struct au8522_register_config filter_coef[] = { + {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} }, + {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} }, + {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} }, + {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} }, + {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} }, + {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} }, + {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} }, + {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} }, + {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} }, + {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} }, + {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} }, + {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} }, + {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} }, + {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} }, + {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} }, + {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} }, + {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} }, + {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} }, + {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} }, + {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} }, + {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} }, + +}; +#define NUM_FILTER_COEF (sizeof(filter_coef)\ + / sizeof(struct au8522_register_config)) + + +/* Registers 0x060b through 0x0652 are the LP Filter coefficients + The values are as follows from left to right + 0="SIF" 1="ATVRF/ATVRF13" + Note: the "ATVRF/ATVRF13" mode has never been tested +*/ +struct au8522_register_config lpfilter_coef[] = { + {0x060b, {0x21, 0x0b} }, + {0x060c, {0xad, 0xad} }, + {0x060d, {0x70, 0xf0} }, + {0x060e, {0xea, 0xe9} }, + {0x060f, {0xdd, 0xdd} }, + {0x0610, {0x08, 0x64} }, + {0x0611, {0x60, 0x60} }, + {0x0612, {0xf8, 0xb2} }, + {0x0613, {0x01, 0x02} }, + {0x0614, {0xe4, 0xb4} }, + {0x0615, {0x19, 0x02} }, + {0x0616, {0xae, 0x2e} }, + {0x0617, {0xee, 0xc5} }, + {0x0618, {0x56, 0x56} }, + {0x0619, {0x30, 0x58} }, + {0x061a, {0xf9, 0xf8} }, + {0x061b, {0x24, 0x64} }, + {0x061c, {0x07, 0x07} }, + {0x061d, {0x30, 0x30} }, + {0x061e, {0xa9, 0xed} }, + {0x061f, {0x09, 0x0b} }, + {0x0620, {0x42, 0xc2} }, + {0x0621, {0x1d, 0x2a} }, + {0x0622, {0xd6, 0x56} }, + {0x0623, {0x95, 0x8b} }, + {0x0624, {0x2b, 0x2b} }, + {0x0625, {0x30, 0x24} }, + {0x0626, {0x3e, 0x3e} }, + {0x0627, {0x62, 0xe2} }, + {0x0628, {0xe9, 0xf5} }, + {0x0629, {0x99, 0x19} }, + {0x062a, {0xd4, 0x11} }, + {0x062b, {0x03, 0x04} }, + {0x062c, {0xb5, 0x85} }, + {0x062d, {0x1e, 0x20} }, + {0x062e, {0x2a, 0xea} }, + {0x062f, {0xd7, 0xd2} }, + {0x0630, {0x15, 0x15} }, + {0x0631, {0xa3, 0xa9} }, + {0x0632, {0x1f, 0x1f} }, + {0x0633, {0xf9, 0xd1} }, + {0x0634, {0xc0, 0xc3} }, + {0x0635, {0x4d, 0x8d} }, + {0x0636, {0x21, 0x31} }, + {0x0637, {0x83, 0x83} }, + {0x0638, {0x08, 0x8c} }, + {0x0639, {0x19, 0x19} }, + {0x063a, {0x45, 0xa5} }, + {0x063b, {0xef, 0xec} }, + {0x063c, {0x8a, 0x8a} }, + {0x063d, {0xf4, 0xf6} }, + {0x063e, {0x8f, 0x8f} }, + {0x063f, {0x44, 0x0c} }, + {0x0640, {0xef, 0xf0} }, + {0x0641, {0x66, 0x66} }, + {0x0642, {0xcc, 0xd2} }, + {0x0643, {0x41, 0x41} }, + {0x0644, {0x63, 0x93} }, + {0x0645, {0x8e, 0x8e} }, + {0x0646, {0xa2, 0x42} }, + {0x0647, {0x7b, 0x7b} }, + {0x0648, {0x04, 0x04} }, + {0x0649, {0x00, 0x00} }, + {0x064a, {0x40, 0x40} }, + {0x064b, {0x8c, 0x98} }, + {0x064c, {0x00, 0x00} }, + {0x064d, {0x63, 0xc3} }, + {0x064e, {0x04, 0x04} }, + {0x064f, {0x20, 0x20} }, + {0x0650, {0x00, 0x00} }, + {0x0651, {0x40, 0x40} }, + {0x0652, {0x01, 0x01} }, +}; +#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\ + / sizeof(struct au8522_register_config)) + +static inline struct au8522_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct au8522_state, sd); +} + +static void setup_vbi(struct au8522_state *state, int aud_input) +{ + int i; + + /* These are set to zero regardless of what mode we're in */ + au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H, + 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H, + 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H, + 0x00); + + /* Setup the VBI registers */ + for (i = 0x30; i < 0x60; i++) + au8522_writereg(state, i, 0x40); + + /* For some reason, every register is 0x40 except register 0x44 + (confirmed via the HVR-950q USB capture) */ + au8522_writereg(state, 0x44, 0x60); + + /* Enable VBI (we always do this regardless of whether the user is + viewing closed caption info) */ + au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, + AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON); + +} + +static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) +{ + int i; + int filter_coef_type; + + /* Provide reasonable defaults for picture tuning values */ + au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07); + au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed); + state->brightness = 0xed - 128; + au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79); + state->contrast = 0x79; + au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80); + au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80); + au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00); + au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00); + + /* Other decoder registers */ + au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00); + + if (input_mode == 0x23) { + /* S-Video input mapping */ + au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04); + } else { + /* All other modes (CVBS/ATVRF etc.) */ + au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00); + } + + au8522_writereg(state, AU8522_TVDEC_PGA_REG012H, + AU8522_TVDEC_PGA_REG012H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H, + AU8522_TVDEC_COMB_MODE_REG015H_CVBS); + au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H, + AU8522_TVDED_DBG_MODE_REG060H_CVBS); + au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H, + AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13); + au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H, + AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13); + au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H, + AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS); + au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H, + AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H, + AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H, + AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H, + AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H, + AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H, + AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH, + AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH, + AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH, + AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH, + AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH, + AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS); + au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH, + AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H, + AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS); + au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS); + au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H, + AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS); + au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS); + au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS); + au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H, + AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS); + au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H, + AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS); + au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H, + AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS); + au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH, + AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS); + au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH, + AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS); + au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H, + AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS); + au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H, + AU8522_TOREGAAGC_REG0E5H_CVBS); + au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS); + + setup_vbi(state, 0); + + if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 || + input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) { + /* Despite what the table says, for the HVR-950q we still need + to be in CVBS mode for the S-Video input (reason uknown). */ + /* filter_coef_type = 3; */ + filter_coef_type = 5; + } else { + filter_coef_type = 5; + } + + /* Load the Video Decoder Filter Coefficients */ + for (i = 0; i < NUM_FILTER_COEF; i++) { + au8522_writereg(state, filter_coef[i].reg_name, + filter_coef[i].reg_val[filter_coef_type]); + } + + /* It's not clear what these registers are for, but they are always + set to the same value regardless of what mode we're in */ + au8522_writereg(state, AU8522_REG42EH, 0x87); + au8522_writereg(state, AU8522_REG42FH, 0xa2); + au8522_writereg(state, AU8522_REG430H, 0xbf); + au8522_writereg(state, AU8522_REG431H, 0xcb); + au8522_writereg(state, AU8522_REG432H, 0xa1); + au8522_writereg(state, AU8522_REG433H, 0x41); + au8522_writereg(state, AU8522_REG434H, 0x88); + au8522_writereg(state, AU8522_REG435H, 0xc2); + au8522_writereg(state, AU8522_REG436H, 0x3c); +} + +static void au8522_setup_cvbs_mode(struct au8522_state *state) +{ + /* here we're going to try the pre-programmed route */ + au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, + AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS); + + au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00); + au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e); + au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10); + + au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, + AU8522_INPUT_CONTROL_REG081H_CVBS_CH1); + + setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); +} + +static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state) +{ + /* here we're going to try the pre-programmed route */ + au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, + AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS); + + /* It's not clear why they turn off the PGA before enabling the clamp + control, but the Windows trace does it so we will too... */ + au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00); + + /* Enable clamping control */ + au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e); + + /* Turn on the PGA */ + au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10); + + /* Set input mode to CVBS on channel 4 with SIF audio input enabled */ + au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, + AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF); + + setup_decoder_defaults(state, + AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); +} + +static void au8522_setup_svideo_mode(struct au8522_state *state) +{ + au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, + AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO); + + /* Set input to Y on Channe1, C on Channel 3 */ + au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, + AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13); + + /* Disable clamping control (required for S-video) */ + au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00); + + setup_decoder_defaults(state, + AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); +} + +/* ----------------------------------------------------------------------- */ + +static void disable_audio_input(struct au8522_state *state) +{ + /* This can probably be optimized */ + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00); + au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80); + au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84); + + au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); + au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO); + au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40); + + au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11); + msleep(5); + au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04); + au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03); + au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); +} + +/* 0=disable, 1=SIF */ +static void set_audio_input(struct au8522_state *state, int aud_input) +{ + int i; + + /* Note that this function needs to be used in conjunction with setting + the input routing via register 0x81 */ + + if (aud_input == AU8522_AUDIO_NONE) { + disable_audio_input(state); + return; + } + + if (aud_input != AU8522_AUDIO_SIF) { + /* The caller asked for a mode we don't currently support */ + printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n", + aud_input); + return; + } + + /* Load the Audio Decoder Filter Coefficients */ + for (i = 0; i < NUM_LPFILTER_COEF; i++) { + au8522_writereg(state, lpfilter_coef[i].reg_name, + lpfilter_coef[i].reg_val[0]); + } + + /* Setup audio */ + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00); + au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80); + au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84); + msleep(150); + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00); + msleep(1); + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d); + msleep(50); + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); + au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff); + msleep(80); + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); + au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO); + au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82); + msleep(70); + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09); + au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03); + au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2); +} + +/* ----------------------------------------------------------------------- */ + +static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct au8522_state *state = to_state(sd); + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + state->brightness = ctrl->value; + au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, + ctrl->value - 128); + break; + case V4L2_CID_CONTRAST: + state->contrast = ctrl->value; + au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, + ctrl->value); + break; + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + case V4L2_CID_AUDIO_VOLUME: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_MUTE: + /* Not yet implemented */ + default: + return -EINVAL; + } + + return 0; +} + +static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct au8522_state *state = to_state(sd); + + /* Note that we are using values cached in the state structure instead + of reading the registers due to issues with i2c reads not working + properly/consistently yet on the HVR-950q */ + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = state->brightness; + break; + case V4L2_CID_CONTRAST: + ctrl->value = state->contrast; + break; + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + case V4L2_CID_AUDIO_VOLUME: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_MUTE: + /* Not yet supported */ + default: + return -EINVAL; + } + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + switch (fmt->type) { + default: + return -EINVAL; + } + return 0; +} + +static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + switch (fmt->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + /* Not yet implemented */ + break; + default: + return -EINVAL; + } + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int au8522_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct au8522_state *state = to_state(sd); + + if (!v4l2_chip_match_i2c_client(client, ®->match)) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + reg->val = au8522_readreg(state, reg->reg & 0xffff); + return 0; +} + +static int au8522_s_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct au8522_state *state = to_state(sd); + + if (!v4l2_chip_match_i2c_client(client, ®->match)) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + au8522_writereg(state, reg->reg, reg->val & 0xff); + return 0; +} +#endif + +static int au8522_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct au8522_state *state = to_state(sd); + + if (enable) { + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + 0x01); + msleep(1); + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); + } else { + /* This does not completely power down the device + (it only reduces it from around 140ma to 80ma) */ + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + 1 << 5); + } + return 0; +} + +static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) +{ + switch (qc->id) { + case V4L2_CID_CONTRAST: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, + AU8522_TVDEC_CONTRAST_REG00BH_CVBS); + case V4L2_CID_BRIGHTNESS: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + /* Not yet implemented */ + default: + break; + } + + qc->type = 0; + return -EINVAL; +} + +static int au8522_reset(struct v4l2_subdev *sd, u32 val) +{ + struct au8522_state *state = to_state(sd); + + au8522_writereg(state, 0xa4, 1 << 5); + + return 0; +} + +static int au8522_s_video_routing(struct v4l2_subdev *sd, + const struct v4l2_routing *route) +{ + struct au8522_state *state = to_state(sd); + + au8522_reset(sd, 0); + + /* Jam open the i2c gate to the tuner. We do this here to handle the + case where the user went into digital mode (causing the gate to be + closed), and then came back to analog mode */ + au8522_writereg(state, 0x106, 1); + + if (route->input == AU8522_COMPOSITE_CH1) { + au8522_setup_cvbs_mode(state); + } else if (route->input == AU8522_SVIDEO_CH13) { + au8522_setup_svideo_mode(state); + } else if (route->input == AU8522_COMPOSITE_CH4_SIF) { + au8522_setup_cvbs_tuner_mode(state); + } else { + printk(KERN_ERR "au8522 mode not currently supported\n"); + return -EINVAL; + } + return 0; +} + +static int au8522_s_audio_routing(struct v4l2_subdev *sd, + const struct v4l2_routing *route) +{ + struct au8522_state *state = to_state(sd); + set_audio_input(state, route->input); + return 0; +} + +static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) +{ + int val = 0; + struct au8522_state *state = to_state(sd); + u8 lock_status; + + /* Interrogate the decoder to see if we are getting a real signal */ + lock_status = au8522_readreg(state, 0x00); + if (lock_status == 0xa2) + vt->signal = 0x01; + else + vt->signal = 0x00; + + vt->capability |= + V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | + V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + + val = V4L2_TUNER_SUB_MONO; + vt->rxsubchans = val; + vt->audmode = V4L2_TUNER_MODE_STEREO; + return 0; +} + +static int au8522_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct au8522_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev); +} + +static int au8522_log_status(struct v4l2_subdev *sd) +{ + /* FIXME: Add some status info here */ + return 0; +} + +static int au8522_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_subdev_core_ops au8522_core_ops = { + .log_status = au8522_log_status, + .g_chip_ident = au8522_g_chip_ident, + .g_ctrl = au8522_g_ctrl, + .s_ctrl = au8522_s_ctrl, + .queryctrl = au8522_queryctrl, + .reset = au8522_reset, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = au8522_g_register, + .s_register = au8522_s_register, +#endif +}; + +static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = { + .g_tuner = au8522_g_tuner, +}; + +static const struct v4l2_subdev_audio_ops au8522_audio_ops = { + .s_routing = au8522_s_audio_routing, +}; + +static const struct v4l2_subdev_video_ops au8522_video_ops = { + .s_routing = au8522_s_video_routing, + .g_fmt = au8522_g_fmt, + .s_fmt = au8522_s_fmt, + .s_stream = au8522_s_stream, +}; + +static const struct v4l2_subdev_ops au8522_ops = { + .core = &au8522_core_ops, + .tuner = &au8522_tuner_ops, + .audio = &au8522_audio_ops, + .video = &au8522_video_ops, +}; + +/* ----------------------------------------------------------------------- */ + +static int au8522_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct au8522_state *state; + struct v4l2_subdev *sd; + int instance; + struct au8522_config *demod_config; + + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + return -EIO; + } + + /* allocate memory for the internal state */ + instance = au8522_get_state(&state, client->adapter, client->addr); + switch (instance) { + case 0: + printk(KERN_ERR "au8522_decoder allocation failed\n"); + return -EIO; + case 1: + /* new demod instance */ + printk(KERN_INFO "au8522_decoder creating new instance...\n"); + break; + default: + /* existing demod instance */ + printk(KERN_INFO "au8522_decoder attach existing instance.\n"); + break; + } + + demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL); + demod_config->demod_address = 0x8e >> 1; + + state->config = demod_config; + state->i2c = client->adapter; + + sd = &state->sd; + v4l2_i2c_subdev_init(sd, client, &au8522_ops); + + state->c = client; + state->vid_input = AU8522_COMPOSITE_CH1; + state->aud_input = AU8522_AUDIO_NONE; + state->id = 8522; + state->rev = 0; + + /* Jam open the i2c gate to the tuner */ + au8522_writereg(state, 0x106, 1); + + return 0; +} + +static int au8522_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + v4l2_device_unregister_subdev(sd); + au8522_release_state(to_state(sd)); + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id au8522_id[] = { + {"au8522", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, au8522_id); + +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "au8522", + .driverid = I2C_DRIVERID_AU8522, + .command = au8522_command, + .probe = au8522_probe, + .remove = au8522_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = au8522_id, +#endif +}; -- cgit v1.2.3 From d42d95e43ed8a60e001ff0a8a4f323380098be7d Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 15 Mar 2009 19:05:51 -0400 Subject: au8522: finish conversion to v4l2_device/subdev From: Devin Heitmueller Per Hans Verkuil instruction, remove the au8522_command and replace v4l2-i2c-drv-legacy.h with v4l2-i2c-drv.h Thanks to Hans Verkuil for reviewing the au8522 analog support. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/frontends/au8522_decoder.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_decoder.c b/linux/drivers/media/dvb/frontends/au8522_decoder.c index b4a205809..7c782b8d5 100644 --- a/linux/drivers/media/dvb/frontends/au8522_decoder.c +++ b/linux/drivers/media/dvb/frontends/au8522_decoder.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include "compat.h" #include "au8522.h" @@ -726,11 +726,6 @@ static int au8522_log_status(struct v4l2_subdev *sd) return 0; } -static int au8522_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); -} - /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops au8522_core_ops = { @@ -841,7 +836,6 @@ MODULE_DEVICE_TABLE(i2c, au8522_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "au8522", .driverid = I2C_DRIVERID_AU8522, - .command = au8522_command, .probe = au8522_probe, .remove = au8522_remove, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) -- cgit v1.2.3 From 72323c965e7e5472d7e8bc29775b1205cad63c78 Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Wed, 18 Mar 2009 00:21:18 +0300 Subject: Fix CiMax stability in Netup Dual DVB-S2 CI From: Abylay Ospan It appears TS discontinuity about one per 10 hrs if CAM used. Patch to fix it. Signed-off-by: Abylay Ospan --- linux/drivers/media/dvb/frontends/stv0900_core.c | 2 +- linux/drivers/media/dvb/frontends/stv0900_init.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv0900_core.c b/linux/drivers/media/dvb/frontends/stv0900_core.c index 67cce764f..899b1e7ed 100644 --- a/linux/drivers/media/dvb/frontends/stv0900_core.c +++ b/linux/drivers/media/dvb/frontends/stv0900_core.c @@ -254,7 +254,7 @@ enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params) } msleep(3); - for (i = 0; i < 180; i++) + for (i = 0; i < 182; i++) stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]); if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) { diff --git a/linux/drivers/media/dvb/frontends/stv0900_init.h b/linux/drivers/media/dvb/frontends/stv0900_init.h index fa8dbe197..ff388b47a 100644 --- a/linux/drivers/media/dvb/frontends/stv0900_init.h +++ b/linux/drivers/media/dvb/frontends/stv0900_init.h @@ -217,7 +217,7 @@ static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoo { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D } }; -static const u16 STV0900_InitVal[180][2] = { +static const u16 STV0900_InitVal[182][2] = { { R0900_OUTCFG , 0x00 }, { R0900_MODECFG , 0xff }, { R0900_AGCRF1CFG , 0x11 }, @@ -396,6 +396,8 @@ static const u16 STV0900_InitVal[180][2] = { { R0900_DATA72CFG , 0x52 }, { R0900_P1_TSCFGM , 0xc0 }, { R0900_P2_TSCFGM , 0xc0 }, + { R0900_P1_TSCFGH , 0xe0 }, /* DVB-CI timings */ + { R0900_P2_TSCFGH , 0xe0 }, /* DVB-CI timings */ { R0900_P1_TSSPEED , 0x40 }, { R0900_P2_TSSPEED , 0x40 }, }; -- cgit v1.2.3 From 5248d72ef4f84010b6c5d5c2c04face875655ea2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Mar 2009 20:39:07 +0100 Subject: au8522: fix compilation warning. From: Hans Verkuil normal_i2c and I2C_CLIENT_INSMOD are only necessary for kernels < 2.6.22. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/frontends/au8522_decoder.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_decoder.c b/linux/drivers/media/dvb/frontends/au8522_decoder.c index 7c782b8d5..70af9cda7 100644 --- a/linux/drivers/media/dvb/frontends/au8522_decoder.c +++ b/linux/drivers/media/dvb/frontends/au8522_decoder.c @@ -48,15 +48,17 @@ MODULE_LICENSE("GPL"); static int au8522_analog_debug; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) static unsigned short normal_i2c[] = { 0x8e >> 1, I2C_CLIENT_END }; +I2C_CLIENT_INSMOD; +#endif + module_param_named(analog_debug, au8522_analog_debug, int, 0644); MODULE_PARM_DESC(analog_debug, "Analog debugging messages [0=Off (default) 1=On]"); -I2C_CLIENT_INSMOD; - struct au8522_register_config { u16 reg_name; u8 reg_val[8]; -- cgit v1.2.3 From d149bb041dbb783fcd3b56dafd8a719e217335b3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Mar 2009 21:03:09 -0300 Subject: au8522/au0828: Fix Kconfig dependencies From: Mauro Carvalho Chehab au8522 is now dependent of V4L2, as reported by Randy Dunlap : au8522_decoder.c:(.text+0x199898): undefined reference to `v4l2_ctrl_query_fill' au8522_decoder.c:(.text+0x1998b3): undefined reference to `v4l2_ctrl_query_fill' au8522_decoder.c:(.text+0x199944): undefined reference to `v4l2_device_unregister_subdev' au8522_decoder.c:(.text+0x19997c): undefined reference to `v4l2_chip_ident_i2c_client' au8522_decoder.c:(.text+0x199f1e): undefined reference to `v4l2_i2c_subdev_init' Priority: normal CC: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 5c78f6329..a206cee23 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -437,7 +437,7 @@ config DVB_S5H1409 config DVB_AU8522 tristate "Auvitek AU8522 based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && VIDEO_V4L2 default m if DVB_FE_CUSTOMISE help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want -- cgit v1.2.3 From d1f8343e844fdb906b58a31d33e5d69c8e7853ad Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Mar 2009 21:41:08 -0300 Subject: dvb_dummy_fe: Fix compilation breakage From: Mauro Carvalho Chehab As reported by Randy Dunlap : ERROR: "dvb_dummy_fe_ofdm_attach" [drivers/media/video/cx231xx/cx231xx-dvb.ko] undefined! This happens since cx231xx DVB part still misses the frontend modules. So, the dummy frontend were used for development. The proper fix is to implement the DVB modules there, as they will be required. While this won't happen, lets allow the compilation with or without the dummy FE testing module. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/dvb_dummy_fe.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/dvb_dummy_fe.h b/linux/drivers/media/dvb/frontends/dvb_dummy_fe.h index 8210f19d5..1fcb987d6 100644 --- a/linux/drivers/media/dvb/frontends/dvb_dummy_fe.h +++ b/linux/drivers/media/dvb/frontends/dvb_dummy_fe.h @@ -25,8 +25,27 @@ #include #include "dvb_frontend.h" +#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \ +defined(MODULE)) extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void); extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void); extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void); +#else +static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_DUMMY_FE */ #endif // DVB_DUMMY_FE_H -- cgit v1.2.3 From f0878865f48611e7662e50450e128e8d046b646c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 27 Mar 2009 14:16:57 -0300 Subject: siano: add high level SDIO interface driver for SMS based cards From: Uri Shkolnik 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. Priority: low Signed-off-by: Pierre Ossman Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smssdio.c | 356 ++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 linux/drivers/media/dvb/siano/smssdio.c (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smssdio.c b/linux/drivers/media/dvb/siano/smssdio.c new file mode 100644 index 000000000..31ba8c5af --- /dev/null +++ b/linux/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.2.3 From a728c348653d59c62786e26db627004f9b402519 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Mar 2009 19:33:59 -0300 Subject: Kconfig: replace all occurrences of CUSTOMIZE to CUSTOMISE From: Mauro Carvalho Chehab There are several Kconfig items using CUSTOMIZE. Yet, most use the English writing CUSTOMISE. This generates lots of trouble, because people sometimes type the Kbuild item different. Let's standardise every occurrence using the same syntax. The changes were generated by this small shell script: for i in `find linux -type f`; do sed s,CUSTOMIZE,CUSTOMISE,g $i >/tmp/a && mv /tmp/a $i; done Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/b2c2/Kconfig | 2 +- linux/drivers/media/dvb/bt8xx/Kconfig | 2 +- linux/drivers/media/dvb/dvb-usb/Kconfig | 48 ++++++++++++++++----------------- linux/drivers/media/dvb/ttpci/Kconfig | 2 +- 4 files changed, 27 insertions(+), 27 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/Kconfig b/linux/drivers/media/dvb/b2c2/Kconfig index a8c6249c4..9e5781400 100644 --- a/linux/drivers/media/dvb/b2c2/Kconfig +++ b/linux/drivers/media/dvb/b2c2/Kconfig @@ -13,7 +13,7 @@ config DVB_B2C2_FLEXCOP select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE select DVB_ISL6421 if !DVB_FE_CUSTOMISE select DVB_CX24123 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE help Support for the digital TV receiver chip made by B2C2 Inc. included in diff --git a/linux/drivers/media/dvb/bt8xx/Kconfig b/linux/drivers/media/dvb/bt8xx/Kconfig index 27edb0ece..8668e634c 100644 --- a/linux/drivers/media/dvb/bt8xx/Kconfig +++ b/linux/drivers/media/dvb/bt8xx/Kconfig @@ -8,7 +8,7 @@ config DVB_BT8XX select DVB_OR51211 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE help Support for PCI cards based on the Bt8xx PCI bridge. Examples are the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index b899d509a..5b0c8cc25 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -25,7 +25,7 @@ config DVB_USB_A800 depends on DVB_USB select DVB_DIB3000MC select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. @@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB depends on DVB_USB select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_DIB3000MB - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE help Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-B demodulator. @@ -55,7 +55,7 @@ config DVB_USB_DIBUSB_MC tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" depends on DVB_USB select DVB_DIB3000MC - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE help Support for USB2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-C/P demodulator. @@ -75,11 +75,11 @@ config DVB_USB_DIB0700 select DVB_S5H1411 if !DVB_FE_CUSTOMISE select DVB_LGDT3305 if !DVB_FE_CUSTOMISE select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The USB bridge is also present in devices having the DiB7700 DVB-T-USB @@ -97,7 +97,7 @@ config DVB_USB_UMT_010 depends on DVB_USB select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_DIB3000MC - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE select DVB_MT352 if !DVB_FE_CUSTOMISE help Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. @@ -113,9 +113,9 @@ config DVB_USB_CXUSB select DVB_DIB7000P if !DVB_FE_CUSTOMISE select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode @@ -129,8 +129,8 @@ config DVB_USB_M920X depends on DVB_USB select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. Currently, only devices with a product id of @@ -141,7 +141,7 @@ config DVB_USB_GL861 tristate "Genesys Logic GL861 USB2.0 support" depends on DVB_USB select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 receiver with USB ID 0db0:5581. @@ -150,7 +150,7 @@ config DVB_USB_AU6610 tristate "Alcor Micro AU6610 USB2.0 support" depends on DVB_USB select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver. @@ -203,7 +203,7 @@ config DVB_USB_NOVA_T_USB2 depends on DVB_USB select DVB_DIB3000MC select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. @@ -239,8 +239,8 @@ config DVB_USB_OPERA1 config DVB_USB_AF9005 tristate "Afatech AF9005 DVB-T USB1.1 support" depends on DVB_USB && EXPERIMENTAL - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver and the TerraTec Cinergy T USB XE (Rev.1) @@ -288,7 +288,7 @@ config DVB_USB_DTV5100 tristate "AME DTV-5100 USB2.0 DVB-T support" depends on DVB_USB select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. @@ -297,10 +297,10 @@ config DVB_USB_AF9015 depends on DVB_USB && EXPERIMENTAL select DVB_AF9013 select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig index ab0bcd208..772990415 100644 --- a/linux/drivers/media/dvb/ttpci/Kconfig +++ b/linux/drivers/media/dvb/ttpci/Kconfig @@ -108,7 +108,7 @@ config DVB_BUDGET_CI select DVB_STB6100 if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE select DVB_TDA10023 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE select VIDEO_IR help Support for simple SAA7146 based DVB cards -- cgit v1.2.3 From a3bb275ba5d574b4c3aa8a7437548afdfd2d974c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 25 Mar 2009 21:48:15 +0200 Subject: zl10353: add support for Intel CE6230 and Intel CE6231 From: Antti Palosaari Add chip IDs and configuration registers needed for Intel CE6230 and Intel CE6231. Priority: normal Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/frontends/zl10353.c | 8 +++++++- linux/drivers/media/dvb/frontends/zl10353.h | 4 ++++ linux/drivers/media/dvb/frontends/zl10353_priv.h | 8 +++++++- 3 files changed, 18 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index 96ccc1720..6b58bf961 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -581,6 +581,10 @@ static int zl10353_init(struct dvb_frontend *fe) #endif if (state->config.parallel_ts) zl10353_reset_attach[2] &= ~0x20; + if (state->config.clock_ctl_1) + zl10353_reset_attach[3] = state->config.clock_ctl_1; + if (state->config.pll_0) + zl10353_reset_attach[4] = state->config.pll_0; /* Do a "hard" reset if not already done */ if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] || @@ -625,6 +629,7 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, struct i2c_adapter *i2c) { struct zl10353_state *state = NULL; + int id; /* allocate memory for the internal state */ state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL); @@ -636,7 +641,8 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, memcpy(&state->config, config, sizeof(struct zl10353_config)); /* check if the demod is there */ - if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) + id = zl10353_read_register(state, CHIP_ID); + if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231)) goto error; /* create dvb_frontend */ diff --git a/linux/drivers/media/dvb/frontends/zl10353.h b/linux/drivers/media/dvb/frontends/zl10353.h index 2287bac46..6e3ca9eed 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.h +++ b/linux/drivers/media/dvb/frontends/zl10353.h @@ -41,6 +41,10 @@ struct zl10353_config /* set if i2c_gate_ctrl disable is required */ u8 disable_i2c_gate_ctrl:1; + + /* clock control registers (0x51-0x54) */ + u8 clock_ctl_1; /* default: 0x46 */ + u8 pll_0; /* default: 0x15 */ }; #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) diff --git a/linux/drivers/media/dvb/frontends/zl10353_priv.h b/linux/drivers/media/dvb/frontends/zl10353_priv.h index 055ff1f7e..e0dd1d3e0 100644 --- a/linux/drivers/media/dvb/frontends/zl10353_priv.h +++ b/linux/drivers/media/dvb/frontends/zl10353_priv.h @@ -22,7 +22,9 @@ #ifndef _ZL10353_PRIV_ #define _ZL10353_PRIV_ -#define ID_ZL10353 0x14 +#define ID_ZL10353 0x14 /* Zarlink ZL10353 */ +#define ID_CE6230 0x18 /* Intel CE6230 */ +#define ID_CE6231 0x19 /* Intel CE6231 */ #define msb(x) (((x) >> 8) & 0xff) #define lsb(x) ((x) & 0xff) @@ -50,6 +52,10 @@ enum zl10353_reg_addr { TPS_RECEIVED_0 = 0x1E, TPS_CURRENT_1 = 0x1F, TPS_CURRENT_0 = 0x20, + CLOCK_CTL_0 = 0x51, + CLOCK_CTL_1 = 0x52, + PLL_0 = 0x53, + PLL_1 = 0x54, RESET = 0x55, AGC_TARGET = 0x56, MCLK_RATIO = 0x5C, -- cgit v1.2.3 From 271ff892e19406f748d58d75cb6bb9d5b2ad7076 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 25 Mar 2009 21:59:45 +0200 Subject: Add driver for Intel CE6230 DVB-T USB2.0 From: Antti Palosaari Add driver for Intel CE6230 DVB-T USB 2.0 COFDM demodulator Priority: normal Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/Kconfig | 8 + linux/drivers/media/dvb/dvb-usb/Makefile | 2 + linux/drivers/media/dvb/dvb-usb/ce6230.c | 331 ++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/ce6230.h | 69 ++++++ linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 + 5 files changed, 412 insertions(+) create mode 100644 linux/drivers/media/dvb/dvb-usb/ce6230.c create mode 100644 linux/drivers/media/dvb/dvb-usb/ce6230.h (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 5b0c8cc25..6103caad1 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -304,3 +304,11 @@ config DVB_USB_AF9015 select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver + +config DVB_USB_CE6230 + tristate "Intel CE6230 DVB-T USB2.0 support" + depends on DVB_USB && EXPERIMENTAL + select DVB_ZL10353 + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE + help + Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile index 3122b7cc2..f92734ed7 100644 --- a/linux/drivers/media/dvb/dvb-usb/Makefile +++ b/linux/drivers/media/dvb/dvb-usb/Makefile @@ -76,6 +76,8 @@ obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o +dvb-usb-ce6230-objs = ce6230.o +obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 diff --git a/linux/drivers/media/dvb/dvb-usb/ce6230.c b/linux/drivers/media/dvb/dvb-usb/ce6230.c new file mode 100644 index 000000000..2a959c4bd --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/ce6230.c @@ -0,0 +1,331 @@ +/* + * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver + * + * Copyright (C) 2009 Antti Palosaari + * + * 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 "ce6230.h" +#include "zl10353.h" +#include "mxl5005s.h" + +/* debug */ +static int dvb_usb_ce6230_debug; +module_param_named(debug, dvb_usb_ce6230_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static struct zl10353_config ce6230_zl10353_config; + +static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req) +{ + int ret; + unsigned int pipe; + u8 request; + u8 requesttype; + u16 value; + u16 index; + u8 buf[req->data_len]; + + request = req->cmd; + value = req->value; + index = req->index; + + switch (req->cmd) { + case I2C_READ: + case DEMOD_READ: + case REG_READ: + requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); + break; + case I2C_WRITE: + case DEMOD_WRITE: + case REG_WRITE: + requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); + break; + default: + err("unknown command:%02x", req->cmd); + ret = -EPERM; + goto error; + } + + if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) { + /* write */ + memcpy(buf, req->data, req->data_len); + pipe = usb_sndctrlpipe(udev, 0); + } else { + /* read */ + pipe = usb_rcvctrlpipe(udev, 0); + } + + msleep(1); /* avoid I2C errors */ + + ret = usb_control_msg(udev, pipe, request, requesttype, value, index, + buf, sizeof(buf), CE6230_USB_TIMEOUT); + + ce6230_debug_dump(request, requesttype, value, index, buf, + req->data_len, deb_xfer); + + if (ret < 0) + deb_info("%s: usb_control_msg failed:%d\n", __func__, ret); + else + ret = 0; + + /* read request, copy returned data to return buf */ + if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) + memcpy(req->data, buf, req->data_len); + +error: + return ret; +} + +static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) +{ + return ce6230_rw_udev(d->udev, req); +} + +/* I2C */ +static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i = 0; + struct req_t req; + int ret; + memset(&req, 0, sizeof(&req)); + + if (num > 2) + return -EINVAL; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + while (i < num) { + if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { + if (msg[i].addr == + ce6230_zl10353_config.demod_address) { + req.cmd = DEMOD_READ; + req.value = msg[i].addr >> 1; + req.index = msg[i].buf[0]; + req.data_len = msg[i+1].len; + req.data = &msg[i+1].buf[0]; + ret = ce6230_ctrl_msg(d, &req); + } else { + err("i2c read not implemented"); + ret = -EPERM; + } + i += 2; + } else { + if (msg[i].addr == + ce6230_zl10353_config.demod_address) { + req.cmd = DEMOD_WRITE; + req.value = msg[i].addr >> 1; + req.index = msg[i].buf[0]; + req.data_len = msg[i].len-1; + req.data = &msg[i].buf[1]; + ret = ce6230_ctrl_msg(d, &req); + } else { + req.cmd = I2C_WRITE; + req.value = 0x2000 + (msg[i].addr >> 1); + req.index = 0x0000; + req.data_len = msg[i].len; + req.data = &msg[i].buf[0]; + ret = ce6230_ctrl_msg(d, &req); + } + i += 1; + } + if (ret) + break; + } + + mutex_unlock(&d->i2c_mutex); + return ret ? ret : i; +} + +static u32 ce6230_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm ce6230_i2c_algo = { + .master_xfer = ce6230_i2c_xfer, + .functionality = ce6230_i2c_func, +#ifdef NEED_ALGO_CONTROL + .algo_control = dummy_algo_control, +#endif +}; + +/* Callbacks for DVB USB */ +static struct zl10353_config ce6230_zl10353_config = { + .demod_address = 0x1e, + .adc_clock = 450000, + .if2 = 45700, + .no_tuner = 1, + .parallel_ts = 1, + .clock_ctl_1 = 0x34, + .pll_0 = 0x0e, +}; + +static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap) +{ + deb_info("%s:\n", __func__); + adap->fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config, + &adap->dev->i2c_adap); + if (adap->fe == NULL) + return -ENODEV; + return 0; +} + +static struct mxl5005s_config ce6230_mxl5003s_config = { + .i2c_address = 0xc6, + .if_freq = IF_FREQ_4570000HZ, + .xtal_freq = CRYSTAL_FREQ_16000000HZ, + .agc_mode = MXL_SINGLE_AGC, + .tracking_filter = MXL_TF_DEFAULT, + .rssi_enable = MXL_RSSI_ENABLE, + .cap_select = MXL_CAP_SEL_ENABLE, + .div_out = MXL_DIV_OUT_4, + .clock_out = MXL_CLOCK_OUT_DISABLE, + .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, + .top = MXL5005S_TOP_25P2, + .mod_mode = MXL_DIGITAL_MODE, + .if_mode = MXL_ZERO_IF, + .AgcMasterByte = 0x00, +}; + +static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) +{ + int ret; + deb_info("%s:\n", __func__); + ret = dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap, + &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0; + return ret; +} + +static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + int ret; + deb_info("%s: onoff:%d\n", __func__, onoff); + + /* InterfaceNumber 1 / AlternateSetting 0 idle + InterfaceNumber 1 / AlternateSetting 1 streaming */ + ret = usb_set_interface(d->udev, 1, onoff); + if (ret) + err("usb_set_interface failed with error:%d", ret); + + return ret; +} + +/* DVB USB Driver stuff */ +static struct dvb_usb_device_properties ce6230_properties; + +static int ce6230_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + int ret = 0; + struct dvb_usb_device *d = NULL; + + deb_info("%s: interface:%d\n", __func__, + intf->cur_altsetting->desc.bInterfaceNumber); + + if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { + ret = dvb_usb_device_init(intf, &ce6230_properties, THIS_MODULE, + &d, adapter_nr); + if (ret) + err("init failed with error:%d\n", ret); + } + + return ret; +} + +static struct usb_device_id ce6230_table[] = { + { USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, ce6230_table); + +static struct dvb_usb_device_properties ce6230_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = DEVICE_SPECIFIC, + .no_reconnect = 1, + + .size_of_priv = 0, + + .num_adapters = 1, + .adapter = { + { + .frontend_attach = ce6230_zl10353_frontend_attach, + .tuner_attach = ce6230_mxl5003s_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 6, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + } + }, + + .power_ctrl = ce6230_power_ctrl, + + .i2c_algo = &ce6230_i2c_algo, + + .num_device_descs = 1, + .devices = { + { + .name = "Intel CE9500 reference design", + .cold_ids = {NULL}, + .warm_ids = {&ce6230_table[0], NULL}, + }, + } +}; + +static struct usb_driver ce6230_driver = { + .name = "dvb_usb_ce6230", + .probe = ce6230_probe, + .disconnect = dvb_usb_device_exit, + .id_table = ce6230_table, +}; + +/* module stuff */ +static int __init ce6230_module_init(void) +{ + int ret; + deb_info("%s:\n", __func__); + ret = usb_register(&ce6230_driver); + if (ret) + err("usb_register failed with error:%d", ret); + + return ret; +} + +static void __exit ce6230_module_exit(void) +{ + deb_info("%s:\n", __func__); + /* deregister this driver from the USB subsystem */ + usb_deregister(&ce6230_driver); +} + +module_init(ce6230_module_init); +module_exit(ce6230_module_exit); + +MODULE_AUTHOR("Antti Palosaari "); +MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/dvb-usb/ce6230.h b/linux/drivers/media/dvb/dvb-usb/ce6230.h new file mode 100644 index 000000000..97c42482c --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/ce6230.h @@ -0,0 +1,69 @@ +/* + * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver + * + * Copyright (C) 2009 Antti Palosaari + * + * 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 _DVB_USB_CE6230_H_ +#define _DVB_USB_CE6230_H_ + +#define DVB_USB_LOG_PREFIX "ce6230" +#include "dvb-usb.h" + +#define deb_info(args...) dprintk(dvb_usb_ce6230_debug, 0x01, args) +#define deb_rc(args...) dprintk(dvb_usb_ce6230_debug, 0x02, args) +#define deb_xfer(args...) dprintk(dvb_usb_ce6230_debug, 0x04, args) +#define deb_reg(args...) dprintk(dvb_usb_ce6230_debug, 0x08, args) +#define deb_i2c(args...) dprintk(dvb_usb_ce6230_debug, 0x10, args) +#define deb_fw(args...) dprintk(dvb_usb_ce6230_debug, 0x20, args) + +#define ce6230_debug_dump(r, t, v, i, b, l, func) { \ + int loop_; \ + func("%02x %02x %02x %02x %02x %02x %02x %02x", \ + t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \ + if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \ + func(" >>> "); \ + else \ + func(" <<< "); \ + for (loop_ = 0; loop_ < l; loop_++) \ + func("%02x ", b[loop_]); \ + func("\n");\ +} + +#define CE6230_USB_TIMEOUT 1000 + +struct req_t { + u8 cmd; /* [1] */ + u16 value; /* [2|3] */ + u16 index; /* [4|5] */ + u16 data_len; /* [6|7] */ + u8 *data; +}; + +enum ce6230_cmd { + CONFIG_READ = 0xd0, /* rd 0 (unclear) */ + UNKNOWN_WRITE = 0xc7, /* wr 7 (unclear) */ + I2C_READ = 0xd9, /* rd 9 (unclear) */ + I2C_WRITE = 0xca, /* wr a */ + DEMOD_READ = 0xdb, /* rd b */ + DEMOD_WRITE = 0xcc, /* wr c */ + REG_READ = 0xde, /* rd e */ + REG_WRITE = 0xcf, /* wr f */ +}; + +#endif diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 3dfb27174..0f239c668 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -33,6 +33,7 @@ #define USB_VID_HANFTEK 0x15f4 #define USB_VID_HAUPPAUGE 0x2040 #define USB_VID_HYPER_PALTEK 0x1025 +#define USB_VID_INTEL 0x8086 #define USB_VID_KWORLD 0xeb2a #define USB_VID_KWORLD_2 0x1b80 #define USB_VID_KYE 0x0458 @@ -96,6 +97,7 @@ #define USB_PID_UNIWILL_STK7700P 0x6003 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 +#define USB_PID_INTEL_CE9500 0x9500 #define USB_PID_KWORLD_399U 0xe399 #define USB_PID_KWORLD_395U 0xe396 #define USB_PID_KWORLD_395U_2 0xe39b -- cgit v1.2.3 From 03ddd50e8bf14d07eacd58ead6b8fd9236ef0982 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 26 Mar 2009 20:47:48 +0000 Subject: [PATCH] pluto2: silence spew of card hung up messages From: Alan Cox If the card is ejected on some systems you get a spew of messages as other shared IRQ devices interrupt between the card eject and the card IRQ disable. We don't need to spew them all out Closes #7472 Signed-off-by: Alan Cox Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/pluto2/pluto2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c index 8522757a5..b27073216 100644 --- a/linux/drivers/media/dvb/pluto2/pluto2.c +++ b/linux/drivers/media/dvb/pluto2/pluto2.c @@ -116,6 +116,7 @@ struct pluto { /* irq */ unsigned int overflow; + unsigned int dead; /* dma */ dma_addr_t dma_addr; @@ -344,8 +345,10 @@ static irqreturn_t pluto_irq(int irq, void *dev_id) return IRQ_NONE; if (tscr == 0xffffffff) { - // FIXME: maybe recover somehow - dev_err(&pluto->pdev->dev, "card hung up :(\n"); + if (pluto->dead == 0) + dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n"); + /* It's dead Jim */ + pluto->dead = 1; return IRQ_HANDLED; } -- cgit v1.2.3 From b02ab8e4ddec4578f3d68e296e76032accdd378b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 26 Mar 2009 09:45:53 +0000 Subject: Remove debug output from stb6100_cfg.h From: Artem Makhutov This patch removes the debug output from stb6100_cfg.h as it is flooding the syslog with tuning data during normal operation. Signed-off-by: Artem Makhutov Acked-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/stb6100_cfg.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stb6100_cfg.h b/linux/drivers/media/dvb/frontends/stb6100_cfg.h index d3133405d..6314d18c7 100644 --- a/linux/drivers/media/dvb/frontends/stb6100_cfg.h +++ b/linux/drivers/media/dvb/frontends/stb6100_cfg.h @@ -36,7 +36,6 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) return err; } *frequency = t_state.frequency; - printk("%s: Frequency=%d\n", __func__, t_state.frequency); } return 0; } @@ -59,7 +58,6 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) return err; } } - printk("%s: Frequency=%d\n", __func__, t_state.frequency); return 0; } @@ -81,7 +79,6 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) } *bandwidth = t_state.bandwidth; } - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); return 0; } @@ -103,6 +100,5 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) return err; } } - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); return 0; } -- cgit v1.2.3 From 5512312e53f2dcc8c53a6a48363e5b4647be9152 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 27 Mar 2009 01:27:10 +0200 Subject: af9015: remove experimental From: Antti Palosaari Remove experimental from DVB USB AF9015 device. Priority: normal Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 6103caad1..53a4a4732 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -294,7 +294,7 @@ config DVB_USB_DTV5100 config DVB_USB_AF9015 tristate "Afatech AF9015 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL + depends on DVB_USB select DVB_AF9013 select DVB_PLL if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE -- cgit v1.2.3 From 670efc5efe630fe0ea45bfb66d10c69f857e7930 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 27 Mar 2009 01:41:05 +0200 Subject: af9015: add new USB ID for KWorld USB DVB-T TV Stick II (VS-DVB-T 395U) From: Antti Palosaari Add new USB ID (1b80:e395) for KWorld USB DVB-T TV Stick II (VS-DVB-T 395U). Thanks to Julian Aron Prenner for reporting this. Priority: normal Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/af9015.c | 4 +++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index ca7609583..d998d7b59 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -1240,6 +1240,7 @@ static struct usb_device_id af9015_usb_table[] = { /* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1440,7 +1441,8 @@ static struct dvb_usb_device_properties af9015_properties[] = { .name = "KWorld USB DVB-T TV Stick II " \ "(VS-DVB-T 395U)", .cold_ids = {&af9015_usb_table[16], - &af9015_usb_table[17], NULL}, + &af9015_usb_table[17], + &af9015_usb_table[18], NULL}, .warm_ids = {NULL}, }, } diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 0f239c668..ba4115d1a 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -101,6 +101,7 @@ #define USB_PID_KWORLD_399U 0xe399 #define USB_PID_KWORLD_395U 0xe396 #define USB_PID_KWORLD_395U_2 0xe39b +#define USB_PID_KWORLD_395U_3 0xe395 #define USB_PID_KWORLD_PC160_2T 0xc160 #define USB_PID_KWORLD_VSTREAM_COLD 0x17de #define USB_PID_KWORLD_VSTREAM_WARM 0x17df -- cgit v1.2.3 From 01e907edffbde4b2f45bd79bc59db7a2107b419e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 27 Mar 2009 02:07:18 +0200 Subject: af9015: add support for TrekStor DVB-T USB Stick From: Marc Schneider Add USB ID (15a4:901b) and remote for TrekStor DVB-T USB Stick. Priority: normal Signed-off-by: Marc Schneider Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/af9015.c | 18 ++++++- linux/drivers/media/dvb/dvb-usb/af9015.h | 67 ++++++++++++++++++++++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 3 files changed, 83 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index d998d7b59..e7a8f61da 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -836,6 +836,16 @@ static int af9015_read_config(struct usb_device *udev) af9015_ir_table_msi; af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_msi); + } else if (udev->descriptor.idProduct == + cpu_to_le16(USB_PID_TREKSTOR_DVBT)) { + af9015_properties[i].rc_key_map = + af9015_rc_keys_trekstor; + af9015_properties[i].rc_key_map_size = + ARRAY_SIZE(af9015_rc_keys_trekstor); + af9015_config.ir_table = + af9015_ir_table_trekstor; + af9015_config.ir_table_size = + ARRAY_SIZE(af9015_ir_table_trekstor); } break; case USB_VID_AVERMEDIA: @@ -1241,6 +1251,7 @@ static struct usb_device_id af9015_usb_table[] = { {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, {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)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1405,7 +1416,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 7, + .num_device_descs = 8, .devices = { { .name = "Xtensions XD-380", @@ -1445,6 +1456,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { &af9015_usb_table[18], NULL}, .warm_ids = {NULL}, }, + { + .name = "TrekStor DVB-T USB Stick", + .cold_ids = {&af9015_usb_table[19], NULL}, + .warm_ids = {NULL}, + }, } } }; diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.h b/linux/drivers/media/dvb/dvb-usb/af9015.h index 00e257146..5c44bad28 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.h +++ b/linux/drivers/media/dvb/dvb-usb/af9015.h @@ -120,11 +120,11 @@ struct af9015_config { enum af9015_remote { AF9015_REMOTE_NONE = 0, - AF9015_REMOTE_A_LINK_DTU_M, +/* 1 */ AF9015_REMOTE_A_LINK_DTU_M, AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, AF9015_REMOTE_MYGICTV_U718, AF9015_REMOTE_DIGITTRADE_DVB_T, - AF9015_REMOTE_AVERMEDIA_KS, +/* 5 */ AF9015_REMOTE_AVERMEDIA_KS, }; /* Leadtek WinFast DTV Dongle Gold */ @@ -691,4 +691,67 @@ static u8 af9015_ir_table_digittrade[] = { 0x00, 0xff, 0x1d, 0xe2, 0x40, 0x00, 0x00, }; +/* TREKSTOR DVB-T USB Stick */ +static struct dvb_usb_rc_key af9015_rc_keys_trekstor[] = { + { 0x07, 0x04, KEY_AGAIN }, /* Home */ + { 0x07, 0x05, KEY_MUTE }, /* Mute */ + { 0x07, 0x06, KEY_UP }, /* Up */ + { 0x07, 0x07, KEY_DOWN }, /* Down */ + { 0x07, 0x09, KEY_RIGHT }, /* Right */ + { 0x07, 0x0a, KEY_ENTER }, /* OK */ + { 0x07, 0x0b, KEY_FASTFORWARD }, /* Fast forward */ + { 0x07, 0x0c, KEY_REWIND }, /* Rewind */ + { 0x07, 0x0d, KEY_PLAY }, /* Play/Pause */ + { 0x07, 0x0e, KEY_VOLUMEUP }, /* Volume + */ + { 0x07, 0x0f, KEY_VOLUMEDOWN }, /* Volume - */ + { 0x07, 0x10, KEY_RECORD }, /* Record */ + { 0x07, 0x11, KEY_STOP }, /* Stop */ + { 0x07, 0x12, KEY_ZOOM }, /* TV */ + { 0x07, 0x13, KEY_EPG }, /* Info/EPG */ + { 0x07, 0x14, KEY_CHANNELDOWN }, /* Channel - */ + { 0x07, 0x15, KEY_CHANNELUP }, /* Channel + */ + { 0x07, 0x1e, KEY_1 }, + { 0x07, 0x1f, KEY_2 }, + { 0x07, 0x20, KEY_3 }, + { 0x07, 0x21, KEY_4 }, + { 0x07, 0x22, KEY_5 }, + { 0x07, 0x23, KEY_6 }, + { 0x07, 0x24, KEY_7 }, + { 0x07, 0x25, KEY_8 }, + { 0x07, 0x26, KEY_9 }, + { 0x07, 0x08, KEY_LEFT }, /* LEFT */ + { 0x07, 0x27, KEY_0 }, +}; + +static u8 af9015_ir_table_trekstor[] = { + 0x00, 0xff, 0x86, 0x79, 0x04, 0x07, 0x00, + 0x00, 0xff, 0x85, 0x7a, 0x05, 0x07, 0x00, + 0x00, 0xff, 0x87, 0x78, 0x06, 0x07, 0x00, + 0x00, 0xff, 0x8c, 0x73, 0x07, 0x07, 0x00, + 0x00, 0xff, 0x89, 0x76, 0x09, 0x07, 0x00, + 0x00, 0xff, 0x88, 0x77, 0x0a, 0x07, 0x00, + 0x00, 0xff, 0x8a, 0x75, 0x0b, 0x07, 0x00, + 0x00, 0xff, 0x9e, 0x61, 0x0c, 0x07, 0x00, + 0x00, 0xff, 0x8d, 0x72, 0x0d, 0x07, 0x00, + 0x00, 0xff, 0x8b, 0x74, 0x0e, 0x07, 0x00, + 0x00, 0xff, 0x9b, 0x64, 0x0f, 0x07, 0x00, + 0x00, 0xff, 0x9d, 0x62, 0x10, 0x07, 0x00, + 0x00, 0xff, 0x8e, 0x71, 0x11, 0x07, 0x00, + 0x00, 0xff, 0x9c, 0x63, 0x12, 0x07, 0x00, + 0x00, 0xff, 0x8f, 0x70, 0x13, 0x07, 0x00, + 0x00, 0xff, 0x93, 0x6c, 0x14, 0x07, 0x00, + 0x00, 0xff, 0x97, 0x68, 0x15, 0x07, 0x00, + 0x00, 0xff, 0x92, 0x6d, 0x1e, 0x07, 0x00, + 0x00, 0xff, 0x96, 0x69, 0x1f, 0x07, 0x00, + 0x00, 0xff, 0x9a, 0x65, 0x20, 0x07, 0x00, + 0x00, 0xff, 0x91, 0x6e, 0x21, 0x07, 0x00, + 0x00, 0xff, 0x95, 0x6a, 0x22, 0x07, 0x00, + 0x00, 0xff, 0x99, 0x66, 0x23, 0x07, 0x00, + 0x00, 0xff, 0x90, 0x6f, 0x24, 0x07, 0x00, + 0x00, 0xff, 0x94, 0x6b, 0x25, 0x07, 0x00, + 0x00, 0xff, 0x98, 0x67, 0x26, 0x07, 0x00, + 0x00, 0xff, 0x9f, 0x60, 0x08, 0x07, 0x00, + 0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00, +}; + #endif diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index ba4115d1a..cd22d6dde 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -64,6 +64,7 @@ #define USB_PID_AFATECH_AF9005 0x9020 #define USB_PID_AFATECH_AF9015_9015 0x9015 #define USB_PID_AFATECH_AF9015_9016 0x9016 +#define USB_PID_TREKSTOR_DVBT 0x901b #define USB_VID_ALINK_DTU 0xf170 #define USB_PID_ANSONIC_DVBT_USB 0x6000 #define USB_PID_ANYSEE 0x861f -- cgit v1.2.3 From 7c6ce73528aae8f96ce13949569a1776d67adb6d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 28 Mar 2009 13:35:40 +0100 Subject: dst_ca: fix compile warning. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/bt8xx/dst_ca.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/bt8xx/dst_ca.c b/linux/drivers/media/dvb/bt8xx/dst_ca.c index e71c269c1..bdc22a467 100644 --- a/linux/drivers/media/dvb/bt8xx/dst_ca.c +++ b/linux/drivers/media/dvb/bt8xx/dst_ca.c @@ -650,16 +650,17 @@ free_mem_and_exit: static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg) { - lock_kernel(); - - struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; - struct dst_state* state = (struct dst_state*) dvbdev->priv; + struct dvb_device *dvbdev; + struct dst_state *state; struct ca_slot_info *p_ca_slot_info; struct ca_caps *p_ca_caps; struct ca_msg *p_ca_message; void __user *arg = (void __user *)ioctl_arg; int result = 0; + lock_kernel(); + dvbdev = (struct dvb_device *)file->private_data; + state = (struct dst_state *)dvbdev->priv; p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); -- cgit v1.2.3 From ed2a80c674f393482227987d6aeed8c60328cca4 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sun, 29 Mar 2009 12:46:58 +0200 Subject: Code cleanup (passes checkpatch now) of the b2c2-flexcop-drivers 1/2 From: Uwe Bugla This patch cleans up the source code of the b2c2 flexcop-driver. It is the first of a total of two. The code is now passing the checkpatch-script. Priority: normal Signed-off-by: Uwe Bugla Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/Makefile | 1 - linux/drivers/media/dvb/b2c2/flexcop-common.h | 64 ++++---- linux/drivers/media/dvb/b2c2/flexcop-dma.c | 27 ++-- linux/drivers/media/dvb/b2c2/flexcop-eeprom.c | 47 +++--- linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 6 +- linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c | 171 ++++++++++++--------- linux/drivers/media/dvb/b2c2/flexcop-i2c.c | 49 +++--- linux/drivers/media/dvb/b2c2/flexcop-misc.c | 68 ++++---- linux/drivers/media/dvb/b2c2/flexcop-reg.h | 21 ++- linux/drivers/media/dvb/b2c2/flexcop-sram.c | 112 +++++--------- linux/drivers/media/dvb/b2c2/flexcop-usb.h | 62 ++++---- linux/drivers/media/dvb/b2c2/flexcop.c | 85 +++++----- linux/drivers/media/dvb/b2c2/flexcop.h | 20 ++- .../drivers/media/dvb/b2c2/flexcop_ibi_value_be.h | 7 +- .../drivers/media/dvb/b2c2/flexcop_ibi_value_le.h | 7 +- 15 files changed, 353 insertions(+), 394 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/Makefile b/linux/drivers/media/dvb/b2c2/Makefile index d9db066f9..b97cf7208 100644 --- a/linux/drivers/media/dvb/b2c2/Makefile +++ b/linux/drivers/media/dvb/b2c2/Makefile @@ -2,7 +2,6 @@ b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \ flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o - ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),) b2c2-flexcop-objs += flexcop-dma.o endif diff --git a/linux/drivers/media/dvb/b2c2/flexcop-common.h b/linux/drivers/media/dvb/b2c2/flexcop-common.h index 166f0fb09..cee2956cb 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-common.h +++ b/linux/drivers/media/dvb/b2c2/flexcop-common.h @@ -29,11 +29,14 @@ /* Steal from usb.h */ #undef err -#define err(format, arg...) printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg) +#define err(format, arg...) \ + printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg) #undef info -#define info(format, arg...) printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg) +#define info(format, arg...) \ + printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg) #undef warn -#define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg) +#define warn(format, arg...) \ + printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg) struct flexcop_dma { struct pci_dev *pdev; @@ -92,16 +95,14 @@ struct flexcop_device { int fullts_streaming_state; /* bus specific callbacks */ - flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register); - int (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value); - - - int (*i2c_request) (struct flexcop_i2c_adapter*, + flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *, + flexcop_ibi_register); + int (*write_ibi_reg) (struct flexcop_device *, + flexcop_ibi_register, flexcop_ibi_value); + int (*i2c_request) (struct flexcop_i2c_adapter *, flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); - int (*stream_control) (struct flexcop_device*, int); - + int (*stream_control) (struct flexcop_device *, int); int (*get_mac_addr) (struct flexcop_device *fc, int extended); - void *bus_specific; }; @@ -112,22 +113,28 @@ void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len); void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no); struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len); -void flexcop_device_kfree(struct flexcop_device*); +void flexcop_device_kfree(struct flexcop_device *); -int flexcop_device_initialize(struct flexcop_device*); +int flexcop_device_initialize(struct flexcop_device *); void flexcop_device_exit(struct flexcop_device *fc); - void flexcop_reset_block_300(struct flexcop_device *fc); /* from flexcop-dma.c */ -int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size); +int flexcop_dma_allocate(struct pci_dev *pdev, + struct flexcop_dma *dma, u32 size); void flexcop_dma_free(struct flexcop_dma *dma); -int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); -int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); -int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx); -int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff); -int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); +int flexcop_dma_control_timer_irq(struct flexcop_device *fc, + flexcop_dma_index_t no, int onoff); +int flexcop_dma_control_size_irq(struct flexcop_device *fc, + flexcop_dma_index_t no, int onoff); +int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, + flexcop_dma_index_t dma_idx); +int flexcop_dma_xfer_control(struct flexcop_device *fc, + flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, + int onoff); +int flexcop_dma_config_timer(struct flexcop_device *fc, + flexcop_dma_index_t dma_idx, u8 cycles); /* from flexcop-eeprom.c */ /* the PCI part uses this call to get the MAC address, the USB part has its own */ @@ -142,13 +149,15 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); /* from flexcop-sram.c */ -int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target); +int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, + flexcop_sram_dest_target_t target); void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s); -void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill); +void flexcop_sram_ctrl(struct flexcop_device *fc, + int usb_wan, int sramdma, int maximumfill); /* global prototypes for the flexcop-chip */ /* from flexcop-fe-tuner.c */ -int flexcop_frontend_init(struct flexcop_device *card); +int flexcop_frontend_init(struct flexcop_device *fc); void flexcop_frontend_exit(struct flexcop_device *fc); /* from flexcop-i2c.c */ @@ -160,11 +169,14 @@ int flexcop_sram_init(struct flexcop_device *fc); /* from flexcop-misc.c */ void flexcop_determine_revision(struct flexcop_device *fc); -void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix); -void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num); +void flexcop_device_name(struct flexcop_device *fc, + const char *prefix, const char *suffix); +void flexcop_dump_reg(struct flexcop_device *fc, + flexcop_ibi_register reg, int num); /* from flexcop-hw-filter.c */ -int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff); +int flexcop_pid_feed_control(struct flexcop_device *fc, + struct dvb_demux_feed *dvbdmxfeed, int onoff); void flexcop_hw_filter_init(struct flexcop_device *fc); void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff); diff --git a/linux/drivers/media/dvb/b2c2/flexcop-dma.c b/linux/drivers/media/dvb/b2c2/flexcop-dma.c index 02a0f07a1..2c0eab398 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-dma.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-dma.c @@ -1,13 +1,12 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop. - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-dma.c - configuring and controlling the DMA of the FlexCop + * see flexcop.c for copyright information */ #include "flexcop.h" -int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size) +int flexcop_dma_allocate(struct pci_dev *pdev, + struct flexcop_dma *dma, u32 size) { u8 *tcpu; dma_addr_t tdma = 0; @@ -32,7 +31,8 @@ EXPORT_SYMBOL(flexcop_dma_allocate); void flexcop_dma_free(struct flexcop_dma *dma) { - pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0); + pci_free_consistent(dma->pdev, dma->size*2, + dma->cpu_addr0, dma->dma_addr0); memset(dma,0,sizeof(struct flexcop_dma)); } EXPORT_SYMBOL(flexcop_dma_free); @@ -44,8 +44,8 @@ int flexcop_dma_config(struct flexcop_device *fc, flexcop_ibi_value v0x0,v0x4,v0xc; v0x0.raw = v0x4.raw = v0xc.raw = 0; - v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; - v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; + v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; + v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; v0x4.dma_0x4_write.dma_addr_size = dma->size / 4; if ((dma_idx & FC_DMA_1) == dma_idx) { @@ -57,7 +57,8 @@ int flexcop_dma_config(struct flexcop_device *fc, fc->write_ibi_reg(fc,dma2_014,v0x4); fc->write_ibi_reg(fc,dma2_01c,v0xc); } else { - err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call."); + err("either DMA1 or DMA2 can be configured within one " + "flexcop_dma_config call."); return -EINVAL; } @@ -81,7 +82,8 @@ int flexcop_dma_xfer_control(struct flexcop_device *fc, r0x0 = dma2_010; r0xc = dma2_01c; } else { - err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call."); + err("either transfer DMA1 or DMA2 can be started within one " + "flexcop_dma_xfer_control call."); return -EINVAL; } @@ -154,8 +156,7 @@ EXPORT_SYMBOL(flexcop_dma_control_timer_irq); /* 1 cycles = 1.97 msec */ int flexcop_dma_config_timer(struct flexcop_device *fc, - flexcop_dma_index_t dma_idx, - u8 cycles) + flexcop_dma_index_t dma_idx, u8 cycles) { flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; flexcop_ibi_value v = fc->read_ibi_reg(fc,r); diff --git a/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c b/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c index 5d563fbc7..4f42efa26 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c @@ -1,9 +1,7 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used) - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading) + * see flexcop.c for copyright information */ #include "flexcop.h" @@ -14,17 +12,17 @@ static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len) return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len); } -static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries) +static int eeprom_lrc_write(struct adapter *adapter, u32 addr, + u32 len, u8 *wbuf, u8 *rbuf, int retries) { - int i; +int i; - for (i = 0; i < retries; i++) { - if (eeprom_write(adapter, addr, wbuf, len) == len) { - if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1) - return 1; +for (i = 0; i < retries; i++) { + if (eeprom_write(adapter, addr, wbuf, len) == len) { + if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1) + return 1; } } - return 0; } @@ -39,12 +37,10 @@ static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len) return 0; memcpy(wbuf, key, len); - wbuf[16] = 0; wbuf[17] = 0; wbuf[18] = 0; wbuf[19] = calc_lrc(wbuf, 19); - return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4); } @@ -59,7 +55,6 @@ static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len) return 0; memcpy(key, buf, len); - return 1; } @@ -74,9 +69,7 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac) tmp[3] = mac[5]; tmp[4] = mac[6]; tmp[5] = mac[7]; - } else { - tmp[0] = mac[0]; tmp[1] = mac[1]; tmp[2] = mac[2]; @@ -90,11 +83,11 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac) if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8) return 1; - return 0; } -static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len) +static int flexcop_eeprom_read(struct flexcop_device *fc, + u16 addr, u8 *buf, u16 len) { return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len); } @@ -110,7 +103,8 @@ static u8 calc_lrc(u8 *buf, int len) return sum; } -static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries) +static int flexcop_eeprom_request(struct flexcop_device *fc, + flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries) { int i,ret = 0; u8 chipaddr = 0x50 | ((addr >> 8) & 3); @@ -123,7 +117,8 @@ static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t return ret; } -static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries) +static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, + u8 *buf, u16 len, int retries) { int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries); if (ret == 0) @@ -133,8 +128,7 @@ static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, } /* JJ's comment about extended == 1: it is not presently used anywhere but was - * added to the low-level functions for possible support of EUI64 - */ + * added to the low-level functions for possible support of EUI64 */ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended) { u8 buf[8]; @@ -142,12 +136,9 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended) if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) { if (extended != 0) { - err("TODO: extended (EUI64) MAC addresses aren't completely supported yet"); + err("TODO: extended (EUI64) MAC addresses aren't " + "completely supported yet"); ret = -EINVAL; -/* memcpy(fc->dvb_adapter.proposed_mac,buf,3); - mac[3] = 0xfe; - mac[4] = 0xff; - memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */ } else memcpy(fc->dvb_adapter.proposed_mac,buf,6); } diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 5cded3708..f7afab594 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -592,14 +592,14 @@ int flexcop_frontend_init(struct flexcop_device *fc) fc->fe_sleep = ops->sleep; ops->sleep = flexcop_sleep; - fc->dev_type = FC_SKY; + 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_DVB; + fc->dev_type = FC_AIR_DVBT; fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; goto fe_found; } @@ -653,7 +653,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) fc->fe_sleep = ops->sleep; ops->sleep = flexcop_sleep; - fc->dev_type = FC_SKY_OLD; + fc->dev_type = FC_SKY_REV23; goto fe_found; } diff --git a/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c index 451974ba3..77e45475f 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c @@ -1,33 +1,30 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions. - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-hw-filter.c - pid and mac address filtering and control functions + * see flexcop.c for copyright information */ #include "flexcop.h" static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff); - - deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off"); + flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff); + deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off"); } void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff); + flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff); } static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff); + flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff); } void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]) { - flexcop_ibi_value v418,v41c; - v41c = fc->read_ibi_reg(fc,mac_address_41c); + flexcop_ibi_value v418, v41c; + v41c = fc->read_ibi_reg(fc, mac_address_41c); v418.mac_address_418.MAC1 = mac[0]; v418.mac_address_418.MAC2 = mac[1]; @@ -36,27 +33,28 @@ void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]) v41c.mac_address_41c.MAC7 = mac[4]; v41c.mac_address_41c.MAC8 = mac[5]; - fc->write_ibi_reg(fc,mac_address_418,v418); - fc->write_ibi_reg(fc,mac_address_41c,v41c); + fc->write_ibi_reg(fc, mac_address_418, v418); + fc->write_ibi_reg(fc, mac_address_41c, v41c); } void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff); + flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff); } -static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask) +static void flexcop_pid_group_filter(struct flexcop_device *fc, + u16 pid, u16 mask) { /* index_reg_310.extra_index_reg need to 0 or 7 to work */ flexcop_ibi_value v30c; v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid; v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask; - fc->write_ibi_reg(fc,pid_filter_30c,v30c); + fc->write_ibi_reg(fc, pid_filter_30c, v30c); } static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff); + flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff); } /* this fancy define reduces the code size of the quite similar PID controlling of @@ -65,91 +63,112 @@ static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff) #define pid_ctrl(vregname,field,enablefield,trans_field,transval) \ flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \ - v208 = fc->read_ibi_reg(fc, ctrl_208); \ -\ - vpid.vregname.field = onoff ? pid : 0x1fff; \ - vpid.vregname.trans_field = transval; \ - v208.ctrl_208.enablefield = onoff; \ -\ - fc->write_ibi_reg(fc,vregname,vpid); \ - fc->write_ibi_reg(fc,ctrl_208,v208); +v208 = fc->read_ibi_reg(fc, ctrl_208); \ +vpid.vregname.field = onoff ? pid : 0x1fff; \ +vpid.vregname.trans_field = transval; \ +v208.ctrl_208.enablefield = onoff; \ +fc->write_ibi_reg(fc, vregname, vpid); \ +fc->write_ibi_reg(fc, ctrl_208, v208); -static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) +static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, + u16 pid, int onoff) { - pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0); + pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig, + Stream1_trans, 0); } -static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) +static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, + u16 pid, int onoff) { - pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0); + pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig, + Stream2_trans, 0); } -static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) +static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, + u16 pid, int onoff) { - pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0); + pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0); } -static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) +static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, + u16 pid, int onoff) { - pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0); + pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0); } -static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) +static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, + u16 pid, int onoff) { - pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0); + pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0); } -static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) +static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, + u16 pid, int onoff) { - pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0); + pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0); } -static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff) +static void flexcop_pid_control(struct flexcop_device *fc, + int index, u16 pid, int onoff) { if (pid == 0x2000) return; - deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off"); + deb_ts("setting pid: %5d %04x at index %d '%s'\n", + pid, pid, index, onoff ? "on" : "off"); /* We could use bit magic here to reduce source code size. * I decided against it, but to use the real register names */ switch (index) { - case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break; - case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break; - case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break; - case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break; - case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break; - case 5: flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break; - default: - if (fc->has_32_hw_pid_filter && index < 38) { - flexcop_ibi_value vpid,vid; - - /* set the index */ - vid = fc->read_ibi_reg(fc,index_reg_310); - vid.index_reg_310.index_reg = index - 6; - fc->write_ibi_reg(fc,index_reg_310, vid); - - vpid = fc->read_ibi_reg(fc,pid_n_reg_314); - vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff; - vpid.pid_n_reg_314.PID_enable_bit = onoff; - fc->write_ibi_reg(fc,pid_n_reg_314, vpid); - } - break; + case 0: + flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff); + break; + case 1: + flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff); + break; + case 2: + flexcop_pid_PCR_PID_ctrl(fc, pid, onoff); + break; + case 3: + flexcop_pid_PMT_PID_ctrl(fc, pid, onoff); + break; + case 4: + flexcop_pid_EMM_PID_ctrl(fc, pid, onoff); + break; + case 5: + flexcop_pid_ECM_PID_ctrl(fc, pid, onoff); + break; + default: + if (fc->has_32_hw_pid_filter && index < 38) { + flexcop_ibi_value vpid, vid; + + /* set the index */ + vid = fc->read_ibi_reg(fc, index_reg_310); + vid.index_reg_310.index_reg = index - 6; + fc->write_ibi_reg(fc, index_reg_310, vid); + + vpid = fc->read_ibi_reg(fc, pid_n_reg_314); + vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff; + vpid.pid_n_reg_314.PID_enable_bit = onoff; + fc->write_ibi_reg(fc, pid_n_reg_314, vpid); + } + break; } } -static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff) +static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff) { if (fc->fullts_streaming_state != onoff) { deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling"); flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff)); - flexcop_pid_group_filter_ctrl(fc,onoff); + flexcop_pid_group_filter_ctrl(fc, onoff); fc->fullts_streaming_state = onoff; } return 0; } -int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff) +int flexcop_pid_feed_control(struct flexcop_device *fc, + struct dvb_demux_feed *dvbdmxfeed, int onoff) { int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; @@ -164,24 +183,25 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d * - or the requested pid is 0x2000 */ if (!fc->pid_filtering && fc->feedcount == onoff) - flexcop_toggle_fullts_streaming(fc,onoff); + flexcop_toggle_fullts_streaming(fc, onoff); if (fc->pid_filtering) { - flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); + flexcop_pid_control \ + (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff); if (fc->extra_feedcount > 0) - flexcop_toggle_fullts_streaming(fc,1); + flexcop_toggle_fullts_streaming(fc, 1); else if (dvbdmxfeed->pid == 0x2000) - flexcop_toggle_fullts_streaming(fc,onoff); + flexcop_toggle_fullts_streaming(fc, onoff); else - flexcop_toggle_fullts_streaming(fc,0); + flexcop_toggle_fullts_streaming(fc, 0); } /* if it was the first or last feed request change the stream-status */ if (fc->feedcount == onoff) { - flexcop_rcv_data_ctrl(fc,onoff); + flexcop_rcv_data_ctrl(fc, onoff); if (fc->stream_control) /* device specific stream control */ - fc->stream_control(fc,onoff); + fc->stream_control(fc, onoff); /* feeding stopped -> reset the flexcop filter*/ if (onoff == 0) { @@ -189,7 +209,6 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d flexcop_hw_filter_init(fc); } } - return 0; } EXPORT_SYMBOL(flexcop_pid_feed_control); @@ -199,15 +218,15 @@ void flexcop_hw_filter_init(struct flexcop_device *fc) int i; flexcop_ibi_value v; for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) - flexcop_pid_control(fc,i,0x1fff,0); + flexcop_pid_control(fc, i, 0x1fff, 0); flexcop_pid_group_filter(fc, 0, 0x1fe0); - flexcop_pid_group_filter_ctrl(fc,0); + flexcop_pid_group_filter_ctrl(fc, 0); - v = fc->read_ibi_reg(fc,pid_filter_308); + v = fc->read_ibi_reg(fc, pid_filter_308); v.pid_filter_308.EMM_filter_4 = 1; v.pid_filter_308.EMM_filter_6 = 0; - fc->write_ibi_reg(fc,pid_filter_308,v); + fc->write_ibi_reg(fc, pid_filter_308, v); flexcop_null_filter_ctrl(fc, 1); } diff --git a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c index 1c07eeafc..06a90f67e 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -1,17 +1,14 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization - * - * see flexcop.c for copyright information. + * see flexcop.c for copyright information */ #include "flexcop.h" #define FC_MAX_I2C_RETRIES 100000 -/* #define DUMP_I2C_MESSAGES */ - -static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100) +static int flexcop_i2c_operation(struct flexcop_device *fc, + flexcop_ibi_value *r100) { int i; flexcop_ibi_value r; @@ -26,7 +23,7 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r r = fc->read_ibi_reg(fc, tw_sm_c_100); if (!r.tw_sm_c_100.no_base_addr_ack_error) { - if (r.tw_sm_c_100.st_done) { /* && !r.tw_sm_c_100.working_start */ + if (r.tw_sm_c_100.st_done) { *r100 = r; deb_i2c("i2c success\n"); return 0; @@ -36,15 +33,17 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r return -EREMOTEIO; } } - deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i); + deb_i2c("tried %d times i2c operation, " + "never finished or too many ack errors.\n", i); return -EREMOTEIO; } static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c, - flexcop_ibi_value r100, u8 *buf) + flexcop_ibi_value r100, u8 *buf) { flexcop_ibi_value r104; - int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */ + int len = r100.tw_sm_c_100.total_bytes, + /* remember total_bytes is buflen-1 */ ret; /* work-around to have CableStar2 and SkyStar2 rev 2.7 work @@ -81,11 +80,11 @@ static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c, if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg; if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg; } - return 0; } -static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf) +static int flexcop_i2c_write4(struct flexcop_device *fc, + flexcop_ibi_value r100, u8 *buf) { flexcop_ibi_value r104; int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */ @@ -93,7 +92,6 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, /* there is at least one byte, otherwise we wouldn't be here */ r100.tw_sm_c_100.data1_reg = buf[0]; - r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0; r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0; r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0; @@ -106,7 +104,7 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, } int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, - flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) + flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) { int ret; @@ -129,7 +127,6 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, printk("rd("); else printk("wr("); - printk("%02x): %02x ", chipaddr, addr); #endif @@ -175,7 +172,8 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, EXPORT_SYMBOL(flexcop_i2c_request); /* master xfer callback for demodulator */ -static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num) { struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap); int i, ret = 0; @@ -194,12 +192,13 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs /* reading */ if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) { ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr, - msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len); + msgs[i].buf[0], msgs[i+1].buf, + msgs[i+1].len); i++; /* skip the following message */ } else /* writing */ ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr, - msgs[i].buf[0], &msgs[i].buf[1], - msgs[i].len - 1); + msgs[i].buf[0], &msgs[i].buf[1], + msgs[i].len - 1); if (ret < 0) { err("i2c master_xfer failed"); break; @@ -229,23 +228,21 @@ static struct i2c_algorithm flexcop_algo = { int flexcop_i2c_init(struct flexcop_device *fc) { int ret; - mutex_init(&fc->i2c_mutex); fc->fc_i2c_adap[0].fc = fc; fc->fc_i2c_adap[1].fc = fc; fc->fc_i2c_adap[2].fc = fc; - fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD; fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM; fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER; strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod", - sizeof(fc->fc_i2c_adap[0].i2c_adap.name)); + sizeof(fc->fc_i2c_adap[0].i2c_adap.name)); strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom", - sizeof(fc->fc_i2c_adap[1].i2c_adap.name)); + sizeof(fc->fc_i2c_adap[1].i2c_adap.name)); strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner", - sizeof(fc->fc_i2c_adap[2].i2c_adap.name)); + sizeof(fc->fc_i2c_adap[2].i2c_adap.name)); i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]); i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); @@ -283,7 +280,6 @@ adap_2_failed: i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); adap_1_failed: i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); - return ret; } @@ -294,6 +290,5 @@ void flexcop_i2c_exit(struct flexcop_device *fc) i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); } - fc->init_state &= ~FC_STATE_I2C_INIT; } diff --git a/linux/drivers/media/dvb/b2c2/flexcop-misc.c b/linux/drivers/media/dvb/b2c2/flexcop-misc.c index 93d20e56f..e56627d2f 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-misc.c @@ -1,9 +1,7 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-misc.c - miscellaneous functions. - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-misc.c - miscellaneous functions + * see flexcop.c for copyright information */ #include "flexcop.h" @@ -12,39 +10,43 @@ void flexcop_determine_revision(struct flexcop_device *fc) flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); switch (v.misc_204.Rev_N_sig_revision_hi) { - case 0x2: - deb_info("found a FlexCopII.\n"); - fc->rev = FLEXCOP_II; - break; - case 0x3: - deb_info("found a FlexCopIIb.\n"); - fc->rev = FLEXCOP_IIB; - break; - case 0x0: - deb_info("found a FlexCopIII.\n"); - fc->rev = FLEXCOP_III; - break; - default: - err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi); - break; + case 0x2: + deb_info("found a FlexCopII.\n"); + fc->rev = FLEXCOP_II; + break; + case 0x3: + deb_info("found a FlexCopIIb.\n"); + fc->rev = FLEXCOP_IIB; + break; + case 0x0: + deb_info("found a FlexCopIII.\n"); + fc->rev = FLEXCOP_III; + break; + default: + err("unknown FlexCop Revision: %x. Please report this to " + "linux-dvb@linuxtv.org.", + v.misc_204.Rev_N_sig_revision_hi); + break; } if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps)) - deb_info("this FlexCop has the additional 32 hardware pid filter.\n"); + deb_info("this FlexCop has " + "the additional 32 hardware pid filter.\n"); else - deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n"); + deb_info("this FlexCop has " + "the 6 basic main hardware pid filter.\n"); /* bus parts have to decide if hw pid filtering is used or not. */ } static const char *flexcop_revision_names[] = { - "Unkown chip", + "Unknown chip", "FlexCopII", "FlexCopIIb", "FlexCopIII", }; static const char *flexcop_device_names[] = { - "Unkown device", + "Unknown device", "Air2PC/AirStar 2 DVB-T", "Air2PC/AirStar 2 ATSC 1st generation", "Air2PC/AirStar 2 ATSC 2nd generation", @@ -61,21 +63,23 @@ static const char *flexcop_bus_names[] = { "PCI", }; -void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const - char *suffix) +void flexcop_device_name(struct flexcop_device *fc, + const char *prefix, const char *suffix) { - info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix, - flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type], - flexcop_revision_names[fc->rev],suffix); + info("%s '%s' at the '%s' bus controlled by a '%s' %s", + prefix, flexcop_device_names[fc->dev_type], + flexcop_bus_names[fc->bus_type], + flexcop_revision_names[fc->rev], suffix); } -void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num) +void flexcop_dump_reg(struct flexcop_device *fc, + flexcop_ibi_register reg, int num) { flexcop_ibi_value v; int i; for (i = 0; i < num; i++) { - v = fc->read_ibi_reg(fc,reg+4*i); - deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw); + v = fc->read_ibi_reg(fc, reg+4*i); + deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw); } deb_rdump("\n"); } diff --git a/linux/drivers/media/dvb/b2c2/flexcop-reg.h b/linux/drivers/media/dvb/b2c2/flexcop-reg.h index 7599fccc1..dc4528dcb 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/linux/drivers/media/dvb/b2c2/flexcop-reg.h @@ -1,14 +1,11 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII - * - * see flexcop.c for copyright information. + * see flexcop.c for copyright information */ #ifndef __FLEXCOP_REG_H__ #define __FLEXCOP_REG_H__ - typedef enum { FLEXCOP_UNK = 0, FLEXCOP_II, @@ -18,13 +15,13 @@ typedef enum { typedef enum { FC_UNK = 0, - FC_AIR_DVB, + FC_CABLE, + FC_AIR_DVBT, FC_AIR_ATSC1, FC_AIR_ATSC2, - FC_SKY, - FC_SKY_OLD, - FC_CABLE, FC_AIR_ATSC3, + FC_SKY_REV23, + FC_SKY_REV26, FC_SKY_REV27, FC_SKY_REV28, } flexcop_device_type_t; @@ -36,12 +33,12 @@ typedef enum { /* FlexCop IBI Registers */ #if defined(__LITTLE_ENDIAN) - #include "flexcop_ibi_value_le.h" +#include "flexcop_ibi_value_le.h" #else #if defined(__BIG_ENDIAN) - #include "flexcop_ibi_value_be.h" +#include "flexcop_ibi_value_be.h" #else - #error no endian defined +#error no endian defined #endif #endif diff --git a/linux/drivers/media/dvb/b2c2/flexcop-sram.c b/linux/drivers/media/dvb/b2c2/flexcop-sram.c index cfb196ef7..d0e82a360 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-sram.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-sram.c @@ -1,45 +1,43 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-sram.c - functions for controlling the SRAM. - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-sram.c - functions for controlling the SRAM + * see flexcop.c for copyright information */ #include "flexcop.h" -static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type) +static void flexcop_sram_set_chip(struct flexcop_device *fc, + flexcop_sram_type_t type) { - flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type); + flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type); } int flexcop_sram_init(struct flexcop_device *fc) { switch (fc->rev) { - case FLEXCOP_II: - case FLEXCOP_IIB: - flexcop_sram_set_chip(fc,FC_SRAM_1_32KB); - break; - case FLEXCOP_III: - flexcop_sram_set_chip(fc,FC_SRAM_1_48KB); - break; - default: - return -EINVAL; + case FLEXCOP_II: + case FLEXCOP_IIB: + flexcop_sram_set_chip(fc, FC_SRAM_1_32KB); + break; + case FLEXCOP_III: + flexcop_sram_set_chip(fc, FC_SRAM_1_48KB); + break; + default: + return -EINVAL; } return 0; } -int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target) +int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, + flexcop_sram_dest_target_t target) { flexcop_ibi_value v; - - v = fc->read_ibi_reg(fc,sram_dest_reg_714); + v = fc->read_ibi_reg(fc, sram_dest_reg_714); if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) { err("SRAM destination target to available on FlexCopII(b)\n"); return -EINVAL; } - - deb_sram("sram dest: %x target: %x\n",dest, target); + deb_sram("sram dest: %x target: %x\n", dest, target); if (dest & FC_SRAM_DEST_NET) v.sram_dest_reg_714.NET_Dest = target; @@ -154,14 +152,12 @@ static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len else bank = 0x10000000; } - flex_sram_write(adapter, bank, addr & 0x7fff, buf, len); } static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len) { u32 bank; - bank = 0; if (adapter->dw_sram_type == 0x20000) { @@ -174,26 +170,22 @@ static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len) else bank = 0x10000000; } - flex_sram_read(adapter, bank, addr & 0x7fff, buf, len); } static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len) { u32 length; - while (len != 0) { length = len; - - // check if the address range belongs to the same - // 32K memory chip. If not, the data is read from - // one chip at a time. + /* check if the address range belongs to the same + * 32K memory chip. If not, the data is read + * from one chip at a time */ if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) { length = (((addr >> 0x0f) + 1) << 0x0f) - addr; } sram_read_chunk(adapter, addr, buf, length); - addr = addr + length; buf = buf + length; len = len - length; @@ -203,19 +195,17 @@ static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len) static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len) { u32 length; - while (len != 0) { length = len; - // check if the address range belongs to the same - // 32K memory chip. If not, the data is written to - // one chip at a time. + /* check if the address range belongs to the same + * 32K memory chip. If not, the data is + * written to one chip at a time */ if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) { length = (((addr >> 0x0f) + 1) << 0x0f) - addr; } sram_write_chunk(adapter, addr, buf, length); - addr = addr + length; buf = buf + length; len = len - length; @@ -224,39 +214,29 @@ static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len) static void sram_set_size(struct adapter *adapter, u32 mask) { - write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c)))); + write_reg_dw(adapter, 0x71c, + (mask | (~0x30000 & read_reg_dw(adapter, 0x71c)))); } static void sram_init(struct adapter *adapter) { u32 tmp; - tmp = read_reg_dw(adapter, 0x71c); - write_reg_dw(adapter, 0x71c, 1); if (read_reg_dw(adapter, 0x71c) != 0) { write_reg_dw(adapter, 0x71c, tmp); - adapter->dw_sram_type = tmp & 0x30000; - ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type); - } else { - adapter->dw_sram_type = 0x10000; - ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type); } - - /* return value is never used? */ -/* return adapter->dw_sram_type; */ } static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) { u8 tmp1, tmp2; - dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr); sram_set_size(adapter, mask); @@ -269,7 +249,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) sram_write(adapter, addr + 4, &tmp1, 1); tmp2 = 0; - mdelay(20); sram_read(adapter, addr, &tmp2, 1); @@ -287,7 +266,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) sram_write(adapter, addr + 4, &tmp1, 1); tmp2 = 0; - mdelay(20); sram_read(adapter, addr, &tmp2, 1); @@ -297,26 +275,24 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) if (tmp2 != 0x5a) return 0; - return 1; } static u32 sram_length(struct adapter *adapter) { if (adapter->dw_sram_type == 0x10000) - return 32768; // 32K + return 32768; /* 32K */ if (adapter->dw_sram_type == 0x00000) - return 65536; // 64K + return 65536; /* 64K */ if (adapter->dw_sram_type == 0x20000) - return 131072; // 128K - - return 32768; // 32K + return 131072; /* 128K */ + return 32768; /* 32K */ } /* FlexcopII can work with 32K, 64K or 128K of external SRAM memory. - - for 128K there are 4x32K chips at bank 0,1,2,3. - - for 64K there are 2x32K chips at bank 1,2. - - for 32K there is one 32K chip at bank 0. + - for 128K there are 4x32K chips at bank 0,1,2,3. + - for 64K there are 2x32K chips at bank 1,2. + - for 32K there is one 32K chip at bank 0. FlexCop works only with one bank at a time. The bank is selected by bits 28-29 of the 0x700 register. @@ -324,24 +300,18 @@ static u32 sram_length(struct adapter *adapter) bank 0 covers addresses 0x00000-0x07fff bank 1 covers addresses 0x08000-0x0ffff bank 2 covers addresses 0x10000-0x17fff - bank 3 covers addresses 0x18000-0x1ffff -*/ + bank 3 covers addresses 0x18000-0x1ffff */ static int flexcop_sram_detect(struct flexcop_device *fc) { - flexcop_ibi_value r208,r71c_0,vr71c_1; - + flexcop_ibi_value r208, r71c_0, vr71c_1; r208 = fc->read_ibi_reg(fc, ctrl_208); fc->write_ibi_reg(fc, ctrl_208, ibi_zero); r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c); - write_reg_dw(adapter, 0x71c, 1); - tmp3 = read_reg_dw(adapter, 0x71c); - dprintk("%s: tmp3 = %x\n", __func__, tmp3); - write_reg_dw(adapter, 0x71c, tmp2); // check for internal SRAM ??? @@ -350,9 +320,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_set_size(adapter, 0x10000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: sram size = 32K\n", __func__); - return 32; } @@ -360,9 +328,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_set_size(adapter, 0x20000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: sram size = 128K\n", __func__); - return 128; } @@ -370,9 +336,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_set_size(adapter, 0x00000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: sram size = 64K\n", __func__); - return 64; } @@ -380,18 +344,14 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_set_size(adapter, 0x10000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: sram size = 32K\n", __func__); - return 32; } sram_set_size(adapter, 0x10000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: SRAM detection failed. Set to 32K \n", __func__); - return 0; } diff --git a/linux/drivers/media/dvb/b2c2/flexcop-usb.h b/linux/drivers/media/dvb/b2c2/flexcop-usb.h index 0e31b9881..5fa250e33 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-usb.h +++ b/linux/drivers/media/dvb/b2c2/flexcop-usb.h @@ -1,15 +1,20 @@ +/* + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-usb.h - header file for the USB part + * see flexcop.c for copyright information + */ #ifndef __FLEXCOP_USB_H_INCLUDED__ #define __FLEXCOP_USB_H_INCLUDED__ #include /* transfer parameters */ -#define B2C2_USB_FRAMES_PER_ISO 4 -#define B2C2_USB_NUM_ISO_URB 4 +#define B2C2_USB_FRAMES_PER_ISO 4 +#define B2C2_USB_NUM_ISO_URB 4 -#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev,0) -#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev,0) -#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev,0x81) +#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0) +#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0) +#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81) struct flexcop_usb { struct usb_device *udev; @@ -18,8 +23,8 @@ struct flexcop_usb { u8 *iso_buffer; int buffer_size; dma_addr_t dma_addr; - struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; + struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; struct flexcop_device *fc_dev; u8 tmp_buffer[1023+190]; @@ -30,14 +35,6 @@ struct flexcop_usb { /* request types TODO What is its use?*/ typedef enum { -/* something is wrong with this part - RTYPE_READ_DW = (1 << 6), - RTYPE_WRITE_DW_1 = (3 << 6), - RTYPE_READ_V8_MEMORY = (6 << 6), - RTYPE_WRITE_V8_MEMORY = (7 << 6), - RTYPE_WRITE_V8_FLASH = (8 << 6), - RTYPE_GENERIC = (9 << 6), -*/ } flexcop_usb_request_type_t; #endif @@ -47,7 +44,6 @@ typedef enum { B2C2_USB_READ_V8_MEM = 0x05, B2C2_USB_READ_REG = 0x08, B2C2_USB_WRITE_REG = 0x0A, -/* B2C2_USB_WRITEREGLO = 0x0A, */ B2C2_USB_WRITEREGHI = 0x0B, B2C2_USB_FLASH_BLOCK = 0x10, B2C2_USB_I2C_REQUEST = 0x11, @@ -62,15 +58,13 @@ typedef enum { USB_FUNC_I2C_REPEATWRITE = 0x04, USB_FUNC_GET_DESCRIPTOR = 0x05, USB_FUNC_I2C_REPEATREAD = 0x06, -/* DKT 020208 - add this to support special case of DiSEqC */ + /* DKT 020208 - add this to support special case of DiSEqC */ USB_FUNC_I2C_CHECKWRITE = 0x07, USB_FUNC_I2C_CHECKRESULT = 0x08, } flexcop_usb_i2c_function_t; -/* - * function definition for UTILITY request 0x12 - * DKT 020304 - new utility function - */ +/* function definition for UTILITY request 0x12 + * DKT 020304 - new utility function */ typedef enum { UTILITY_SET_FILTER = 0x01, UTILITY_DATA_ENABLE = 0x02, @@ -84,7 +78,7 @@ typedef enum { UTILITY_DATA_RESET = 0x0A, UTILITY_GET_DATA_STATUS = 0x10, UTILITY_GET_V8_REG = 0x11, -/* DKT 020326 - add function for v1.14 */ + /* DKT 020326 - add function for v1.14 */ UTILITY_SRAM_WRITE = 0x12, UTILITY_SRAM_READ = 0x13, UTILITY_SRAM_TESTFILL = 0x14, @@ -92,13 +86,13 @@ typedef enum { UTILITY_SRAM_TESTVERIFY = 0x16, } flexcop_usb_utility_function_t; -#define B2C2_WAIT_FOR_OPERATION_RW 1*HZ /* 1 s */ -#define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ /* 3 s */ -#define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ /* 1 s */ +#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ) +#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ) +#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ) -#define B2C2_WAIT_FOR_OPERATION_V8READ 3*HZ /* 3 s */ -#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3*HZ /* 3 s */ -#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3*HZ /* 3 s */ +#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ) +#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ) +#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ) typedef enum { V8_MEMORY_PAGE_DVB_CI = 0x20, @@ -107,13 +101,11 @@ typedef enum { V8_MEMORY_PAGE_FLASH = 0x80 } flexcop_usb_mem_page_t; -#define V8_MEMORY_EXTENDED (1 << 15) - -#define USB_MEM_READ_MAX 32 -#define USB_MEM_WRITE_MAX 1 -#define USB_FLASH_MAX 8 - -#define V8_MEMORY_PAGE_SIZE 0x8000 // 32K -#define V8_MEMORY_PAGE_MASK 0x7FFF +#define V8_MEMORY_EXTENDED (1 << 15) +#define USB_MEM_READ_MAX 32 +#define USB_MEM_WRITE_MAX 1 +#define USB_FLASH_MAX 8 +#define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */ +#define V8_MEMORY_PAGE_MASK 0x7FFF #endif diff --git a/linux/drivers/media/dvb/b2c2/flexcop.c b/linux/drivers/media/dvb/b2c2/flexcop.c index e836caece..2df1b0214 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop.c +++ b/linux/drivers/media/dvb/b2c2/flexcop.c @@ -1,22 +1,20 @@ /* - * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * Copyright (C) 2004-5 Patrick Boettcher - * - * based on the skystar2-driver - * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop.c - main module part + * Copyright (C) 2004-9 Patrick Boettcher + * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc * * Acknowledgements: - * John Jurrius from BBTI, Inc. for extensive support with - * code examples and data books - * - * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting) + * John Jurrius from BBTI, Inc. for extensive support + * with code examples and data books + * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting) * * Contributions to the skystar2-driver have been done by - * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes) - * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code) - * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering) - * + * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes) + * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code) + * Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu) + * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac + * filtering) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -46,7 +44,10 @@ int b2c2_flexcop_debug; module_param_named(debug, b2c2_flexcop_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS); +MODULE_PARM_DESC(debug, + "set debug level (1=info,2=tuner,4=i2c,8=ts," + "16=sram,32=reg (|-able))." + DEBSTATUS); #undef DEBSTATUS DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -57,37 +58,36 @@ flexcop_ibi_value ibi_zero; static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) { struct flexcop_device *fc = dvbdmxfeed->demux->priv; - return flexcop_pid_feed_control(fc,dvbdmxfeed,1); + return flexcop_pid_feed_control(fc, dvbdmxfeed, 1); } static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) { struct flexcop_device *fc = dvbdmxfeed->demux->priv; - return flexcop_pid_feed_control(fc,dvbdmxfeed,0); + return flexcop_pid_feed_control(fc, dvbdmxfeed, 0); } static int flexcop_dvb_init(struct flexcop_device *fc) { int ret = dvb_register_adapter(&fc->dvb_adapter, - "FlexCop Digital TV device", fc->owner, - fc->dev, adapter_nr); + "FlexCop Digital TV device", fc->owner, + fc->dev, adapter_nr); if (ret < 0) { err("error registering DVB adapter"); return ret; } fc->dvb_adapter.priv = fc; - fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); + fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING + | DMX_MEMORY_BASED_FILTERING); fc->demux.priv = fc; - fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED; - fc->demux.start_feed = flexcop_dvb_start_feed; fc->demux.stop_feed = flexcop_dvb_stop_feed; fc->demux.write_to_decoder = NULL; if ((ret = dvb_dmx_init(&fc->demux)) < 0) { - err("dvb_dmx failed: error %d",ret); + err("dvb_dmx failed: error %d", ret); goto err_dmx; } @@ -97,23 +97,23 @@ static int flexcop_dvb_init(struct flexcop_device *fc) fc->dmxdev.demux = &fc->demux.dmx; fc->dmxdev.capabilities = 0; if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) { - err("dvb_dmxdev_init failed: error %d",ret); + err("dvb_dmxdev_init failed: error %d", ret); goto err_dmx_dev; } if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { - err("adding hw_frontend to dmx failed: error %d",ret); + err("adding hw_frontend to dmx failed: error %d", ret); goto err_dmx_add_hw_frontend; } fc->mem_frontend.source = DMX_MEMORY_FE; if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) { - err("adding mem_frontend to dmx failed: error %d",ret); + err("adding mem_frontend to dmx failed: error %d", ret); goto err_dmx_add_mem_frontend; } if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { - err("connect frontend failed: error %d",ret); + err("connect frontend failed: error %d", ret); goto err_connect_frontend; } @@ -123,9 +123,9 @@ static int flexcop_dvb_init(struct flexcop_device *fc) return 0; err_connect_frontend: - fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); + fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend); err_dmx_add_mem_frontend: - fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend); + fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend); err_dmx_add_hw_frontend: dvb_dmxdev_release(&fc->dmxdev); err_dmx_dev: @@ -141,12 +141,13 @@ static void flexcop_dvb_exit(struct flexcop_device *fc) dvb_net_release(&fc->dvbnet); fc->demux.dmx.close(&fc->demux.dmx); - fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); - fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend); + fc->demux.dmx.remove_frontend(&fc->demux.dmx, + &fc->mem_frontend); + fc->demux.dmx.remove_frontend(&fc->demux.dmx, + &fc->hw_frontend); dvb_dmxdev_release(&fc->dmxdev); dvb_dmx_release(&fc->demux); dvb_unregister_adapter(&fc->dvb_adapter); - deb_info("deinitialized dvb stuff\n"); } fc->init_state &= ~FC_STATE_DVB_INIT; @@ -168,9 +169,9 @@ EXPORT_SYMBOL(flexcop_pass_dmx_packets); static void flexcop_reset(struct flexcop_device *fc) { - flexcop_ibi_value v210,v204; + flexcop_ibi_value v210, v204; -/* reset the flexcop itself */ + /* reset the flexcop itself */ fc->write_ibi_reg(fc,ctrl_208,ibi_zero); v210.raw = 0; @@ -183,13 +184,11 @@ static void flexcop_reset(struct flexcop_device *fc) v210.sw_reset_210.reset_block_600 = 1; v210.sw_reset_210.reset_block_700 = 1; v210.sw_reset_210.Block_reset_enable = 0xb2; - v210.sw_reset_210.Special_controls = 0xc259; - fc->write_ibi_reg(fc,sw_reset_210,v210); msleep(1); -/* reset the periphical devices */ + /* reset the periphical devices */ v204 = fc->read_ibi_reg(fc,misc_204); v204.misc_204.Per_reset_sig = 0; @@ -201,11 +200,10 @@ static void flexcop_reset(struct flexcop_device *fc) void flexcop_reset_block_300(struct flexcop_device *fc) { - flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208), - v210 = fc->read_ibi_reg(fc,sw_reset_210); - - deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw); + flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208), + v210 = fc->read_ibi_reg(fc, sw_reset_210); + deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw); fc->write_ibi_reg(fc,ctrl_208,ibi_zero); v210.sw_reset_210.reset_block_300 = 1; @@ -218,7 +216,8 @@ void flexcop_reset_block_300(struct flexcop_device *fc) struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len) { void *bus; - struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), GFP_KERNEL); + struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), + GFP_KERNEL); if (!fc) { err("no memory"); return NULL; @@ -253,7 +252,6 @@ int flexcop_device_initialize(struct flexcop_device *fc) flexcop_determine_revision(fc); flexcop_sram_init(fc); flexcop_hw_filter_init(fc); - flexcop_smc_ctrl(fc, 0); if ((ret = flexcop_dvb_init(fc))) @@ -278,7 +276,6 @@ int flexcop_device_initialize(struct flexcop_device *fc) goto error; flexcop_device_name(fc,"initialization of","complete"); - return 0; error: diff --git a/linux/drivers/media/dvb/b2c2/flexcop.h b/linux/drivers/media/dvb/b2c2/flexcop.h index 0cebe1d92..897b10c85 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop.h +++ b/linux/drivers/media/dvb/b2c2/flexcop.h @@ -1,9 +1,7 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop.h - private header file for all flexcop-chip-source files. - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop.h - private header file for all flexcop-chip-source files + * see flexcop.c for copyright information */ #ifndef __FLEXCOP_H__ #define __FLEXCOP_H___ @@ -21,11 +19,11 @@ extern int b2c2_flexcop_debug; #define dprintk(level,args...) #endif -#define deb_info(args...) dprintk(0x01,args) -#define deb_tuner(args...) dprintk(0x02,args) -#define deb_i2c(args...) dprintk(0x04,args) -#define deb_ts(args...) dprintk(0x08,args) -#define deb_sram(args...) dprintk(0x10,args) -#define deb_rdump(args...) dprintk(0x20,args) +#define deb_info(args...) dprintk(0x01, args) +#define deb_tuner(args...) dprintk(0x02, args) +#define deb_i2c(args...) dprintk(0x04, args) +#define deb_ts(args...) dprintk(0x08, args) +#define deb_sram(args...) dprintk(0x10, args) +#define deb_rdump(args...) dprintk(0x20, args) #endif diff --git a/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h index ed9a6756b..8f64bdbd7 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h +++ b/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h @@ -1,10 +1,7 @@ -/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * +/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III * register descriptions - * - * see flexcop.c for copyright information. + * see flexcop.c for copyright information */ - /* This file is automatically generated, do not edit things here. */ #ifndef __FLEXCOP_IBI_VALUE_INCLUDED__ #define __FLEXCOP_IBI_VALUE_INCLUDED__ diff --git a/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h index 49f2315b6..c75830d7d 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h +++ b/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h @@ -1,10 +1,7 @@ -/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * +/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III * register descriptions - * - * see flexcop.c for copyright information. + * see flexcop.c for copyright information */ - /* This file is automatically generated, do not edit things here. */ #ifndef __FLEXCOP_IBI_VALUE_INCLUDED__ #define __FLEXCOP_IBI_VALUE_INCLUDED__ -- cgit v1.2.3 From a4a53ca9c540139e89446d304d7f83c79bd96b84 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sun, 29 Mar 2009 13:13:01 +0200 Subject: Code cleanup (passes checkpatch now) of the b2c2-flexcop-drivers 2/2 From: Uwe Bugla This is the second part of the code cleanup changing the usb and pci-driver cores. Priority: normal Signed-off-by: Uwe Bugla Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/flexcop-pci.c | 180 +++++++------- linux/drivers/media/dvb/b2c2/flexcop-usb.c | 368 ++++++++++++++++------------- 2 files changed, 289 insertions(+), 259 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop-pci.c b/linux/drivers/media/dvb/b2c2/flexcop-pci.c index 72710fee2..e3ee05d98 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-pci.c @@ -1,9 +1,7 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-pci.c - covers the PCI part including DMA transfers. - * - * see flexcop.c for copyright information. + * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-pci.c - covers the PCI part including DMA transfers + * see flexcop.c for copyright information */ #define FC_LOG_PREFIX "flexcop-pci" @@ -11,7 +9,8 @@ static int enable_pid_filtering = 1; module_param(enable_pid_filtering, int, 0444); -MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); +MODULE_PARM_DESC(enable_pid_filtering, + "enable hardware pid filtering: supported values: 0 (fullts), 1"); static int irq_chk_intv = 100; module_param(irq_chk_intv, int, 0644); @@ -26,17 +25,17 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); #define DEBSTATUS " (debugging is not enabled)" #endif -#define deb_info(args...) dprintk(0x01,args) -#define deb_reg(args...) dprintk(0x02,args) -#define deb_ts(args...) dprintk(0x04,args) -#define deb_irq(args...) dprintk(0x08,args) -#define deb_chk(args...) dprintk(0x10,args) +#define deb_info(args...) dprintk(0x01, args) +#define deb_reg(args...) dprintk(0x02, args) +#define deb_ts(args...) dprintk(0x04, args) +#define deb_irq(args...) dprintk(0x08, args) +#define deb_chk(args...) dprintk(0x10, args) static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))." - DEBSTATUS); + DEBSTATUS); #define DRIVER_VERSION "0.1" #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" @@ -51,30 +50,30 @@ struct flexcop_pci { void __iomem *io_mem; u32 irq; -/* buffersize (at least for DMA1, need to be % 188 == 0, - * this logic is required */ + /* buffersize (at least for DMA1, need to be % 188 == 0, + * this logic is required */ #define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188) #define FC_DEFAULT_DMA2_BUFSIZE (10 * 188) struct flexcop_dma dma[2]; int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ - u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ + u32 last_dma1_cur_pos; + /* position of the pointer last time the timer/packet irq occured */ int count; int count_prev; int stream_problem; spinlock_t irq_lock; - unsigned long last_irq; struct delayed_work irq_check_work; - struct flexcop_device *fc_dev; }; -static int lastwreg,lastwval,lastrreg,lastrval; +static int lastwreg, lastwval, lastrreg, lastrval; -static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r) +static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc, + flexcop_ibi_register r) { struct flexcop_pci *fc_pci = fc->bus_specific; flexcop_ibi_value v; @@ -82,19 +81,20 @@ static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, fl if (lastrreg != r || lastrval != v.raw) { lastrreg = r; lastrval = v.raw; - deb_reg("new rd: %3x: %08x\n",r,v.raw); + deb_reg("new rd: %3x: %08x\n", r, v.raw); } return v; } -static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v) +static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, + flexcop_ibi_register r, flexcop_ibi_value v) { struct flexcop_pci *fc_pci = fc->bus_specific; if (lastwreg != r || lastwval != v.raw) { lastwreg = r; lastwval = v.raw; - deb_reg("new wr: %3x: %08x\n",r,v.raw); + deb_reg("new wr: %3x: %08x\n", r, v.raw); } writel(v.raw, fc_pci->io_mem + r); @@ -119,14 +119,14 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) #if 0 flexcop_ibi_value v = fc->read_ibi_reg(fc, sram_dest_reg_714); deb_chk("net_ovflow_error: %d, media_ovflow_error: %d," - "cai_ovflow_error: %d, cao_ovflow_error: %d, " - "sram_dma: %d, maximumfill: %d\n", - v.sram_dest_reg_714.net_ovflow_error, - v.sram_dest_reg_714.media_ovflow_error, - v.sram_dest_reg_714.cai_ovflow_error, - v.sram_dest_reg_714.cao_ovflow_error, - v.sram_dest_reg_714.ctrl_sramdma, - v.sram_dest_reg_714.ctrl_maximumfill); + "cai_ovflow_error: %d, cao_ovflow_error: %d, " + "sram_dma: %d, maximumfill: %d\n", + v.sram_dest_reg_714.net_ovflow_error, + v.sram_dest_reg_714.media_ovflow_error, + v.sram_dest_reg_714.cai_ovflow_error, + v.sram_dest_reg_714.cao_ovflow_error, + v.sram_dest_reg_714.ctrl_sramdma, + v.sram_dest_reg_714.ctrl_maximumfill); #endif if (fc_pci->count == fc_pci->count_prev) { @@ -137,12 +137,12 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) spin_lock_irq(&fc->demux.lock); list_for_each_entry(feed, &fc->demux.feed_list, - list_head) { + list_head) { flexcop_pid_feed_control(fc, feed, 0); } list_for_each_entry(feed, &fc->demux.feed_list, - list_head) { + list_head) { flexcop_pid_feed_control(fc, feed, 1); } spin_unlock_irq(&fc->demux.lock); @@ -174,11 +174,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) flexcop_ibi_value v; irqreturn_t ret = IRQ_HANDLED; - spin_lock_irqsave(&fc_pci->irq_lock,flags); - - v = fc->read_ibi_reg(fc,irq_20c); + spin_lock_irqsave(&fc_pci->irq_lock, flags); + v = fc->read_ibi_reg(fc, irq_20c); - /* errors */ + /* errors */ if (v.irq_20c.Data_receiver_error) deb_chk("data receiver error\n"); if (v.irq_20c.Continuity_error_flag) @@ -189,24 +188,29 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) deb_chk("Transport error\n"); if ((fc_pci->count % 1000) == 0) - deb_chk("%d valid irq took place so far\n",fc_pci->count); + deb_chk("%d valid irq took place so far\n", fc_pci->count); if (v.irq_20c.DMA1_IRQ_Status == 1) { if (fc_pci->active_dma1_addr == 0) - flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188); + flexcop_pass_dmx_packets(fc_pci->fc_dev, + fc_pci->dma[0].cpu_addr0, + fc_pci->dma[0].size / 188); else - flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188); + flexcop_pass_dmx_packets(fc_pci->fc_dev, + fc_pci->dma[0].cpu_addr1, + fc_pci->dma[0].size / 188); deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr); fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr; - } else if (v.irq_20c.DMA1_Timer_Status == 1) { /* for the timer IRQ we only can use buffer dmx feeding, because we don't have * complete TS packets when reading from the DMA memory */ + } else if (v.irq_20c.DMA1_Timer_Status == 1) { dma_addr_t cur_addr = fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; - deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ", + deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, " + "last_cur_pos: %08x ", jiffies_to_usecs(jiffies - fc_pci->last_irq), v.raw, (unsigned long long)cur_addr, cur_pos, fc_pci->last_dma1_cur_pos); @@ -216,30 +220,36 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) * pass the data from last_cur_pos to the buffer end to the demux */ if (cur_pos < fc_pci->last_dma1_cur_pos) { - deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos); + deb_irq(" end was reached: passing %d bytes ", + (fc_pci->dma[0].size*2 - 1) - + fc_pci->last_dma1_cur_pos); flexcop_pass_dmx_data(fc_pci->fc_dev, - fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, - (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos); + fc_pci->dma[0].cpu_addr0 + + fc_pci->last_dma1_cur_pos, + (fc_pci->dma[0].size*2) - + fc_pci->last_dma1_cur_pos); fc_pci->last_dma1_cur_pos = 0; } if (cur_pos > fc_pci->last_dma1_cur_pos) { - deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos); + deb_irq(" passing %d bytes ", + cur_pos - fc_pci->last_dma1_cur_pos); flexcop_pass_dmx_data(fc_pci->fc_dev, - fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, - cur_pos - fc_pci->last_dma1_cur_pos); + fc_pci->dma[0].cpu_addr0 + + fc_pci->last_dma1_cur_pos, + cur_pos - fc_pci->last_dma1_cur_pos); } deb_irq("\n"); fc_pci->last_dma1_cur_pos = cur_pos; fc_pci->count++; } else { - deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw); + deb_irq("isr for flexcop called, " + "apparently without reason (%08x)\n", v.raw); ret = IRQ_NONE; } - spin_unlock_irqrestore(&fc_pci->irq_lock,flags); - + spin_unlock_irqrestore(&fc_pci->irq_lock, flags); return ret; } @@ -247,52 +257,48 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) { struct flexcop_pci *fc_pci = fc->bus_specific; if (onoff) { - flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1); - flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2); - - flexcop_dma_config_timer(fc,FC_DMA_1,0); - - flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1); + flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1); + flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2); + flexcop_dma_config_timer(fc, FC_DMA_1, 0); + flexcop_dma_xfer_control(fc, FC_DMA_1, + FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1); deb_irq("DMA xfer enabled\n"); fc_pci->last_dma1_cur_pos = 0; - flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); + flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1); deb_irq("IRQ enabled\n"); - fc_pci->count_prev = fc_pci->count; - -// fc_pci->active_dma1_addr = 0; -// flexcop_dma_control_size_irq(fc,FC_DMA_1,1); - } else { - flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); + flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0); deb_irq("IRQ disabled\n"); -// flexcop_dma_control_size_irq(fc,FC_DMA_1,0); - - flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0); + flexcop_dma_xfer_control(fc, FC_DMA_1, + FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0); deb_irq("DMA xfer disabled\n"); } - return 0; } static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci) { int ret; - if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) + ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0], + FC_DEFAULT_DMA1_BUFSIZE); + if (ret != 0) return ret; - if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) { + ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1], + FC_DEFAULT_DMA2_BUFSIZE); + if (ret != 0) { flexcop_dma_free(&fc_pci->dma[0]); return ret; } - flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); - flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); - + flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA | + FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); + flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO | + FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); fc_pci->init_state |= FC_PCI_DMA_INIT; - return ret; } @@ -315,12 +321,8 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) if ((ret = pci_enable_device(fc_pci->pdev)) != 0) return ret; - pci_set_master(fc_pci->pdev); - /* enable interrupts */ - // pci_write_config_dword(pdev, 0x6c, 0x8000); - if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0) goto err_pci_disable_device; @@ -363,8 +365,8 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci) fc_pci->init_state &= ~FC_PCI_INIT; } - -static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int flexcop_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { struct flexcop_device *fc; struct flexcop_pci *fc_pci; @@ -375,7 +377,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e return -ENOMEM; } -/* general flexcop init */ + /* general flexcop init */ fc_pci = fc->bus_specific; fc_pci->fc_dev = fc; @@ -383,7 +385,6 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e fc->write_ibi_reg = flexcop_pci_write_ibi_reg; fc->i2c_request = flexcop_i2c_request; fc->get_mac_addr = flexcop_eeprom_check_mac_addr; - fc->stream_control = flexcop_pci_stream_control; if (enable_pid_filtering) @@ -393,20 +394,19 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e fc->pid_filtering = enable_pid_filtering; fc->bus_type = FC_PCI; - fc->dev = &pdev->dev; fc->owner = THIS_MODULE; -/* bus specific part */ + /* bus specific part */ fc_pci->pdev = pdev; if ((ret = flexcop_pci_init(fc_pci)) != 0) goto err_kfree; -/* init flexcop */ + /* init flexcop */ if ((ret = flexcop_device_initialize(fc)) != 0) goto err_pci_exit; -/* init dma */ + /* init dma */ if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) goto err_fc_exit; @@ -416,10 +416,11 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); #endif - if (irq_chk_intv > 0) - schedule_delayed_work(&fc_pci->irq_check_work, - msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); - + if (irq_chk_intv > 0) + schedule_delayed_work(&fc_pci->irq_check_work, + msecs_to_jiffies(irq_chk_intv < 100 ? + 100 : + irq_chk_intv)); return ret; err_fc_exit: @@ -449,7 +450,6 @@ static void flexcop_pci_remove(struct pci_dev *pdev) static struct pci_device_id flexcop_pci_tbl[] = { { PCI_DEVICE(0x13d0, 0x2103) }, -/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */ { }, }; diff --git a/linux/drivers/media/dvb/b2c2/flexcop-usb.c b/linux/drivers/media/dvb/b2c2/flexcop-usb.c index 4be298e90..65206b656 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-usb.c @@ -1,11 +1,8 @@ /* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-usb.c - covers the USB part. - * - * see flexcop.c for copyright information. + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-usb.c - covers the USB part + * see flexcop.c for copyright information */ - #define FC_LOG_PREFIX "flexcop_usb" #include "flexcop-usb.h" #include "flexcop-common.h" @@ -18,42 +15,47 @@ /* debug */ #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG #define dprintk(level,args...) \ - do { if ((debug & level)) { printk(args); } } while (0) -#define debug_dump(b,l,method) {\ + do { if ((debug & level)) printk(args); } while (0) + +#define debug_dump(b, l, method) do {\ int i; \ - for (i = 0; i < l; i++) method("%02x ", b[i]); \ - method("\n");\ -} + for (i = 0; i < l; i++) \ + method("%02x ", b[i]); \ + method("\n"); \ +} while (0) #define DEBSTATUS "" #else -#define dprintk(level,args...) -#define debug_dump(b,l,method) +#define dprintk(level, args...) +#define debug_dump(b, l, method) #define DEBSTATUS " (debugging is not enabled)" #endif static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); +MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2," + "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); #undef DEBSTATUS -#define deb_info(args...) dprintk(0x01,args) -#define deb_ts(args...) dprintk(0x02,args) -#define deb_ctrl(args...) dprintk(0x04,args) -#define deb_i2c(args...) dprintk(0x08,args) -#define deb_v8(args...) dprintk(0x10,args) +#define deb_info(args...) dprintk(0x01, args) +#define deb_ts(args...) dprintk(0x02, args) +#define deb_ctrl(args...) dprintk(0x04, args) +#define deb_i2c(args...) dprintk(0x08, args) +#define deb_v8(args...) dprintk(0x10, args) /* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits * in the IBI address, to make the V8 code simpler. - * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used) + * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used) * in general: 0000 0HHH 000L LL00 * IBI ADDRESS FORMAT: RHHH BLLL * * where R is the read(1)/write(0) bit, B is the busy bit * and HHH and LLL are the two sets of three bits from the PCI address. */ -#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70)) -#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4)) +#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \ + (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70)) +#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \ + (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4)) /* * DKT 020228 @@ -69,12 +71,13 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, struct flexcop_usb *fc_usb = fc->bus_specific; u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG; u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR; - u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0); + u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | + (read ? 0x80 : 0); int len = usb_control_msg(fc_usb->udev, read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT, request, - request_type, /* 0xc0 read or 0x40 write*/ + request_type, /* 0xc0 read or 0x40 write */ wAddress, 0, val, @@ -82,55 +85,49 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, B2C2_WAIT_FOR_OPERATION_RDW * HZ); if (len != sizeof(u32)) { - err("error while %s dword from %d (%d).",read ? "reading" : "writing", - wAddress,wRegOffsPCI); + err("error while %s dword from %d (%d).", read ? "reading" : + "writing", wAddress, wRegOffsPCI); return -EIO; } return 0; } - /* * DKT 010817 - add support for V8 memory read/write and flash update */ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb, flexcop_usb_request_t req, u8 page, u16 wAddress, - u8 *pbBuffer,u32 buflen) + u8 *pbBuffer, u32 buflen) { -// u8 dwRequestType; u8 request_type = USB_TYPE_VENDOR; u16 wIndex; - int nWaitTime,pipe,len; - + int nWaitTime, pipe, len; wIndex = page << 8; switch (req) { - case B2C2_USB_READ_V8_MEM: - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ; - request_type |= USB_DIR_IN; -// dwRequestType = (u8) RTYPE_READ_V8_MEMORY; - pipe = B2C2_USB_CTRL_PIPE_IN; + case B2C2_USB_READ_V8_MEM: + nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ; + request_type |= USB_DIR_IN; + pipe = B2C2_USB_CTRL_PIPE_IN; break; - case B2C2_USB_WRITE_V8_MEM: - wIndex |= pbBuffer[0]; - request_type |= USB_DIR_OUT; - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE; -// dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY; - pipe = B2C2_USB_CTRL_PIPE_OUT; + case B2C2_USB_WRITE_V8_MEM: + wIndex |= pbBuffer[0]; + request_type |= USB_DIR_OUT; + nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE; + pipe = B2C2_USB_CTRL_PIPE_OUT; break; - case B2C2_USB_FLASH_BLOCK: - request_type |= USB_DIR_OUT; - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH; -// dwRequestType = (u8) RTYPE_WRITE_V8_FLASH; - pipe = B2C2_USB_CTRL_PIPE_OUT; + case B2C2_USB_FLASH_BLOCK: + request_type |= USB_DIR_OUT; + nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH; + pipe = B2C2_USB_CTRL_PIPE_OUT; break; - default: - deb_info("unsupported request for v8_mem_req %x.\n",req); + default: + deb_info("unsupported request for v8_mem_req %x.\n", req); return -EINVAL; } - deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req, - wAddress,wIndex,buflen); + deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req, + wAddress, wIndex, buflen); - len = usb_control_msg(fc_usb->udev,pipe, + len = usb_control_msg(fc_usb->udev, pipe, req, request_type, wAddress, @@ -139,39 +136,53 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb, buflen, nWaitTime * HZ); - debug_dump(pbBuffer,len,deb_v8); - + debug_dump(pbBuffer, len, deb_v8); return len == buflen ? 0 : -EIO; } #define bytes_left_to_read_on_page(paddr,buflen) \ - ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \ - ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK))) + ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \ + ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK))) -static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req, - flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len) +static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb, + flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start, + u32 addr, int extended, u8 *buf, u32 len) { int i,ret = 0; u16 wMax; u32 pagechunk = 0; switch(req) { - case B2C2_USB_READ_V8_MEM: wMax = USB_MEM_READ_MAX; break; - case B2C2_USB_WRITE_V8_MEM: wMax = USB_MEM_WRITE_MAX; break; - case B2C2_USB_FLASH_BLOCK: wMax = USB_FLASH_MAX; break; - default: - return -EINVAL; + case B2C2_USB_READ_V8_MEM: + wMax = USB_MEM_READ_MAX; + break; + case B2C2_USB_WRITE_V8_MEM: + wMax = USB_MEM_WRITE_MAX; + break; + case B2C2_USB_FLASH_BLOCK: + wMax = USB_FLASH_MAX; + break; + default: + return -EINVAL; break; } for (i = 0; i < len;) { - pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len); - deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended)); - if ((ret = flexcop_usb_v8_memory_req(fc_usb,req, - page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */ - (addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended), - &buf[i],pagechunk)) < 0) + pagechunk = + wMax < bytes_left_to_read_on_page(addr, len) ? + wMax : + bytes_left_to_read_on_page(addr, len); + deb_info("%x\n", + (addr & V8_MEMORY_PAGE_MASK) | + (V8_MEMORY_EXTENDED*extended)); + + ret = flexcop_usb_v8_memory_req(fc_usb, req, + page_start + (addr / V8_MEMORY_PAGE_SIZE), + (addr & V8_MEMORY_PAGE_MASK) | + (V8_MEMORY_EXTENDED*extended), + &buf[i], pagechunk); + + if (ret < 0) return ret; - addr += pagechunk; len -= pagechunk; } @@ -180,8 +191,9 @@ static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended) { - return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM, - V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6); + return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM, + V8_MEMORY_PAGE_FLASH, 0x1f010, 1, + fc->dvb_adapter.proposed_mac, 6); } #if 0 /* keep */ @@ -191,11 +203,8 @@ static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set, { u16 wValue; u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR; -// u8 dwRequestType = (u8) RTYPE_GENERIC, int nWaitTime = 2, - pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, - len; - + pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len; wValue = (func << 8) | extra; len = usb_control_msg(fc_usb->udev,pipe, @@ -218,36 +227,35 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, struct flexcop_usb *fc_usb = i2c->fc->bus_specific; u16 wValue, wIndex; int nWaitTime,pipe,len; -// u8 dwRequestType; u8 request_type = USB_TYPE_VENDOR; switch (func) { - case USB_FUNC_I2C_WRITE: - case USB_FUNC_I2C_MULTIWRITE: - case USB_FUNC_I2C_REPEATWRITE: + case USB_FUNC_I2C_WRITE: + case USB_FUNC_I2C_MULTIWRITE: + case USB_FUNC_I2C_REPEATWRITE: /* DKT 020208 - add this to support special case of DiSEqC */ - case USB_FUNC_I2C_CHECKWRITE: - pipe = B2C2_USB_CTRL_PIPE_OUT; - nWaitTime = 2; -// dwRequestType = (u8) RTYPE_GENERIC; - request_type |= USB_DIR_OUT; + case USB_FUNC_I2C_CHECKWRITE: + pipe = B2C2_USB_CTRL_PIPE_OUT; + nWaitTime = 2; + request_type |= USB_DIR_OUT; break; - case USB_FUNC_I2C_READ: - case USB_FUNC_I2C_REPEATREAD: - pipe = B2C2_USB_CTRL_PIPE_IN; - nWaitTime = 2; -// dwRequestType = (u8) RTYPE_GENERIC; - request_type |= USB_DIR_IN; + case USB_FUNC_I2C_READ: + case USB_FUNC_I2C_REPEATREAD: + pipe = B2C2_USB_CTRL_PIPE_IN; + nWaitTime = 2; + request_type |= USB_DIR_IN; break; - default: - deb_info("unsupported function for i2c_req %x\n",func); - return -EINVAL; + default: + deb_info("unsupported function for i2c_req %x\n", func); + return -EINVAL; } wValue = (func << 8) | (i2c->port << 4); wIndex = (chipaddr << 8 ) | addr; - deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, - wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8); + deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n", + func, request_type, req, + wValue & 0xff, wValue >> 8, + wIndex & 0xff, wIndex >> 8); len = usb_control_msg(fc_usb->udev,pipe, req, @@ -257,44 +265,49 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, buf, buflen, nWaitTime * HZ); - return len == buflen ? 0 : -EREMOTEIO; } -/* actual bus specific access functions, make sure prototype are/will be equal to pci */ -static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg) +/* actual bus specific access functions, + make sure prototype are/will be equal to pci */ +static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, + flexcop_ibi_register reg) { flexcop_ibi_value val; val.raw = 0; - flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1); + flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1); return val; } -static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val) +static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, + flexcop_ibi_register reg, flexcop_ibi_value val) { - return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0); + return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0); } static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c, - flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) + flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) { if (op == FC_READ) return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, - USB_FUNC_I2C_READ, chipaddr, addr, buf, len); + USB_FUNC_I2C_READ, chipaddr, addr, buf, len); else return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, - USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len); + USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len); } -static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length) +static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, + u8 *buffer, int buffer_length) { u8 *b; int l; - deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length); + deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", + fc_usb->tmp_buffer_length, buffer_length); if (fc_usb->tmp_buffer_length > 0) { - memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length); + memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, + buffer_length); fc_usb->tmp_buffer_length += buffer_length; b = fc_usb->tmp_buffer; l = fc_usb->tmp_buffer_length; @@ -304,23 +317,26 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, in } while (l >= 190) { - if (*b == 0xff) + if (*b == 0xff) { switch (*(b+1) & 0x03) { - case 0x01: /* media packet */ - if ( *(b+2) == 0x47 ) - flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1); - else - deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) ); - - b += 190; - l -= 190; + case 0x01: /* media packet */ + if (*(b+2) == 0x47) + flexcop_pass_dmx_packets( + fc_usb->fc_dev, b+2, 1); + else + deb_ts( + "not ts packet %02x %02x %02x %02x \n", + *(b+2), *(b+3), + *(b+4), *(b+5)); + b += 190; + l -= 190; break; - default: - deb_ts("wrong packet type\n"); - l = 0; + default: + deb_ts("wrong packet type\n"); + l = 0; break; } - else { + } else { deb_ts("wrong header\n"); l = 0; } @@ -341,23 +357,26 @@ static void flexcop_usb_urb_complete(struct urb *urb) int i; if (urb->actual_length > 0) - deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length); + deb_ts("urb completed, bufsize: %d actlen; %d\n", + urb->transfer_buffer_length, urb->actual_length); for (i = 0; i < urb->number_of_packets; i++) { if (urb->iso_frame_desc[i].status < 0) { - err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status); + err("iso frame descriptor %d has an error: %d\n", i, + urb->iso_frame_desc[i].status); } else if (urb->iso_frame_desc[i].actual_length > 0) { - deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length); + deb_ts("passed %d bytes to the demux\n", + urb->iso_frame_desc[i].actual_length); flexcop_usb_process_frame(fc_usb, - urb->transfer_buffer + urb->iso_frame_desc[i].offset, + urb->transfer_buffer + + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); - } + } urb->iso_frame_desc[i].status = 0; urb->iso_frame_desc[i].actual_length = 0; } - usb_submit_urb(urb,GFP_ATOMIC); } @@ -378,35 +397,47 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb) } if (fc_usb->iso_buffer != NULL) - pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr); + pci_free_consistent(NULL, + fc_usb->buffer_size, fc_usb->iso_buffer, + fc_usb->dma_addr); } static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) { - u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); - int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret; + u16 frame_size = le16_to_cpu( + fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); + int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * + frame_size, i, j, ret; int buffer_offset = 0; - deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n", - B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize); + deb_ts("creating %d iso-urbs with %d frames " + "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB, + B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize); - fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr); + fc_usb->iso_buffer = pci_alloc_consistent(NULL, + bufsize, &fc_usb->dma_addr); if (fc_usb->iso_buffer == NULL) return -ENOMEM; + memset(fc_usb->iso_buffer, 0, bufsize); fc_usb->buffer_size = bufsize; /* creating iso urbs */ - for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) - if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) { + for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { + fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO, + GFP_ATOMIC); + if (fc_usb->iso_urb[i] == NULL) { ret = -ENOMEM; goto urb_error; } + } + /* initialising and submitting iso urbs */ for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { int frame_offset = 0; struct urb *urb = fc_usb->iso_urb[i]; - deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset); + deb_ts("initializing and submitting urb no. %d " + "(buf_offset: %d).\n", i, buffer_offset); urb->dev = fc_usb->udev; urb->context = fc_usb; @@ -420,26 +451,26 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO; for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) { - deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset); + deb_ts("urb no: %d, frame: %d, frame_offset: %d\n", + i, j, frame_offset); urb->iso_frame_desc[j].offset = frame_offset; urb->iso_frame_desc[j].length = frame_size; frame_offset += frame_size; } if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) { - err("submitting urb %d failed with %d.",i,ret); + err("submitting urb %d failed with %d.", i, ret); goto urb_error; } deb_ts("submitted urb no. %d.\n",i); } -/* SRAM */ - - flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET | - FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB); - flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); - flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); - + /* SRAM */ + flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA | + FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, + FC_SRAM_DEST_TARGET_WAN_USB); + flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS); + flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1); return 0; urb_error: @@ -452,20 +483,20 @@ static int flexcop_usb_init(struct flexcop_usb *fc_usb) /* use the alternate setting with the larges buffer */ usb_set_interface(fc_usb->udev,0,1); switch (fc_usb->udev->speed) { - case USB_SPEED_LOW: - err("cannot handle USB speed because it is to sLOW."); - return -ENODEV; - break; - case USB_SPEED_FULL: - info("running at FULL speed."); - break; - case USB_SPEED_HIGH: - info("running at HIGH speed."); - break; - case USB_SPEED_UNKNOWN: /* fall through */ - default: - err("cannot handle USB speed because it is unkown."); - return -ENODEV; + case USB_SPEED_LOW: + err("cannot handle USB speed because it is too slow."); + return -ENODEV; + break; + case USB_SPEED_FULL: + info("running at FULL speed."); + break; + case USB_SPEED_HIGH: + info("running at HIGH speed."); + break; + case USB_SPEED_UNKNOWN: /* fall through */ + default: + err("cannot handle USB speed because it is unknown."); + return -ENODEV; } usb_set_intfdata(fc_usb->uintf, fc_usb); return 0; @@ -489,7 +520,7 @@ static int flexcop_usb_probe(struct usb_interface *intf, return -ENOMEM; } -/* general flexcop init */ + /* general flexcop init */ fc_usb = fc->bus_specific; fc_usb->fc_dev = fc; @@ -506,21 +537,21 @@ static int flexcop_usb_probe(struct usb_interface *intf, fc->dev = &udev->dev; fc->owner = THIS_MODULE; -/* bus specific part */ + /* bus specific part */ fc_usb->udev = udev; fc_usb->uintf = intf; if ((ret = flexcop_usb_init(fc_usb)) != 0) goto err_kfree; -/* init flexcop */ + /* init flexcop */ if ((ret = flexcop_device_initialize(fc)) != 0) goto err_usb_exit; -/* xfer init */ + /* xfer init */ if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0) goto err_fc_exit; - info("%s successfully initialized and connected.",DRIVER_NAME); + info("%s successfully initialized and connected.", DRIVER_NAME); return 0; err_fc_exit: @@ -539,12 +570,12 @@ static void flexcop_usb_disconnect(struct usb_interface *intf) flexcop_device_exit(fc_usb->fc_dev); flexcop_usb_exit(fc_usb); flexcop_device_kfree(fc_usb->fc_dev); - info("%s successfully deinitialized and disconnected.",DRIVER_NAME); + info("%s successfully deinitialized and disconnected.", DRIVER_NAME); } static struct usb_device_id flexcop_usb_table [] = { - { USB_DEVICE(0x0af7, 0x0101) }, - { } + { USB_DEVICE(0x0af7, 0x0101) }, + { } }; MODULE_DEVICE_TABLE (usb, flexcop_usb_table); @@ -561,10 +592,9 @@ static int __init flexcop_usb_module_init(void) { int result; if ((result = usb_register(&flexcop_usb_driver))) { - err("usb_register failed. (%d)",result); + err("usb_register failed. (%d)", result); return result; } - return 0; } -- cgit v1.2.3 From ad5e78a7b1caf2e54f4ca0f3009152c4aaa03837 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sun, 29 Mar 2009 13:43:36 +0200 Subject: Patch for Yuan MC770 DVB-T (1164:0871) From: Xoan Loureiro This patch adds support for the Yuan MC770 DVB-T (1164:0871). Thanks to Xoan Loureiro. Priority: normal Signed-off-by: Xoan Loureiro Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index d8901f7a8..f0f98529d 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1495,6 +1495,7 @@ struct usb_device_id dib0700_usb_id_table[] = { /* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) }, + { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1810,7 +1811,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 5, + .num_device_descs = 7, .devices = { { "Terratec Cinergy HT USB XE", { &dib0700_usb_id_table[27], NULL }, @@ -1836,6 +1837,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[39], NULL }, { NULL }, }, + { "YUAN High-Tech MC770", + { &dib0700_usb_id_table[48], NULL }, + { NULL }, + }, }, .rc_interval = DEFAULT_RC_INTERVAL, .rc_key_map = dib0700_rc_keys, diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 0f239c668..138ce1b5c 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -239,6 +239,7 @@ #define USB_PID_YUAN_EC372S 0x1edc #define USB_PID_YUAN_STK7700PH 0x1f08 #define USB_PID_YUAN_PD378S 0x2edc +#define USB_PID_YUAN_MC770 0x0871 #define USB_PID_DW2102 0x2102 #define USB_PID_XTENSIONS_XD_380 0x0381 #define USB_PID_TELESTAR_STARSTICK_2 0x8000 -- cgit v1.2.3 From df3d6b341372341ba57dc1ea30ef6059bc24d088 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sun, 29 Mar 2009 14:12:06 +0200 Subject: Add Elgato EyeTV DTT to dibcom driver From: Klaus Flittner This patch introduces support for DVB-T for the following dibcom based card: Elgato EyeTV DTT (USB-ID: 0fd9:0021) Priority: normal Signed-off-by: Klaus Flittner Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 4 +++- linux/drivers/media/dvb/dvb-usb/dvb-usb.h | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index f0f98529d..31fe6e10a 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1496,6 +1496,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) }, { 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) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1695,7 +1696,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 10, + .num_device_descs = 11, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1733,6 +1734,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[33], NULL }, { NULL }, }, + { "Elgato EyeTV DTT", + { &dib0700_usb_id_table[49], NULL }, + { NULL }, + }, { "Yuan PD378S", { &dib0700_usb_id_table[45], NULL }, { NULL }, diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 138ce1b5c..dc7ea21cd 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -27,6 +27,7 @@ #define USB_VID_DIBCOM 0x10b8 #define USB_VID_DPOSH 0x1498 #define USB_VID_DVICO 0x0fe9 +#define USB_VID_ELGATO 0x0fd9 #define USB_VID_EMPIA 0xeb1a #define USB_VID_GENPIX 0x09c0 #define USB_VID_GRANDTEC 0x5032 @@ -49,6 +50,7 @@ #define USB_VID_TERRATEC 0x0ccd #define USB_VID_TELESTAR 0x10b9 #define USB_VID_VISIONPLUS 0x13d3 +#define USB_VID_SONY 0x1415 #define USB_VID_TWINHAN 0x1822 #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 #define USB_VID_UNIWILL 0x1584 @@ -56,7 +58,6 @@ #define USB_VID_GIGABYTE 0x1044 #define USB_VID_YUAN 0x1164 #define USB_VID_XTENSIONS 0x1ae7 -#define USB_VID_SONY 0x1415 /* Product IDs */ #define USB_PID_ADSTECH_USB2_COLD 0xa333 @@ -245,5 +246,6 @@ #define USB_PID_TELESTAR_STARSTICK_2 0x8000 #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 #define USB_PID_SONY_PLAYTV 0x0003 +#define USB_PID_ELGATO_EYETV_DTT 0x0021 #endif diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h index 081550761..fd64daa06 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -224,7 +224,7 @@ struct dvb_usb_device_properties { int generic_bulk_ctrl_endpoint; int num_device_descs; - struct dvb_usb_device_description devices[10]; + struct dvb_usb_device_description devices[11]; }; /** -- cgit v1.2.3 From d1daa96b2ee8d633ec40e440c2a97c6719cd8b7a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 30 Mar 2009 12:08:30 +0200 Subject: au8522: remove unused I2C_DRIVERID From: Hans Verkuil I2C_DRIVERIDs are no longer needed with v4l2_subdev and will be removed from the kernel soon. Priority: normal Signed-off-by: Hans Verkuil CC: Devin Heitmueller --- linux/drivers/media/dvb/frontends/au8522_decoder.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_decoder.c b/linux/drivers/media/dvb/frontends/au8522_decoder.c index 70af9cda7..326f94d1e 100644 --- a/linux/drivers/media/dvb/frontends/au8522_decoder.c +++ b/linux/drivers/media/dvb/frontends/au8522_decoder.c @@ -837,7 +837,6 @@ MODULE_DEVICE_TABLE(i2c, au8522_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "au8522", - .driverid = I2C_DRIVERID_AU8522, .probe = au8522_probe, .remove = au8522_remove, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) -- cgit v1.2.3 From 868c60ab580a0b1d3939600a6b9522886982528b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 30 Mar 2009 21:36:19 -0400 Subject: fix misspelling of kconfig option From: Kyle McMartin CUSTOMISE appears to be the one actually defined... Signed-off-by: Kyle McMartin Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 6103caad1..089ba4513 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -309,6 +309,6 @@ config DVB_USB_CE6230 tristate "Intel CE6230 DVB-T USB2.0 support" depends on DVB_USB && EXPERIMENTAL select DVB_ZL10353 - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver -- cgit v1.2.3 From 79e38b2e91236313fe56aa090ed33a0719763e97 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 29 Mar 2009 02:36:18 +0000 Subject: Add AVerMedia A310 USB IDs to CE6230 driver. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Juan Jesús García de Soria Lucena The CE6230 DVB USB driver works correctly for the AVerMedia A310 USB2.0 DVB-T tuner. Add the required USB ID's and hardware names so that the driver will handle it. Priority: normal Signed-off-by: Juan Jesús García de Soria Lucena Acked-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/ce6230.c | 8 +++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/ce6230.c b/linux/drivers/media/dvb/dvb-usb/ce6230.c index 1682af62f..3ae3bde45 100644 --- a/linux/drivers/media/dvb/dvb-usb/ce6230.c +++ b/linux/drivers/media/dvb/dvb-usb/ce6230.c @@ -253,6 +253,7 @@ static int ce6230_probe(struct usb_interface *intf, static struct usb_device_id ce6230_table[] = { { USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) }, + { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, ce6230_table); @@ -287,13 +288,18 @@ static struct dvb_usb_device_properties ce6230_properties = { .i2c_algo = &ce6230_i2c_algo, - .num_device_descs = 1, + .num_device_descs = 2, .devices = { { .name = "Intel CE9500 reference design", .cold_ids = {NULL}, .warm_ids = {&ce6230_table[0], NULL}, }, + { + .name = "AVerMedia A310 USB 2.0 DVB-T tuner", + .cold_ids = {NULL}, + .warm_ids = {&ce6230_table[1], NULL}, + }, } }; diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index dc7ea21cd..ffe2a7335 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -167,6 +167,7 @@ #define USB_PID_AVERMEDIA_VOLAR_X 0xa815 #define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150 #define USB_PID_AVERMEDIA_A309 0xa309 +#define USB_PID_AVERMEDIA_A310 0xa310 #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.2.3 From 1784ea5527ed756f946958f45f74d1f15797c366 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 30 Mar 2009 01:04:44 +0200 Subject: v4l2: use old-style i2c API for kernels < 2.6.26 instead of < 2.6.22 From: Hans Verkuil Originally the intention was to switch to the new style i2c API starting with the introduction of the API in 2.6.22. However, the i2c_new_probed_device() function has a lethal bug that wasn't fixed until 2.6.25. Or more accurately, it was only fixed in the stable series of 2.6.25 and 2.6.26. Given the fact that the new i2c API also changed starting with 2.6.26 (the addition of i2c_device_id), it is easiest to switch APIs starting with 2.6.26. This patch updates all the legacy code accordingly. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/frontends/au8522_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_decoder.c b/linux/drivers/media/dvb/frontends/au8522_decoder.c index 326f94d1e..81d517765 100644 --- a/linux/drivers/media/dvb/frontends/au8522_decoder.c +++ b/linux/drivers/media/dvb/frontends/au8522_decoder.c @@ -48,7 +48,7 @@ MODULE_LICENSE("GPL"); static int au8522_analog_debug; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) static unsigned short normal_i2c[] = { 0x8e >> 1, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; -- cgit v1.2.3 From b4d23428b3c4456414ad8bf5e974757fd354a66f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 2 Apr 2009 16:26:22 +0200 Subject: v4l2-subdev: change s_routing prototype From: Hans Verkuil It is no longer needed to use a struct pointer as argument, since v4l2_subdev doesn't require that ioctl-like approach anymore. Instead just pass the input, output and config (new!) arguments directly. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/frontends/au8522_decoder.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_decoder.c b/linux/drivers/media/dvb/frontends/au8522_decoder.c index 81d517765..0d449ce23 100644 --- a/linux/drivers/media/dvb/frontends/au8522_decoder.c +++ b/linux/drivers/media/dvb/frontends/au8522_decoder.c @@ -658,7 +658,7 @@ static int au8522_reset(struct v4l2_subdev *sd, u32 val) } static int au8522_s_video_routing(struct v4l2_subdev *sd, - const struct v4l2_routing *route) + u32 input, u32 output, u32 config) { struct au8522_state *state = to_state(sd); @@ -669,11 +669,11 @@ static int au8522_s_video_routing(struct v4l2_subdev *sd, closed), and then came back to analog mode */ au8522_writereg(state, 0x106, 1); - if (route->input == AU8522_COMPOSITE_CH1) { + if (input == AU8522_COMPOSITE_CH1) { au8522_setup_cvbs_mode(state); - } else if (route->input == AU8522_SVIDEO_CH13) { + } else if (input == AU8522_SVIDEO_CH13) { au8522_setup_svideo_mode(state); - } else if (route->input == AU8522_COMPOSITE_CH4_SIF) { + } else if (input == AU8522_COMPOSITE_CH4_SIF) { au8522_setup_cvbs_tuner_mode(state); } else { printk(KERN_ERR "au8522 mode not currently supported\n"); @@ -683,10 +683,10 @@ static int au8522_s_video_routing(struct v4l2_subdev *sd, } static int au8522_s_audio_routing(struct v4l2_subdev *sd, - const struct v4l2_routing *route) + u32 input, u32 output, u32 config) { struct au8522_state *state = to_state(sd); - set_audio_input(state, route->input); + set_audio_input(state, input); return 0; } -- cgit v1.2.3 From 65c8976997f4e297c5d082a1c80ffc80d67bfda5 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 30 Mar 2009 23:57:51 +0300 Subject: af9015: remove wrong definitions From: Antti Palosaari Remove wrong GPIO definitions. GPIOs used by AF9015 are property of the AF9013 demodulator and are coming from there. Priority: normal Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/af9015.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.h b/linux/drivers/media/dvb/dvb-usb/af9015.h index 5c44bad28..8d81a17c1 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.h +++ b/linux/drivers/media/dvb/dvb-usb/af9015.h @@ -64,14 +64,6 @@ #define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1) -#define AF9015_GPIO_ON (1 << 0) -#define AF9015_GPIO_EN (1 << 1) -#define AF9015_GPIO_O (1 << 2) -#define AF9015_GPIO_I (1 << 3) - -#define AF9015_GPIO_TUNER_ON (AF9015_GPIO_ON|AF9015_GPIO_EN) -#define AF9015_GPIO_TUNER_OFF (AF9015_GPIO_ON|AF9015_GPIO_EN|AF9015_GPIO_O) - struct req_t { u8 cmd; /* [0] */ /* seq */ /* [1] */ -- cgit v1.2.3 From fdab553be22b01acd8124650ed75da649169596f Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 31 Mar 2009 23:01:02 +0300 Subject: af9015: add support for AverMedia AVerTV Volar Black HD (A850) From: Antti Palosaari Add USB ID (07ca:850a) and configuration hack for AverMedia AVerTV Volar Black HD (A850) DVB-T USB stick. Priority: normal Signed-off-by: Antti Palosaari Tested-by: Olivier MENUEL Tested-by: Thomas Renard --- linux/drivers/media/dvb/dvb-usb/af9015.c | 24 +++++++++++++++++++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index e7a8f61da..5feed970a 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -994,6 +994,21 @@ error: if (ret) err("eeprom read failed:%d", ret); + /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM + content :-( Override some wrong values here. */ + if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA && + le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) { + deb_info("%s: AverMedia A850: overriding config\n", __func__); + /* disable dual mode */ + af9015_config.dual_mode = 0; + /* disable 2nd adapter */ + for (i = 0; i < af9015_properties_count; i++) + af9015_properties[i].num_adapters = 1; + + /* set correct IF */ + af9015_af9013_config[0].tuner_if = 4570; + } + return ret; } @@ -1252,6 +1267,7 @@ 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)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1416,7 +1432,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 8, + .num_device_descs = 9, .devices = { { .name = "Xtensions XD-380", @@ -1461,6 +1477,12 @@ static struct dvb_usb_device_properties af9015_properties[] = { .cold_ids = {&af9015_usb_table[19], NULL}, .warm_ids = {NULL}, }, + { + .name = "AverMedia AVerTV Volar Black HD " \ + "(A850)", + .cold_ids = {&af9015_usb_table[20], NULL}, + .warm_ids = {NULL}, + }, } } }; diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index cd22d6dde..7031bafe6 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -168,6 +168,7 @@ #define USB_PID_AVERMEDIA_VOLAR_X 0xa815 #define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150 #define USB_PID_AVERMEDIA_A309 0xa309 +#define USB_PID_AVERMEDIA_A850 0x850a #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.2.3 From f59d306e416b8bfd707417c9a8c1d77e2e87f173 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 1 Apr 2009 07:35:10 +0000 Subject: Support for Legend Silicon LGS8913/LGS8GL5/LGS8GXX China DMB-TH digital demodulator From: David Wong This patch contains the unified driver for Legend Silicon LGS8913 and LGS8GL5. It should replace lgs8gl5.c in media/dvb/frontends in the future. Signed-off-by: David T.L. Wong Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/Kconfig | 7 + linux/drivers/media/dvb/frontends/Makefile | 1 + linux/drivers/media/dvb/frontends/lgs8gxx.c | 859 +++++++++++++++++++++++ linux/drivers/media/dvb/frontends/lgs8gxx.h | 90 +++ linux/drivers/media/dvb/frontends/lgs8gxx_priv.h | 70 ++ 5 files changed, 1027 insertions(+) create mode 100644 linux/drivers/media/dvb/frontends/lgs8gxx.c create mode 100644 linux/drivers/media/dvb/frontends/lgs8gxx.h create mode 100644 linux/drivers/media/dvb/frontends/lgs8gxx_priv.h (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index a206cee23..578b834bf 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -513,6 +513,13 @@ config DVB_LGS8GL5 help A DMB-TH tuner module. Say Y when you want to support this frontend. +config DVB_LGS8GXX + tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DMB-TH tuner module. Say Y when you want to support this frontend. + comment "Tools to develop new frontends" config DVB_DUMMY_FE diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 65a336aa1..bc2b00abd 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_DVB_TDA10048) += tda10048.o obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o obj-$(CONFIG_DVB_S5H1411) += s5h1411.o obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o +obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o obj-$(CONFIG_DVB_AF9013) += af9013.o obj-$(CONFIG_DVB_CX24116) += cx24116.o diff --git a/linux/drivers/media/dvb/frontends/lgs8gxx.c b/linux/drivers/media/dvb/frontends/lgs8gxx.c new file mode 100644 index 000000000..1395f3b5b --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgs8gxx.c @@ -0,0 +1,859 @@ +/* + * Support for Legend Silicon DMB-TH demodulator + * LGS8913, LGS8GL5 + * experimental support LGS8G42, LGS8G52 + * + * Copyright (C) 2007,2008 David T.L. Wong + * Copyright (C) 2008 Sirius International (Hong Kong) Limited + * Timothy Lee (for initial work on LGS8GL5) + * + * 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 "dvb_frontend.h" + +#include "lgs8gxx.h" +#include "lgs8gxx_priv.h" + +#define dprintk(args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG "lgs8gxx: " args); \ + } while (0) + +static int debug; +static int fake_signal_str; + +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)."); + +/* LGS8GXX internal helper functions */ + +static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data) +{ + int ret; + u8 buf[] = { reg, data }; + struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; + + msg.addr = priv->config->demod_address; + if (reg >= 0xC0) + msg.addr += 0x02; + + if (debug >= 2) + printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n", + __func__, reg, data); + + ret = i2c_transfer(priv->i2c, &msg, 1); + + if (ret != 1) + dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n", + __func__, reg, data, ret); + + return (ret != 1) ? -1 : 0; +} + +static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data) +{ + int ret; + u8 dev_addr; + + u8 b0[] = { reg }; + u8 b1[] = { 0 }; + struct i2c_msg msg[] = { + { .flags = 0, .buf = b0, .len = 1 }, + { .flags = I2C_M_RD, .buf = b1, .len = 1 }, + }; + + dev_addr = priv->config->demod_address; + if (reg >= 0xC0) + dev_addr += 0x02; + msg[1].addr = msg[0].addr = dev_addr; + + ret = i2c_transfer(priv->i2c, msg, 2); + if (ret != 2) { + dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n", + __func__, reg, ret); + return -1; + } + + *p_data = b1[0]; + if (debug >= 2) + printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n", + __func__, reg, b1[0]); + return 0; +} + +static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv) +{ + lgs8gxx_write_reg(priv, 0x02, 0x00); + msleep(1); + lgs8gxx_write_reg(priv, 0x02, 0x01); + msleep(100); + + return 0; +} + +static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv) +{ + const struct lgs8gxx_config *config = priv->config; + u8 if_conf; + + if_conf = 0x10; /* AGC output on; */ + + if_conf |= + ((config->ext_adc) ? 0x80 : 0x00) | + ((config->if_neg_center) ? 0x04 : 0x00) | + ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */ + ((config->ext_adc && config->adc_signed) ? 0x02 : 0x00) | + ((config->ext_adc && config->if_neg_edge) ? 0x01 : 0x00); + + if (config->ext_adc && + (config->prod == LGS8GXX_PROD_LGS8G52)) { + lgs8gxx_write_reg(priv, 0xBA, 0x40); + } + + lgs8gxx_write_reg(priv, 0x07, if_conf); + + return 0; +} + +static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/) +{ + u64 val; + u32 v32; + u32 if_clk; + + if_clk = priv->config->if_clk_freq; + + val = freq; + if (freq != 0) { + val *= (u64)1 << 32; + if (if_clk != 0) + do_div(val, if_clk); + v32 = val & 0xFFFFFFFF; + dprintk("Set IF Freq to %dkHz\n", freq); + } else { + v32 = 0; + dprintk("Set IF Freq to baseband\n"); + } + dprintk("AFC_INIT_FREQ = 0x%08X\n", v32); + + lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32)); + lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8)); + lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16)); + lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24)); + + return 0; +} + +static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv) +{ + u8 t; + + if (priv->config->prod == LGS8GXX_PROD_LGS8913) + lgs8gxx_write_reg(priv, 0xC6, 0x01); + + lgs8gxx_read_reg(priv, 0x7E, &t); + lgs8gxx_write_reg(priv, 0x7E, t | 0x01); + + /* clear FEC self reset */ + lgs8gxx_read_reg(priv, 0xC5, &t); + lgs8gxx_write_reg(priv, 0xC5, t & 0xE0); + + if (priv->config->prod == LGS8GXX_PROD_LGS8913) { + /* FEC auto detect */ + lgs8gxx_write_reg(priv, 0xC1, 0x03); + + lgs8gxx_read_reg(priv, 0x7C, &t); + t = (t & 0x8C) | 0x03; + lgs8gxx_write_reg(priv, 0x7C, t); + } + + + if (priv->config->prod == LGS8GXX_PROD_LGS8913) { + /* BER test mode */ + lgs8gxx_read_reg(priv, 0xC3, &t); + t = (t & 0xEF) | 0x10; + lgs8gxx_write_reg(priv, 0xC3, t); + } + + if (priv->config->prod == LGS8GXX_PROD_LGS8G52) + lgs8gxx_write_reg(priv, 0xD9, 0x40); + + return 0; +} + +static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv) +{ + int ret = 0; + u8 t; + + /* turn off auto-detect; manual settings */ + lgs8gxx_write_reg(priv, 0x7E, 0); + if (priv->config->prod == LGS8GXX_PROD_LGS8913) + lgs8gxx_write_reg(priv, 0xC1, 0); + + ret = lgs8gxx_read_reg(priv, 0xC5, &t); + t = (t & 0xE0) | 0x06; + lgs8gxx_write_reg(priv, 0xC5, t); + + lgs8gxx_soft_reset(priv); + + return 0; +} + +static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked) +{ + int ret = 0; + u8 t; + + ret = lgs8gxx_read_reg(priv, 0x4B, &t); + if (ret != 0) + return ret; + + *locked = ((t & 0xC0) == 0xC0) ? 1 : 0; + return 0; +} + +static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv, + u8 *finished) +{ + int ret = 0; + u8 t; + + ret = lgs8gxx_read_reg(priv, 0xA4, &t); + if (ret != 0) + return ret; + + *finished = ((t & 0x3) == 0x1) ? 1 : 0; + + return 0; +} + +static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked) +{ + int err; + u8 ad_fini = 0; + + if (gi == GI_945) + dprintk("try GI 945\n"); + else if (gi == GI_595) + dprintk("try GI 595\n"); + else if (gi == GI_420) + dprintk("try GI 420\n"); + lgs8gxx_write_reg(priv, 0x04, gi); + lgs8gxx_soft_reset(priv); + msleep(50); + err = lgs8gxx_is_autodetect_finished(priv, &ad_fini); + if (err != 0) + return err; + if (ad_fini) { + err = lgs8gxx_is_locked(priv, locked); + if (err != 0) + return err; + } + + return 0; +} + +static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv, + u8 *detected_param, u8 *gi) +{ + int i, j; + int err = 0; + u8 locked = 0, tmp_gi; + + dprintk("%s\n", __func__); + + lgs8gxx_set_mode_auto(priv); + /* Guard Interval */ + lgs8gxx_write_reg(priv, 0x03, 00); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + tmp_gi = GI_945; + err = lgs8gxx_autolock_gi(priv, GI_945, &locked); + if (err) + goto out; + if (locked) + goto locked; + } + for (j = 0; j < 2; j++) { + tmp_gi = GI_420; + err = lgs8gxx_autolock_gi(priv, GI_420, &locked); + if (err) + goto out; + if (locked) + goto locked; + } + tmp_gi = GI_595; + err = lgs8gxx_autolock_gi(priv, GI_595, &locked); + if (err) + goto out; + if (locked) + goto locked; + } + +locked: + if ((err == 0) && (locked == 1)) { + u8 t; + + lgs8gxx_read_reg(priv, 0xA2, &t); + *detected_param = t; + + if (tmp_gi == GI_945) + dprintk("GI 945 locked\n"); + else if (tmp_gi == GI_595) + dprintk("GI 595 locked\n"); + else if (tmp_gi == GI_420) + dprintk("GI 420 locked\n"); + *gi = tmp_gi; + } + if (!locked) + err = -1; + +out: + return err; +} + +static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv) +{ + s8 err; + u8 gi = 0x2; + u8 detected_param = 0; + + err = lgs8gxx_auto_detect(priv, &detected_param, &gi); + + if (err != 0) { +#if 0 + /* Set auto guardinterval detection */ + lgs8gxx_write_reg(priv, 0x03, 0x01); +#endif + dprintk("lgs8gxx_auto_detect failed\n"); + } + + /* Apply detected parameters */ + if (priv->config->prod == LGS8GXX_PROD_LGS8913) { + u8 inter_leave_len = detected_param & TIM_MASK ; + inter_leave_len = (inter_leave_len == TIM_LONG) ? 0x60 : 0x40; + detected_param &= CF_MASK | SC_MASK | LGS_FEC_MASK; + detected_param |= inter_leave_len; + } + lgs8gxx_write_reg(priv, 0x7D, detected_param); + if (priv->config->prod == LGS8GXX_PROD_LGS8913) + lgs8gxx_write_reg(priv, 0xC0, detected_param); + /* lgs8gxx_soft_reset(priv); */ + + /* Enter manual mode */ + lgs8gxx_set_mode_manual(priv); + + switch (gi) { + case GI_945: + priv->curr_gi = 945; break; + case GI_595: + priv->curr_gi = 595; break; + case GI_420: + priv->curr_gi = 420; break; + default: + priv->curr_gi = 945; break; + } +} + +static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv, + u8 serial, u8 clk_pol, u8 clk_gated) +{ + int ret = 0; + u8 t; + + ret = lgs8gxx_read_reg(priv, 0xC2, &t); + if (ret != 0) + return ret; + + t &= 0xF8; + t |= serial ? TS_SERIAL : TS_PARALLEL; + t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL; + t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN; + + ret = lgs8gxx_write_reg(priv, 0xC2, t); + if (ret != 0) + return ret; + + return 0; +} + + +/* LGS8913 demod frontend functions */ + +static int lgs8913_init(struct lgs8gxx_state *priv) +{ + u8 t; + + /* LGS8913 specific */ + lgs8gxx_write_reg(priv, 0xc1, 0x3); + + lgs8gxx_read_reg(priv, 0x7c, &t); + lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3); + + /* LGS8913 specific */ + lgs8gxx_read_reg(priv, 0xc3, &t); + lgs8gxx_write_reg(priv, 0xc3, t&0x10); + +#if 0 + /* set AGC ref */ + /* TODO better set from configuration per hardware */ + lgs8gxx_write_reg(priv, 0x2C, 0); + lgs8gxx_write_reg(priv, 0x2D, 0x18); + lgs8gxx_write_reg(priv, 0x2E, 0xA2); +#endif + + return 0; +} + +static int lgs8gxx_init(struct dvb_frontend *fe) +{ + struct lgs8gxx_state *priv = + (struct lgs8gxx_state *)fe->demodulator_priv; + const struct lgs8gxx_config *config = priv->config; + u8 data = 0; + s8 err; + dprintk("%s\n", __func__); + + lgs8gxx_read_reg(priv, 0, &data); + dprintk("reg 0 = 0x%02X\n", data); + + /* Setup MPEG output format */ + err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts, + config->ts_clk_pol, + config->ts_clk_gated); + if (err != 0) + return -EIO; + + if (config->prod == LGS8GXX_PROD_LGS8913) + lgs8913_init(priv); + lgs8gxx_set_if_freq(priv, priv->config->if_freq); + if (config->prod != LGS8GXX_PROD_LGS8913) + lgs8gxx_set_ad_mode(priv); + + return 0; +} + +static void lgs8gxx_release(struct dvb_frontend *fe) +{ + struct lgs8gxx_state *state = fe->demodulator_priv; + dprintk("%s\n", __func__); + + kfree(state); +} + +#if 0 +static int lgs8gxx_sleep(struct dvb_frontend *fe) +{ + dprintk("%s\n", __func__); + + return 0; +} +#endif + +static int lgs8gxx_write(struct dvb_frontend *fe, u8 *buf, int len) +{ + struct lgs8gxx_state *priv = fe->demodulator_priv; + + if (len != 2) + return -EINVAL; + + return lgs8gxx_write_reg(priv, buf[0], buf[1]); +} + +static int lgs8gxx_set_fe(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fe_params) +{ + struct lgs8gxx_state *priv = fe->demodulator_priv; + + dprintk("%s\n", __func__); + + /* set frequency */ + if (fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, fe_params); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + /* start auto lock */ + lgs8gxx_auto_lock(priv); + + msleep(10); + + return 0; +} + +static int lgs8gxx_get_fe(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fe_params) +{ + struct lgs8gxx_state *priv = fe->demodulator_priv; + u8 t; +#if 0 + int translated_fec = FEC_1_2; +#endif + + dprintk("%s\n", __func__); + + /* TODO: get real readings from device */ + /* inversion status */ + fe_params->inversion = INVERSION_OFF; + + /* bandwidth */ + fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + + + lgs8gxx_read_reg(priv, 0x7D, &t); +#if 0 + /* FEC. No exact match for DMB-TH, pick approx. value */ + switch (t & LGS_FEC_MASK) { + case LGS_FEC_0_4: /* FEC 0.4 */ + translated_fec = FEC_1_2; + break; + case LGS_FEC_0_6: /* FEC 0.6 */ + translated_fec = FEC_2_3; + break; + case LGS_FEC_0_8: /* FEC 0.8 */ + translated_fec = FEC_5_6; + break; + default: + translated_fec = FEC_1_2; + } + fe_params->u.ofdm.code_rate_HP = translated_fec; + fe_params->u.ofdm.code_rate_LP = translated_fec; +#endif + fe_params->u.ofdm.code_rate_HP = FEC_AUTO; + fe_params->u.ofdm.code_rate_LP = FEC_AUTO; + + /* constellation */ + switch (t & SC_MASK) { + case SC_QAM64: + fe_params->u.ofdm.constellation = QAM_64; + break; + case SC_QAM32: + fe_params->u.ofdm.constellation = QAM_32; + break; + case SC_QAM16: + fe_params->u.ofdm.constellation = QAM_16; + break; + case SC_QAM4: + case SC_QAM4NR: + fe_params->u.ofdm.constellation = QPSK; + break; + default: + fe_params->u.ofdm.constellation = QAM_64; + } + + /* transmission mode */ + fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; + + /* guard interval */ + fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; + + /* hierarchy */ + fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE; + + return 0; +} + +static +int lgs8gxx_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *fesettings) +{ + /* FIXME: copy from tda1004x.c */ + fesettings->min_delay_ms = 800; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; +} + +static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status) +{ + struct lgs8gxx_state *priv = fe->demodulator_priv; + s8 ret; + u8 t; + + dprintk("%s\n", __func__); + + ret = lgs8gxx_read_reg(priv, 0x4B, &t); + if (ret != 0) + return -EIO; + + dprintk("Reg 0x4B: 0x%02X\n", t); + + *fe_status = 0; + if (priv->config->prod == LGS8GXX_PROD_LGS8913) { + if ((t & 0x40) == 0x40) + *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; + if ((t & 0x80) == 0x80) + *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + } else { + if ((t & 0x80) == 0x80) + *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + } + + /* success */ + dprintk("%s: fe_status=0x%x\n", __func__, *fe_status); + return 0; +} + +static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal) +{ + u16 v; + u8 agc_lvl[2], cat; + + dprintk("%s()\n", __func__); + lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]); + lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]); + + v = agc_lvl[0]; + v <<= 8; + v |= agc_lvl[1]; + + dprintk("agc_lvl: 0x%04X\n", v); + + if (v < 0x100) + cat = 0; + else if (v < 0x190) + cat = 5; + else if (v < 0x2A8) + cat = 4; + else if (v < 0x381) + cat = 3; + else if (v < 0x400) + cat = 2; + else if (v == 0x400) + cat = 1; + else + cat = 0; + + *signal = cat; + + return 0; +} + +static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal) +{ + u8 t; s8 ret; + s16 max_strength = 0; + u8 str; + u16 i, gi = priv->curr_gi; + + dprintk("%s\n", __func__); + + ret = lgs8gxx_read_reg(priv, 0x4B, &t); + if (ret != 0) + return -EIO; + + if (fake_signal_str) { + if ((t & 0xC0) == 0xC0) { + dprintk("Fake signal strength as 50\n"); + *signal = 0x32; + } else + *signal = 0; + return 0; + } + + dprintk("gi = %d\n", gi); + for (i = 0; i < gi; i++) { + + if ((i & 0xFF) == 0) + lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8)); + lgs8gxx_write_reg(priv, 0x83, i & 0xFF); + + lgs8gxx_read_reg(priv, 0x94, &str); + if (max_strength < str) + max_strength = str; + } + + *signal = max_strength; + dprintk("%s: signal=0x%02X\n", __func__, *signal); + + lgs8gxx_read_reg(priv, 0x95, &t); + dprintk("%s: AVG Noise=0x%02X\n", __func__, t); + + return 0; +} + +static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal) +{ + struct lgs8gxx_state *priv = fe->demodulator_priv; + + if (priv->config->prod == LGS8GXX_PROD_LGS8913) + return lgs8913_read_signal_strength(priv, signal); + else + return lgs8gxx_read_signal_agc(priv, signal); +} + +static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct lgs8gxx_state *priv = fe->demodulator_priv; + u8 t; + *snr = 0; + + lgs8gxx_read_reg(priv, 0x95, &t); + dprintk("AVG Noise=0x%02X\n", t); + *snr = 256 - t; + *snr <<= 8; + dprintk("snr=0x%x\n", *snr); + + return 0; +} + +static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + *ucblocks = 0; + dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks); + return 0; +} + +static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct lgs8gxx_state *priv = fe->demodulator_priv; + u8 r0, r1, r2, r3; + u32 total_cnt, err_cnt; + + dprintk("%s\n", __func__); + + lgs8gxx_write_reg(priv, 0xc6, 0x01); + lgs8gxx_write_reg(priv, 0xc6, 0x41); + lgs8gxx_write_reg(priv, 0xc6, 0x01); + + msleep(200); + + lgs8gxx_write_reg(priv, 0xc6, 0x81); + lgs8gxx_read_reg(priv, 0xd0, &r0); + lgs8gxx_read_reg(priv, 0xd1, &r1); + lgs8gxx_read_reg(priv, 0xd2, &r2); + lgs8gxx_read_reg(priv, 0xd3, &r3); + total_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0); + lgs8gxx_read_reg(priv, 0xd4, &r0); + lgs8gxx_read_reg(priv, 0xd5, &r1); + lgs8gxx_read_reg(priv, 0xd6, &r2); + lgs8gxx_read_reg(priv, 0xd7, &r3); + err_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0); + dprintk("error=%d total=%d\n", err_cnt, total_cnt); + + if (total_cnt == 0) + *ber = 0; + else + *ber = err_cnt * 100 / total_cnt; + + dprintk("%s: ber=0x%x\n", __func__, *ber); + return 0; +} + +static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct lgs8gxx_state *priv = fe->demodulator_priv; + + if (priv->config->tuner_address == 0) + return 0; + if (enable) { + u8 v = 0x80 | priv->config->tuner_address; + return lgs8gxx_write_reg(priv, 0x01, v); + } + return lgs8gxx_write_reg(priv, 0x01, 0); +} + +static struct dvb_frontend_ops lgs8gxx_ops = { + .info = { + .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH", + .type = FE_OFDM, + .frequency_min = 474000000, + .frequency_max = 858000000, + .frequency_stepsize = 10000, + .caps = + FE_CAN_FEC_AUTO | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO + }, + + .release = lgs8gxx_release, + + .init = lgs8gxx_init, +#if 0 + .sleep = lgs8gxx_sleep, +#endif + .write = lgs8gxx_write, + .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl, + + .set_frontend = lgs8gxx_set_fe, + .get_frontend = lgs8gxx_get_fe, + .get_tune_settings = lgs8gxx_get_tune_settings, + + .read_status = lgs8gxx_read_status, + .read_ber = lgs8gxx_read_ber, + .read_signal_strength = lgs8gxx_read_signal_strength, + .read_snr = lgs8gxx_read_snr, + .read_ucblocks = lgs8gxx_read_ucblocks, +}; + +struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, + struct i2c_adapter *i2c) +{ + struct lgs8gxx_state *priv = NULL; + u8 data = 0; + + dprintk("%s()\n", __func__); + + if (config == NULL || i2c == NULL) + return NULL; + + priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL); + if (priv == NULL) + goto error_out; + + priv->config = config; + priv->i2c = i2c; + + /* check if the demod is there */ + if (lgs8gxx_read_reg(priv, 0, &data) != 0) { + dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n", + __func__, priv->config->demod_address); + goto error_out; + } + + lgs8gxx_read_reg(priv, 1, &data); + + memcpy(&priv->frontend.ops, &lgs8gxx_ops, + sizeof(struct dvb_frontend_ops)); + priv->frontend.demodulator_priv = priv; + + return &priv->frontend; + +error_out: + dprintk("%s() error_out\n", __func__); + kfree(priv); + return NULL; + +} +EXPORT_SYMBOL(lgs8gxx_attach); + +MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver"); +MODULE_AUTHOR("David T. L. Wong "); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/lgs8gxx.h b/linux/drivers/media/dvb/frontends/lgs8gxx.h new file mode 100644 index 000000000..321d366a8 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgs8gxx.h @@ -0,0 +1,90 @@ +/* + * Support for Legend Silicon DMB-TH demodulator + * LGS8913, LGS8GL5 + * experimental support LGS8G42, LGS8G52 + * + * Copyright (C) 2007,2008 David T.L. Wong + * Copyright (C) 2008 Sirius International (Hong Kong) Limited + * Timothy Lee (for initial work on LGS8GL5) + * + * 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 __LGS8GXX_H__ +#define __LGS8GXX_H__ + +#include +#include + +#define LGS8GXX_PROD_LGS8913 0 +#define LGS8GXX_PROD_LGS8GL5 1 +#define LGS8GXX_PROD_LGS8G42 3 +#define LGS8GXX_PROD_LGS8G52 4 +#define LGS8GXX_PROD_LGS8G54 5 + +struct lgs8gxx_config { + + /* product type */ + u8 prod; + + /* the demodulator's i2c address */ + u8 demod_address; + + /* parallel or serial transport stream */ + u8 serial_ts; + + /* transport stream polarity*/ + u8 ts_clk_pol; + + /* transport stream clock gated by ts_valid */ + u8 ts_clk_gated; + + /* A/D Clock frequency */ + u32 if_clk_freq; /* in kHz */ + + /* IF frequency */ + u32 if_freq; /* in kHz */ + + /*Use External ADC*/ + u8 ext_adc; + + /*External ADC output two's complement*/ + u8 adc_signed; + + /*Sample IF data at falling edge of IF_CLK*/ + u8 if_neg_edge; + + /*IF use Negative center frequency*/ + u8 if_neg_center; + + /* slave address and configuration of the tuner */ + u8 tuner_address; +}; + +#if defined(CONFIG_DVB_LGS8GXX) || \ + (defined(CONFIG_DVB_LGS8GXX_MODULE) && defined(MODULE)) +extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, + struct i2c_adapter *i2c); +#else +static inline +struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, + struct i2c_adapter *i2c) { + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_LGS8GXX */ + +#endif /* __LGS8GXX_H__ */ diff --git a/linux/drivers/media/dvb/frontends/lgs8gxx_priv.h b/linux/drivers/media/dvb/frontends/lgs8gxx_priv.h new file mode 100644 index 000000000..9776d3068 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgs8gxx_priv.h @@ -0,0 +1,70 @@ +/* + * Support for Legend Silicon DMB-TH demodulator + * LGS8913, LGS8GL5 + * experimental support LGS8G42, LGS8G52 + * + * Copyright (C) 2007,2008 David T.L. Wong + * Copyright (C) 2008 Sirius International (Hong Kong) Limited + * Timothy Lee (for initial work on LGS8GL5) + * + * 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 LGS8913_PRIV_H +#define LGS8913_PRIV_H + +struct lgs8gxx_state { + struct i2c_adapter *i2c; + /* configuration settings */ + const struct lgs8gxx_config *config; + struct dvb_frontend frontend; + u16 curr_gi; /* current guard interval */ +}; + +#define SC_MASK 0x1C /* Sub-Carrier Modulation Mask */ +#define SC_QAM64 0x10 /* 64QAM modulation */ +#define SC_QAM32 0x0C /* 32QAM modulation */ +#define SC_QAM16 0x08 /* 16QAM modulation */ +#define SC_QAM4NR 0x04 /* 4QAM modulation */ +#define SC_QAM4 0x00 /* 4QAM modulation */ + +#define LGS_FEC_MASK 0x03 /* FEC Rate Mask */ +#define LGS_FEC_0_4 0x00 /* FEC Rate 0.4 */ +#define LGS_FEC_0_6 0x01 /* FEC Rate 0.6 */ +#define LGS_FEC_0_8 0x02 /* FEC Rate 0.8 */ + +#define TIM_MASK 0x20 /* Time Interleave Length Mask */ +#define TIM_LONG 0x00 /* Time Interleave Length = 720 */ +#define TIM_MIDDLE 0x20 /* Time Interleave Length = 240 */ + +#define CF_MASK 0x80 /* Control Frame Mask */ +#define CF_EN 0x80 /* Control Frame On */ + +#define GI_MASK 0x03 /* Guard Interval Mask */ +#define GI_420 0x00 /* 1/9 Guard Interval */ +#define GI_595 0x01 /* */ +#define GI_945 0x02 /* 1/4 Guard Interval */ + + +#define TS_PARALLEL 0x00 /* Parallel TS Output a.k.a. SPI */ +#define TS_SERIAL 0x01 /* Serial TS Output a.k.a. SSI */ +#define TS_CLK_NORMAL 0x00 /* MPEG Clock Normal */ +#define TS_CLK_INVERTED 0x02 /* MPEG Clock Inverted */ +#define TS_CLK_GATED 0x00 /* MPEG clock gated */ +#define TS_CLK_FREERUN 0x04 /* MPEG clock free running*/ + + +#endif -- cgit v1.2.3 From 5d077a339744b7da7c3a5611c5d433ecdac55ecf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 1 Apr 2009 20:25:00 +0000 Subject: Revert "V4L/DVB (10962): fired-avc: fix printk formatting warning." From: Stefan Richter Commit 34aecd2851bba5c2b7dae2f0dbe8e629b1c5e4ac was made obsolete and invalid by commit 40cf65d149053889c8876c6c2b4ce204fde55baa. Signed-off-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/firewire/firedtv-avc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/firewire/firedtv-avc.c b/linux/drivers/media/dvb/firewire/firedtv-avc.c index d8dae2599..79fab477c 100644 --- a/linux/drivers/media/dvb/firewire/firedtv-avc.c +++ b/linux/drivers/media/dvb/firewire/firedtv-avc.c @@ -150,7 +150,7 @@ static void debug_fcp(const u8 *data, size_t length) subunit_type = data[1] >> 3; subunit_id = data[1] & 7; op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2]; - printk(KERN_INFO "%ssu=%x.%x l=%zu: %-8s - %s\n", + printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n", prefix, subunit_type, subunit_id, length, debug_fcp_ctype(data[0]), debug_fcp_opcode(op, data, length)); -- cgit v1.2.3 From 42628535c1ee2b9d89e7fe0d4d430df926a2368c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 2 Apr 2009 11:25:09 +0300 Subject: af9015: support for DigitalNow TinyTwin remote From: Stuart Hall Patch to provide basic support for DigitalNow TinyTwin Remote. It uses same remote as TwinHan AzureWave AD-TU700(704J). Priority: normal Signed-off-by: Stuart Hall Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/af9015.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index 5feed970a..ceea6676b 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -785,17 +785,14 @@ static int af9015_read_config(struct usb_device *udev) ARRAY_SIZE(af9015_ir_table_leadtek); break; case USB_VID_VISIONPLUS: - if (udev->descriptor.idProduct == - cpu_to_le16(USB_PID_AZUREWAVE_AD_TU700)) { - af9015_properties[i].rc_key_map = - af9015_rc_keys_twinhan; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_twinhan); - af9015_config.ir_table = - af9015_ir_table_twinhan; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_twinhan); - } + af9015_properties[i].rc_key_map = + af9015_rc_keys_twinhan; + af9015_properties[i].rc_key_map_size = + ARRAY_SIZE(af9015_rc_keys_twinhan); + af9015_config.ir_table = + af9015_ir_table_twinhan; + af9015_config.ir_table_size = + ARRAY_SIZE(af9015_ir_table_twinhan); break; case USB_VID_KWORLD_2: /* TODO: use correct rc keys */ -- cgit v1.2.3 From f5ea7eb5503fdf00a99adcd6ef0d43271f6cecda Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 20 Apr 2009 11:35:06 -0300 Subject: Siano: SDIO interface driver - remove two redundant lines From: Uri Shkolnik Remove two redundant lines, based on Klimov Alexey code review. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smssdio.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smssdio.c b/linux/drivers/media/dvb/siano/smssdio.c index 31ba8c5af..4f8fa59a9 100644 --- a/linux/drivers/media/dvb/siano/smssdio.c +++ b/linux/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.2.3 From 82c030337cbead2e29d30808dcab8e558c4dfa89 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 5 Apr 2009 08:12:51 +0000 Subject: Siano: core header - add definitions and structures From: Uri Shkolnik [PATCH] [0904_2] Siano: core header - add definitions and structures Add new definitions (of Siano's protocol messages), and protocol structures (for future commits usage) Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 85da09f86..cac8fe2be 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -47,6 +47,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) \ @@ -162,6 +163,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 @@ -191,6 +193,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; \ @@ -198,6 +207,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, @@ -222,8 +240,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.2.3 From 4c25b22d66ac58fedf280b2d59dcc38ebc17dbed Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 5 Apr 2009 08:21:23 +0000 Subject: [PATCH] [0904_3] Siano: core - move and update the main core structure declaration From: Uri Shkolnik smscoreapi - move the main core structure declaration to the header, in order to enable other components (such as IR) to use it. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 36 -------------------- linux/drivers/media/dvb/siano/smscoreapi.h | 54 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 36 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 8c37a060b..9a9db2588 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/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/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index cac8fe2be..54264b5d3 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -122,6 +122,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.2.3 From 8e8624523d0528593547570641d323fb709775b5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 5 Apr 2009 08:26:50 +0000 Subject: [PATCH] [0904_5] Siano: core header - indentation From: Uri Shkolnik Some more indentation for the smscoreapi.h There are no implementation changes in this patch. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.h | 42 ++++++++++++++++-------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 54264b5d3..83e0e55f7 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -47,14 +47,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 { @@ -85,13 +85,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 { @@ -118,7 +118,6 @@ struct smsclient_params_t { int data_type; onresponse_t onresponse_handler; onremove_t onremove_handler; - void *context; }; @@ -254,13 +253,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, @@ -316,11 +316,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; @@ -354,10 +355,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 */ @@ -365,8 +368,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.2.3 From ddf57e9054c6d575bd185bcfe58cca2214ae330e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 5 Apr 2009 09:01:37 +0000 Subject: [PATCH] [0904_9] Siano: add support for infra-red (IR) controllers From: Uri Shkolnik This patch add support for IR (infra-red) remote controllers. Further commits are needed in order to enable the activation of the IR components. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsir.c | 301 ++++++++++++++++++++++++++++++++++ linux/drivers/media/dvb/siano/smsir.h | 93 +++++++++++ 2 files changed, 394 insertions(+) create mode 100644 linux/drivers/media/dvb/siano/smsir.c create mode 100644 linux/drivers/media/dvb/siano/smsir.h (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsir.c b/linux/drivers/media/dvb/siano/smsir.c new file mode 100644 index 000000000..a5f302c58 --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/siano/smsir.h b/linux/drivers/media/dvb/siano/smsir.h new file mode 100644 index 000000000..b7d703e2d --- /dev/null +++ b/linux/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.2.3 From 56e85790c8d7256d555de35a62fa0e13535f62fd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 20 Apr 2009 13:00:52 -0300 Subject: Siano: add messages handling for big-endian target From: Uri Shkolnik Add code that modify the content of Siano's protocol messages when running with big-endian target. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsendian.c | 100 ++++++++++++++++++++++++++++++ linux/drivers/media/dvb/siano/smsendian.h | 32 ++++++++++ 2 files changed, 132 insertions(+) create mode 100644 linux/drivers/media/dvb/siano/smsendian.c create mode 100644 linux/drivers/media/dvb/siano/smsendian.h (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsendian.c b/linux/drivers/media/dvb/siano/smsendian.c new file mode 100644 index 000000000..d79aa0512 --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/siano/smsendian.h b/linux/drivers/media/dvb/siano/smsendian.h new file mode 100644 index 000000000..7fbedc6a6 --- /dev/null +++ b/linux/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.2.3 From b16003f763962973b1ec89b94f4f1f063b25e957 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 5 Apr 2009 10:25:06 +0000 Subject: Siano: unified the debug filter module parameter (dvb and core) From: Uri Shkolnik The sms_debug module parameter sets the debug filter for the smsmdtv module. It has been moved to the core component, and replace the smsdvb's. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 4 ++-- linux/drivers/media/dvb/siano/smscoreapi.h | 3 ++- linux/drivers/media/dvb/siano/smsdvb.c | 3 --- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 9a9db2588..5cf5bb5d9 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -34,8 +34,8 @@ #include "smscoreapi.h" #include "sms-cards.h" -static int sms_dbg; -module_param_named(debug, sms_dbg, int, 0644); +int sms_debug; +module_param_named(debug, sms_debug, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); struct smscore_device_notifyee_t { diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 83e0e55f7..875cbe6c7 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -658,6 +658,7 @@ int smscore_led_state(struct smscore_device_t *core, int led); /* ------------------------------------------------------------------------ */ +extern int sms_debug; #define DBG_INFO 1 #define DBG_ADV 2 @@ -666,7 +667,7 @@ int smscore_led_state(struct smscore_device_t *core, int led); printk(kern "%s: " fmt "\n", __func__, ##arg) #define dprintk(kern, lvl, fmt, arg...) do {\ - if (sms_dbg & lvl) \ + if (sms_debug & lvl) \ sms_printk(kern, fmt, ##arg); } while (0) #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 035bd52c9..329cbce07 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -50,9 +50,6 @@ struct smsdvb_client_t { static struct list_head g_smsdvb_clients; static struct mutex g_smsdvb_clientslock; -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))"); static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { -- cgit v1.2.3 From 045548622863911d1e32b2264efbf076d970ece4 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 6 Apr 2009 22:45:20 +0400 Subject: Initial go at TT S2-1600 From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/Kconfig | 22 + linux/drivers/media/dvb/frontends/Makefile | 4 +- linux/drivers/media/dvb/frontends/isl6423.c | 293 ++ linux/drivers/media/dvb/frontends/isl6423.h | 63 + linux/drivers/media/dvb/frontends/stv090x.c | 4797 +++++++++++++++++++++ linux/drivers/media/dvb/frontends/stv090x.h | 109 + linux/drivers/media/dvb/frontends/stv090x_priv.h | 274 ++ linux/drivers/media/dvb/frontends/stv090x_reg.h | 2300 ++++++++++ linux/drivers/media/dvb/frontends/stv6110x.c | 442 ++ linux/drivers/media/dvb/frontends/stv6110x.h | 71 + linux/drivers/media/dvb/frontends/stv6110x_priv.h | 77 + linux/drivers/media/dvb/frontends/stv6110x_reg.h | 82 + linux/drivers/media/dvb/ttpci/budget-ci.c | 83 + 13 files changed, 8616 insertions(+), 1 deletion(-) create mode 100644 linux/drivers/media/dvb/frontends/isl6423.c create mode 100644 linux/drivers/media/dvb/frontends/isl6423.h create mode 100644 linux/drivers/media/dvb/frontends/stv090x.c create mode 100644 linux/drivers/media/dvb/frontends/stv090x.h create mode 100644 linux/drivers/media/dvb/frontends/stv090x_priv.h create mode 100644 linux/drivers/media/dvb/frontends/stv090x_reg.h create mode 100644 linux/drivers/media/dvb/frontends/stv6110x.c create mode 100644 linux/drivers/media/dvb/frontends/stv6110x.h create mode 100644 linux/drivers/media/dvb/frontends/stv6110x_priv.h create mode 100644 linux/drivers/media/dvb/frontends/stv6110x_reg.h (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index a206cee23..29276960d 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/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/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 65a336aa1..83f7c7e7e 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -70,4 +70,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/linux/drivers/media/dvb/frontends/isl6423.c b/linux/drivers/media/dvb/frontends/isl6423.c new file mode 100644 index 000000000..c1943dcb8 --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/frontends/isl6423.h b/linux/drivers/media/dvb/frontends/isl6423.h new file mode 100644 index 000000000..e1a37fba0 --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c new file mode 100644 index 000000000..fc0781961 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -0,0 +1,4797 @@ +/* + 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 */ +}; + +#if 0 +static struct stv090x_reg stv090x_defval[] = { + + { STV090x_MID, 0x20 }, /* MID */ + { STV090x_DACR1, 0x00 }, /* DACR1 */ + { STV090x_DACR2, 0x00 }, /* DACR2 */ + { STV090x_OUTCFG, 0x00 }, /* OUTCFG */ +#if 0 + { STV090x_MODECFG, 0xff }, /* MODECFG */ +#endif + { STV090x_IRQSTATUS3, 0x00 }, /* IRQSTATUS3 */ + { STV090x_IRQSTATUS2, 0x00 }, /* IRQSTATUS2 */ + { STV090x_IRQSTATUS1, 0x00 }, /* IRQSTATUS1 */ + { STV090x_IRQSTATUS0, 0x00 }, /* IRQSTATUS0 */ + { STV090x_IRQMASK3, 0x3f }, /* IRQMASK3 */ + { STV090x_IRQMASK2, 0xff }, /* IRQMASK2 */ + { STV090x_IRQMASK1, 0xff }, /* IRQMASK1 */ + { STV090x_IRQMASK0, 0xff }, /* IRQMASK0 */ + { STV090x_I2CCFG, 0x08 }, /* I2CCFG */ + { STV090x_P1_I2CRPT, 0x44 }, /* P1_I2CRPT */ + { STV090x_P2_I2CRPT, 0x44 }, /* P2_I2CRPT */ + { STV090x_CLKI2CFG, 0x82 }, /* CLKI2CFG */ + { STV090x_GPIO1CFG, 0x82 }, /* GPIO1CFG */ + { STV090x_GPIO2CFG, 0x82 }, /* GPIO2CFG */ + { STV090x_GPIO3CFG, 0x82 }, /* GPIO3CFG */ + { STV090x_GPIO4CFG, 0x82 }, /* GPIO4CFG */ + { STV090x_GPIO5CFG, 0x82 }, /* GPIO5CFG */ + { STV090x_GPIO6CFG, 0x82 }, /* GPIO6CFG */ + { STV090x_GPIO7CFG, 0x82 }, /* GPIO7CFG */ + { STV090x_GPIO8CFG, 0x82 }, /* GPIO8CFG */ + { STV090x_GPIO9CFG, 0x82 }, /* GPIO9CFG */ + { STV090x_GPIO10CFG, 0x82 }, /* GPIO10CFG */ + { STV090x_GPIO11CFG, 0x82 }, /* GPIO11CFG */ + { STV090x_GPIO12CFG, 0x82 }, /* GPIO12CFG */ + { STV090x_GPIO13CFG, 0x82 }, /* GPIO13CFG */ + { STV090x_CS0CFG, 0x82 }, /* CS0CFG */ + { STV090x_CS1CFG, 0x82 }, /* CS1CFG */ + { STV090x_STDBYCFG, 0x82 }, /* STDBYCFG */ + { STV090x_DIRCLKCFG, 0x82 }, /* DIRCLKCFG */ + { STV090x_AGCRF1CFG, 0x11 }, /* AGCRF1CFG */ + { STV090x_SDAT1CFG, 0xb0 }, /* SDAT1CFG */ + { STV090x_SCLT1CFG, 0xb2 }, /* SCLT1CFG */ + { STV090x_DISEQCO1CFG, 0x14 }, /* DISEQCO1CFG */ + { STV090x_AGCRF2CFG, 0x13 }, /* AGCRF2CFG */ + { STV090x_SDAT2CFG, 0xb4 }, /* SDAT2CFG */ + { STV090x_SCLT2CFG, 0xb6 }, /* SCLT2CFG */ + { STV090x_DISEQCO2CFG, 0x16 }, /* DISEQCO2CFG */ + { STV090x_CLKOUT27CFG, 0x7e }, /* ERROR1CFG */ + { STV090x_DPN1CFG, 0xc0 }, /* DPN1CFG */ + { STV090x_STROUT1CFG, 0xc2 }, /* STROUT1CFG */ + { STV090x_CLKOUT1CFG, 0xc6 }, /* CLKOUT1CFG */ + { STV090x_DATA71CFG, 0xc8 }, /* DATA71CFG */ + { STV090x_ERROR2CFG, 0xce }, /* ERROR2CFG */ + { STV090x_DPN2CFG, 0xca }, /* DPN2CFG */ + { STV090x_STROUT2CFG, 0xcc }, /* STROUT2CFG */ + { STV090x_CLKOUT2CFG, 0xd0 }, /* CLKOUT2CFG */ + { STV090x_DATA72CFG, 0xd2 }, /* DATA72CFG */ + { STV090x_ERROR3CFG, 0xd8 }, /* ERROR3CFG */ + { STV090x_DPN3CFG, 0xd4 }, /* DPN3CFG */ + { STV090x_STROUT3CFG, 0xd6 }, /* STROUT3CFG */ + { STV090x_CLKOUT3CFG, 0xda }, /* CLKOUT3CFG */ + { STV090x_DATA73CFG, 0xdc }, /* DATA73CFG */ + { STV090x_FSKTFC2, 0x8c }, /* FSKTFC2 */ + { STV090x_FSKTFC1, 0x75 }, /* FSKTFC1 */ + { STV090x_FSKTFC0, 0xc2 }, /* FSKTFC0 */ + { STV090x_FSKTDELTAF1, 0x02 }, /* FSKTDELTAF1 */ + { STV090x_FSKTDELTAF0, 0x0c }, /* FSKTDELTAF0 */ + { STV090x_FSKTCTRL, 0x04 }, /* FSKTCTRL */ + { STV090x_FSKRFC2, 0x10 }, /* FSKRFC2 */ + { STV090x_FSKRFC1, 0x75 }, /* FSKRFC1 */ + { STV090x_FSKRFC0, 0xc2 }, /* FSKRFC0 */ + { STV090x_FSKRK1, 0x3a }, /* FSKRK1 */ + { STV090x_FSKRK2, 0x74 }, /* FSKRK2 */ + { STV090x_FSKRAGCR, 0x28 }, /* FSKRAGCR */ + { STV090x_FSKRAGC, 0xff }, /* FSKRAGC */ + { STV090x_FSKRALPHA, 0x17 }, /* FSKRALPHA */ + { STV090x_FSKRPLTH1, 0x80 }, /* FSKRPLTH1 */ + { STV090x_FSKRPLTH0, 0x00 }, /* FSKRPLTH0 */ + { STV090x_FSKRDF1, 0x80 }, /* FSKRDF1 */ + { STV090x_FSKRDF0, 0x00 }, /* FSKRDF0 */ + { STV090x_FSKRSTEPP, 0x30 }, /* FSKRSTEPP */ + { STV090x_FSKRSTEPM, 0x70 }, /* FSKRSTEPM */ + { STV090x_FSKRDET1, 0x00 }, /* FSKRDET1 */ + { STV090x_FSKRDET0, 0x00 }, /* FSKRDET0 */ + { STV090x_FSKRDTH1, 0x11 }, /* FSKRDTH1 */ + { STV090x_FSKRDTH0, 0x89 }, /* FSKRDTH0 */ + { STV090x_FSKRLOSS, 0x06 }, /* FSKRLOSS */ + { STV090x_P2_DISTXCTL, 0x22 }, /* P2_DISTXCTL */ + { STV090x_P2_DISRXCTL, 0x80 }, /* P2_DISRXCTL */ + { STV090x_P2_DISRX_ST0, 0x04 }, /* P2_DISRX_ST0 */ + { STV090x_P2_DISRX_ST1, 0x00 }, /* P2_DISRX_ST1 */ + { STV090x_P2_DISRXDATA, 0x00 }, /* P2_DISRXDATA */ + { STV090x_P2_DISTXDATA, 0x00 }, /* P2_DISTXDATA */ + { STV090x_P2_DISTXSTATUS, 0x20 }, /* P2_DISTXSTATUS */ + { STV090x_P2_F22TX, 0xc0 }, /* P2_F22TX */ + { STV090x_P2_F22RX, 0xc0 }, /* P2_F22RX */ + { STV090x_P2_ACRPRESC, 0x01 }, /* P2_ACRPRESC */ + { STV090x_P2_ACRDIV, 0x14 }, /* P2_ACRDIV */ + { STV090x_P1_DISTXCTL, 0x22 }, /* P1_DISTXCTL */ + { STV090x_P1_DISRXCTL, 0x80 }, /* P1_DISRXCTL */ + { STV090x_P1_DISRX_ST0, 0x14 }, /* P1_DISRX_ST0 */ + { STV090x_P1_DISRX_ST1, 0x80 }, /* P1_DISRX_ST1 */ + { STV090x_P1_DISRXDATA, 0x00 }, /* P1_DISRXDATA */ + { STV090x_P1_DISTXDATA, 0x00 }, /* P1_DISTXDATA */ + { STV090x_P1_DISTXSTATUS, 0x20 }, /* P1_DISTXSTATUS */ + { STV090x_P1_F22TX, 0xc0 }, /* P1_F22TX */ + { STV090x_P1_F22RX, 0xc0 }, /* P1_F22RX */ + { STV090x_P1_ACRPRESC, 0x01 }, /* P1_ACRPRESC */ + { STV090x_P1_ACRDIV, 0x14 }, /* P1_ACRDIV */ + { STV090x_NCOARSE, 0x13 }, /* NCOARSE */ + { STV090x_SYNTCTRL, 0x22 }, /* SYNTCTRL (default CLKI) */ + { STV090x_FILTCTRL, 0x01 }, /* FILTCTRL */ + { STV090x_PLLSTAT, 0xc0 }, /* PLLSTAT */ + { STV090x_STOPCLK1, 0x00 }, /* STOPCLK1 */ + { STV090x_STOPCLK2, 0x00 }, /* STOPCLK2 */ + { STV090x_TSTTNR0, 0x04 }, /* TSTTNR0 */ + { STV090x_TSTTNR1, 0x27 }, /* TSTTNR1 */ + { STV090x_TSTTNR2, 0x21 }, /* TSTTNR2 */ + { STV090x_TSTTNR3, 0x27 }, /* TSTTNR3 */ + { STV090x_TSTTNR4, 0x21 }, /* TSTTNR4 */ + { STV090x_P2_IQCONST, 0x00 }, /* P2_IQCONST */ + { STV090x_P2_NOSCFG, 0x1c }, /* P2_NOSCFG */ + { STV090x_P2_ISYMB, 0x27 }, /* P2_ISYMB */ + { STV090x_P2_QSYMB, 0x2a }, /* P2_QSYMB */ + { STV090x_P2_AGC1CFG, 0x54 }, /* P2_AGC1CFG */ + { STV090x_P2_AGC1CN, 0xd9 }, /* P2_AGC1CN */ + { STV090x_P2_AGC1REF, 0x58 }, /* P2_AGC1REF */ + { STV090x_P2_IDCCOMP, 0x00 }, /* P2_IDCCOMP */ + { STV090x_P2_QDCCOMP, 0xfd }, /* P2_QDCCOMP */ + { STV090x_P2_POWERI, 0x0e }, /* P2_POWERI */ + { STV090x_P2_POWERQ, 0x0c }, /* P2_POWERQ */ + { STV090x_P2_AGC1AMM, 0x19 }, /* P2_AGC1AMM */ + { STV090x_P2_AGC1QUAD, 0xf9 }, /* P2_AGC1QUAD */ + { STV090x_P2_AGCIQIN1, 0x00 }, /* P2_AGCIQIN1 */ + { STV090x_P2_AGCIQIN0, 0x00 }, /* P2_AGCIQIN0 */ + { STV090x_P2_DEMOD, 0x08 }, /* P2_DEMOD */ + { STV090x_P2_DMDMODCOD, 0x10 }, /* P2_DMDMODCOD */ + { STV090x_P2_DSTATUS, 0x10 }, /* P2_DSTATUS */ + { STV090x_P2_DSTATUS2, 0x88 }, /* P2_DSTATUS2 */ + { STV090x_P2_DMDCFGMD, 0xf9 }, /* P2_DMDCFGMD */ + { STV090x_P2_DMDCFG2, 0x3b }, /* P2_DMDCFG2 */ + { STV090x_P2_DMDISTATE, 0x5c }, /* P2_DMDISTATE */ +#if 0 + { STV090x_P2_DMDT0M, 0x20 }, /* P2_DMDT0M */ +#endif + { STV090x_P2_DMDSTATE, 0x1c }, /* P2_DMDSTATE */ + { STV090x_P2_DMDFLYW, 0x00 }, /* P2_DMDFLYW */ + { STV090x_P2_DSTATUS3, 0x00 }, /* P2_DSTATUS3 */ + { STV090x_P2_DMDCFG3, 0x68 }, /* P2_DMDCFG3 */ +#if 0 + { STV090x_P2_DMDCFG4, 0x10 }, /* P2_DMDCFG4 */ +#endif + { STV090x_P2_CORRELMANT, 0x70 }, /* P2_CORRELMANT */ + { STV090x_P2_CORRELABS, 0x88 }, /* P2_CORRELABS */ + { STV090x_P2_CORRELEXP, 0xaa }, /* P2_CORRELEXP */ + { STV090x_P2_PLHMODCOD, 0x42 }, /* P2_PLHMODCOD */ +#if 0 + { STV090x_P2_AGCK32, 0x00 }, /* P2_AGCK32 */ + { STV090x_P2_AGC2O, 0x5b }, /* P2_AGC2O */ +#endif + { STV090x_P2_AGC2REF, 0x38 }, /* P2_AGC2REF */ + { STV090x_P2_AGC1ADJ, 0x58 }, /* P2_AGC1ADJ */ + { STV090x_P2_AGC2I1, 0x00 }, /* P2_AGC2I1 */ + { STV090x_P2_AGC2I0, 0x60 }, /* P2_AGC2I0 */ + { STV090x_P2_CARCFG, 0xe4 }, /* P2_CARCFG */ + { STV090x_P2_ACLC, 0x1a }, /* P2_ACLC */ + { STV090x_P2_BCLC, 0x09 }, /* P2_BCLC */ + { STV090x_P2_CARFREQ, 0x38 }, /* P2_CARFREQ */ + { STV090x_P2_CARHDR, 0x20 }, /* P2_CARHDR */ + { STV090x_P2_LDT, 0xd0 }, /* P2_LDT */ + { STV090x_P2_LDT2, 0xb0 }, /* P2_LDT2 */ + { STV090x_P2_CFRICFG, 0xf8 }, /* P2_CFRICFG */ + { STV090x_P2_CFRUP1, 0x3f }, /* P2_CFRUP1 */ + { STV090x_P2_CFRUP0, 0xff }, /* P2_CFRUP0 */ + { STV090x_P2_CFRLOW1, 0xc0 }, /* P2_CFRLOW1 */ + { STV090x_P2_CFRLOW0, 0x01 }, /* P2_CFRLOW0 */ + { STV090x_P2_CFRINIT1, 0xfc }, /* P2_CFRINIT1 */ + { STV090x_P2_CFRINIT0, 0xff }, /* P2_CFRINIT0 */ + { STV090x_P2_CFRINC1, 0x03 }, /* P2_CFRINC1 */ + { STV090x_P2_CFRINC0, 0x00 }, /* P2_CFRINC0 */ + { STV090x_P2_CFR2, 0xfc }, /* P2_CFR2 */ + { STV090x_P2_CFR1, 0xff }, /* P2_CFR1 */ + { STV090x_P2_CFR0, 0x00 }, /* P2_CFR0 */ + { STV090x_P2_LDI, 0x80 }, /* P2_LDI */ + { STV090x_P2_TMGCFG, 0xd2 }, /* P2_TMGCFG */ + { STV090x_P2_RTC, 0x88 }, /* P2_RTC */ + { STV090x_P2_RTCS2, 0x66 }, /* P2_RTCS2 */ + { STV090x_P2_TMGTHRISE, 0x20 }, /* P2_TMGTHRISE */ + { STV090x_P2_TMGTHFALL, 0x00 }, /* P2_TMGTHFALL */ + { STV090x_P2_SFRUPRATIO, 0xf0 }, /* P2_SFRUPRATIO */ + { STV090x_P2_SFRLOWRATIO, 0x70 }, /* P2_SFRLOWRATIO */ + { STV090x_P2_KREFTMG, 0x31 }, /* P2_KREFTMG */ + { STV090x_P2_SFRSTEP, 0x58 }, /* P2_SFRSTEP */ + { STV090x_P2_TMGCFG2, 0x01 }, /* P2_TMGCFG2 */ + { STV090x_P2_SFRINIT1, 0x03 }, /* P2_SFRINIT1 */ + { STV090x_P2_SFRINIT0, 0x01 }, /* P2_SFRINIT0 */ + { STV090x_P2_SFRUP1, 0x83 }, /* P2_SFRUP1 */ + { STV090x_P2_SFRUP0, 0xc0 }, /* P2_SFRUP0 */ + { STV090x_P2_SFRLOW1, 0x82 }, /* P2_SFRLOW1 */ + { STV090x_P2_SFRLOW0, 0xa0 }, /* P2_SFRLOW0 */ + { STV090x_P2_SFR3, 0x03 }, /* P2_SFR3 */ + { STV090x_P2_SFR2, 0x01 }, /* P2_SFR2 */ + { STV090x_P2_SFR1, 0x00 }, /* P2_SFR1 */ + { STV090x_P2_SFR0, 0x00 }, /* P2_SFR0 */ + { STV090x_P2_TMGREG2, 0x00 }, /* P2_TMGREG2 */ + { STV090x_P2_TMGREG1, 0x00 }, /* P2_TMGREG1 */ + { STV090x_P2_TMGREG0, 0x00 }, /* P2_TMGREG0 */ + { STV090x_P2_TMGLOCK1, 0x00 }, /* P2_TMGLOCK1 */ + { STV090x_P2_TMGLOCK0, 0x00 }, /* P2_TMGLOCK0 */ + { STV090x_P2_TMGOBS, 0x10 }, /* P2_TMGOBS */ + { STV090x_P2_EQUALCFG, 0x41 }, /* P2_EQUALCFG */ + { STV090x_P2_EQUAI1, 0xf0 }, /* P2_EQUAI1 */ + { STV090x_P2_EQUAQ1, 0x00 }, /* P2_EQUAQ1 */ + { STV090x_P2_EQUAI2, 0xf0 }, /* P2_EQUAI2 */ + { STV090x_P2_EQUAQ2, 0x00 }, /* P2_EQUAQ2 */ + { STV090x_P2_EQUAI3, 0xf0 }, /* P2_EQUAI3 */ + { STV090x_P2_EQUAQ3, 0x00 }, /* P2_EQUAQ3 */ + { STV090x_P2_EQUAI4, 0xf0 }, /* P2_EQUAI4 */ + { STV090x_P2_EQUAQ4, 0x00 }, /* P2_EQUAQ4 */ + { STV090x_P2_EQUAI5, 0xf0 }, /* P2_EQUAI5 */ + { STV090x_P2_EQUAQ5, 0x00 }, /* P2_EQUAQ5 */ + { STV090x_P2_EQUAI6, 0xf0 }, /* P2_EQUAI6 */ + { STV090x_P2_EQUAQ6, 0x00 }, /* P2_EQUAQ6 */ + { STV090x_P2_EQUAI7, 0xf0 }, /* P2_EQUAI7 */ + { STV090x_P2_EQUAQ7, 0x00 }, /* P2_EQUAQ7 */ + { STV090x_P2_EQUAI8, 0xf0 }, /* P2_EQUAI8 */ + { STV090x_P2_EQUAQ8, 0x00 }, /* P2_EQUAQ8 */ + { STV090x_P2_NNOSDATAT1, 0x01 }, /* P2_NNOSDATAT1 */ + { STV090x_P2_NNOSDATAT0, 0x65 }, /* P2_NNOSDATAT0 */ + { STV090x_P2_NNOSDATA1, 0x00 }, /* P2_NNOSDATA1 */ + { STV090x_P2_NNOSDATA0, 0x0d }, /* P2_NNOSDATA0 */ + { STV090x_P2_NNOSPLHT1, 0x4d }, /* P2_NNOSPLHT1 */ + { STV090x_P2_NNOSPLHT0, 0x6a }, /* P2_NNOSPLHT0 */ + { STV090x_P2_NNOSPLH1, 0x57 }, /* P2_NNOSPLH1 */ + { STV090x_P2_NNOSPLH0, 0x52 }, /* P2_NNOSPLH0 */ + { STV090x_P2_NOSDATAT1, 0x01 }, /* P2_NOSDATAT1 */ + { STV090x_P2_NOSDATAT0, 0x39 }, /* P2_NOSDATAT0 */ + { STV090x_P2_NOSDATA1, 0x00 }, /* P2_NOSDATA1 */ + { STV090x_P2_NOSDATA0, 0x0a }, /* P2_NOSDATA0 */ + { STV090x_P2_NOSPLHT1, 0x43 }, /* P2_NOSPLHT1 */ + { STV090x_P2_NOSPLHT0, 0xbd }, /* P2_NOSPLHT0 */ + { STV090x_P2_NNOSPLH1, 0x42 }, /* P2_NOSPLH1 */ + { STV090x_P2_NNOSPLH0, 0xdb }, /* P2_NOSPLH0 */ + { STV090x_P2_CAR2CFG, 0x26 }, /* P2_CAR2CFG */ + { STV090x_P2_ACLC2, 0x28 }, /* P2_ACLC2 */ + { STV090x_P2_BCLC2, 0x25 }, /* P2_BCLC2 */ +#if 0 + { STV090x_P2_CFR22, 0x00 }, /* P2_CFR22 */ + { STV090x_P2_CFR21, 0x00 }, /* P2_CFR21 */ + { STV090x_P2_CFR20, 0x00 }, /* P2_CFR20 */ +#endif + { STV090x_P2_ACLC2S2Q, 0x6a }, /* P2_ACLC2S2Q */ + { STV090x_P2_ACLC2S28, 0x58 }, /* P2_ACLC2S28 */ + { STV090x_P2_ACLC2S216A, 0x68 }, /* P2_ACLC2S216A */ + { STV090x_P2_ACLC2S232A, 0x68 }, /* P2_ACLC2S232A */ + + { STV090x_P2_BCLC2S2Q, 0x86 }, /* P2_BCLC2S2Q */ + { STV090x_P2_BCLC2S28, 0x86 }, /* P2_BCLC2S28 */ + { STV090x_P2_BCLC2S216A, 0xa5 }, /* P2_BCLC2S216A */ + { STV090x_P2_BCLC2S232A, 0xa5 }, /* P2_BCLC2S232A */ + + { STV090x_P2_PLROOT2, 0x00 }, /* P2_PLROOT2 */ + { STV090x_P2_FECM, 0x10 }, /* P2_FECM */ + { STV090x_P2_PLROOT1, 0x00 }, /* P2_PLROOT1 */ + { STV090x_P2_PLROOT0, 0x01 }, /* P2_PLROOT0 */ + { STV090x_P2_MODCODLST0, 0xff }, /* P2_MODCODLST0 */ + { STV090x_P2_MODCODLST1, 0xff }, /* P2_MODCODLST1 */ + { STV090x_P2_MODCODLST2, 0xff }, /* P2_MODCODLST2 */ + { STV090x_P2_MODCODLST3, 0xff }, /* P2_MODCODLST3 */ + { STV090x_P2_MODCODLST4, 0xff }, /* P2_MODCODLST4 */ + { STV090x_P2_MODCODLST5, 0xff }, /* P2_MODCODLST5 */ + { STV090x_P2_MODCODLST6, 0xff }, /* P2_MODCODLST6 */ + { STV090x_P2_MODCODLST7, 0xcc }, /* P2_MODCODLST7 */ + { STV090x_P2_MODCODLST8, 0xcc }, /* P2_MODCODLST8 */ + { STV090x_P2_MODCODLST9, 0xcc }, /* P2_MODCODLST9 */ + { STV090x_P2_MODCODLSTA, 0xcc }, /* P2_MODCODLSTA */ + { STV090x_P2_MODCODLSTB, 0xcc }, /* P2_MODCODLSTB */ + { STV090x_P2_MODCODLSTC, 0xcc }, /* P2_MODCODLSTC */ + { STV090x_P2_MODCODLSTD, 0xcc }, /* P2_MODCODLSTD */ + { STV090x_P2_MODCODLSTE, 0xcc }, /* P2_MODCODLSTE */ + { STV090x_P2_MODCODLSTF, 0xcf }, /* P2_MODCODLSTF */ + { STV090x_P2_DMDRESCFG, 0x29 }, /* P2_DMDRESCFG */ + { STV090x_P2_DMDRESADR, 0x11 }, /* P2_DMDRESADR */ + { STV090x_P2_DMDRESDATA7, 0x47 }, /* P2_DMDRESDATA7 */ + { STV090x_P2_DMDRESDATA6, 0x82 }, /* P2_DMDRESDATA6 */ + { STV090x_P2_DMDRESDATA5, 0x00 }, /* P2_DMDRESDATA5 */ + { STV090x_P2_DMDRESDATA4, 0x00 }, /* P2_DMDRESDATA4 */ + { STV090x_P2_DMDRESDATA3, 0x92 }, /* P2_DMDRESDATA3 */ + { STV090x_P2_DMDRESDATA2, 0x4c }, /* P2_DMDRESDATA2 */ + { STV090x_P2_DMDRESDATA1, 0x00 }, /* P2_DMDRESDATA1 */ + { STV090x_P2_DMDRESDATA0, 0x07 }, /* P2_DMDRESDATA0 */ + { STV090x_P2_FFEI1, 0x00 }, /* P2_FFEI1 */ + { STV090x_P2_FFEQ1, 0x00 }, /* P2_FFEQ1 */ + { STV090x_P2_FFEI2, 0x00 }, /* P2_FFEI2 */ + { STV090x_P2_FFEQ2, 0x00 }, /* P2_FFEQ2 */ + { STV090x_P2_FFEI3, 0x00 }, /* P2_FFEI3 */ + { STV090x_P2_FFEQ3, 0x00 }, /* P2_FFEQ3 */ + { STV090x_P2_FFEI4, 0x00 }, /* P2_FFEI4 */ + { STV090x_P2_FFEQ4, 0x00 }, /* P2_FFEQ4 */ + { STV090x_P2_FFECFG, 0x31 }, /* P2_FFECFG */ +#if 0 + { STV090x_P2_TNRCFG, 0xef }, /* P2_TNRCFG */ + { STV090x_P2_TNRCFG2, 0x02 }, /* P2_TNRCFG2 */ + { STV090x_P2_TNRXTAL, 0x1b }, /* P2_TNRXTAL */ + { STV090x_P2_TNRSTEPS, 0x87 }, /* P2_TNRSTEPS */ + { STV090x_P2_TNRGAIN, 0x09 }, /* P2_TNRGAIN */ + { STV090x_P2_TNRRF1, 0x47 }, /* P2_TNRRF1 */ + { STV090x_P2_TNRRF0, 0x82 }, /* P2_TNRRF0 */ + { STV090x_P2_TNRBW, 0x24 }, /* P2_TNRBW */ + { STV090x_P2_TNRADJ, 0x1f }, /* P2_TNRADJ */ + { STV090x_P2_TNRCTL2, 0x37 }, /* P2_TNRCTL2 */ + { STV090x_P2_TNRCFG3, 0x02 }, /* P2_TNRCFG3 */ + { STV090x_P2_TNRLAUNCH, 0x00 }, /* P2_TNRLAUNCH */ + { STV090x_P2_TNRLD, 0x00 }, /* P2_TNRLD */ + { STV090x_P2_TNROBSL, 0x50 }, /* P2_TNROBSL */ + { STV090x_P2_TNRRESTE, 0x00 }, /* P2_TNRRESTE */ +#endif + { STV090x_P2_SMAPCOEF7, 0x06 }, /* P2_SMAPCOEF7 */ + { STV090x_P2_SMAPCOEF6, 0x00 }, /* P2_SMAPCOEF6 */ + { STV090x_P2_SMAPCOEF5, 0x04 }, /* P2_SMAPCOEF5 */ + { STV090x_P2_DMDPLHSTAT, 0x00 }, /* P2_DMDPLHSTAT */ + { STV090x_P2_LOCKTIME3, 0xff }, /* P2_LOCKTIME3 */ + { STV090x_P2_LOCKTIME2, 0xf0 }, /* P2_LOCKTIME2 */ + { STV090x_P2_LOCKTIME1, 0x5a }, /* P2_LOCKTIME1 */ + { STV090x_P2_LOCKTIME0, 0x86 }, /* P2_LOCKTIME0 */ + { STV090x_P2_VITSCALE, 0x00 }, /* P2_VITSCALE */ + { STV090x_P2_FECM, 0x10 }, /* P2_FECM */ + { STV090x_P2_VTH12, 0xd0 }, /* P2_VTH12 */ + { STV090x_P2_VTH23, 0x7d }, /* P2_VTH23 */ + { STV090x_P2_VTH34, 0x53 }, /* P2_VTH34 */ + { STV090x_P2_VTH56, 0x2f }, /* P2_VTH56 */ + { STV090x_P2_VTH67, 0x24 }, /* P2_VTH67 */ + { STV090x_P2_VTH78, 0x1f }, /* P2_VTH78 */ + { STV090x_P2_VITCURPUN, 0x0d }, /* P2_VITCURPUN */ + { STV090x_P2_VERROR, 0xff }, /* P2_VERROR */ + { STV090x_P2_PRVIT, 0x3f }, /* P2_PRVIT */ + { STV090x_P2_VAVSRVIT, 0x00 }, /* P2_VAVSRVIT */ + { STV090x_P2_VSTATUSVIT, 0xa7 }, /* P2_VSTATUSVIT */ + { STV090x_P2_VTHINUSE, 0x01 }, /* P2_VTHINUSE */ + { STV090x_P2_KDIV12, 0x27 }, /* P2_KDIV12 */ + { STV090x_P2_KDIV23, 0x32 }, /* P2_KDIV23 */ + { STV090x_P2_KDIV34, 0x32 }, /* P2_KDIV34 */ + { STV090x_P2_KDIV56, 0x32 }, /* P2_KDIV56 */ + { STV090x_P2_KDIV67, 0x32 }, /* P2_KDIV67 */ + { STV090x_P2_KDIV78, 0x50 }, /* P2_KDIV78 */ + { STV090x_P2_PDELCTRL1, 0x00 }, /* P2_PDELCTRL1 */ + { STV090x_P2_PDELCTRL2, 0x20 }, /* P2_PDELCTRL2 */ + { STV090x_P2_HYSTTHRESH, 0x41 }, /* P2_HYSTTHRESH */ + { STV090x_P2_ISIENTRY, 0x00 }, /* P2_ISIENTRY */ + { STV090x_P2_ISIBITENA, 0x00 }, /* P2_ISIBITENA */ + { STV090x_P2_MATSTR1, 0xf0 }, /* P2_MATSTR1 */ + { STV090x_P2_MATSTR0, 0x00 }, /* P2_MATSTR0 */ + { STV090x_P2_UPLSTR1, 0x05 }, /* P2_UPLSTR1 */ + { STV090x_P2_UPLSTR0, 0xe0 }, /* P2_UPLSTR0 */ + { STV090x_P2_DFLSTR1, 0x7d }, /* P2_DFLSTR1 */ + { STV090x_P2_DFLSTR0, 0x80 }, /* P2_DFLSTR0 */ + { STV090x_P2_SYNCSTR, 0x47 }, /* P2_SYNCSTR */ + { STV090x_P2_SYNCDSTR1, 0x00 }, /* P2_SYNCDSTR1 */ + { STV090x_P2_SYNCDSTR0, 0x00 }, /* P2_SYNCDSTR0 */ + { STV090x_P2_PDELSTATUS1, 0x94 }, /* P2_PDELSTATUS1 */ + { STV090x_P2_PDELSTATUS2, 0x90 }, /* P2_PDELSTATUS2 */ + { STV090x_P2_BBFCRCKO1, 0x00 }, /* P2_BBFCRCKO1 */ + { STV090x_P2_BBFCRCKO0, 0x00 }, /* P2_BBFCRCKO0 */ + { STV090x_P2_UPCRCKO1, 0x00 }, /* P2_UPCRCKO1 */ + { STV090x_P2_UPCRCKO0, 0x00 }, /* P2_UPCRCKO0 */ + { STV090x_P2_TSSTATEM, 0xb0 }, /* P2_TSSTATEM */ + { STV090x_P2_TSCFGH, 0x40 }, /* P2_TSCFGH */ + { STV090x_P2_TSCFGM, 0x00 }, /* P2_TSCFGM */ + { STV090x_P2_TSCFGL, 0x20 }, /* P2_TSCFGL */ + { STV090x_P2_TSINSDELH, 0x00 }, /* P2_TSINSDELH */ + { STV090x_P2_TSSPEED, 0xff }, /* P2_TSSPEED */ + { STV090x_P2_TSSTATUS, 0x52 }, /* P2_TSSTATUS */ + { STV090x_P2_TSSTATUS2, 0xea }, /* P2_TSSTATUS2 */ + { STV090x_P2_TSBITRATE1, 0x00 }, /* P2_TSBITRATE1 */ + { STV090x_P2_TSBITRATE0, 0x00 }, /* P2_TSBITRATE0 */ + { STV090x_P2_ERRCTRL1, 0x35 }, /* P2_ERRCTRL1 */ + { STV090x_P2_ERRCNT12, 0x80 }, /* P2_ERRCNT12 */ + { STV090x_P2_ERRCNT11, 0x00 }, /* P2_ERRCNT11 */ + { STV090x_P2_ERRCNT10, 0x00 }, /* P2_ERRCNT10 */ + { STV090x_P2_ERRCTRL2, 0xc1 }, /* P2_ERRCTRL2 */ + { STV090x_P2_ERRCNT22, 0x00 }, /* P2_ERRCNT22 */ + { STV090x_P2_ERRCNT21, 0x00 }, /* P2_ERRCNT21 */ + { STV090x_P2_ERRCNT20, 0x00 }, /* P2_ERRCNT20 */ + { STV090x_P2_FECSPY, 0xa8 }, /* P2_FECSPY */ + { STV090x_P2_FSPYCFG, 0x2c }, /* P2_FSPYCFG */ + { STV090x_P2_FSPYDATA, 0x3a }, /* P2_FSPYDATA */ + { STV090x_P2_FSPYOUT, 0x07 }, /* P2_FSPYOUT */ + { STV090x_P2_FSTATUS, 0x00 }, /* P2_FSTATUS */ + { STV090x_P2_FBERCPT4, 0x00 }, /* P2_FBERCPT4 */ + { STV090x_P2_FBERCPT3, 0x00 }, /* P2_FBERCPT3 */ + { STV090x_P2_FBERCPT2, 0x00 }, /* P2_FBERCPT2 */ + { STV090x_P2_FBERCPT1, 0x00 }, /* P2_FBERCPT1 */ + { STV090x_P2_FBERCPT0, 0x00 }, /* P2_FBERCPT0 */ + { STV090x_P2_FBERERR2, 0x00 }, /* P2_FBERERR2 */ + { STV090x_P2_FBERERR1, 0x00 }, /* P2_FBERERR1 */ + { STV090x_P2_FBERERR0, 0x00 }, /* P2_FBERERR0 */ + { STV090x_P2_FSPYBER, 0x10 }, /* P2_FSPYBER */ + { STV090x_P1_IQCONST, 0x00 }, /* P1_IQCONST */ + { STV090x_P1_NOSCFG, 0x1c }, /* P1_NOSCFG */ + { STV090x_P1_ISYMB, 0x29 }, /* P1_ISYMB */ + { STV090x_P1_QSYMB, 0x29 }, /* P1_QSYMB */ + { STV090x_P1_AGC1CFG, 0x54 }, /* P1_AGC1CFG */ + { STV090x_P1_AGC1CN, 0x99 }, /* P1_AGC1CN */ + { STV090x_P1_AGC1REF, 0x58 }, /* P1_AGC1REF */ + { STV090x_P1_IDCCOMP, 0x03 }, /* P1_IDCCOMP */ + { STV090x_P1_QDCCOMP, 0xfe }, /* P1_QDCCOMP */ + { STV090x_P1_POWERI, 0x91 }, /* P1_POWERI */ + { STV090x_P1_POWERQ, 0x86 }, /* P1_POWERQ */ + { STV090x_P1_AGC1AMM, 0x08 }, /* P1_AGC1AMM */ + { STV090x_P1_AGC1QUAD, 0x02 }, /* P1_AGC1QUAD */ + { STV090x_P1_AGCIQIN1, 0x68 }, /* P1_AGCIQIN1 */ + { STV090x_P1_AGCIQIN0, 0x20 }, /* P1_AGCIQIN0 */ + { STV090x_P1_DEMOD, 0x08 }, /* P1_DEMOD */ + { STV090x_P1_DMDMODCOD, 0x10 }, /* P1_DMDMODCOD */ + { STV090x_P1_DSTATUS, 0x10 }, /* P1_DSTATUS */ + { STV090x_P1_DSTATUS2, 0x80 }, /* P1_DSTATUS2 */ + { STV090x_P1_DMDCFGMD, 0xf9 }, /* P1_DMDCFGMD */ + { STV090x_P1_DMDCFG2, 0x3b }, /* P1_DMDCFG2 */ + { STV090x_P1_DMDISTATE, 0x5c }, /* P1_DMDISTATE */ +#if 0 + { STV090x_P1_DMDT0M, 0x20 }, /* P1_DMDT0M */ +#endif + { STV090x_P1_DMDSTATE, 0x1c }, /* P1_DMDSTATE */ + { STV090x_P1_DMDFLYW, 0x00 }, /* P1_DMDFLYW */ + { STV090x_P1_DSTATUS3, 0x00 }, /* P1_DSTATUS3 */ + { STV090x_P1_DMDCFG3, 0x68 }, /* P1_DMDCFG3 */ +#if 0 + { STV090x_P1_DMDCFG4, 0x10 }, /* P1_DMDCFG4 */ +#endif + { STV090x_P1_CORRELMANT, 0x70 }, /* P1_CORRELMANT */ + { STV090x_P1_CORRELABS, 0x88 }, /* P1_CORRELABS */ + { STV090x_P1_CORRELEXP, 0xaa }, /* P1_CORRELEXP */ + { STV090x_P1_PLHMODCOD, 0x42 }, /* P1_PLHMODCOD */ +#if 0 + { STV090x_P1_AGCK32, 0x00 }, /* P1_AGCK32 */ + { STV090x_P1_AGC2O, 0x5b }, /* P1_AGC2O */ +#endif + { STV090x_P1_AGC2REF, 0x38 }, /* P1_AGC2REF */ + { STV090x_P1_AGC1ADJ, 0x58 }, /* P1_AGC1ADJ */ + { STV090x_P1_AGC2I1, 0x00 }, /* P1_AGC2I1 */ + { STV090x_P1_AGC2I0, 0x60 }, /* P1_AGC2I0 */ + { STV090x_P1_CARCFG, 0xe4 }, /* P1_CARCFG */ + { STV090x_P2_AGC2REF, 0x38 }, + { STV090x_P1_ACLC, 0x1a }, /* P1_ACLC */ + { STV090x_P1_BCLC, 0x09 }, /* P1_BCLC */ + { STV090x_P1_CARFREQ, 0x38 }, /* P1_CARFREQ */ + { STV090x_P1_CARHDR, 0x20 }, /* P1_CARHDR */ + { STV090x_P1_LDT, 0xd0 }, /* P1_LDT */ + { STV090x_P1_LDT2, 0xb0 }, /* P1_LDT2 */ + { STV090x_P1_CFRICFG, 0xf8 }, /* P1_CFRICFG */ + { STV090x_P1_CFRUP1, 0x3f }, /* P1_CFRUP1 */ + { STV090x_P1_CFRUP0, 0xff }, /* P1_CFRUP0 */ + { STV090x_P1_CFRLOW1, 0xc0 }, /* P1_CFRLOW1 */ + { STV090x_P1_CFRLOW0, 0x01 }, /* P1_CFRLOW0 */ + { STV090x_P1_CFRINIT1, 0x03 }, /* P1_CFRINIT1 */ + { STV090x_P1_CFRINIT0, 0x00 }, /* P1_CFRINIT0 */ + { STV090x_P1_CFRINC1, 0x03 }, /* P1_CFRINC1 */ + { STV090x_P1_CFRINC0, 0x00 }, /* P1_CFRINC0 */ + { STV090x_P1_CFR2, 0x03 }, /* P1_CFR2 */ + { STV090x_P1_CFR1, 0x00 }, /* P1_CFR1 */ + { STV090x_P1_CFR0, 0x00 }, /* P1_CFR0 */ + { STV090x_P1_LDI, 0x80 }, /* P1_LDI */ + { STV090x_P1_TMGCFG, 0xd3 }, /* P1_TMGCFG */ + { STV090x_P1_RTC, 0x88 }, /* P1_RTC */ + { STV090x_P1_RTCS2, 0x66 }, /* P1_RTCS2 */ + { STV090x_P1_TMGTHRISE, 0x20 }, /* P1_TMGTHRISE */ + { STV090x_P1_TMGTHFALL, 0x00 }, /* P1_TMGTHFALL */ + { STV090x_P1_SFRUPRATIO, 0xf0 }, /* P1_SFRUPRATIO */ + { STV090x_P1_SFRLOWRATIO, 0x70 }, /* P1_SFRLOWRATIO */ + { STV090x_P1_KREFTMG, 0x31 }, /* P1_KREFTMG */ + { STV090x_P1_SFRSTEP, 0x58 }, /* P1_SFRSTEP */ + { STV090x_P1_TMGCFG2, 0x01 }, /* P1_TMGCFG2 */ + { STV090x_P1_SFRINIT1, 0x03 }, /* P1_SFRINIT1 */ + { STV090x_P1_SFRINIT0, 0x01 }, /* P1_SFRINIT0 */ + { STV090x_P1_SFRUP1, 0x83 }, /* P1_SFRUP1 */ + { STV090x_P1_SFRUP0, 0xc0 }, /* P1_SFRUP0 */ + { STV090x_P2_AGC2REF, 0x38 }, + { STV090x_P1_SFRLOW1, 0x82 }, /* P1_SFRLOW1 */ + { STV090x_P1_SFRLOW0, 0xa0 }, /* P1_SFRLOW0 */ + { STV090x_P1_SFR3, 0x03 }, /* P1_SFR3 */ + { STV090x_P1_SFR2, 0x01 }, /* P1_SFR2 */ + { STV090x_P1_SFR1, 0x00 }, /* P1_SFR1 */ + { STV090x_P1_SFR0, 0x00 }, /* P1_SFR0 */ + { STV090x_P1_TMGREG2, 0x00 }, /* P1_TMGREG2 */ + { STV090x_P1_TMGREG1, 0x00 }, /* P1_TMGREG1 */ + { STV090x_P1_TMGREG0, 0x00 }, /* P1_TMGREG0 */ + { STV090x_P1_TMGLOCK1, 0x00 }, /* P1_TMGLOCK1 */ + { STV090x_P1_TMGLOCK0, 0x00 }, /* P1_TMGLOCK0 */ + { STV090x_P1_TMGOBS, 0x10 }, /* P1_TMGOBS */ + { STV090x_P1_EQUALCFG, 0x41 }, /* P1_EQUALCFG */ + { STV090x_P1_EQUAI1, 0xf1 }, /* P1_EQUAI1 */ + { STV090x_P1_EQUAQ1, 0x00 }, /* P1_EQUAQ1 */ + { STV090x_P1_EQUAI2, 0xf1 }, /* P1_EQUAI2 */ + { STV090x_P1_EQUAQ2, 0x00 }, /* P1_EQUAQ2 */ + { STV090x_P1_EQUAI3, 0xf1 }, /* P1_EQUAI3 */ + { STV090x_P1_EQUAQ3, 0x00 }, /* P1_EQUAQ3 */ + { STV090x_P1_EQUAI4, 0xf1 }, /* P1_EQUAI4 */ + { STV090x_P1_EQUAQ4, 0x00 }, /* P1_EQUAQ4 */ + { STV090x_P1_EQUAI5, 0xf1 }, /* P1_EQUAI5 */ + { STV090x_P1_EQUAQ5, 0x00 }, /* P1_EQUAQ5 */ + { STV090x_P1_EQUAI6, 0xf1 }, /* P1_EQUAI6 */ + { STV090x_P1_EQUAQ6, 0x00 }, /* P1_EQUAQ6 */ + { STV090x_P1_EQUAI7, 0xf1 }, /* P1_EQUAI7 */ + { STV090x_P1_EQUAQ7, 0x00 }, /* P1_EQUAQ7 */ + { STV090x_P1_EQUAI8, 0xf1 }, /* P1_EQUAI8 */ + { STV090x_P1_EQUAQ8, 0x00 }, /* P1_EQUAQ8 */ + { STV090x_P1_NNOSDATAT1, 0x01 }, /* P1_NNOSDATAT1 */ + { STV090x_P1_NNOSDATAT0, 0xab }, /* P1_NNOSDATAT0 */ + { STV090x_P1_NNOSDATA1, 0x00 }, /* P1_NNOSDATA1 */ + { STV090x_P1_NNOSDATA0, 0x12 }, /* P1_NNOSDATA0 */ + { STV090x_P1_NNOSPLHT1, 0x4d }, /* P1_NNOSPLHT1 */ + { STV090x_P1_NNOSPLHT0, 0x7b }, /* P1_NNOSPLHT0 */ + { STV090x_P1_NNOSPLH1, 0x57 }, /* P1_NNOSPLH1 */ + { STV090x_P1_NNOSPLH0, 0x52 }, /* P1_NNOSPLH0 */ + { STV090x_P1_NOSDATAT1, 0x01 }, /* P1_NOSDATAT1 */ + { STV090x_P1_NOSDATAT0, 0x76 }, /* P1_NOSDATAT0 */ + { STV090x_P1_NOSDATA1, 0x00 }, /* P1_NOSDATA1 */ + { STV090x_P1_NOSDATA0, 0x0e }, /* P1_NOSDATA0 */ + { STV090x_P1_NOSPLHT1, 0x43 }, /* P1_NOSPLHT1 */ + { STV090x_P1_NOSPLHT0, 0xcc }, /* P1_NOSPLHT0 */ + { STV090x_P1_NNOSPLH1, 0x42 }, /* P1_NOSPLH1 */ + { STV090x_P1_NNOSPLH0, 0xdb }, /* P1_NOSPLH0 */ + { STV090x_P1_CAR2CFG, 0x26 }, /* P1_CAR2CFG */ + { STV090x_P1_ACLC2, 0x28 }, /* P1_ACLC2 */ + { STV090x_P1_BCLC2, 0x25 }, /* P1_BCLC2 */ +#if 0 + { STV090x_P1_CFR22, 0x00 }, /* P2_CFR22 */ + { STV090x_P1_CFR21, 0x00 }, /* P2_CFR21 */ + { STV090x_P1_CFR20, 0x00 }, /* P2_CFR20 */ +#endif + { STV090x_P1_ACLC2S2Q, 0x6a }, /* P1_ACLC2S2Q */ + { STV090x_P1_ACLC2S28, 0x58 }, /* P1_ACLC2S28 */ + { STV090x_P1_ACLC2S216A, 0x68 }, /* P2_ACLC2S216A */ + { STV090x_P1_ACLC2S232A, 0x68 }, /* P2_ACLC2S232A */ + { STV090x_P1_BCLC2S2Q, 0x86 }, /* P1_BCLC2S2Q */ + { STV090x_P1_BCLC2S28, 0x86 }, /* P1_BCLC2S28 */ + { STV090x_P1_BCLC2S216A, 0xa5 }, /* P2_BCLC2S216A */ + { STV090x_P1_BCLC2S232A, 0xa5 }, /* P2_BCLC2S232A */ + + { STV090x_P1_PLROOT2, 0x00 }, /* P1_PLROOT2 */ + { STV090x_P1_PLROOT1, 0x00 }, /* P1_PLROOT1 */ + { STV090x_P1_PLROOT0, 0x01 }, /* P1_PLROOT0 */ + { STV090x_P1_MODCODLST0, 0xff }, /* P1_MODCODLST0 */ + { STV090x_P1_MODCODLST1, 0xff }, /* P1_MODCODLST1 */ + { STV090x_P1_MODCODLST2, 0xff }, /* P1_MODCODLST2 */ + { STV090x_P1_MODCODLST3, 0xff }, /* P1_MODCODLST3 */ + { STV090x_P1_MODCODLST4, 0xff }, /* P1_MODCODLST4 */ + { STV090x_P1_MODCODLST5, 0xff }, /* P1_MODCODLST5 */ + { STV090x_P1_MODCODLST6, 0xff }, /* P1_MODCODLST6 */ + { STV090x_P1_MODCODLST7, 0xcc }, /* P1_MODCODLST7 */ + { STV090x_P1_MODCODLST8, 0xcc }, /* P1_MODCODLST8 */ + { STV090x_P1_MODCODLST9, 0xcc }, /* P1_MODCODLST9 */ + { STV090x_P1_MODCODLSTA, 0xcc }, /* P1_MODCODLSTA */ + { STV090x_P1_MODCODLSTB, 0xcc }, /* P1_MODCODLSTB */ + { STV090x_P1_MODCODLSTC, 0xcc }, /* P1_MODCODLSTC */ + { STV090x_P1_MODCODLSTD, 0xcc }, /* P1_MODCODLSTD */ + { STV090x_P1_MODCODLSTE, 0xcc }, /* P1_MODCODLSTE */ + { STV090x_P1_MODCODLSTF, 0xcf }, /* P1_MODCODLSTF */ + { STV090x_P1_DMDRESCFG, 0x29 }, /* P1_DMDRESCFG */ + { STV090x_P1_DMDRESADR, 0x11 }, /* P1_DMDRESADR */ + { STV090x_P1_DMDRESDATA7, 0x4e }, /* P1_DMDRESDATA7 */ + { STV090x_P1_DMDRESDATA6, 0x7f }, /* P1_DMDRESDATA6 */ + { STV090x_P1_DMDRESDATA5, 0x00 }, /* P1_DMDRESDATA5 */ + { STV090x_P1_DMDRESDATA4, 0x04 }, /* P1_DMDRESDATA4 */ + { STV090x_P1_DMDRESDATA3, 0x92 }, /* P1_DMDRESDATA3 */ + { STV090x_P1_DMDRESDATA2, 0xcc }, /* P1_DMDRESDATA2 */ + { STV090x_P1_DMDRESDATA1, 0x0a }, /* P1_DMDRESDATA1 */ + { STV090x_P1_DMDRESDATA0, 0x07 }, /* P1_DMDRESDATA0 */ + { STV090x_P1_FFEI1, 0x00 }, /* P1_FFEI1 */ + { STV090x_P1_FFEQ1, 0x00 }, /* P1_FFEQ1 */ + { STV090x_P1_FFEI2, 0x00 }, /* P1_FFEI2 */ + { STV090x_P1_FFEQ2, 0x00 }, /* P1_FFEQ2 */ + { STV090x_P1_FFEI3, 0x00 }, /* P1_FFEI3 */ + { STV090x_P1_FFEQ3, 0x00 }, /* P1_FFEQ3 */ + { STV090x_P1_FFEI4, 0x00 }, /* P1_FFEI4 */ + { STV090x_P1_FFEQ4, 0x00 }, /* P1_FFEQ4 */ + { STV090x_P1_FFECFG, 0x31 }, /* P1_FFECFG */ +#if 0 + { STV090x_P1_TNRCFG, 0xec }, /* P1_TNRCFG */ + { STV090x_P1_TNRCFG2, 0x82 }, /* P1_TNRCFG2 */ + { STV090x_P1_TNRXTAL, 0x1b }, /* P1_TNRXTAL */ + { STV090x_P1_TNRSTEPS, 0x87 }, /* P1_TNRSTEPS */ + { STV090x_P1_TNRGAIN, 0x09 }, /* P1_TNRGAIN */ + { STV090x_P1_TNRRF1, 0x4e }, /* P1_TNRRF1 */ + { STV090x_P1_TNRRF0, 0x7f }, /* P1_TNRRF0 */ + { STV090x_P1_TNRBW, 0x64 }, /* P1_TNRBW */ + { STV090x_P1_TNRADJ, 0x1f }, /* P1_TNRADJ */ + { STV090x_P1_TNRCTL2, 0x37 }, /* P1_TNRCTL2 */ + { STV090x_P1_TNRCFG3, 0x02 }, /* P1_TNRCFG3 */ + { STV090x_P1_TNRLAUNCH, 0x00 }, /* P1_TNRLAUNCH */ + { STV090x_P1_TNRLD, 0x00 }, /* P1_TNRLD */ + { STV090x_P1_TNROBSL, 0x50 }, /* P1_TNROBSL */ + { STV090x_P1_TNRRESTE, 0x40 }, /* P1_TNRRESTE */ +#endif + { STV090x_P1_SMAPCOEF7, 0x06 }, /* P1_SMAPCOEF7 */ + { STV090x_P1_SMAPCOEF6, 0x00 }, /* P1_SMAPCOEF6 */ + { STV090x_P1_SMAPCOEF5, 0x04 }, /* P1_SMAPCOEF5 */ + { STV090x_P1_DMDPLHSTAT, 0x00 }, /* P1_DMDPLHSTAT */ + { STV090x_P1_LOCKTIME3, 0xff }, /* P1_LOCKTIME3 */ + { STV090x_P1_LOCKTIME2, 0xf0 }, /* P1_LOCKTIME2 */ + { STV090x_P1_LOCKTIME1, 0x73 }, /* P1_LOCKTIME1 */ + { STV090x_P1_LOCKTIME0, 0x27 }, /* P1_LOCKTIME0 */ + { STV090x_P1_VITSCALE, 0x00 }, /* P1_VITSCALE */ + { STV090x_P1_FECM, 0x10 }, /* P1_FECM */ + { STV090x_P1_VTH12, 0xd0 }, /* P1_VTH12 */ + { STV090x_P1_VTH23, 0x7d }, /* P1_VTH23 */ + { STV090x_P1_VTH34, 0x53 }, /* P1_VTH34 */ + { STV090x_P1_VTH56, 0x2f }, /* P1_VTH56 */ + { STV090x_P1_VTH67, 0x24 }, /* P1_VTH67 */ + { STV090x_P1_VTH78, 0x1f }, /* P1_VTH78 */ + { STV090x_P1_VITCURPUN, 0x0d }, /* P1_VITCURPUN */ + { STV090x_P1_VERROR, 0xff }, /* P1_VERROR */ + { STV090x_P1_PRVIT, 0x3f }, /* P1_PRVIT */ + { STV090x_P1_VAVSRVIT, 0x00 }, /* P1_VAVSRVIT */ + { STV090x_P1_VSTATUSVIT, 0xa5 }, /* P1_VSTATUSVIT */ + { STV090x_P1_VTHINUSE, 0x01 }, /* P1_VTHINUSE */ + { STV090x_P1_KDIV12, 0x27 }, /* P1_KDIV12 */ + { STV090x_P1_KDIV23, 0x32 }, /* P1_KDIV23 */ + { STV090x_P1_KDIV34, 0x32 }, /* P1_KDIV34 */ + { STV090x_P2_AGC2REF, 0x38 }, + { STV090x_P1_KDIV56, 0x32 }, /* P1_KDIV56 */ + { STV090x_P1_KDIV67, 0x32 }, /* P1_KDIV67 */ + { STV090x_P1_KDIV78, 0x50 }, /* P1_KDIV78 */ + { STV090x_P1_PDELCTRL1, 0x00 }, /* P1_PDELCTRL1 */ + { STV090x_P1_PDELCTRL2, 0x00 }, /* P1_PDELCTRL2 */ + { STV090x_P1_HYSTTHRESH, 0x41 }, /* P1_HYSTTHRESH */ + { STV090x_P1_ISIENTRY, 0x00 }, /* P1_ISIENTRY */ + { STV090x_P1_ISIBITENA, 0x00 }, /* P1_ISIBITENA */ + { STV090x_P1_MATSTR1, 0xf0 }, /* P1_MATSTR1 */ + { STV090x_P1_MATSTR0, 0x00 }, /* P1_MATSTR0 */ + { STV090x_P1_UPLSTR1, 0x05 }, /* P1_UPLSTR1 */ + { STV090x_P1_UPLSTR0, 0xe0 }, /* P1_UPLSTR0 */ + { STV090x_P1_DFLSTR1, 0x7d }, /* P1_DFLSTR1 */ + { STV090x_P1_DFLSTR0, 0x80 }, /* P1_DFLSTR0 */ + { STV090x_P1_SYNCSTR, 0x47 }, /* P1_SYNCSTR */ + { STV090x_P1_SYNCDSTR1, 0x00 }, /* P1_SYNCDSTR1 */ + { STV090x_P1_SYNCDSTR0, 0x00 }, /* P1_SYNCDSTR0 */ + { STV090x_P1_PDELSTATUS1, 0x94 }, /* P1_PDELSTATUS1 */ + { STV090x_P1_PDELSTATUS2, 0x10 }, /* P1_PDELSTATUS2 */ + { STV090x_P1_BBFCRCKO1, 0x00 }, /* P1_BBFCRCKO1 */ + { STV090x_P1_BBFCRCKO0, 0x00 }, /* P1_BBFCRCKO0 */ + { STV090x_P1_UPCRCKO1, 0x00 }, /* P1_UPCRCKO1 */ + { STV090x_P1_UPCRCKO0, 0x00 }, /* P1_UPCRCKO0 */ + { STV090x_P1_TSSTATEM, 0xb0 }, /* P1_TSSTATEM */ + { STV090x_P1_TSCFGH, 0x40 }, /* P1_TSCFGH */ + { STV090x_P1_TSCFGM, 0x00 }, /* P1_TSCFGM */ + { STV090x_P1_TSCFGL, 0x20 }, /* P1_TSCFGL */ + { STV090x_P1_TSINSDELH, 0x00 }, /* P1_TSINSDELH */ + { STV090x_P1_TSSPEED, 0xff }, /* P1_TSSPEED */ + { STV090x_P1_TSSTATUS, 0x52 }, /* P1_TSSTATUS */ + { STV090x_P1_TSSTATUS2, 0x6a }, /* P1_TSSTATUS2 */ + { STV090x_P1_TSBITRATE1, 0x00 }, /* P1_TSBITRATE1 */ + { STV090x_P1_TSBITRATE0, 0x00 }, /* P1_TSBITRATE0 */ + { STV090x_P1_ERRCTRL1, 0x35 }, /* P1_ERRCTRL1 */ + { STV090x_P1_ERRCNT12, 0x80 }, /* P1_ERRCNT12 */ + { STV090x_P1_ERRCNT11, 0x00 }, /* P1_ERRCNT11 */ + { STV090x_P1_ERRCNT10, 0x00 }, /* P1_ERRCNT10 */ + { STV090x_P1_ERRCTRL2, 0xc1 }, /* P1_ERRCTRL2 */ + { STV090x_P1_ERRCNT22, 0x00 }, /* P1_ERRCNT22 */ + { STV090x_P1_ERRCNT21, 0x00 }, /* P1_ERRCNT21 */ + { STV090x_P1_ERRCNT20, 0x00 }, /* P1_ERRCNT20 */ + { STV090x_P1_FECSPY, 0xa8 }, /* P1_FECSPY */ + { STV090x_P1_FSPYCFG, 0x2c }, /* P1_FSPYCFG */ + { STV090x_P1_FSPYDATA, 0x3a }, /* P1_FSPYDATA */ + { STV090x_P1_FSPYOUT, 0x07 }, /* P1_FSPYOUT */ + { STV090x_P2_AGC2REF, 0x38 }, + { STV090x_P1_FSTATUS, 0x00 }, /* P1_FSTATUS */ + { STV090x_P1_FBERCPT4, 0x00 }, /* P1_FBERCPT4 */ + { STV090x_P1_FBERCPT3, 0x00 }, /* P1_FBERCPT3 */ + { STV090x_P1_FBERCPT2, 0x00 }, /* P1_FBERCPT2 */ + { STV090x_P1_FBERCPT1, 0x00 }, /* P1_FBERCPT1 */ + { STV090x_P1_FBERCPT0, 0x00 }, /* P1_FBERCPT0 */ + { STV090x_P1_FBERERR2, 0x00 }, /* P1_FBERERR2 */ + { STV090x_P1_FBERERR1, 0x00 }, /* P1_FBERERR1 */ + { STV090x_P1_FBERERR0, 0x00 }, /* P1_FBERERR0 */ + { STV090x_P1_FSPYBER, 0x10 }, /* P1_FSPYBER */ +#if 0 + { STV090x_RCCFGH, 0x20 }, /* RCCFGH */ +#endif + { STV090x_TSGENERAL, 0x14 }, /* TSGENERAL */ +#if 0 + { STV090x_TSGENERAL1X, 0x00 }, /* TSGENERAL1X */ +#endif + { STV090x_NBITER_NF4, 0x37 }, /* NBITER_NF4 */ + { STV090x_AGCRF2CFG, 0x13 }, + + { STV090x_NBITER_NF5, 0x29 }, /* NBITER_NF5 */ + { STV090x_NBITER_NF6, 0x37 }, /* NBITER_NF6 */ + { STV090x_NBITER_NF7, 0x33 }, /* NBITER_NF7 */ + { STV090x_NBITER_NF8, 0x31 }, /* NBITER_NF8 */ + { STV090x_NBITER_NF9, 0x2f }, /* NBITER_NF9 */ + { STV090x_NBITER_NF10, 0x39 }, /* NBITER_NF10 */ + { STV090x_NBITER_NF11, 0x3a }, /* NBITER_NF11 */ + { STV090x_NBITER_NF12, 0x29 }, /* NBITER_NF12 */ + { STV090x_NBITER_NF13, 0x37 }, /* NBITER_NF13 */ + { STV090x_P2_AGC2REF, 0x38 }, + { STV090x_NBITER_NF14, 0x33 }, /* NBITER_NF14 */ + { STV090x_NBITER_NF15, 0x2f }, /* NBITER_NF15 */ + { STV090x_NBITER_NF16, 0x39 }, /* NBITER_NF16 */ + { STV090x_NBITER_NF17, 0x3a }, /* NBITER_NF17 */ + { STV090x_NBITERNOERR, 0x04 }, /* NBITERNOERR */ + { STV090x_GAINLLR_NF4, 0x21 }, /* GAINLLR_NF4 */ + { STV090x_GAINLLR_NF5, 0x21 }, /* GAINLLR_NF5 */ + { STV090x_GAINLLR_NF6, 0x20 }, /* GAINLLR_NF6 */ + { STV090x_GAINLLR_NF7, 0x1f }, /* GAINLLR_NF7 */ + { STV090x_GAINLLR_NF8, 0x1e }, /* GAINLLR_NF8 */ + { STV090x_GAINLLR_NF9, 0x1e }, /* GAINLLR_NF9 */ + { STV090x_GAINLLR_NF10, 0x1d }, /* GAINLLR_NF10 */ + { STV090x_GAINLLR_NF11, 0x1b }, /* GAINLLR_NF11 */ + { STV090x_GAINLLR_NF12, 0x20 }, /* GAINLLR_NF12 */ + { STV090x_GAINLLR_NF13, 0x20 }, /* GAINLLR_NF13 */ + { STV090x_GAINLLR_NF14, 0x20 }, /* GAINLLR_NF14 */ + { STV090x_GAINLLR_NF15, 0x20 }, /* GAINLLR_NF15 */ + { STV090x_GAINLLR_NF16, 0x20 }, /* GAINLLR_NF16 */ + { STV090x_GAINLLR_NF17, 0x21 }, /* GAINLLR_NF17 */ +#if 0 + { STV090x_CFGEXT, 0x01 }, /* CFGEXT */ +#endif + { STV090x_GENCFG, 0x1d }, /* GENCFG */ + { STV090x_P2_AGC2REF, 0x38 }, + { STV090x_LDPCERR1, 0x00 }, /* LDPCERR1 */ + { STV090x_LDPCERR0, 0x00 }, /* LDPCERR0 */ + { STV090x_BCHERR, 0x00 }, /* BCHERR */ + { STV090x_TSTRES0, 0x00 }, /* TSTRES0 */ + { STV090x_P2_TSTDISRX, 0x00 }, /* P2_TSTDISRX */ + { STV090x_P1_TSTDISRX, 0x00 }, /* P1_TSTDISRX */ +}; +#endif + +static struct stv090x_reg stv0900_initval[] = { + + { STV090x_OUTCFG, 0x00 }, +#if 0 + { STV090x_MODECFG, 0xff }, +#endif + { STV090x_AGCRF1CFG, 0x11 }, + { STV090x_AGCRF2CFG, 0x13 }, +#if 0 + { STV090x_TSGENERAL1X, 0x14 }, +#endif + { STV090x_TSTTNR2, 0x21 }, + { STV090x_TSTTNR4, 0x21 }, + { STV090x_P2_DISTXCTL, 0x22 }, + { STV090x_P2_F22TX, 0xc0 }, + { STV090x_P2_F22RX, 0xc0 }, + { STV090x_P2_DISRXCTL, 0x00 }, +#if 0 + { STV090x_P2_TNRSTEPS, 0x87 }, + { STV090x_P2_TNRGAIN, 0x09 }, +#endif + { STV090x_P2_DMDCFGMD, 0xF9 }, + { STV090x_P2_DEMOD, 0x08 }, + { STV090x_P2_DMDCFG3, 0xc4 }, + { STV090x_P2_CARFREQ, 0xed }, +#if 0 + { STV090x_P2_TNRCFG2, 0x02 }, + { STV090x_P2_TNRCFG3, 0x02 }, +#endif + { 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 }, +#if 0 + { STV090x_P2_DMDT0M, 0x20 }, +#endif + { STV090x_P2_CORRELMANT, 0x70 }, + { STV090x_P2_CORRELABS, 0x88 }, +#if 0 + { STV090x_P2_AGC2O, 0x5b }, +#endif + { 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 }, +#if 0 + { STV090x_P1_TNRSTEPS, 0x87 }, + { STV090x_P1_TNRGAIN, 0x09 }, +#endif + { STV090x_P1_DMDCFGMD, 0xf9 }, + { STV090x_P1_DEMOD, 0x08 }, + { STV090x_P1_DMDCFG3, 0xc4 }, +#if 0 + { STV090x_P1_DMDT0M, 0x20 }, +#endif + { STV090x_P1_CARFREQ, 0xed }, +#if 0 + { STV090x_P1_TNRCFG2, 0x82 }, + { STV090x_P1_TNRCFG3, 0x02 }, +#endif + { 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 }, +#if 0 + { STV090x_P1_AGC2O, 0x5b }, +#endif + { 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 }, +#if 0 + { STV090x_RCCFGH, 0x20 }, +#endif + { 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 }, +#if 0 + { STV090x_TNRSTEPS, 0x87 }, + { STV090x_TNRGAIN, 0x09 }, +#endif + { STV090x_P1_DMDCFGMD, 0xF9 }, + { STV090x_P1_DEMOD, 0x08 }, + { STV090x_P1_DMDCFG3, 0xc4 }, + { STV090x_P1_CARFREQ, 0xed }, + { STV090x_P1_TNRCFG2, 0x82 }, +#if 0 + { STV090x_P1_TNRCFG3, 0x03 }, +#endif + { 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 }, +#if 0 + { STV090x_P1_DMDT0M, 0x20 }, +#endif + { STV090x_P1_CORRELMANT, 0x70 }, + { STV090x_P1_CORRELABS, 0x88 }, +#if 0 + { STV090x_P1_AGC2O, 0x5b }, +#endif + { 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 }, +#if 0 + { STV090x_RCCFGH, 0x20 }, +#endif + { 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 }, +#if 0 + { STV090x_P2_DMDCFG4, 0x10 }, +#endif + { 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 }, +#if 0 + { STV090x_P1_DMDCFG4, 0x10 }, +#endif + { 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 }, +#if 0 + { STV090x_P1_DMDCFG4, 0x10 }, +#endif + { 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 } +}; + +#if 0 +/* 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 } +}; +#endif + +/* 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 } +}; + +#if 0 +/* 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 } +}; +#endif + +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 } +}; + +#if 0 +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 } +}; +#endif + +/* 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 } +}; + +#if 0 +static struct stv090x_short_frame_vsmod_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 } +}; +#endif + +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: +#if 0 + stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10); +#endif + break; + + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: +#if 0 + stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16); +#endif + 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: +#if 0 + stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14); +#endif + break; + + case STV090x_TSMODE_PARALLEL_PUNCTURED: + case STV090x_TSMODE_DVBCI: +#if 0 + stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12); +#endif + 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); + } +#if 0 + /* write defval to image map */ + for (i = 0; i < (ARRAY_SIZE(stv090x_defval)); i++) { + dprintk(FE_DEBUG, 1, "Setting up defaults"); + if (stv090x_write_reg(state, stv090x_defval[i].addr, stv090x_defval[i].data) < 0) + goto err; + } + /* check register fields */ + + reg = STV090x_READ_DEMOD(state, TNRCFG); + STV090x_SETFIELD_Px(reg, TUN_TYPE, 6); + STV090x_WRITE_DEMOD(state, TNRCFG, reg); +#endif + + /* 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/linux/drivers/media/dvb/frontends/stv090x.h b/linux/drivers/media/dvb/frontends/stv090x.h new file mode 100644 index 000000000..d1cc36985 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/stv090x.h @@ -0,0 +1,109 @@ +/* + 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; +#if 0 + int (*tuner_init) (struct dvb_frontend *fe); + 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_refclock) (struct dvb_frontend *fe, u32 refclk); +#endif + + 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; +} + +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/linux/drivers/media/dvb/frontends/stv090x_priv.h b/linux/drivers/media/dvb/frontends/stv090x_priv.h new file mode 100644 index 000000000..9d536226e --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/frontends/stv090x_reg.h b/linux/drivers/media/dvb/frontends/stv090x_reg.h new file mode 100644 index 000000000..b59eca953 --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/frontends/stv6110x.c b/linux/drivers/media/dvb/frontends/stv6110x.c new file mode 100644 index 000000000..c818e21f4 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/stv6110x.c @@ -0,0 +1,442 @@ +/* + 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; +} + +#if 0 +static int stv6110x_get_state(struct dvb_frontend *fe, + enum tuner_param param, + struct tuner_state *state) +{ + switch (param) { + case DVBFE_TUNER_FREQUENCY: + stv6110x_get_frequency(fe, &state->frequency); + break; + + case DVBFE_TUNER_TUNERSTEP: + break; + + case DVBFE_TUNER_IFFREQ: + break; + + case DVBFE_TUNER_BANDWIDTH: + stv6110x_get_bandwidth(fe, &state->bandwidth); + break; + + case DVBFE_TUNER_REFCLOCK: + break; + + default: + break; + } + + return 0; +} + +static int stv6110x_set_state(struct dvb_frontend *fe, + enum tuner_param param, + struct tuner_state *tstate) +{ + struct stv6110x_state *stv6110x = fe->tuner_priv; + + switch (param) { + case DVBFE_TUNER_FREQUENCY: + stv6110x_set_frequency(fe, stv6110x->frequency); + tstate->frequency = stv6110x->frequency; + break; + + case DVBFE_TUNER_TUNERSTEP: + break; + + case DVBFE_TUNER_IFFREQ: + break; + + case DVBFE_TUNER_BANDWIDTH: + stv6110x_set_bandwidth(fe, stv6110x->bandwidth); + tstate->bandwidth = stv6110x->bandwidth; + break; + + case DVBFE_TUNER_REFCLOCK: + stv6110x_set_refclock(fe, stv6110x->reference); + tstate->refclock = stv6110x->reference; + break; + + default: + break; + } + + return 0; +} +#endif + +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, +#if 0 + .get_status = stv6110x_get_status, + .get_state = stv6110x_get_state, + .set_state = stv6110x_set_state, +#endif + .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/linux/drivers/media/dvb/frontends/stv6110x.h b/linux/drivers/media/dvb/frontends/stv6110x.h new file mode 100644 index 000000000..6d43c294e --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/frontends/stv6110x_priv.h b/linux/drivers/media/dvb/frontends/stv6110x_priv.h new file mode 100644 index 000000000..1295272fc --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/frontends/stv6110x_reg.h b/linux/drivers/media/dvb/frontends/stv6110x_reg.h new file mode 100644 index 000000000..93e5c70e5 --- /dev/null +++ b/linux/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/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 1b564eb79..bab8a041c 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -57,6 +57,9 @@ #include "bsru6.h" #include "tda1002x.h" #include "tda827x.h" +#include "stv6110x.h" +#include "stv090x.h" +#include "isl6423.h" /* * Regarding DEBIADDR_IR: @@ -1354,6 +1357,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) { @@ -1473,6 +1511,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) { @@ -1564,6 +1645,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), @@ -1574,6 +1656,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.2.3 From bd6cdb0ea9b6db322a484ad00da53cdd7307fc43 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 6 Apr 2009 22:46:50 +0400 Subject: Fix incorrect default CLOCK setup From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: MAnu Abraham --- linux/drivers/media/dvb/ttpci/budget-ci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index bab8a041c..2e05479dc 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -1360,11 +1360,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, @@ -1383,11 +1383,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.2.3 From 028d9a0c9dfc2039314063233c47fef4905d9071 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 7 Apr 2009 12:19:54 +0400 Subject: * Reference clock was unused * Fix missing repeater level setup From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 9 +++++++-- linux/drivers/media/dvb/frontends/stv090x.h | 13 +++++++++++++ linux/drivers/media/dvb/frontends/stv6110x_priv.h | 6 ++---- linux/drivers/media/dvb/ttpci/budget-ci.c | 2 ++ 4 files changed, 24 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index fc0781961..7d6cb0600 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -1484,16 +1484,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; @@ -4629,6 +4632,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; @@ -4668,7 +4672,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/linux/drivers/media/dvb/frontends/stv090x.h b/linux/drivers/media/dvb/frontends/stv090x.h index d1cc36985..b75a66baf 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.h +++ b/linux/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; @@ -61,6 +72,8 @@ struct stv090x_config { u8 ts1_mode; u8 ts2_mode; + + enum stv090x_i2crpt repeater_level; #if 0 int (*tuner_init) (struct dvb_frontend *fe); int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); diff --git a/linux/drivers/media/dvb/frontends/stv6110x_priv.h b/linux/drivers/media/dvb/frontends/stv6110x_priv.h index 1295272fc..7260da633 100644 --- a/linux/drivers/media/dvb/frontends/stv6110x_priv.h +++ b/linux/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/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 2e05479dc..74ae43592 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -1369,6 +1369,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.2.3 From 27ff4755ec3de948d144d09307b5d9ffb74dc7e2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 20 Apr 2009 14:52:21 -0300 Subject: revert changeset 11562:fd645c976997 From: Mauro Carvalho Chehab The changeset created breakage on both modules: WARNING: "sms_debug" [/home/v4l/master/v4l/smsusb.ko] undefined! WARNING: "sms_debug" [/home/v4l/master/v4l/smsdvb.ko] undefined! Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 4 ++-- linux/drivers/media/dvb/siano/smscoreapi.h | 3 +-- linux/drivers/media/dvb/siano/smsdvb.c | 3 +++ 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 5cf5bb5d9..9a9db2588 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -34,8 +34,8 @@ #include "smscoreapi.h" #include "sms-cards.h" -int sms_debug; -module_param_named(debug, sms_debug, int, 0644); +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))"); struct smscore_device_notifyee_t { diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 875cbe6c7..83e0e55f7 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -658,7 +658,6 @@ int smscore_led_state(struct smscore_device_t *core, int led); /* ------------------------------------------------------------------------ */ -extern int sms_debug; #define DBG_INFO 1 #define DBG_ADV 2 @@ -667,7 +666,7 @@ extern int sms_debug; printk(kern "%s: " fmt "\n", __func__, ##arg) #define dprintk(kern, lvl, fmt, arg...) do {\ - if (sms_debug & lvl) \ + if (sms_dbg & lvl) \ sms_printk(kern, fmt, ##arg); } while (0) #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 329cbce07..035bd52c9 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -50,6 +50,9 @@ struct smsdvb_client_t { static struct list_head g_smsdvb_clients; static struct mutex g_smsdvb_clientslock; +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))"); static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { -- cgit v1.2.3 From f9a56ea326e7bf2efc796a2a7bbbc376a332fa25 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 7 Apr 2009 23:08:26 +0400 Subject: Fix Undocumented Registers From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 71 +++---------------------- linux/drivers/media/dvb/frontends/stv090x_reg.h | 69 +++++++++++++++--------- 2 files changed, 52 insertions(+), 88 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 7d6cb0600..7267e21a4 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -179,9 +179,7 @@ static struct stv090x_reg stv090x_defval[] = { { STV090x_DACR1, 0x00 }, /* DACR1 */ { STV090x_DACR2, 0x00 }, /* DACR2 */ { STV090x_OUTCFG, 0x00 }, /* OUTCFG */ -#if 0 { STV090x_MODECFG, 0xff }, /* MODECFG */ -#endif { STV090x_IRQSTATUS3, 0x00 }, /* IRQSTATUS3 */ { STV090x_IRQSTATUS2, 0x00 }, /* IRQSTATUS2 */ { STV090x_IRQSTATUS1, 0x00 }, /* IRQSTATUS1 */ @@ -314,24 +312,18 @@ static struct stv090x_reg stv090x_defval[] = { { STV090x_P2_DMDCFGMD, 0xf9 }, /* P2_DMDCFGMD */ { STV090x_P2_DMDCFG2, 0x3b }, /* P2_DMDCFG2 */ { STV090x_P2_DMDISTATE, 0x5c }, /* P2_DMDISTATE */ -#if 0 - { STV090x_P2_DMDT0M, 0x20 }, /* P2_DMDT0M */ -#endif + { STV090x_P2_DMDTOM, 0x20 }, /* P2_DMDT0M */ { STV090x_P2_DMDSTATE, 0x1c }, /* P2_DMDSTATE */ { STV090x_P2_DMDFLYW, 0x00 }, /* P2_DMDFLYW */ { STV090x_P2_DSTATUS3, 0x00 }, /* P2_DSTATUS3 */ { STV090x_P2_DMDCFG3, 0x68 }, /* P2_DMDCFG3 */ -#if 0 { STV090x_P2_DMDCFG4, 0x10 }, /* P2_DMDCFG4 */ -#endif { STV090x_P2_CORRELMANT, 0x70 }, /* P2_CORRELMANT */ { STV090x_P2_CORRELABS, 0x88 }, /* P2_CORRELABS */ { STV090x_P2_CORRELEXP, 0xaa }, /* P2_CORRELEXP */ { STV090x_P2_PLHMODCOD, 0x42 }, /* P2_PLHMODCOD */ -#if 0 { STV090x_P2_AGCK32, 0x00 }, /* P2_AGCK32 */ { STV090x_P2_AGC2O, 0x5b }, /* P2_AGC2O */ -#endif { STV090x_P2_AGC2REF, 0x38 }, /* P2_AGC2REF */ { STV090x_P2_AGC1ADJ, 0x58 }, /* P2_AGC1ADJ */ { STV090x_P2_AGC2I1, 0x00 }, /* P2_AGC2I1 */ @@ -591,24 +583,18 @@ static struct stv090x_reg stv090x_defval[] = { { STV090x_P1_DMDCFGMD, 0xf9 }, /* P1_DMDCFGMD */ { STV090x_P1_DMDCFG2, 0x3b }, /* P1_DMDCFG2 */ { STV090x_P1_DMDISTATE, 0x5c }, /* P1_DMDISTATE */ -#if 0 - { STV090x_P1_DMDT0M, 0x20 }, /* P1_DMDT0M */ -#endif + { STV090x_P1_DMDTOM, 0x20 }, /* P1_DMDT0M */ { STV090x_P1_DMDSTATE, 0x1c }, /* P1_DMDSTATE */ { STV090x_P1_DMDFLYW, 0x00 }, /* P1_DMDFLYW */ { STV090x_P1_DSTATUS3, 0x00 }, /* P1_DSTATUS3 */ { STV090x_P1_DMDCFG3, 0x68 }, /* P1_DMDCFG3 */ -#if 0 { STV090x_P1_DMDCFG4, 0x10 }, /* P1_DMDCFG4 */ -#endif { STV090x_P1_CORRELMANT, 0x70 }, /* P1_CORRELMANT */ { STV090x_P1_CORRELABS, 0x88 }, /* P1_CORRELABS */ { STV090x_P1_CORRELEXP, 0xaa }, /* P1_CORRELEXP */ { STV090x_P1_PLHMODCOD, 0x42 }, /* P1_PLHMODCOD */ -#if 0 { STV090x_P1_AGCK32, 0x00 }, /* P1_AGCK32 */ { STV090x_P1_AGC2O, 0x5b }, /* P1_AGC2O */ -#endif { STV090x_P1_AGC2REF, 0x38 }, /* P1_AGC2REF */ { STV090x_P1_AGC1ADJ, 0x58 }, /* P1_AGC1ADJ */ { STV090x_P1_AGC2I1, 0x00 }, /* P1_AGC2I1 */ @@ -848,13 +834,9 @@ static struct stv090x_reg stv090x_defval[] = { { STV090x_P1_FBERERR1, 0x00 }, /* P1_FBERERR1 */ { STV090x_P1_FBERERR0, 0x00 }, /* P1_FBERERR0 */ { STV090x_P1_FSPYBER, 0x10 }, /* P1_FSPYBER */ -#if 0 { STV090x_RCCFGH, 0x20 }, /* RCCFGH */ -#endif { STV090x_TSGENERAL, 0x14 }, /* TSGENERAL */ -#if 0 { STV090x_TSGENERAL1X, 0x00 }, /* TSGENERAL1X */ -#endif { STV090x_NBITER_NF4, 0x37 }, /* NBITER_NF4 */ { STV090x_AGCRF2CFG, 0x13 }, @@ -887,9 +869,7 @@ static struct stv090x_reg stv090x_defval[] = { { STV090x_GAINLLR_NF15, 0x20 }, /* GAINLLR_NF15 */ { STV090x_GAINLLR_NF16, 0x20 }, /* GAINLLR_NF16 */ { STV090x_GAINLLR_NF17, 0x21 }, /* GAINLLR_NF17 */ -#if 0 { STV090x_CFGEXT, 0x01 }, /* CFGEXT */ -#endif { STV090x_GENCFG, 0x1d }, /* GENCFG */ { STV090x_P2_AGC2REF, 0x38 }, { STV090x_LDPCERR1, 0x00 }, /* LDPCERR1 */ @@ -904,14 +884,10 @@ static struct stv090x_reg stv090x_defval[] = { static struct stv090x_reg stv0900_initval[] = { { STV090x_OUTCFG, 0x00 }, -#if 0 { STV090x_MODECFG, 0xff }, -#endif { STV090x_AGCRF1CFG, 0x11 }, { STV090x_AGCRF2CFG, 0x13 }, -#if 0 { STV090x_TSGENERAL1X, 0x14 }, -#endif { STV090x_TSTTNR2, 0x21 }, { STV090x_TSTTNR4, 0x21 }, { STV090x_P2_DISTXCTL, 0x22 }, @@ -945,14 +921,10 @@ static struct stv090x_reg stv0900_initval[] = { { STV090x_P2_ERRCTRL2, 0xc1 }, { STV090x_P2_CFRICFG, 0xf8 }, { STV090x_P2_NOSCFG, 0x1c }, -#if 0 - { STV090x_P2_DMDT0M, 0x20 }, -#endif + { STV090x_P2_DMDTOM, 0x20 }, { STV090x_P2_CORRELMANT, 0x70 }, { STV090x_P2_CORRELABS, 0x88 }, -#if 0 { STV090x_P2_AGC2O, 0x5b }, -#endif { STV090x_P2_AGC2REF, 0x38 }, { STV090x_P2_CARCFG, 0xe4 }, { STV090x_P2_ACLC, 0x1A }, @@ -998,9 +970,7 @@ static struct stv090x_reg stv0900_initval[] = { { STV090x_P1_DMDCFGMD, 0xf9 }, { STV090x_P1_DEMOD, 0x08 }, { STV090x_P1_DMDCFG3, 0xc4 }, -#if 0 - { STV090x_P1_DMDT0M, 0x20 }, -#endif + { STV090x_P1_DMDTOM, 0x20 }, { STV090x_P1_CARFREQ, 0xed }, #if 0 { STV090x_P1_TNRCFG2, 0x82 }, @@ -1024,9 +994,7 @@ static struct stv090x_reg stv0900_initval[] = { { STV090x_P1_NOSCFG, 0x1c }, { STV090x_P1_CORRELMANT, 0x70 }, { STV090x_P1_CORRELABS, 0x88 }, -#if 0 { STV090x_P1_AGC2O, 0x5b }, -#endif { STV090x_P1_AGC2REF, 0x38 }, { STV090x_P1_CARCFG, 0xe4 }, { STV090x_P1_ACLC, 0x1A }, @@ -1088,9 +1056,7 @@ static struct stv090x_reg stv0900_initval[] = { { STV090x_GAINLLR_NF15, 0x1A }, { STV090x_GAINLLR_NF16, 0x1F }, { STV090x_GAINLLR_NF17, 0x21 }, -#if 0 { STV090x_RCCFGH, 0x20 }, -#endif { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */ { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */ { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */ @@ -1136,18 +1102,14 @@ static struct stv090x_reg stv0903_initval[] = { { STV090x_P1_ERRCTRL2, 0xc1 }, { STV090x_P1_CFRICFG, 0xf8 }, { STV090x_P1_NOSCFG, 0x1c }, -#if 0 - { STV090x_P1_DMDT0M, 0x20 }, -#endif + { STV090x_P1_DMDTOM, 0x20 }, { STV090x_P1_CORRELMANT, 0x70 }, { STV090x_P1_CORRELABS, 0x88 }, -#if 0 { STV090x_P1_AGC2O, 0x5b }, -#endif - { STV090x_P1_AGC2REF, 0x38 } , + { 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 }, @@ -1205,9 +1167,7 @@ static struct stv090x_reg stv0903_initval[] = { { STV090x_GAINLLR_NF15, 0x1A }, { STV090x_GAINLLR_NF16, 0x1F }, { STV090x_GAINLLR_NF17, 0x21 }, -#if 0 { STV090x_RCCFGH, 0x20 }, -#endif { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */ { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/ }; @@ -1215,9 +1175,7 @@ static struct stv090x_reg stv0903_initval[] = { static struct stv090x_reg stv0900_cut20_val[] = { { STV090x_P2_DMDCFG3, 0xe8 }, -#if 0 { STV090x_P2_DMDCFG4, 0x10 }, -#endif { STV090x_P2_CARFREQ, 0x38 }, { STV090x_P2_CARHDR, 0x20 }, { STV090x_P2_KREFTMG, 0x5a }, @@ -1226,9 +1184,7 @@ static struct stv090x_reg stv0900_cut20_val[] = { { STV090x_P2_SMAPCOEF5, 0x04 }, { STV090x_P2_NOSCFG, 0x0c }, { STV090x_P1_DMDCFG3, 0xe8 }, -#if 0 { STV090x_P1_DMDCFG4, 0x10 }, -#endif { STV090x_P1_CARFREQ, 0x38 }, { STV090x_P1_CARHDR, 0x20 }, { STV090x_P1_KREFTMG, 0x5a }, @@ -1254,9 +1210,7 @@ static struct stv090x_reg stv0900_cut20_val[] = { static struct stv090x_reg stv0903_cut20_val[] = { { STV090x_P1_DMDCFG3, 0xe8 }, -#if 0 { STV090x_P1_DMDCFG4, 0x10 }, -#endif { STV090x_P1_CARFREQ, 0x38 }, { STV090x_P1_CARHDR, 0x20 }, { STV090x_P1_KREFTMG, 0x5a }, @@ -1484,11 +1438,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); @@ -4449,16 +4401,12 @@ static int stv090x_set_tspath(struct stv090x_state *state) case STV090x_TSMODE_SERIAL_PUNCTURED: case STV090x_TSMODE_SERIAL_CONTINUOUS: default: -#if 0 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10); -#endif break; case STV090x_TSMODE_PARALLEL_PUNCTURED: case STV090x_TSMODE_DVBCI: -#if 0 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16); -#endif 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) @@ -4482,16 +4430,12 @@ static int stv090x_set_tspath(struct stv090x_state *state) case STV090x_TSMODE_SERIAL_PUNCTURED: case STV090x_TSMODE_SERIAL_CONTINUOUS: default: -#if 0 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14); -#endif break; case STV090x_TSMODE_PARALLEL_PUNCTURED: case STV090x_TSMODE_DVBCI: -#if 0 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12); -#endif break; } break; @@ -4762,6 +4706,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/linux/drivers/media/dvb/frontends/stv090x_reg.h b/linux/drivers/media/dvb/frontends/stv090x_reg.h index b59eca953..0dff56d4e 100644 --- a/linux/drivers/media/dvb/frontends/stv090x_reg.h +++ b/linux/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.2.3 From ea62326fb834d265d25c6d2bf8b9335e601969ed Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 7 Apr 2009 23:09:52 +0400 Subject: Various ISL64231 fixes Use external modulation From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/isl6423.c | 35 ++++++++++++++++++++--------- linux/drivers/media/dvb/ttpci/budget-ci.c | 1 + 2 files changed, 26 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/isl6423.c b/linux/drivers/media/dvb/frontends/isl6423.c index c1943dcb8..dca5bebfe 100644 --- a/linux/drivers/media/dvb/frontends/isl6423.c +++ b/linux/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/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 74ae43592..b1d189ccc 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -1391,6 +1391,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.2.3 From e9b59da1542294b667400c0aa2340368e3dc4a80 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 9 Apr 2009 00:27:51 +0400 Subject: Add tone burst control From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 66 +++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 7267e21a4..19e5d4961 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -4145,6 +4145,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; @@ -4158,8 +4167,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) @@ -4680,6 +4745,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.2.3 From fa0f1c1e69e4c7711855792ff509c438034fddfc Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 9 Apr 2009 00:28:41 +0400 Subject: Fix incorrectly used mode From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 19e5d4961..011ef160a 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -2707,7 +2707,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 */ @@ -2858,7 +2858,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.2.3 From e380ca95f7765ba08766f2a412d74c67f77a269a Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 9 Apr 2009 01:27:10 +0400 Subject: Switch i/p ADC as well during Power management From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 011ef160a..6071b3aab 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -4279,6 +4279,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"); @@ -4298,6 +4303,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.2.3 From 5fa5b751c79a00c20a2717b642094fab5945c1b3 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 9 Apr 2009 02:45:43 +0400 Subject: Set DiSEqC frequency to 22kHz From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 6071b3aab..219b10d0c 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -4408,6 +4408,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.2.3 From f0275699c613cb8cbe3aebf02b8db03c68ba28f1 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 9 Apr 2009 03:14:00 +0400 Subject: Support > 60MSPS, simplify Srate calculation From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 60 +++++++++++++++++++---------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 219b10d0c..3a98731f0 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -1510,18 +1510,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"); @@ -1533,17 +1537,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"); @@ -1555,13 +1571,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.2.3 From c3403e5da51196983e3245ef276ee773ed2e9877 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 9 Apr 2009 03:18:50 +0400 Subject: Code simplification From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 3a98731f0..17f8d7e41 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -2153,7 +2153,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); @@ -2162,16 +2161,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.2.3 From a4d648b94c25506bd0bfa3665c4481d1be4924bd Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 9 Apr 2009 03:24:53 +0400 Subject: Code simplification From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 17f8d7e41..2044288a3 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -3136,19 +3136,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.2.3 From 0d047c69b6b735f6fc53dcbc268fe5a106e9efde Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 9 Apr 2009 03:30:29 +0400 Subject: Code Simplification From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 2044288a3..2c7b5e6e3 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -3007,23 +3007,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.2.3 From 9a1e3bf0799562e60be8d8c254a77d931eca4f81 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 9 Apr 2009 15:16:12 +0300 Subject: af9015: add new dvb_usb_device_properties entry for upcoming USB IDs From: Antti Palosaari Add 3rd dvb_usb_device_properties entry for upcoming USB IDs because current entries are full. Priority: normal Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/af9015.c | 65 ++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index ceea6676b..ba4ab61eb 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/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[] = { @@ -1324,7 +1324,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", @@ -1429,7 +1429,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", @@ -1481,7 +1481,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.2.3 From 000a3988dda531d977b79f3b335a41582c4f116f Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 9 Apr 2009 21:14:18 +0300 Subject: af9015: support for AverMedia AVerTV Volar GPS 805 (A805) From: Antti Palosaari Add USB ID (07ca:a805) for AverMedia AVerTV Volar GPS 805 (A805). Thanks to Chris Brown for reporting and testing. Priority: normal Signed-off-by: Antti Palosaari Tested-by: Chris Brown --- linux/drivers/media/dvb/dvb-usb/af9015.c | 10 ++++++++-- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index ba4ab61eb..11346263c 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -1264,7 +1264,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); @@ -1535,8 +1536,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/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index f506c7411..a25b06825 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/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.2.3 From 074a4772727768fbe6cebc0c11f14e529a33ff9f Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 9 Apr 2009 23:16:41 +0300 Subject: af9015: support for Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0 From: Marcel Jueling Add USB ID (1b80:e397) for Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0. Priority: normal Signed-off-by: Marcel Jueling Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/dvb-usb/af9015.c | 9 ++++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index 11346263c..57c678892 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -1266,6 +1266,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); @@ -1536,13 +1537,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/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index a25b06825..ca0051272 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/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.2.3 From ea7c6424150b7c03840e34b1a38a42c05c4a0489 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Fri, 10 Apr 2009 15:20:00 +0200 Subject: dvb-ttpci: Add TS replay capability From: Oliver Endriss Implemented TS replay capability. audio/video devices are able to process PES and TS data now. Priority: normal Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110_av.c | 95 +++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 17 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/av7110_av.c b/linux/drivers/media/dvb/ttpci/av7110_av.c index e4d0900d5..2fc90e9a8 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_av.c +++ b/linux/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.2.3 From f05ceff50bdfc30402afc53b669c3e2c130c931f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 12 Apr 2009 19:58:52 +0000 Subject: remove broken macro from dvb stv0900_priv.h From: Mariusz Kozlowski 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 --- linux/drivers/media/dvb/frontends/stv0900_priv.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv0900_priv.h b/linux/drivers/media/dvb/frontends/stv0900_priv.h index 762d5af62..67dc8ec63 100644 --- a/linux/drivers/media/dvb/frontends/stv0900_priv.h +++ b/linux/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.2.3 From a548457acf0e54ce1864d1ec7c3f5fc876568cbe Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 14 Apr 2009 10:13:44 -0300 Subject: backport commit 9137f05f7e72517d44b6b0c15b11b419ecb5d201 From: Mauro Carvalho Chehab Author: Jaswinder Singh Date: Mon Apr 6 14:34:12 2009 -0700 firmware: convert av7110 driver to request_firmware() kernel-sync: Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/ttpci/av7110_hw.c | 35 +++++++++++-------------------- linux/drivers/media/dvb/ttpci/av7110_hw.h | 3 ++- 2 files changed, 14 insertions(+), 24 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/av7110_hw.c b/linux/drivers/media/dvb/ttpci/av7110_hw.c index afae0266a..276be4056 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_hw.c +++ b/linux/drivers/media/dvb/ttpci/av7110_hw.c @@ -198,29 +198,10 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len) /* we cannot write av7110 DRAM directly, so load a bootloader into * the DPRAM which implements a simple boot protocol */ -static u8 bootcode[] = { - 0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, 0xe2, 0x5e, 0xf0, 0x04, - 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04, - 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, 0x2c, 0x00, 0x00, 0x24, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x34, - 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0x5a, 0x5a, 0x00, 0x1f, 0x15, 0x55, - 0x00, 0x00, 0x00, 0x09, 0xe5, 0x9f, 0xd0, 0x7c, 0xe5, 0x9f, 0x40, 0x74, - 0xe3, 0xa0, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x04, - 0xe5, 0x9f, 0x10, 0x70, 0xe5, 0x9f, 0x20, 0x70, 0xe5, 0x9f, 0x30, 0x64, - 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe1, 0x51, 0x00, 0x02, - 0xda, 0xff, 0xff, 0xfb, 0xe5, 0x9f, 0xf0, 0x50, 0xe1, 0xd4, 0x10, 0xb0, - 0xe3, 0x51, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xfc, 0xe1, 0xa0, 0x10, 0x0d, - 0xe5, 0x94, 0x30, 0x04, 0xe1, 0xd4, 0x20, 0xb2, 0xe2, 0x82, 0x20, 0x3f, - 0xe1, 0xb0, 0x23, 0x22, 0x03, 0xa0, 0x00, 0x02, 0xe1, 0xc4, 0x00, 0xb0, - 0x0a, 0xff, 0xff, 0xf4, 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, - 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe2, 0x52, 0x20, 0x01, - 0x1a, 0xff, 0xff, 0xf9, 0xe2, 0x2d, 0xdb, 0x05, 0xea, 0xff, 0xff, 0xec, - 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00, 0x9e, 0x00, 0x08, 0x00, - 0x2c, 0x00, 0x00, 0x74, 0x2c, 0x00, 0x00, 0xc0 -}; - int av7110_bootarm(struct av7110 *av7110) { + const struct firmware *fw; + const char *fw_name = "av7110/bootcode.bin"; struct saa7146_dev *dev = av7110->dev; u32 ret; int i; @@ -261,7 +242,15 @@ int av7110_bootarm(struct av7110 *av7110) //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT); //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT); - mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode)); + ret = request_firmware(&fw, fw_name, &dev->pci->dev); + if (ret) { + printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n", + fw_name); + return ret; + } + + mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size); + release_firmware(fw); iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); if (saa7146_wait_for_debi_done(av7110->dev, 1)) { @@ -302,7 +291,7 @@ int av7110_bootarm(struct av7110 *av7110) av7110->arm_ready = 1; return 0; } - +MODULE_FIRMWARE("av7110/bootcode.bin"); /**************************************************************************** * DEBI command polling diff --git a/linux/drivers/media/dvb/ttpci/av7110_hw.h b/linux/drivers/media/dvb/ttpci/av7110_hw.h index ca99e5c1f..1634aba5c 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_hw.h +++ b/linux/drivers/media/dvb/ttpci/av7110_hw.h @@ -390,7 +390,8 @@ static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, } /* buffer writes */ -static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, u8 *val, int count) +static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, + const u8 *val, int count) { memcpy(av7110->debi_virt, val, count); av7110_debiwrite(av7110, config, addr, 0, count); -- cgit v1.2.3 From 24f0a7073801c6f55ba324d3141a9bdeee2b5034 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 14 Apr 2009 10:16:40 -0300 Subject: backport commit 4f8d182513690b42b20fb81e487be4cd4729e27c From: Mauro Carvalho Chehab Author: Jaswinder Singh Date: Sun Jun 22 18:24:19 2008 +0530 Remove fdump tool for av7110 firmware There's no point in this, since the user can use the BUILTIN_FIRMWARE option to include arbitrary firmware files directly in the kernel image. Thanks to David Woodhouse for help. kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/ttpci/Kconfig | 23 ++++-------------- linux/drivers/media/dvb/ttpci/Makefile | 9 ------- linux/drivers/media/dvb/ttpci/av7110.c | 16 ------------- linux/drivers/media/dvb/ttpci/fdump.c | 44 ---------------------------------- 4 files changed, 5 insertions(+), 87 deletions(-) delete mode 100644 linux/drivers/media/dvb/ttpci/fdump.c (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig index 772990415..68eb4493f 100644 --- a/linux/drivers/media/dvb/ttpci/Kconfig +++ b/linux/drivers/media/dvb/ttpci/Kconfig @@ -28,25 +28,12 @@ config DVB_AV7110 download/extract it, and then copy it to /usr/lib/hotplug/firmware or /lib/firmware (depending on configuration of firmware hotplug). - Say Y if you own such a card and want to use it. - -config DVB_AV7110_FIRMWARE - bool "Compile AV7110 firmware into the driver" - depends on DVB_AV7110 && !STANDALONE - default y if DVB_AV7110=y - help - The AV7110 firmware is normally loaded by the firmware hotplug manager. - If you want to compile the firmware into the driver you need to say - Y here and provide the correct path of the firmware. You need this - option if you want to compile the whole driver statically into the - kernel. + Alternatively, you can download the file and use the kernel's + EXTRA_FIRMWARE configuration option to build it into your + kernel image by adding the filename to the EXTRA_FIRMWARE + configuration option string. - All other people say N. - -config DVB_AV7110_FIRMWARE_FILE - string "Full pathname of av7110 firmware file" - depends on DVB_AV7110_FIRMWARE - default "/usr/lib/hotplug/firmware/dvb-ttpci-01.fw" + Say Y if you own such a card and want to use it. config DVB_AV7110_OSD bool "AV7110 OSD support" diff --git a/linux/drivers/media/dvb/ttpci/Makefile b/linux/drivers/media/dvb/ttpci/Makefile index 714512372..8a4d5bb20 100644 --- a/linux/drivers/media/dvb/ttpci/Makefile +++ b/linux/drivers/media/dvb/ttpci/Makefile @@ -19,12 +19,3 @@ obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ EXTRA_CFLAGS += -Idrivers/media/common/tuners - -hostprogs-y := fdump - -ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y) -$(obj)/av7110.o: $(obj)/av7110_firm.h - -$(obj)/av7110_firm.h: $(obj)/fdump - $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ -endif diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 841590ed5..1b961db62 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -1521,20 +1521,6 @@ static int check_firmware(struct av7110* av7110) return 0; } -#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE -#include "av7110_firm.h" -static void put_firmware(struct av7110* av7110) -{ - av7110->bin_fw = NULL; -} - -static inline int get_firmware(struct av7110* av7110) -{ - av7110->bin_fw = dvb_ttpci_fw; - av7110->size_fw = sizeof(dvb_ttpci_fw); - return check_firmware(av7110); -} -#else static void put_firmware(struct av7110* av7110) { vfree(av7110->bin_fw); @@ -1583,8 +1569,6 @@ static int get_firmware(struct av7110* av7110) release_firmware(fw); return ret; } -#endif - static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) { diff --git a/linux/drivers/media/dvb/ttpci/fdump.c b/linux/drivers/media/dvb/ttpci/fdump.c deleted file mode 100644 index c90001d35..000000000 --- a/linux/drivers/media/dvb/ttpci/fdump.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - unsigned char buf[8]; - unsigned int i, count, bytes = 0; - FILE *fd_in, *fd_out; - - if (argc != 4) { - fprintf(stderr, "\n\tusage: %s \n\n", argv[0]); - return -1; - } - - fd_in = fopen(argv[1], "rb"); - if (fd_in == NULL) { - fprintf(stderr, "firmware file '%s' not found\n", argv[1]); - return -1; - } - - fd_out = fopen(argv[3], "w+"); - if (fd_out == NULL) { - fprintf(stderr, "cannot create output file '%s'\n", argv[3]); - return -1; - } - - fprintf(fd_out, "\n#include \n\nu8 %s [] = {", argv[2]); - - while ((count = fread(buf, 1, 8, fd_in)) > 0) { - fprintf(fd_out, "\n\t"); - for (i = 0; i < count; i++, bytes++) - fprintf(fd_out, "0x%02x, ", buf[i]); - } - - fprintf(fd_out, "\n};\n\n"); - - fclose(fd_in); - fclose(fd_out); - - return 0; -} -- cgit v1.2.3 From d5193c5902aab5c738cd11481b408771c9050d8b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 14 Apr 2009 10:20:36 -0300 Subject: backport a few language cleanups From: Mauro Carvalho Chehab kernel-sync: Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 578b834bf..23e4cffeb 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -479,7 +479,7 @@ config DVB_TUNER_DIB0070 default m if DVB_FE_CUSTOMISE help A driver for the silicon baseband tuner DiB0070 from DiBcom. - This device is only used inside a SiP called togther with a + This device is only used inside a SiP called together with a demodulator for now. comment "SEC control devices for DVB-S" -- cgit v1.2.3 From 2ec15a3bdd5af9a1ba399e60653b25cd322852e0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 14 Apr 2009 10:25:59 -0300 Subject: backport commit 284901a90a9e0b812ca3f5f852cbbfb60d10249d From: Mauro Carvalho Chehab Author: Yang Hongyang Date: Mon Apr 6 19:01:15 2009 -0700 dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) Replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dm1105/dm1105.c | 2 +- linux/drivers/media/dvb/pluto2/pluto2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dm1105/dm1105.c b/linux/drivers/media/dvb/dm1105/dm1105.c index 5d8afefca..ca1048fd4 100644 --- a/linux/drivers/media/dvb/dm1105/dm1105.c +++ b/linux/drivers/media/dvb/dm1105/dm1105.c @@ -694,7 +694,7 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, if (ret < 0) goto err_kfree; - ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret < 0) goto err_pci_disable_device; diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c index b27073216..647f6290e 100644 --- a/linux/drivers/media/dvb/pluto2/pluto2.c +++ b/linux/drivers/media/dvb/pluto2/pluto2.c @@ -624,7 +624,7 @@ static int __devinit pluto2_probe(struct pci_dev *pdev, /* enable interrupts */ pci_write_config_dword(pdev, 0x6c, 0x8000); - ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret < 0) goto err_pci_disable_device; -- cgit v1.2.3 From 4c6d792a82b4304ed6ccbfccf9f5ed693a3349e2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 14 Apr 2009 13:27:46 -0300 Subject: backport commit 32a0f488ce5e8a9a148491f15edc508ab5e8265b From: Mauro Carvalho Chehab Author: Beat Michel Liechti Date: Thu Mar 26 22:36:52 2009 +0100 DVB: firedtv: FireDTV S2 problems with tuning solved Tuning was broken on FireDTV S2 (and presumably FloppyDTV S2) because a wrong opcode was sent. The box only gave "not implemented" responses. Changing the opcode to _TUNE_QPSK2 fixes this for good. kernel-sync: Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/firewire/firedtv-avc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/firewire/firedtv-avc.c b/linux/drivers/media/dvb/firewire/firedtv-avc.c index 79fab477c..e95a6f094 100644 --- a/linux/drivers/media/dvb/firewire/firedtv-avc.c +++ b/linux/drivers/media/dvb/firewire/firedtv-avc.c @@ -135,6 +135,7 @@ static const char *debug_fcp_opcode(unsigned int opcode, case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC"; case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl"; case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK"; + case SFE_VENDOR_OPCODE_TUNE_QPSK2: return "TuneQPSK2"; case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA"; case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host"; } @@ -271,7 +272,10 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv, c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; + if (fdtv->type == FIREDTV_DVB_S2) + c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK2; + else + c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; c->operand[4] = (params->frequency >> 24) & 0xff; c->operand[5] = (params->frequency >> 16) & 0xff; -- cgit v1.2.3 From 015736e16a8af8a8fe96379031c6a637f4f3a1cb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 14 Apr 2009 13:29:42 -0300 Subject: backport a few minor cleanups From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/firewire/firedtv-avc.c | 4 ++-- linux/drivers/media/dvb/frontends/drx397xD.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/firewire/firedtv-avc.c b/linux/drivers/media/dvb/firewire/firedtv-avc.c index e95a6f094..620fa2c65 100644 --- a/linux/drivers/media/dvb/firewire/firedtv-avc.c +++ b/linux/drivers/media/dvb/firewire/firedtv-avc.c @@ -115,7 +115,7 @@ static const char *debug_fcp_ctype(unsigned int ctype) } static const char *debug_fcp_opcode(unsigned int opcode, - const u8 *data, size_t length) + const u8 *data, int length) { switch (opcode) { case AVC_OPCODE_VENDOR: break; @@ -142,7 +142,7 @@ static const char *debug_fcp_opcode(unsigned int opcode, return "Vendor"; } -static void debug_fcp(const u8 *data, size_t length) +static void debug_fcp(const u8 *data, int length) { unsigned int subunit_type, subunit_id, op; const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> "; diff --git a/linux/drivers/media/dvb/frontends/drx397xD.c b/linux/drivers/media/dvb/frontends/drx397xD.c index 6b3927e8b..0bdb933d0 100644 --- a/linux/drivers/media/dvb/frontends/drx397xD.c +++ b/linux/drivers/media/dvb/frontends/drx397xD.c @@ -75,7 +75,7 @@ static struct { } fw[] = { #define _FW_ENTRY(a, b, c) { \ .name = a, \ - .file = 0, \ + .file = NULL, \ .lock = __RW_LOCK_UNLOCKED(fw[c].lock), \ .refcnt = 0, \ .data = { } } -- cgit v1.2.3 From 9cb965cb8b28ed6832410d2b6b5f709f08bb3a47 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 16 Apr 2009 15:38:46 +0400 Subject: Fix read bug in STV6110x From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv6110x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv6110x.c b/linux/drivers/media/dvb/frontends/stv6110x.c index c818e21f4..cca32f3d6 100644 --- a/linux/drivers/media/dvb/frontends/stv6110x.c +++ b/linux/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.2.3 From d69148350fa7fb334ad5ab1fc2e972a74de82970 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 16 Apr 2009 15:40:36 +0400 Subject: Fix Rolloff From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 37 ++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 2c7b5e6e3..b28bb081d 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -1592,9 +1592,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) @@ -1933,12 +1948,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; @@ -3689,7 +3704,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 */ @@ -3733,7 +3748,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 { @@ -3748,6 +3763,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; } @@ -3785,7 +3802,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) { @@ -3902,6 +3919,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!"); @@ -4806,7 +4827,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.2.3 From 6b2cbdf49bd9c16272aabd0e4323ca5cec5c2103 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 16 Apr 2009 15:43:41 +0400 Subject: Fix incorrect TSMODE usage From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 16 ++++++++-------- linux/drivers/media/dvb/ttpci/budget-ci.c | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index b28bb081d..4637f9890 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -4598,34 +4598,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/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index b1d189ccc..07fec975a 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -1366,8 +1366,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.2.3 From 64653d7d79b02fcce49f6b56e8b12d7ead4201f1 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 19 Apr 2009 19:47:01 +0200 Subject: dvb-ttpci: Check transport error indicator flag From: Oliver Endriss Discard PES packet if transport error indicator flag is set. Priority: normal Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110_av.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/av7110_av.c b/linux/drivers/media/dvb/ttpci/av7110_av.c index 2fc90e9a8..2adcaeff3 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_av.c +++ b/linux/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.2.3 From 91ebcf14b8f1d729a2b5c28f23aa2165ccaf2ee1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 19 Apr 2009 20:21:03 +0000 Subject: av7110_hw: fix compile warning From: Alexey Klimov Signed-off-by: Alexey Klimov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/ttpci/av7110_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/av7110_hw.c b/linux/drivers/media/dvb/ttpci/av7110_hw.c index 276be4056..9c91e3b88 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_hw.c +++ b/linux/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 16:57:49 +0200 Subject: Add Elgato EyeTV DTT deluxe to dibcom driver From: Armin Schenker This patch introduces support for DVB-T for the following dibcom based card: Elgato EyeTV DTT deluxe (USB-ID: 0fd9:0020) Priority: normal Signed-off-by: Armin Schenker Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + linux/drivers/media/dvb/dvb-usb/dvb-usb.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index 31fe6e10a..e39993df0 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1497,6 +1497,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); @@ -1696,7 +1697,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 }, @@ -1742,6 +1743,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/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index ca0051272..6a4062d5d 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/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/linux/drivers/media/dvb/dvb-usb/dvb-usb.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h index fd64daa06..8874221c1 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -224,7 +224,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.2.3 From a904ed23d4d6c515b5a18868ed34e021e23e7a0a Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 23 Apr 2009 21:56:41 +0400 Subject: Fixes: * Cut revision was read too late * Missing increment * wrong return value * mismatched entries From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 4637f9890..20efaf685 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -2728,6 +2728,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); @@ -2788,6 +2789,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); @@ -2850,6 +2852,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) { @@ -2861,6 +2866,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); @@ -2934,7 +2941,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; @@ -3095,7 +3102,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; @@ -3132,7 +3139,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 @@ -3354,8 +3361,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) @@ -3900,7 +3907,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); } } @@ -3924,7 +3931,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 { @@ -4747,12 +4754,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; @@ -4845,7 +4853,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.2.3 From 646f510d1100149a70483eadcda550da9c8fa551 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 23 Apr 2009 21:57:24 +0400 Subject: Fixes Some register definitions From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x_reg.h | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x_reg.h b/linux/drivers/media/dvb/frontends/stv090x_reg.h index 0dff56d4e..55737074e 100644 --- a/linux/drivers/media/dvb/frontends/stv090x_reg.h +++ b/linux/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.2.3 From fefe9f0c6dc0858fd05f26da9230beb27aba3663 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 23 Apr 2009 21:58:36 +0400 Subject: Fixes read_status to return 0 in case of no error From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 20efaf685..0635f3355 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -3948,7 +3948,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); @@ -3958,7 +3957,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 */ @@ -3967,7 +3966,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; } } @@ -3981,7 +3979,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; } } @@ -3989,7 +3986,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) @@ -4000,7 +3997,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.2.3 From ebd9024f2b351ec4874da20b73bbb6ea601b0702 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 23 Apr 2009 21:59:03 +0400 Subject: Fix missing wakeup in init From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 0635f3355..28ab19c22 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -4665,6 +4665,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); @@ -4678,6 +4683,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.2.3 From 23076fb0253b331e86009049488311da2fd762a7 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 23 Apr 2009 21:59:36 +0400 Subject: Use budget driver instead From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/ttpci/budget-ci.c | 86 ------------------------------- linux/drivers/media/dvb/ttpci/budget.c | 85 ++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 86 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 07fec975a..1b564eb79 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -57,9 +57,6 @@ #include "bsru6.h" #include "tda1002x.h" #include "tda827x.h" -#include "stv6110x.h" -#include "stv090x.h" -#include "isl6423.h" /* * Regarding DEBIADDR_IR: @@ -1357,44 +1354,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) { @@ -1514,49 +1473,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) { @@ -1648,7 +1564,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), @@ -1659,7 +1574,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/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c index 83e9e7750..07dced4e7 100644 --- a/linux/drivers/media/dvb/ttpci/budget.c +++ b/linux/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.2.3 From 6de40f28605c851a07f13922c906bc6b89b3bca0 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 23 Apr 2009 22:00:04 +0400 Subject: Use Continuous clock From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/ttpci/budget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c index 07dced4e7..e48380c48 100644 --- a/linux/drivers/media/dvb/ttpci/budget.c +++ b/linux/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.2.3 From 59964b28e0205cdf0a4465194f40867b7c7f5aa6 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Thu, 23 Apr 2009 22:00:40 +0400 Subject: Update demodulator capabilities From: Andreas Regel Signed-off-by: Andreas Regel Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 28ab19c22..39909fefc 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -4799,6 +4799,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.2.3 From 3abdad521cc36eefdd131acfd578c08838fe4aa0 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Fri, 24 Apr 2009 04:24:33 +0200 Subject: dvb-ttpci: Fixed VIDEO_SLOWMOTION ioctl From: Oliver Endriss Fixed VIDEO_SLOWMOTION ioctl. Priority: normal Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110_av.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/av7110_av.c b/linux/drivers/media/dvb/ttpci/av7110_av.c index 2adcaeff3..7b93ab9dc 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_av.c +++ b/linux/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.2.3 From 34efc2efeab79b43139454c4daeef94ff1b69f2c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Apr 2009 01:46:41 -0300 Subject: stv090x.h and stv6110x.h: Fix two trivial compilation breakage errors From: Mauro Carvalho Chehab /home/v4l/master/v4l/stv6110x.h:64: error: expected identifier or '(' before '{' token In file included from /home/v4l/master/v4l/budget.c:52: /home/v4l/master/v4l/stv090x.h:116: error: redefinition of 'stv090x_attach' /home/v4l/master/v4l/stv090x.h:108: error: previous definition of 'stv090x_attach' was here The first pne were due to an extra ';', and the other is due to a duplicated inline function declaration. This patch will need to be merged with the one that added those two headers at -git, to avoid breaking git bisect. CC: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/stv090x.h | 8 -------- linux/drivers/media/dvb/frontends/stv6110x.h | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.h b/linux/drivers/media/dvb/frontends/stv090x.h index b75a66baf..5a567b3b4 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.h +++ b/linux/drivers/media/dvb/frontends/stv090x.h @@ -109,14 +109,6 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } - -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/linux/drivers/media/dvb/frontends/stv6110x.h b/linux/drivers/media/dvb/frontends/stv6110x.h index 6d43c294e..a38257080 100644 --- a/linux/drivers/media/dvb/frontends/stv6110x.h +++ b/linux/drivers/media/dvb/frontends/stv6110x.h @@ -60,7 +60,7 @@ extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, #else static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, const struct stv6110x_config *config, - struct i2c_adapter *i2c); + struct i2c_adapter *i2c) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; -- cgit v1.2.3 From 77ac583a25bcae37eff2c535fc7b3fe6a26d937e Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 2 May 2009 10:07:29 -0400 Subject: tda10048: Add ability to select I/F at attach time. From: Steven Toth tda10048: Add ability to select I/F at attach time. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/frontends/tda10048.c | 219 ++++++++++++++++++++++++++- linux/drivers/media/dvb/frontends/tda10048.h | 14 ++ 2 files changed, 232 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/tda10048.c b/linux/drivers/media/dvb/frontends/tda10048.c index cb5b1efd8..2233e649e 100644 --- a/linux/drivers/media/dvb/frontends/tda10048.c +++ b/linux/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); @@ -835,6 +1047,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) @@ -845,6 +1058,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/linux/drivers/media/dvb/frontends/tda10048.h b/linux/drivers/media/dvb/frontends/tda10048.h index 0457b2460..ab9cf5bd4 100644 --- a/linux/drivers/media/dvb/frontends/tda10048.h +++ b/linux/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.2.3 From 3d2b4c935e8804f2ed232614079f41ab6360aad2 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sun, 3 May 2009 01:26:58 +0400 Subject: STV0900/STV0903: 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. From: Manu Abraham Signed-off-by: Manu Abraham --- linux/drivers/media/dvb/frontends/stv090x.c | 1076 +++++++++++++--------- linux/drivers/media/dvb/frontends/stv090x.h | 8 - linux/drivers/media/dvb/frontends/stv090x_priv.h | 33 +- linux/drivers/media/dvb/frontends/stv090x_reg.h | 72 +- 4 files changed, 733 insertions(+), 456 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/stv090x.c b/linux/drivers/media/dvb/frontends/stv090x.c index 39909fefc..62078400f 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.c +++ b/linux/drivers/media/dvb/frontends/stv090x.c @@ -1234,25 +1234,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 */ @@ -1272,7 +1253,6 @@ static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = { { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d } }; -#if 0 /* 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 */ @@ -1291,7 +1271,6 @@ static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = { { 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 } }; -#endif /* Cut 2.0 Long Frame Tracking CR Loop */ static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = { @@ -1309,7 +1288,6 @@ static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = { { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c } }; -#if 0 /* 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 */ @@ -1325,7 +1303,6 @@ static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut30[] = { { 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 } }; -#endif static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = { /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ @@ -1334,33 +1311,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 } }; -#if 0 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 } }; -#endif -/* 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 } }; -#if 0 -static struct stv090x_short_frame_vsmod_crloop stv090x_s2_short_crl_cut30[] = { +/* 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 } }; -#endif static inline s32 comp2(s32 __x, s32 __width) { @@ -1772,74 +1746,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; @@ -1879,6 +1862,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; @@ -1892,19 +1909,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: @@ -1925,24 +1945,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) @@ -1951,21 +1983,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; + } + + 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; } - stv090x_set_vit_thacq(state); - stv090x_set_viterbi(state); + + if (stv090x_set_viterbi(state) < 0) + goto err; break; } return 0; @@ -1976,45 +2033,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) @@ -2054,7 +2153,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; @@ -2073,14 +2187,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) @@ -2119,7 +2237,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; @@ -2226,15 +2345,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; } @@ -2288,27 +2408,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) { + if (state->config->tuner_set_frequency(fe, state->frequency) < 0) + goto err; + } - if (state->config->tuner_set_frequency) - state->config->tuner_set_frequency(fe, state->frequency); + if (state->config->tuner_set_bandwidth) { + if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) + goto err; + } - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, state->tuner_bw); + 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; } } @@ -2350,11 +2482,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; } @@ -2459,32 +2591,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; @@ -2541,7 +2668,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; @@ -2662,29 +2789,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) { @@ -2816,7 +2953,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; @@ -2831,7 +2968,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; @@ -2847,16 +2983,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; @@ -2896,7 +3022,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: @@ -2905,10 +3032,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; @@ -2918,10 +3043,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; @@ -2935,12 +3058,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; @@ -2961,11 +3080,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); @@ -2986,10 +3100,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; } @@ -3110,16 +3222,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; @@ -3131,12 +3250,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; @@ -3152,6 +3275,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) @@ -3176,19 +3302,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) @@ -3201,7 +3330,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) @@ -3212,26 +3341,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) { @@ -3260,15 +3389,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; @@ -3276,6 +3405,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; @@ -3295,34 +3425,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; } @@ -3352,9 +3469,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; @@ -3418,10 +3553,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; @@ -3447,11 +3579,17 @@ 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; +#if 0 + if (stv090x_set_max_srate(state, state->mclk, srate) < 0) + goto err; + if (stv090x_set_min_srate(state, state->mclk, 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); +#endif blind_tune = 1; } @@ -3467,20 +3605,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) @@ -3491,12 +3627,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; } } @@ -3539,6 +3679,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); @@ -3608,22 +3749,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) { - 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; + if (state->dev_ver <= 0x20) { + /* rolloff to auto mode if DVBS2 */ 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; } @@ -3633,6 +3770,7 @@ err: return -1; } +#if 0 static enum stv090x_signal_state stv090x_acq_fixs1(struct stv090x_state *state) { s32 srate, f_1, f_2; @@ -3645,8 +3783,10 @@ static enum stv090x_signal_state stv090x_acq_fixs1(struct stv090x_state *state) 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); + if (state->algo == STV090x_BLIND_SEARCH) { + if (stv090x_set_srate(state, state->srate) < 0) + goto err; + } stv090x_get_lock_tmg(state); @@ -3704,13 +3844,14 @@ err: dprintk(FE_ERROR, 1, "I/O error"); return -1; } +#endif 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); @@ -3724,18 +3865,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) @@ -3743,14 +3884,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; @@ -3758,16 +3904,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; @@ -3776,60 +3927,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); @@ -3845,32 +4033,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; @@ -3884,18 +4058,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 { @@ -3904,13 +4087,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: @@ -4363,17 +4539,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) @@ -4381,10 +4558,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; @@ -4670,7 +4887,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); @@ -4681,16 +4899,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; + } - stv090x_set_tspath(state); + if (stv090x_i2c_gate_ctrl(fe, 0) < 0) + goto err; + + if (stv090x_set_tspath(state) < 0) + goto err; return 0; err: @@ -4776,6 +5002,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/linux/drivers/media/dvb/frontends/stv090x.h b/linux/drivers/media/dvb/frontends/stv090x.h index 5a567b3b4..e968c98bb 100644 --- a/linux/drivers/media/dvb/frontends/stv090x.h +++ b/linux/drivers/media/dvb/frontends/stv090x.h @@ -74,14 +74,6 @@ struct stv090x_config { u8 ts2_mode; enum stv090x_i2crpt repeater_level; -#if 0 - int (*tuner_init) (struct dvb_frontend *fe); - 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_refclock) (struct dvb_frontend *fe, u32 refclk); -#endif int (*tuner_init) (struct dvb_frontend *fe); int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); diff --git a/linux/drivers/media/dvb/frontends/stv090x_priv.h b/linux/drivers/media/dvb/frontends/stv090x_priv.h index 9d536226e..5a4a01740 100644 --- a/linux/drivers/media/dvb/frontends/stv090x_priv.h +++ b/linux/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/linux/drivers/media/dvb/frontends/stv090x_reg.h b/linux/drivers/media/dvb/frontends/stv090x_reg.h index 55737074e..57b6abbbd 100644 --- a/linux/drivers/media/dvb/frontends/stv090x_reg.h +++ b/linux/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.2.3 From ae3601f13c4816b10e34a719b5f04ebcdc924879 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 5 May 2009 18:30:27 -0400 Subject: tda10048: Added option to block i2c gate control from other drivers. From: Steven Toth 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. Priority: high Signed-off-by: Steven Toth Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/tda10048.c | 3 +++ linux/drivers/media/dvb/frontends/tda10048.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/tda10048.c b/linux/drivers/media/dvb/frontends/tda10048.c index 2233e649e..3163aad5b 100644 --- a/linux/drivers/media/dvb/frontends/tda10048.c +++ b/linux/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/linux/drivers/media/dvb/frontends/tda10048.h b/linux/drivers/media/dvb/frontends/tda10048.h index ab9cf5bd4..ee07b50e9 100644 --- a/linux/drivers/media/dvb/frontends/tda10048.h +++ b/linux/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.2.3 From 8336aa0dd9ebd561d8bd2bd866b37071d0d0c79a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 26 Apr 2009 08:43:59 +0000 Subject: Link firmware to physical device From: Jean Delvare 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 --- linux/drivers/media/dvb/frontends/af9013.c | 2 +- linux/drivers/media/dvb/frontends/cx24116.c | 2 +- linux/drivers/media/dvb/frontends/drx397xD.c | 4 ++-- linux/drivers/media/dvb/frontends/nxt200x.c | 6 ++++-- linux/drivers/media/dvb/frontends/or51132.c | 2 +- linux/drivers/media/dvb/frontends/tda10048.c | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/af9013.c b/linux/drivers/media/dvb/frontends/af9013.c index 937715a96..d12d99802 100644 --- a/linux/drivers/media/dvb/frontends/af9013.c +++ b/linux/drivers/media/dvb/frontends/af9013.c @@ -1456,7 +1456,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/linux/drivers/media/dvb/frontends/cx24116.c b/linux/drivers/media/dvb/frontends/cx24116.c index b5ff0b6a8..fddd27bd1 100644 --- a/linux/drivers/media/dvb/frontends/cx24116.c +++ b/linux/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/linux/drivers/media/dvb/frontends/drx397xD.c b/linux/drivers/media/dvb/frontends/drx397xD.c index 0bdb933d0..95eff4a81 100644 --- a/linux/drivers/media/dvb/frontends/drx397xD.c +++ b/linux/drivers/media/dvb/frontends/drx397xD.c @@ -124,10 +124,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/linux/drivers/media/dvb/frontends/nxt200x.c b/linux/drivers/media/dvb/frontends/nxt200x.c index 846350bc4..748f95b22 100644 --- a/linux/drivers/media/dvb/frontends/nxt200x.c +++ b/linux/drivers/media/dvb/frontends/nxt200x.c @@ -880,7 +880,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"); @@ -944,7 +945,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/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c index 5ed32544d..8133ea3cd 100644 --- a/linux/drivers/media/dvb/frontends/or51132.c +++ b/linux/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/linux/drivers/media/dvb/frontends/tda10048.c b/linux/drivers/media/dvb/frontends/tda10048.c index 3163aad5b..a223e617f 100644 --- a/linux/drivers/media/dvb/frontends/tda10048.c +++ b/linux/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.2.3 From 174bab7f1cc3bfa7b54978080cbe82002b94adbf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 26 Apr 2009 13:03:29 +0000 Subject: firedtv: Storage class should be before const qualifier From: Tobias Klauser 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 --- linux/drivers/media/dvb/firewire/firedtv-rc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/firewire/firedtv-rc.c b/linux/drivers/media/dvb/firewire/firedtv-rc.c index 46a6324d7..27bca2e28 100644 --- a/linux/drivers/media/dvb/firewire/firedtv-rc.c +++ b/linux/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.2.3 From 413c17d0bd1060bf7ebfb0c216cee97a130085df Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Apr 2009 10:50:42 +0000 Subject: Modify the file license to match all other Siano's files From: Uri Shkolnik Modify the file license to match all other Siano's files Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.h | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 83e0e55f7..1aa27f836 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/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 @@ -679,4 +679,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.2.3 From 9ba5733875ddcf79e88cb46977a70a9919932a4b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 May 2009 06:36:27 -0300 Subject: Siano: core header - update include files From: Uri Shkolnik 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. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 1aa27f836..72e385c05 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -28,15 +28,20 @@ along with this program. If not, see . #include #include #include -#include #include +#include +#include + +#include #include "compat.h" +#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.2.3 From 19e333202f72c13f3d78fcdb935ed454d402e779 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Apr 2009 12:09:47 +0000 Subject: Siano: smsdvb - modify license From: Uri Shkolnik Siano: smsdvb - Fix license to match all other Siano's files Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsdvb.c | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 035bd52c9..3991883b7 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/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.2.3 From df5e4d6882589cee518247400d785abbfb470240 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Apr 2009 12:12:37 +0000 Subject: Siano: smsdvb - remove redundent complete instruction From: Uri Shkolnik Remove redundant complete instruction from smsdvb, in the past this was used by the statistics state machine, but no longer. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsdvb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 3991883b7..255ee5719 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -488,7 +488,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.2.3 From 2031afeba8b04f69eaec2813c11809fc5b3b0a99 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2009 04:11:22 +0000 Subject: af9015: support for KWorld MC810 From: Wen-chien Jesse Sung Add USB ID (1b80:c810) for Kworld MC810. Priority: normal Signed-off-by: Wen-chien Jesse Sung Acked-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/af9015.c | 8 +++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index 57c678892..5d9aacd0a 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -1267,6 +1267,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); @@ -1537,7 +1538,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)", @@ -1550,6 +1551,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/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 6a4062d5d..1b5e65f1d 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/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.2.3 From c43f103d41c7e4f9c6763b53c83327d6c2a49253 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 30 Apr 2009 04:09:44 +0200 Subject: dvb-ttpci: Fixed return code of av7110_av_start_play From: Oliver Endriss av7110_av_start_play() should return 0 on success. Priority: normal Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110_av.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/av7110_av.c b/linux/drivers/media/dvb/ttpci/av7110_av.c index 7b93ab9dc..a5ad9b0be 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_av.c +++ b/linux/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.2.3 From 3d88b8ea62d861b60775b3b1437124a9809be4a8 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 30 Apr 2009 04:25:07 +0200 Subject: dvb-ttpci: Some whitespace adjustments From: Oliver Endriss Some whitespace adjustments. Priority: normal Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110_av.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/av7110_av.c b/linux/drivers/media/dvb/ttpci/av7110_av.c index a5ad9b0be..538848141 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_av.c +++ b/linux/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.2.3 From 0ea260891398ca8c39e7b6a524839125c0894ad9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2009 22:18:08 +0000 Subject: remove driver_data direct access of struct device From: Greg Kroah-Hartman 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 --- linux/drivers/media/dvb/firewire/firedtv-1394.c | 4 ++-- linux/drivers/media/dvb/firewire/firedtv-dvb.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/firewire/firedtv-1394.c b/linux/drivers/media/dvb/firewire/firedtv-1394.c index 4e207658c..2b6eeeab5 100644 --- a/linux/drivers/media/dvb/firewire/firedtv-1394.c +++ b/linux/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/linux/drivers/media/dvb/firewire/firedtv-dvb.c b/linux/drivers/media/dvb/firewire/firedtv-dvb.c index 9d308dd32..5742fde79 100644 --- a/linux/drivers/media/dvb/firewire/firedtv-dvb.c +++ b/linux/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.2.3 From b6846f8378e51e39a605b395c560986011bde203 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 May 2009 19:38:47 +0000 Subject: V4L/DVB: cleanup redundant tests on unsigned From: Roel Kluin Remove redundant tests on unsigned. Signed-off-by: Roel Kluin Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/ttpci/av7110_v4l.c | 2 +- linux/drivers/media/dvb/ttpci/budget-av.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/av7110_v4l.c b/linux/drivers/media/dvb/ttpci/av7110_v4l.c index 2210cff73..ce64c6214 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/linux/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/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 855fe74b6..8ea915227 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/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.2.3 From 8daa6a71db80a0910916ffe840d4c9dc520e1310 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 4 May 2009 20:57:41 -0400 Subject: dib0700: reduce xc5000 sleep time for Pinnacle 801e to 10ms From: Devin Heitmueller According to the xc5000 spec, the reset pin only needs to be held low for 10ms. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index e39993df0..ac97b9f42 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/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.2.3 From 77cae28861d7b7a3542ae1d487c8ac43245811e0 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2009 09:57:10 +0200 Subject: Reducing print-level of I2C error prints From: Matthias Schwarzott Reducing the print-levle of I2C error prints cleans some unwanted but unavoidable errors from default syslog-level. Priority: normal Signed-off-by: Matthias Schwarzott Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/flexcop-i2c.c | 2 +- linux/drivers/media/dvb/frontends/mt312.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c index 06a90f67e..df4d6e8d9 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/linux/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/linux/drivers/media/dvb/frontends/mt312.c b/linux/drivers/media/dvb/frontends/mt312.c index 5ac9b1592..a621f7279 100644 --- a/linux/drivers/media/dvb/frontends/mt312.c +++ b/linux/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.2.3 From f947fc2a2490cb5bec7d536e4d7ab98b24e3e333 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2009 10:08:26 +0200 Subject: Rewrote frontend-attach mechanism to gain noise-less deactivation of submodules From: Patrick Boettcher 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. Priority: normal Signed-off-by: Uwe Bugla Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/flexcop-common.h | 8 +- linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 760 +++++++++++++----------- 2 files changed, 413 insertions(+), 355 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop-common.h b/linux/drivers/media/dvb/b2c2/flexcop-common.h index cee2956cb..9d66105d3 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-common.h +++ b/linux/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/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index f7afab594..3f485bf13 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/linux/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.2.3 From 6d72be3d96a2a76833b5e2ef54b83ab0f9cb152e Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2009 10:28:05 +0200 Subject: [PATCH] Leadtek WinFast DTV Dongle H From: tomas petr "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. Priority: normal Signed-off-by: tomas petr Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 8 +++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index ac97b9f42..d309ff7cc 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1498,6 +1498,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); @@ -1821,7 +1822,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 }, @@ -1851,6 +1852,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/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 1b5e65f1d..07227979e 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/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.2.3 From 6e94aca63322b3d936465135c50d873d53b56c93 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2009 10:35:02 +0200 Subject: Added USB IDs for Terratec T3 and T5 From: Patrick Boettcher This patch adds the USB IDs for the Terratec devices T3 and T5. Priority: normal Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 12 ++++++++---- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index d309ff7cc..eda025714 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1499,6 +1499,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); @@ -1732,8 +1734,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", @@ -1794,8 +1797,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/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 07227979e..7340ef4cd 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/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.2.3 From 7965383d6db294fc173ab00dd9f407f4af871ef7 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2009 10:42:33 +0200 Subject: DIBUSB_MC : fix i2c to not corrupt eeprom in case of strange read pattern From: matthieu castet 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. Priority: normal Signed-off-by: Matthieu CASTET Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dibusb-common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb-common.c b/linux/drivers/media/dvb/dvb-usb/dibusb-common.c index d774879df..99b3b9a43 100644 --- a/linux/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/linux/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.2.3 From abdeb4f3e7f1f6ec9cd4f59ad2d1eaabfea6d2a5 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2009 10:52:13 +0200 Subject: Remove support for Genpix-CW3K (damages hardware) From: Alan Nisota 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. Priority: normal Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/gp8psk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/gp8psk.c b/linux/drivers/media/dvb/dvb-usb/gp8psk.c index 3dd684386..003d97f8c 100644 --- a/linux/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/linux/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,12 @@ static struct dvb_usb_device_properties gp8psk_properties = { .cold_ids = { NULL }, .warm_ids = { &gp8psk_usb_table[3], NULL }, }, +#if 0 { .name = "Genpix SkyWalker-CW3K DVB-S receiver", .cold_ids = { NULL }, .warm_ids = { &gp8psk_usb_table[4], NULL }, }, +#endif { NULL }, } }; -- cgit v1.2.3 From 240e6d86113de5254985ae8f151581df10b65a8f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 May 2009 10:57:54 +0000 Subject: Siano: smsusb - update license From: Uri Shkolnik This patch updates the license of the USB interface driver Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsusb.c | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 67be79549..fab73ca39 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/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.2.3 From 68afa52d9809eae342ae42338b0b004ea71257a2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 May 2009 11:24:07 +0000 Subject: Siano: smsusb - handle byte ordering and big endianity From: Uri Shkolnik This patch adds support for byte ordering and big endianity handling for the USB interface driver Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsusb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index fab73ca39..17332a09a 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/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); @@ -180,6 +181,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); } @@ -337,8 +339,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.2.3 From df4ef7800b3db4653ab235d8347dc17d876e8f67 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 May 2009 14:28:41 +0000 Subject: Siano: smsusb - lost buffers bug fix From: Uri Shkolnik This patch fixes a problem were protocol buffers have been lost during USB disconnect events. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsusb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 17332a09a..7f0246fdb 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -69,14 +69,14 @@ static void smsusb_onresponse(struct urb *urb, struct pt_regs *regs) 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; if (urb->actual_length >= phdr->msgLength) { surb->cb->size = phdr->msgLength; @@ -114,7 +114,10 @@ static void smsusb_onresponse(struct urb *urb, struct pt_regs *regs) "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.2.3 From caf7a673bbefc685df483fd4a285c443174fbd24 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 May 2009 06:38:58 -0700 Subject: Siano: Makefile - add smsendian to build From: Uri Shkolnik Add smsendian component to the module build Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/Makefile b/linux/drivers/media/dvb/siano/Makefile index bcf93f482..6354a4718 100644 --- a/linux/drivers/media/dvb/siano/Makefile +++ b/linux/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.2.3 From 933b155b80111900885f3b736fb5ec36207cac98 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2009 09:35:26 -0300 Subject: Siano: fix compilation error due to the lack of EXTERNAL_SYMBOL Priority: normal CC: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsendian.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsendian.c b/linux/drivers/media/dvb/siano/smsendian.c index d79aa0512..457b6d02e 100644 --- a/linux/drivers/media/dvb/siano/smsendian.c +++ b/linux/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.2.3 From 5970b3d8008b625f502690ea408dc756f45a30e3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 May 2009 14:37:09 +0000 Subject: Siano: smsdvb - add big endian support From: Uri Shkolnik Add support for Siano protocol messages with big endian systems. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsdvb.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 255ee5719..b69bd77cb 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/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.2.3 From 30c67c0e526d256d94bc1026d021d62a97947ef1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 May 2009 15:28:46 +0000 Subject: Siano: smsdvb - use 'push' status mechanism From: Uri Shkolnik 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. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 23 +- linux/drivers/media/dvb/siano/smscoreapi.h | 377 +++++++++++++---------------- linux/drivers/media/dvb/siano/smsdvb.c | 266 +++++++++++--------- 3 files changed, 343 insertions(+), 323 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 9a9db2588..15272dbb5 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -904,15 +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; - -#if 1 static unsigned long last_sample_time; /* = 0; */ static int data_total; /* = 0; */ unsigned long time_now = jiffies_to_msecs(jiffies); @@ -930,7 +926,16 @@ void smscore_onresponse(struct smscore_device_t *coredev, } data_total += cb->size; -#endif + /* 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/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 72e385c05..d98b4a749 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -214,19 +214,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 @@ -348,225 +344,202 @@ 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 */ - /* 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 */ + /* 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, + 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 */ - -}; - -struct SmsMsgStatisticsInfo_ST { - u32 RequestResult; - - struct SMSHOSTLIB_STATISTICS_ST Stat; + 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 */ - /* Split the calc of the SNR in DAB */ - u32 Signal; /* dB */ - u32 Noise; /* dB */ + u32 NumMPEReceived; /* DVB-H, Num MPE section received */ + u32 ReservedFields[10]; /* Reserved */ }; -#if 0 -struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST { - /* Per-layer information */ - u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, - * 255 means layer does not exist */ - u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, - * 255 means layer does not exist */ - u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ - u32 BERErrorCount; /* Post Viterbi Error Bits Count */ - u32 BERBitCount; /* Post Viterbi Total Bits Count */ - u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ - u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */ - u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 TILdepthI; /* Time interleaver depth I parameter, - * 255 means layer does not exist */ - u32 NumberOfSegments; /* Number of segments in layer A, - * 255 means layer does not exist */ - u32 TMCCErrors; /* TMCC errors */ +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 SMSHOSTLIB_STATISTICS_ISDBT_ST { - u32 StatisticsType; /* Enumerator identifying the type of the - * structure. Values are the same as - * SMSHOSTLIB_DEVICE_MODES_E - * - * This field MUST always be first in any - * statistics structure */ - - u32 FullSize; /* Total size of the structure returned by the modem. - * If the size requested by the host is smaller than - * FullSize, the struct will be truncated */ - - /* 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 */ - - /* Reception quality */ - s32 SNR; /* dB */ - s32 RSSI; /* dBm */ - s32 InBandPwr; /* In band power in dBM */ - s32 CarrierOffset; /* Carrier Offset in Hz */ - - /* Transmission parameters */ - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz */ - u32 TransmissionMode; /* ISDB-T transmission mode */ - u32 ModemState; /* 0 - Acquisition, 1 - Locked */ - u32 GuardInterval; /* Guard Interval, 1 divided by value */ - u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */ - u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */ - u32 NumOfLayers; /* Number of ISDB-T layers in the network */ - - /* Per-layer information */ - /* Layers A, B and C */ - struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; - /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ +struct PID_DATA_S { + u32 pid; + u32 num_rows; + struct PID_STATISTICS_DATA_S pid_statistics; +}; - /* Interface information */ - u32 SmsToHostTxErrors; /* Total number of transmission errors. */ +#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 */ + /* 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 SMSHOSTLIB_STATISTICS_DVB_ST { - u32 StatisticsType; /* Enumerator identifying the type of the - * structure. Values are the same as - * SMSHOSTLIB_DEVICE_MODES_E - * This field MUST always first in any - * statistics structure */ +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 */ +}; - u32 FullSize; /* Total size of the structure returned by the modem. - * If the size requested by the host is smaller than - * FullSize, the struct will be truncated */ - /* 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 */ - /* Reception quality */ - s32 SNR; /* dB */ - u32 BER; /* Post Viterbi BER [1E-5] */ - u32 BERErrorCount; /* Number of errornous 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 */ +/* 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 */ - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz */ - u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ - u32 TransmissionMode; /* FFT mode carriers in Kilos */ - u32 GuardInterval; /* Guard Interval, 1 divided by value */ - 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 TRANSMISSION_STATISTICS_S TransmissionData; /* 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 */ - - 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 NumMPEReceived; /* DVB-H, Num MPE section received */ - - /* 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 */ - - /* Interface information */ - u32 SmsToHostTxErrors; /* Total number of transmission errors. */ +#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 { @@ -581,7 +554,7 @@ struct SMSHOSTLIB_I2C_RES_ST { u32 ReadCount; /* number of bytes read */ u8 Data[1]; }; -#endif + struct smscore_gpio_config { #define SMS_GPIO_DIRECTION_INPUT 0 diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index b69bd77cb..f265b148f 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/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; @@ -318,24 +377,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); } @@ -360,8 +401,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; } @@ -370,8 +410,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; } @@ -503,8 +542,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.2.3 From dac2a57af684d3f1fd146a0b84a559c011d84102 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 May 2009 16:13:13 +0000 Subject: Siano: smsdvb - small typo fix ad module author From: Uri Shkolnik Fix type at the module description Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsdvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index f265b148f..f43c7f543 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -599,5 +599,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.2.3 From 3e94e24e59b323cdacd22598b28769753866bfc3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 May 2009 20:39:28 +0000 Subject: core: fix potential mutex_unlock without mutex_lock in dvb_dvr_read From: Simon Arlott 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 --- linux/drivers/media/dvb/dvb-core/dmxdev.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index c35fbb8d8..6d6121eb5 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/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.2.3 From 3e3ae9acd7a21aadc994ca194d5799c0cf441a7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2009 19:27:16 +0000 Subject: Siano: smsusb - add big endien support From: Uri Shkolnik Add support for big endien target hosts, which use USB interface. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsusb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 7f0246fdb..adeb920a5 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -78,6 +78,7 @@ static void smsusb_onresponse(struct urb *urb, struct pt_regs *regs) 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) { surb->cb->size = phdr->msgLength; -- cgit v1.2.3 From 99a8dbb1166ea0866ab85aa6990517d75c3d0cd6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2009 19:28:17 +0000 Subject: Siano: move dvb-api headers' includes to dvb adapter From: Uri Shkolnik 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. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.h | 7 ------- linux/drivers/media/dvb/siano/smsdvb.c | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index d98b4a749..0310c3a30 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -35,13 +35,6 @@ along with this program. If not, see . #include #include "compat.h" -#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/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index f43c7f543..39421ee6f 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/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.2.3 From 0d7f5cd403444bc4434d8bf726e528400f2a3926 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2009 19:31:23 +0000 Subject: Siano: smscards - add gpio look-up table From: Uri Shkolnik Add gpio look-up table for various requirements, any target may select any gpio and assign it to a function Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/sms-cards.h | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 64d74c59c..5bd4fb4d3 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/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.2.3 From 11c31c4bd3cd328f0865ec402bf805372fbd6f22 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2009 19:32:12 +0000 Subject: Siano: bind infra-red component From: Uri Shkolnik Add the infra-red to the makefile and declare the assignment in the cards components. Priority: normal [mchehab@redhat.com: Fixed a few trivial merge conflicts] Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/Makefile | 2 +- linux/drivers/media/dvb/siano/sms-cards.c | 1 + linux/drivers/media/dvb/siano/sms-cards.h | 4 ++++ linux/drivers/media/dvb/siano/smscoreapi.h | 3 ++- linux/drivers/media/dvb/siano/smsir.c | 24 ++++++++++++------------ 5 files changed, 20 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/Makefile b/linux/drivers/media/dvb/siano/Makefile index 6354a4718..c6644d909 100644 --- a/linux/drivers/media/dvb/siano/Makefile +++ b/linux/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/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 63e4d0ec6..c35ff1f3f 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/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/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 5bd4fb4d3..447481ab5 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/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/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 0310c3a30..f4aa406ef 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -35,6 +35,7 @@ along with this program. If not, see . #include #include "compat.h" +#include "smsir.h" #define kmutex_init(_p_) mutex_init(_p_) #define kmutex_lock(_p_) mutex_lock(_p_) @@ -168,7 +169,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/linux/drivers/media/dvb/siano/smsir.c b/linux/drivers/media/dvb/siano/smsir.c index a5f302c58..e3d776fee 100644 --- a/linux/drivers/media/dvb/siano/smsir.c +++ b/linux/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.2.3 From 0605798099a08b6dddc3c89ab0047146840eedea Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 May 2009 03:58:54 -0300 Subject: date: Thu May 14 12:29:35 2009 -0700 From: Uri Shkolnik 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. Priority: normal [mchehab@redhat.com: add missing smsendian.h include at smscoreapi.c] Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 98 +++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 15272dbb5..c13d80698 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/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: #if 0 sms_info("no client (%p) or error (%d), " -- cgit v1.2.3 From 8c5084621800a914e3ca5e6a35d2242d8c47143a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2009 19:33:37 +0000 Subject: Siano: smscards - fix wrong firmware assignment From: Uri Shkolnik Remove wrong firmware assignments for Nova, Stellar Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/sms-cards.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index c35ff1f3f..b5dc36dc8 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/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.2.3 From 8a53093333397ea670efada7f563c1c429f7481c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2009 19:34:59 +0000 Subject: Siano: smscards - assign gpio to HPG targets From: Uri Shkolnik Assign using the new gpio structures, i/o for exist HPG targets, without removing the old implementation. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/sms-cards.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index b5dc36dc8..fda483f07 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/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.2.3 From 02f289e848b5b8a9826eb20dd8ea3a100737de16 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 15 May 2009 20:01:57 -0400 Subject: TDA10048: Ensure the I/F changes during DVB-T 6/7/8 bandwidth changes. From: Steven Toth TDA10048: Ensure the I/F changes during DVB-T 6/7/8 bandwidth changes. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/frontends/tda10048.c | 184 ++++++++++++++++++--------- linux/drivers/media/dvb/frontends/tda10048.h | 6 +- 2 files changed, 127 insertions(+), 63 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/tda10048.c b/linux/drivers/media/dvb/frontends/tda10048.c index a223e617f..9bc1ba786 100644 --- a/linux/drivers/media/dvb/frontends/tda10048.c +++ b/linux/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 */ @@ -1032,6 +1048,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, @@ -1046,8 +1101,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; @@ -1061,8 +1116,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/linux/drivers/media/dvb/frontends/tda10048.h b/linux/drivers/media/dvb/frontends/tda10048.h index ee07b50e9..8828ceaf7 100644 --- a/linux/drivers/media/dvb/frontends/tda10048.h +++ b/linux/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.2.3 From abbf3f268166b272916a7af0e798e10e06394926 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 16 May 2009 13:43:51 -0400 Subject: TDA10048: Missing two I/F's / Pll combinations from the PLL table From: Steven Toth This was causing a lock failure in Australia. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/frontends/tda10048.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/tda10048.c b/linux/drivers/media/dvb/frontends/tda10048.c index 9bc1ba786..04596baa9 100644 --- a/linux/drivers/media/dvb/frontends/tda10048.c +++ b/linux/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.2.3 From 431384bb330ec2f151b2e44b3ecc85c61cdf0477 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 17 May 2009 08:59:37 +0000 Subject: Siano: smscore - fix get_common_buffer bug From: Uri Shkolnik get common buffers() should block operation until valid buffer is avaliable. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 38 +++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index c13d80698..c65c9196c 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/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); @@ -1076,12 +1084,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); @@ -1098,8 +1118,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.2.3 From 4ffca8cce22602b296a5358e88a13811f9d9f272 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 17 May 2009 09:01:03 +0000 Subject: Siano: smscore - fix byte ordering bug From: Uri Shkolnik Fix byte ordering bug. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index c65c9196c..0f360d7ba 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/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.2.3 From a201f474c8b7e9763bba588bdfc6fe757020a851 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 17 May 2009 09:01:55 +0000 Subject: Siano: smscore - fix isdb-t firmware name From: Uri Shkolnik Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 0f360d7ba..d31380b26 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/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.2.3 From 748341157e592566108cd3174bad52bdd3c3c07c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 17 May 2009 09:02:46 +0000 Subject: Siano: smscore - bug fix at get_device_mode From: Uri Shkolnik Fix bug that cause error log to echo also if success Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index d31380b26..16917016c 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/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.2.3 From da327f1d8548abe9c1e49220e775407e2c7931f2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 17 May 2009 12:17:51 +0000 Subject: Siano: smsusb - fix typo in module description From: Uri Shkolnik Fix small typo in the module description Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index adeb920a5..4ffc55a03 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -566,6 +566,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.2.3 From 0afb58412d04348dc6819d5fe8da278c857d37ab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 17 May 2009 12:28:55 +0000 Subject: Siano: smsusb - change exit func debug msg From: Uri Shkolnik Change the debug message of the USB interface driver exit function. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 4ffc55a03..3bbbdb197 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -558,9 +558,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.2.3 From a47bd9ff056af0e4adfc7755b121000827d8972f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 12:51:41 +0000 Subject: Siano: cards - add two additional (USB) devices From: Uri Shkolnik Add two additional USB targets, add these to the 'cards' modules and to the 'smsusb' module. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/sms-cards.c | 10 ++++++++++ linux/drivers/media/dvb/siano/sms-cards.h | 2 ++ linux/drivers/media/dvb/siano/smsusb.c | 9 +++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index fda483f07..1a1890680 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/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/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 447481ab5..e183f946a 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/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/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 3bbbdb197..a85538b06 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -531,8 +531,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.2.3 From f19c04a5b4926e17938cbdd708d40446e806509d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 14:15:01 +0000 Subject: Siano: smssdio - revert to stand alone module From: Uri Shkolnik Make the SDIO interface driver a stand alone module. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smssdio.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smssdio.c b/linux/drivers/media/dvb/siano/smssdio.c index 4f8fa59a9..dfaa49a53 100644 --- a/linux/drivers/media/dvb/siano/smssdio.c +++ b/linux/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.2.3 From b4bb609923f3f62aa6fa3dd8efa9b384ee02d177 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 14:49:19 +0000 Subject: Siano: Add new GPIO management interface From: Uri Shkolnik Add new GPIO management interface to replace old (buggy) one. Keeping old interface intact for now. Priority: normal Signed-off-by: Uri Shkolnik Acked-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/sms-cards.c | 2 +- linux/drivers/media/dvb/siano/smscoreapi.c | 235 ++++++++++++++++++++++++++++- linux/drivers/media/dvb/siano/smscoreapi.h | 55 ++++++- 3 files changed, 288 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 1a1890680..370cf513a 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/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/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 16917016c..6446e0f6c 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -1331,8 +1331,9 @@ static int smscore_map_common_buffer(struct smscore_device_t *coredev, } #endif +/* 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; @@ -1401,6 +1402,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/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index f4aa406ef..28663315a 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -550,7 +550,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; @@ -576,6 +576,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); @@ -619,10 +661,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.2.3 From 52057033c8278b7d00e054ea3ea6c5d8e55256a9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 15:10:36 +0000 Subject: Siano: smscore - fix some new GPIO definitions names From: Uri Shkolnik Fix some definitions' names, in order to emphasize the names Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 28663315a..6fbab351f 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -581,10 +581,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 @@ -608,13 +608,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.2.3 From acac54fbcb26b026019f2aed395b998538e3e485 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 15:18:40 +0000 Subject: Siano: smscards - add board (target) events From: Uri Shkolnik Add events handling for targets. All board-specific (target specific) should reside here. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/sms-cards.c | 167 ++++++++++++++++++++++++++++++ linux/drivers/media/dvb/siano/sms-cards.h | 24 +++++ 2 files changed, 191 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 370cf513a..d8b15d583 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/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/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index e183f946a..38f062f6a 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/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.2.3 From 26abee2f5be78d62a6dd302315e71614f93b62bc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 15:24:03 +0000 Subject: Siano: smsusb - remove redundant ifdef From: Uri Shkolnik Remove a redundant ifdef Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsusb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index a85538b06..c31a52d3a 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -489,7 +489,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), @@ -500,7 +499,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.2.3 From 0bd1a842c277e4fbd4b78c3af80708135638e820 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 15:28:02 +0000 Subject: Siano: smsdvb - add DVB v3 events From: Uri Shkolnik Add various DVB-API v3 events, those events will trig target (card) events. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsdvb.c | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 39421ee6f..f8856d9c8 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/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.2.3 From 3c278aedd50ae75abf8b20630363185eff753f88 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 15:34:09 +0000 Subject: Siano: smscore - remove redundant code From: Uri Shkolnik remove redundant code, which in the past handled the various components (now independent modules) registrations. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 88 ------------------------------ 1 file changed, 88 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 6446e0f6c..802d7e6a9 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -1645,99 +1645,11 @@ static int __init smscore_module_init(void) INIT_LIST_HEAD(&g_smscore_registry); kmutex_init(&g_smscore_registrylock); -#if 0 /* def SMS_CHAR_CLIENT */ - /* Char interface Register */ - rc = smschar_register(); - if (rc) { - sms_err("Error registering char device client.\n"); - goto smschar_error; - } -#endif - -#if 0 /* def SMS_DVB_CLIENT */ - /* DVB Register */ - rc = smsdvb_register(); - if (rc) { - sms_err("Error registering DVB client.\n"); - goto smsdvb_error; - } -#endif - -#if 0 /* def SMS_NET_CLIENT */ - /* DVB Register */ - rc = smsnet_register(); - if (rc) { - sms_err("Error registering Network client.\n"); - goto smsnet_error; - } -#endif - -#if 0 /* def SMS_USB_BUS_DRV */ - /* USB Register */ - rc = smsusb_register(); - if (rc) { - sms_err("Error registering USB bus driver.\n"); - goto sms_bus_drv_error; - } -#endif - -#if 0 /* def SMS_SPI_BUS_DRV */ - /* USB Register */ - rc = smsspi_register(); - if (rc) { - sms_err("Error registering spi bus driver.\n"); - goto sms_bus_drv_error; - } -#endif - - return rc; -#if 0 -sms_bus_drv_error: -#endif /* 0 */ -#if 0 /* def SMS_NET_CLIENT */ - smsnet_unregister(); -smsnet_error: -#endif -#if 0 /* def SMS_DVB_CLIENT */ - smsdvb_unregister(); -smsdvb_error: -#endif -#if 0 /* def SMS_CHAR_CLIENT */ - smschar_unregister(); -smschar_error: -#endif - sms_debug("rc %d", rc); - return rc; } static void __exit smscore_module_exit(void) { -#if 0 /* def SMS_CHAR_CLIENT */ - /* Char interface UnRegister */ - smschar_unregister(); -#endif - -#if 0 /* def SMS_DVB_CLIENT */ - /* DVB UnRegister */ - smsdvb_unregister(); -#endif - -#if 0 /* def SMS_NET_CLIENT */ - /* NET UnRegister */ - smsnet_unregister(); -#endif - -#if 0 /* def SMS_USB_BUS_DRV */ - /* Unregister USB */ - smsusb_unregister(); -#endif - -#if 0 /* def SMS_SPI_BUS_DRV */ - /* Unregister SPI */ - smsspi_unregister(); -#endif - kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { struct smscore_device_notifyee_t *notifyee = -- cgit v1.2.3 From 88e23f22d75580ffb879c5fd535d838830dfb7fe Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 15:52:58 +0000 Subject: Siano: smscore - bind the GPIO SMS protocol From: Uri Shkolnik Bind SMS protocol commands to the GPIO commands Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 802d7e6a9..e513408fc 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/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.2.3 From dc637c2382bc5ae4e39c9e07ae657d0eaab6d799 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 15:56:16 +0000 Subject: Siano: smsendien - declare function as extern From: Uri Shkolnik Declare the object function as 'extern' Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsendian.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsendian.h b/linux/drivers/media/dvb/siano/smsendian.h index 7fbedc6a6..1624d6fd3 100644 --- a/linux/drivers/media/dvb/siano/smsendian.h +++ b/linux/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.2.3 From b0ead79496ce5e528b0735acae2d8c0c61803d22 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2009 16:00:42 +0000 Subject: Siano: smscore - remove redundant define From: Uri Shkolnik Remove redundant define. Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smscoreapi.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 6fbab351f..bc4572de6 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -645,7 +645,6 @@ extern int smsclient_sendrequest(struct smscore_client_t *client, extern void smscore_onresponse(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); -#if 1 extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); @@ -653,7 +652,6 @@ extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char *filename); extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf, int size); -#endif extern struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); -- cgit v1.2.3 From 5f623f9662748ffe9662ee5b0561fe746ef3279d Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 20 May 2009 22:58:16 -0400 Subject: dvb_frontend: fix case where fepriv->exit not reset From: Devin Heitmueller 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). Priority: high Signed-off-by: Devin Heitmueller Cc: Thierry Lelegard --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index d359f6841..41166d407 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -668,6 +668,7 @@ restart: } fepriv->thread = NULL; + fepriv->exit = 0; mb(); dvb_frontend_wakeup(fe); -- cgit v1.2.3 From 355e218336f85e723e8061e62c292436b0654104 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 22 May 2009 10:19:14 +0000 Subject: flexcop-pci: dmesg visible names broken From: Matthias Schwarzott 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 --- linux/drivers/media/dvb/b2c2/flexcop-misc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop-misc.c b/linux/drivers/media/dvb/b2c2/flexcop-misc.c index e56627d2f..f06f3a907 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/linux/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.2.3 From 3beb22a88b25f76e30ddde31f6436ac190b61235 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 22 May 2009 20:07:46 -0400 Subject: lnbp21: Add missing newline From: Andy Walls Reported-by: VDR User Priority: normal Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/lnbp21.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lnbp21.c b/linux/drivers/media/dvb/frontends/lnbp21.c index 1dcc56f32..71f607fe8 100644 --- a/linux/drivers/media/dvb/frontends/lnbp21.c +++ b/linux/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.2.3 From 9c9fd460173573929daf32f42a502283a9aaae26 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 27 May 2009 15:32:23 -0300 Subject: Building system: Restore compilation with kernels older than 2.6.29 From: Mauro Carvalho Chehab Mostly due to ir-kdb-i2c, but also due to two new drivers, compilation with kernels older than 2.6.29 were broken. This quick and dirty changeset, generated semi-automatically, restaures backport to the subsystem by adding lots of #ifs. It is possible to write a much more small changeset that would restore backport without adding so many ifs, but, due to the lack of time, this will also solve it. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/siano/smsir.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/siano/smsir.c b/linux/drivers/media/dvb/siano/smsir.c index e3d776fee..ac876859c 100644 --- a/linux/drivers/media/dvb/siano/smsir.c +++ b/linux/drivers/media/dvb/siano/smsir.c @@ -274,7 +274,9 @@ int sms_ir_init(struct smscore_device_t *coredev) coredev->ir.ir_kb_type); input_dev->name = coredev->ir.name; input_dev->phys = coredev->ir.name; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) input_dev->dev.parent = coredev->device; +#endif /* Key press events only */ input_dev->evbit[0] = BIT_MASK(EV_KEY); -- cgit v1.2.3 From 0291002e9dcce64956346325ef3c35478c6c95b5 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 28 May 2009 12:50:36 -0400 Subject: lgdt3305: fix 64bit division in function lgdt3305_set_if From: Michael Krufky Priority: high Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/lgdt3305.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgdt3305.c b/linux/drivers/media/dvb/frontends/lgdt3305.c index f0c0c8199..b16410c64 100644 --- a/linux/drivers/media/dvb/frontends/lgdt3305.c +++ b/linux/drivers/media/dvb/frontends/lgdt3305.c @@ -19,6 +19,7 @@ * */ +#include #include "compat.h" #include #include "dvb_math.h" @@ -497,27 +498,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.2.3 From b8991839208bf9058df16c5afdc4abe46aed454d Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 31 May 2009 23:07:01 +0300 Subject: af9015: support for Genius TVGo DVB-T03 From: Antti Palosaari Add USB ID (0458:4012) for Genius TVGo DVB-T03. Thanks to Petr Vodicka for reporting and testing. Priority: normal Signed-off-by: Antti Palosaari Tested-by: Petr Vodicka --- linux/drivers/media/dvb/dvb-usb/af9015.c | 8 +++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index 5d9aacd0a..a50bf34af 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -1268,6 +1268,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); @@ -1538,7 +1539,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)", @@ -1556,6 +1557,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/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 7340ef4cd..9593b7289 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/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.2.3 From 7ef1e386396d4ebc645310511099bf2526e519c4 Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Sat, 6 Jun 2009 16:31:34 +0400 Subject: TS continuity check: show error message when discontinuity detected or TEI flag detected in header Signed-off-by: Abylay Ospan --- linux/drivers/media/dvb/dvb-core/dvb_demux.c | 42 ++++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-core/dvb_demux.h | 4 +++ 2 files changed, 46 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index e2eca0b1f..cfe2768d2 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/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/linux/drivers/media/dvb/dvb-core/dvb_demux.h b/linux/drivers/media/dvb/dvb-core/dvb_demux.h index 933397c24..1e0ade4ec 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.h @@ -43,6 +43,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]; @@ -128,6 +130,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.2.3 From 29da0924e21b20128e9ce9eca275630941586d84 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 11 Jun 2009 10:33:00 +0200 Subject: b2c2: Fix problems with frontend attachment From: Trent Piepho 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. Priority: normal Signed-off-by: Trent Piepho Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 196 ++++++++++++++---------- 1 file changed, 113 insertions(+), 83 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 3f485bf13..efb4a6c2b 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/linux/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.2.3 From aa180367f345706e7f042506f21cbab42c6e233a Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sat, 13 Jun 2009 14:10:24 +0300 Subject: Remote control debugging for dw2102 driver based USB cards From: Igor M. Liplianin 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 --- linux/drivers/media/dvb/dvb-usb/dw2102.c | 27 ++++++++++++++++++++------- linux/drivers/media/dvb/dvb-usb/dw2102.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.c b/linux/drivers/media/dvb/dvb-usb/dw2102.c index 2b8ee587b..725d5c00d 100644 --- a/linux/drivers/media/dvb/dvb-usb/dw2102.c +++ b/linux/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); @@ -565,26 +567,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/linux/drivers/media/dvb/dvb-usb/dw2102.h b/linux/drivers/media/dvb/dvb-usb/dw2102.h index e3370734e..5cd0b0eb6 100644 --- a/linux/drivers/media/dvb/dvb-usb/dw2102.h +++ b/linux/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.2.3 From 8a7773709ee61adb37f483c166f80d1d9f6ef25b Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Mon, 15 Jun 2009 01:41:22 +0300 Subject: Add keymaps for TeVii and TBS USB DVB-S/S2 cards From: Igor M. Liplianin 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 --- linux/drivers/media/dvb/dvb-usb/dw2102.c | 126 +++++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 16 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.c b/linux/drivers/media/dvb/dvb-usb/dw2102.c index 725d5c00d..cf1fc5e83 100644 --- a/linux/drivers/media/dvb/dvb-usb/dw2102.c +++ b/linux/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); @@ -474,6 +475,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) { @@ -558,14 +560,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, @@ -574,19 +665,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) @@ -667,8 +760,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); @@ -725,7 +821,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, @@ -777,7 +872,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.2.3 From f8eb1c250a545b18aadc3d0962b49b33759a13cc Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Mon, 15 Jun 2009 02:51:45 +0300 Subject: Add support for DVBWorld DVB-C USB Cable card. From: Igor M. Liplianin 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 --- linux/drivers/media/dvb/dvb-usb/dw2102.c | 179 +++++++++++++++++++++++++++++-- 1 file changed, 168 insertions(+), 11 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.c b/linux/drivers/media/dvb/dvb-usb/dw2102.c index cf1fc5e83..0fc9be43a 100644 --- a/linux/drivers/media/dvb/dvb-usb/dw2102.c +++ b/linux/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; @@ -400,6 +473,14 @@ static struct i2c_algorithm dw2104_i2c_algo = { #endif }; +static struct i2c_algorithm dw3101_i2c_algo = { + .master_xfer = dw3101_i2c_transfer, + .functionality = dw210x_i2c_func, +#ifdef NEED_ALGO_CONTROL + .algo_control = dummy_algo_control, +#endif +}; + static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) { int i; @@ -419,6 +500,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; }; @@ -463,6 +545,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, @@ -513,6 +600,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, @@ -528,6 +626,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*/ @@ -697,9 +803,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)}, { } }; @@ -760,7 +867,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); @@ -768,6 +875,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); @@ -811,6 +920,7 @@ static int dw2102_load_firmware(struct usb_device *dev, DW210X_READ_MSG); break; } + msleep(100); kfree(p); } @@ -834,7 +944,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, @@ -915,12 +1025,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; } @@ -952,6 +1107,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.2.3 From 279ab5cb24214bc30fc83bb50f63d418498f00e8 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Mon, 15 Jun 2009 03:34:12 +0300 Subject: Add support for yet another SDMC DM1105 based DVB-S card. From: Igor M. Liplianin 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 --- linux/drivers/media/dvb/dm1105/dm1105.c | 121 +++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 41 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dm1105/dm1105.c b/linux/drivers/media/dvb/dm1105/dm1105.c index ca1048fd4..17edeb66b 100644 --- a/linux/drivers/media/dvb/dm1105/dm1105.c +++ b/linux/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; @@ -316,15 +329,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; } @@ -463,7 +486,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)); @@ -599,46 +622,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) { @@ -662,10 +683,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); @@ -788,14 +816,22 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, #else INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); #endif + 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: @@ -812,8 +848,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: @@ -869,6 +903,11 @@ static struct pci_device_id dm1105_id_table[] __devinitdata = { .device = PCI_DEVICE_ID_DM1105, .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.2.3 From 6f3d74e1d2c5407251649488848e76a576cfc633 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 14 Jun 2009 22:05:20 -0400 Subject: au8522: add support for QAM-64 modulation type From: Frank Dischner Add support for QAM64 modulation type to the au8522 demod driver. Priority: normal Signed-off-by: Frank Dischner Signed-off-by: Devin Heitmueller --- linux/drivers/media/dvb/frontends/au8522_dig.c | 98 ++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c index 41aedcc99..9375905ee 100644 --- a/linux/drivers/media/dvb/frontends/au8522_dig.c +++ b/linux/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.2.3 From aa387bcec63ca659d9c03f9ad7ff70299d41f527 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 16 Jun 2009 00:46:40 -0300 Subject: dvb-usb/Kconfig: DVBWorld DVB-C USB Cable card needs tda1002x frontend From: Mauro Carvalho Chehab Auto-selects tda1002x if !DVB_FE_CUSTOMISE Priority: normal CC: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 60955a70d..8a8a1bede 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/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.2.3 From 337800edfc26abd2a7b3a13733836f35244d8ca5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 4 Jun 2009 14:07:16 +0000 Subject: Add missing __devexit_p() From: Jean Delvare 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 --- linux/drivers/media/dvb/bt8xx/bt878.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/bt8xx/bt878.c b/linux/drivers/media/dvb/bt8xx/bt878.c index 57f0f84b6..456cd8756 100644 --- a/linux/drivers/media/dvb/bt8xx/bt878.c +++ b/linux/drivers/media/dvb/bt8xx/bt878.c @@ -512,12 +512,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; @@ -583,7 +577,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.2.3 From ac8cc4d3dda761c04e7d642d0fc1273e1216f081 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 9 Jun 2009 22:31:55 +0000 Subject: af9015: fix stack corruption bug From: Jan Nikitenko 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 --- linux/drivers/media/dvb/dvb-usb/af9015.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index a50bf34af..b6fc8ddf3 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -541,7 +541,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.2.3 From f4b54f7a0bb1daf912ce8e3013e34cccebba6a34 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 11 Jun 2009 12:38:54 +0000 Subject: lgs8gxx: lgs8913 fake signal strength option default on From: David Wong 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 --- linux/drivers/media/dvb/frontends/lgs8gxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgs8gxx.c b/linux/drivers/media/dvb/frontends/lgs8gxx.c index 1395f3b5b..a5b7bdeff 100644 --- a/linux/drivers/media/dvb/frontends/lgs8gxx.c +++ b/linux/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.2.3 From 4a2e9d7d8ff2bfc867b6ac6b4ebf2c831b1c6e0a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 11 Jun 2009 12:39:04 +0000 Subject: lgs8gxx: update signal strength scale From: David Wong lgs8gxx: update signal strength scale Signed-off-by: David T.L. Wong gmail.com> Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/lgs8gxx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgs8gxx.c b/linux/drivers/media/dvb/frontends/lgs8gxx.c index a5b7bdeff..1ce30aa53 100644 --- a/linux/drivers/media/dvb/frontends/lgs8gxx.c +++ b/linux/drivers/media/dvb/frontends/lgs8gxx.c @@ -650,7 +650,7 @@ static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal) else cat = 0; - *signal = cat; + *signal = cat * 65535 / 5; return 0; } @@ -670,8 +670,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.2.3 From 28f0a28c5e0c37bee44d914bde9533d5fc16b62d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 16 Jun 2009 18:37:35 -0300 Subject: Backport language typo and whitespace differences From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 8a8a1bede..496c1a370 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -216,7 +216,7 @@ config DVB_USB_TTUSB2 help Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The firmware protocol used by this module is similar to the one used by the - old ttusb-driver - that's why the module is called dvb-usb-ttusb2.ko. + old ttusb-driver - that's why the module is called dvb-usb-ttusb2. config DVB_USB_DTT200U tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)" -- cgit v1.2.3 From 9204bc59f7e30d4441efb2262a1debc8782b5b74 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 16 Jun 2009 19:02:10 -0300 Subject: dvb-net: backport upstream changes fb875333c8 and 0eade1f930 From: Mauro Carvalho Chehab kernel-sync: commit fb875333c80942455551f690f306a899ceeee5df Author: Stephen Hemminger Date: Wed Jan 7 18:02:53 2009 -0800 dvb: update network device to current API Use internal network_device_stats that exist in network device and net_device_ops. Compile tested only. commit 0eade1f930fa3ba6461b34baf3ed8fa7c4abc40f Author: Wang Chen Date: Wed Dec 3 21:13:13 2008 -0800 dvb: Kill directly reference of netdev->priv Simply replace netdev->priv with netdev_priv(). Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvb_net.c | 65 +++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c index 5f4856c6d..1eede48a9 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c @@ -126,7 +126,9 @@ static void hexdump( const unsigned char *buf, unsigned short len ) struct dvb_net_priv { int in_use; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) struct net_device_stats stats; +#endif u16 pid; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) struct net_device *net; @@ -391,8 +393,13 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (priv->ule_skb) { dev_kfree_skb( priv->ule_skb ); /* Prepare for next SNDU. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) priv->stats.rx_errors++; priv->stats.rx_frame_errors++; +#else + dev->stats.rx_errors++; + dev->stats.rx_frame_errors++; +#endif } reset_ule(priv); priv->need_pusi = 1; @@ -445,8 +452,13 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) dev_kfree_skb( priv->ule_skb ); /* Prepare for next SNDU. */ // reset_ule(priv); moved to below. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) priv->stats.rx_errors++; priv->stats.rx_frame_errors++; +#else + dev->stats.rx_errors++; + dev->stats.rx_frame_errors++; +#endif } reset_ule(priv); /* skip to next PUSI. */ @@ -467,8 +479,13 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { dev_kfree_skb( priv->ule_skb ); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) priv->stats.rx_errors++; priv->stats.rx_frame_errors++; +#else + dev->stats.rx_errors++; + dev->stats.rx_frame_errors++; +#endif } reset_ule(priv); priv->need_pusi = 1; @@ -484,8 +501,13 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (priv->ule_sndu_remain > 183) { /* Current SNDU lacks more data than there could be available in the * current TS cell. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) priv->stats.rx_errors++; priv->stats.rx_length_errors++; +#else + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; +#endif printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); @@ -527,8 +549,13 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (priv->ule_sndu_len < 5) { printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) priv->stats.rx_errors++; priv->stats.rx_length_errors++; +#else + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; +#endif priv->ule_sndu_len = 0; priv->need_pusi = 1; new_ts = 1; @@ -580,7 +607,11 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (priv->ule_skb == NULL) { printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) priv->stats.rx_dropped++; +#else + dev->stats.rx_dropped++; +#endif return; } @@ -653,8 +684,13 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) ule_dump = 1; #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) priv->stats.rx_errors++; priv->stats.rx_crc_errors++; +#else + dev->stats.rx_errors++; + dev->stats.rx_crc_errors++; +#endif dev_kfree_skb(priv->ule_skb); } else { /* CRC32 verified OK. */ @@ -764,8 +800,13 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) * receive the packet anyhow. */ /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) priv->ule_skb->pkt_type = PACKET_HOST; */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) priv->stats.rx_packets++; priv->stats.rx_bytes += priv->ule_skb->len; +#else + dev->stats.rx_packets++; + dev->stats.rx_bytes += priv->ule_skb->len; +#endif netif_rx(priv->ule_skb); } sndu_done: @@ -820,8 +861,12 @@ static void dvb_net_sec(struct net_device *dev, { u8 *eth; struct sk_buff *skb; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) struct net_device_stats *stats = &((struct dvb_net_priv *) netdev_priv(dev))->stats; +#else + struct net_device_stats *stats = &dev->stats; +#endif int snap = 0; /* note: pkt_len includes a 32bit checksum */ @@ -1269,11 +1314,12 @@ static int dvb_net_stop(struct net_device *dev) return dvb_net_feed_stop(dev); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) static struct net_device_stats * dvb_net_get_stats(struct net_device *dev) { return &((struct dvb_net_priv *) netdev_priv(dev))->stats; } - +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) static const struct header_ops dvb_header_ops = { .create = eth_header, @@ -1282,6 +1328,19 @@ static const struct header_ops dvb_header_ops = { }; #endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) +static const struct net_device_ops dvb_netdev_ops = { + .ndo_open = dvb_net_open, + .ndo_stop = dvb_net_stop, + .ndo_start_xmit = dvb_net_tx, + .ndo_set_multicast_list = dvb_net_set_multicast_list, + .ndo_set_mac_address = dvb_net_set_mac, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; +#endif + static void dvb_net_setup(struct net_device *dev) { ether_setup(dev); @@ -1291,12 +1350,16 @@ static void dvb_net_setup(struct net_device *dev) #else dev->hard_header_cache = NULL; #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) dev->open = dvb_net_open; dev->stop = dvb_net_stop; dev->hard_start_xmit = dvb_net_tx; dev->get_stats = dvb_net_get_stats; dev->set_multicast_list = dvb_net_set_multicast_list; dev->set_mac_address = dvb_net_set_mac; +#else + dev->netdev_ops = &dvb_netdev_ops; +#endif dev->mtu = 4096; dev->mc_count = 0; -- cgit v1.2.3