From 189841c54b3cd1fba77dccb963a046846b14a244 Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Thu, 27 Nov 2014 12:34:46 +0200 Subject: [PATCH] linux: update ngene/octopus I have done some stupid (sysfs related) things to ddbridge in order to make it compile with 3.17. as I dont have the hardware, and there were no volunteers to test it, it was not tested at all. now it's fixed upstream --- .../3.17.4/linux-221-ngene-octopus.patch | 1291 ++++++++++++----- 1 file changed, 967 insertions(+), 324 deletions(-) diff --git a/packages/linux/patches/3.17.4/linux-221-ngene-octopus.patch b/packages/linux/patches/3.17.4/linux-221-ngene-octopus.patch index 4cf1add609..376bd20081 100644 --- a/packages/linux/patches/3.17.4/linux-221-ngene-octopus.patch +++ b/packages/linux/patches/3.17.4/linux-221-ngene-octopus.patch @@ -1,61 +1,63 @@ -From 8bd7907427f0153920b81e615b08e9f6e9c9ee40 Mon Sep 17 00:00:00 2001 +From d3b66936030f30fc4ece37e6b8685d65f4dac3b1 Mon Sep 17 00:00:00 2001 From: Stefan Saraev -Date: Mon, 6 Oct 2014 13:42:00 +0300 +Date: Thu, 27 Nov 2014 12:18:06 +0200 Subject: [PATCH] dvb: ngene/octopus source: http://linuxtv.org/hg/~endriss/media_build_experimental/ note: SYS_DVBC2 not added. ci extensions (en50221) not added. --- - drivers/media/dvb-core/Makefile | 2 +- - drivers/media/dvb-core/dvb_netstream.c | 259 ++ - drivers/media/dvb-core/dvb_netstream.h | 94 + - drivers/media/dvb-core/dvbdev.c | 11 +- - drivers/media/dvb-core/dvbdev.h | 4 + - drivers/media/dvb-frontends/Kconfig | 27 + - drivers/media/dvb-frontends/Makefile | 3 + - drivers/media/dvb-frontends/cxd2843.c | 2021 +++++++++++++ - drivers/media/dvb-frontends/cxd2843.h | 30 + - drivers/media/dvb-frontends/drxk_hard.c | 3602 ++++++++++------------- - drivers/media/dvb-frontends/drxk_hard.h | 298 +- - drivers/media/dvb-frontends/drxk_map.h | 3 - - drivers/media/dvb-frontends/lnbh25.c | 133 + - drivers/media/dvb-frontends/lnbh25.h | 28 + - drivers/media/dvb-frontends/stv0367dd.c | 2331 +++++++++++++++ - drivers/media/dvb-frontends/stv0367dd.h | 17 + - drivers/media/dvb-frontends/stv0367dd_regs.h | 3431 ++++++++++++++++++++++ - drivers/media/dvb-frontends/stv0910.c | 1368 +++++++++ - drivers/media/dvb-frontends/stv0910.h | 31 + - drivers/media/dvb-frontends/stv0910_regs.h | 3998 ++++++++++++++++++++++++++ - drivers/media/dvb-frontends/stv6111.c | 450 +++ - drivers/media/dvb-frontends/stv6111.h | 5 + - drivers/media/dvb-frontends/tda18212dd.c | 974 +++++++ - drivers/media/dvb-frontends/tda18212dd.h | 5 + - drivers/media/dvb-frontends/tda18271c2dd.c | 17 +- - drivers/media/dvb-frontends/tda18271c2dd.h | 6 +- - drivers/media/pci/ddbridge/Kconfig | 11 +- - drivers/media/pci/ddbridge/Makefile | 2 - - drivers/media/pci/ddbridge/ddbridge-core.c | 3718 ++++++++++++++++++------ - drivers/media/pci/ddbridge/ddbridge-i2c.c | 257 ++ - drivers/media/pci/ddbridge/ddbridge-i2c.h | 105 + - drivers/media/pci/ddbridge/ddbridge-mod.c | 1131 ++++++++ - drivers/media/pci/ddbridge/ddbridge-ns.c | 489 ++++ - drivers/media/pci/ddbridge/ddbridge-regs.h | 322 ++- - drivers/media/pci/ddbridge/ddbridge.c | 449 +++ - drivers/media/pci/ddbridge/ddbridge.h | 399 ++- - drivers/media/pci/ddbridge/octonet.c | 191 ++ - drivers/media/pci/ngene/Kconfig | 3 + - drivers/media/pci/ngene/Makefile | 3 +- - drivers/media/pci/ngene/ngene-av.c | 348 +++ - drivers/media/pci/ngene/ngene-cards.c | 778 +++-- - drivers/media/pci/ngene/ngene-core.c | 396 ++- - drivers/media/pci/ngene/ngene-dvb.c | 372 +++ - drivers/media/pci/ngene/ngene-eeprom.c | 284 ++ - drivers/media/pci/ngene/ngene-i2c.c | 113 + - drivers/media/pci/ngene/ngene.h | 40 + - include/uapi/linux/dvb/mod.h | 22 + - include/uapi/linux/dvb/ns.h | 68 + - 48 files changed, 25183 insertions(+), 3466 deletions(-) + drivers/media/dvb-core/Makefile | 2 +- + drivers/media/dvb-core/dvb_netstream.c | 259 ++ + drivers/media/dvb-core/dvb_netstream.h | 94 + + drivers/media/dvb-core/dvbdev.c | 11 +- + drivers/media/dvb-core/dvbdev.h | 4 + + drivers/media/dvb-frontends/Kconfig | 27 + + drivers/media/dvb-frontends/Makefile | 3 + + drivers/media/dvb-frontends/cxd2843.c | 2022 ++++++++++++ + drivers/media/dvb-frontends/cxd2843.h | 30 + + drivers/media/dvb-frontends/drxk_hard.c | 3602 +++++++++----------- + drivers/media/dvb-frontends/drxk_hard.h | 298 +- + drivers/media/dvb-frontends/drxk_map.h | 3 - + drivers/media/dvb-frontends/lnbh25.c | 153 + + drivers/media/dvb-frontends/lnbh25.h | 28 + + drivers/media/dvb-frontends/stv0367dd.c | 2331 +++++++++++++ + drivers/media/dvb-frontends/stv0367dd.h | 17 + + drivers/media/dvb-frontends/stv0367dd_regs.h | 3431 +++++++++++++++++++ + drivers/media/dvb-frontends/stv090x.c | 45 +- + drivers/media/dvb-frontends/stv0910.c | 1371 ++++++++ + drivers/media/dvb-frontends/stv0910.h | 31 + + drivers/media/dvb-frontends/stv0910_regs.h | 3998 +++++++++++++++++++++++ + drivers/media/dvb-frontends/stv6111.c | 450 +++ + drivers/media/dvb-frontends/stv6111.h | 5 + + drivers/media/dvb-frontends/tda18212dd.c | 974 ++++++ + drivers/media/dvb-frontends/tda18212dd.h | 5 + + drivers/media/dvb-frontends/tda18271c2dd.c | 17 +- + drivers/media/dvb-frontends/tda18271c2dd.h | 6 +- + drivers/media/dvb-frontends/tda18271c2dd_maps.h | 8 +- + drivers/media/pci/ddbridge/Kconfig | 11 +- + drivers/media/pci/ddbridge/Makefile | 2 - + drivers/media/pci/ddbridge/ddbridge-core.c | 3924 ++++++++++++++++------ + drivers/media/pci/ddbridge/ddbridge-i2c.c | 257 ++ + drivers/media/pci/ddbridge/ddbridge-i2c.h | 105 + + drivers/media/pci/ddbridge/ddbridge-mod.c | 1148 +++++++ + drivers/media/pci/ddbridge/ddbridge-ns.c | 489 +++ + drivers/media/pci/ddbridge/ddbridge-regs.h | 347 +- + drivers/media/pci/ddbridge/ddbridge.c | 470 +++ + drivers/media/pci/ddbridge/ddbridge.h | 419 ++- + drivers/media/pci/ddbridge/octonet.c | 199 ++ + drivers/media/pci/ngene/Kconfig | 4 + + drivers/media/pci/ngene/Makefile | 3 +- + drivers/media/pci/ngene/ngene-av.c | 348 ++ + drivers/media/pci/ngene/ngene-cards.c | 973 ++++-- + drivers/media/pci/ngene/ngene-core.c | 396 ++- + drivers/media/pci/ngene/ngene-dvb.c | 372 +++ + drivers/media/pci/ngene/ngene-eeprom.c | 284 ++ + drivers/media/pci/ngene/ngene-i2c.c | 113 + + drivers/media/pci/ngene/ngene.h | 40 + + include/uapi/linux/dvb/mod.h | 22 + + include/uapi/linux/dvb/ns.h | 68 + + 50 files changed, 25702 insertions(+), 3517 deletions(-) create mode 100644 drivers/media/dvb-core/dvb_netstream.c create mode 100644 drivers/media/dvb-core/dvb_netstream.h create mode 100644 drivers/media/dvb-frontends/cxd2843.c @@ -570,25 +572,25 @@ index fe0ddcc..b0be45b 100644 depends on DVB_CORE diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile -index edf103d..912ac69 100644 +index edf103d..196b8c2 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile -@@ -106,6 +106,9 @@ obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o +@@ -105,6 +105,9 @@ obj-$(CONFIG_DVB_STV0367) += stv0367.o + obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o obj-$(CONFIG_DVB_DRXK) += drxk.o obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o - obj-$(CONFIG_DVB_SI2165) += si2165.o +obj-$(CONFIG_DVB_STV0367DD) += stv0367dd.o +obj-$(CONFIG_DVB_TDA18212DD) += tda18212dd.o +obj-$(CONFIG_DVB_CXD2843) += cxd2843.o + obj-$(CONFIG_DVB_SI2165) += si2165.o obj-$(CONFIG_DVB_A8293) += a8293.o obj-$(CONFIG_DVB_TDA10071) += tda10071.o - obj-$(CONFIG_DVB_RTL2830) += rtl2830.o diff --git a/drivers/media/dvb-frontends/cxd2843.c b/drivers/media/dvb-frontends/cxd2843.c new file mode 100644 -index 0000000..40595dd +index 0000000..3bcc7c8 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2843.c -@@ -0,0 +1,2021 @@ +@@ -0,0 +1,2022 @@ +/* + * Driver for the Sony CXD2843ER DVB-T/T2/C/C2 demodulator. + * Also supports the CXD2837ER DVB-T/T2/C and the @@ -1758,7 +1760,8 @@ index 0000000..40595dd + writeregx(state, 0xFF, 0x02, 0x00); + usleep_range(4000, 5000); + writeregx(state, 0x00, 0x15, 0x01); -+ writeregx(state, 0x00, 0x17, 0x01); ++ if (state->type != CXD2838) ++ writeregx(state, 0x00, 0x17, 0x01); + usleep_range(4000, 5000); + + writeregx(state, 0x00, 0x10, 0x01); @@ -2453,7 +2456,7 @@ index 0000000..40595dd + FE_CAN_QAM_128 | FE_CAN_QAM_256 | + FE_CAN_FEC_AUTO | + /* DVB-T */ -+ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | @@ -2492,7 +2495,7 @@ index 0000000..40595dd + FE_CAN_QAM_128 | FE_CAN_QAM_256 | + FE_CAN_FEC_AUTO | + /* DVB-T */ -+ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | @@ -2526,7 +2529,7 @@ index 0000000..40595dd + .frequency_max = 865000000, + .symbol_rate_min = 870000, + .symbol_rate_max = 11700000, -+ .caps = FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ .caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | @@ -9538,14 +9541,34 @@ index 761613f..23e16c1 100644 #define OFDM_EQ_TOP_TD_TPS_CONST_64QAM 0x2 diff --git a/drivers/media/dvb-frontends/lnbh25.c b/drivers/media/dvb-frontends/lnbh25.c new file mode 100644 -index 0000000..b7c5099 +index 0000000..f167e67 --- /dev/null +++ b/drivers/media/dvb-frontends/lnbh25.c -@@ -0,0 +1,133 @@ +@@ -0,0 +1,153 @@ +/* -+ * lnbh25.c ++ * Driver for the ST LNBH25 ++ * ++ * Copyright (C) 2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * 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 ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + ++ +#include +#include +#include @@ -15506,12 +15529,91 @@ index 0000000..eec0f57 +#define R367_QAM_T_O_ID_3 0xF4D3 +#define F367_QAM_TS_ID_I_H 0xF4D300FF + +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index 23e872f..cd1e79b 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -3549,6 +3549,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) + return 0; + } + ++#if 0 + static int stv090x_read_per(struct dvb_frontend *fe, u32 *per) + { + struct stv090x_state *state = fe->demodulator_priv; +@@ -3599,6 +3600,27 @@ err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; + } ++#endif ++ ++static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv090x_state *state = fe->demodulator_priv; ++ u32 reg, h, m, l; ++ ++ /* Counter 1: S1: 0x75 BER, S2: 0x67 PER */ ++ reg = STV090x_READ_DEMOD(state, ERRCNT12); ++ h = STV090x_GETFIELD_Px(reg, ERR_CNT12_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT11); ++ m = STV090x_GETFIELD_Px(reg, ERR_CNT11_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT10); ++ l = STV090x_GETFIELD_Px(reg, ERR_CNT10_FIELD); ++ ++ *ber = ((h << 16) | (m << 8) | l); ++ ++ return 0; ++} + + static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) + { +@@ -3719,6 +3741,26 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) + return 0; + } + ++static int stv090x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ struct stv090x_state *state = fe->demodulator_priv; ++ u32 reg, h, m, l; ++ ++ /* Counter 2: 0xc1 TS error count */ ++ 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); ++ ++ *ucblocks = ((h << 16) | (m << 8) | l); ++ ++ return 0; ++} ++ + static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) + { + struct stv090x_state *state = fe->demodulator_priv; +@@ -4902,9 +4944,10 @@ static struct dvb_frontend_ops stv090x_ops = { + + .search = stv090x_search, + .read_status = stv090x_read_status, +- .read_ber = stv090x_read_per, ++ .read_ber = stv090x_read_ber, + .read_signal_strength = stv090x_read_signal_strength, + .read_snr = stv090x_read_cnr, ++ .read_ucblocks = stv090x_read_ucblocks, + }; + + diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c new file mode 100644 -index 0000000..89d7d1f +index 0000000..d247932 --- /dev/null +++ b/drivers/media/dvb-frontends/stv0910.c -@@ -0,0 +1,1368 @@ +@@ -0,0 +1,1371 @@ +/* + * Driver for the ST STV0910 DVB-S/S2 demodulator. + * @@ -16529,6 +16631,7 @@ index 0000000..89d7d1f + if (state->base->count == 0) { + pr_info("remove STV base\n"); + list_del(&state->base->stvlist); ++ kfree(state->base); + } + kfree(state); +} @@ -16754,8 +16857,10 @@ index 0000000..89d7d1f + u32 n, d; + + GetBitErrorRate(state, &n, &d); -+ *ber = n / d; -+ ++ if (d) ++ *ber = n / d; ++ else ++ *ber = 0; + return 0; +} + @@ -22440,6 +22545,45 @@ index dd84f7b..1389c74 100644 struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 adr); #else +diff --git a/drivers/media/dvb-frontends/tda18271c2dd_maps.h b/drivers/media/dvb-frontends/tda18271c2dd_maps.h +index f3bca5c..b87661b 100644 +--- a/drivers/media/dvb-frontends/tda18271c2dd_maps.h ++++ b/drivers/media/dvb-frontends/tda18271c2dd_maps.h +@@ -5,7 +5,7 @@ enum HF_S { + HF_DVBC_8MHZ, HF_DVBC + }; + +-static struct SStandardParam m_StandardTable[] = { ++struct SStandardParam m_StandardTable[] = { + { 0, 0, 0x00, 0x00 }, /* HF_None */ + { 6000000, 7000000, 0x1D, 0x2C }, /* HF_B, */ + { 6900000, 8000000, 0x1E, 0x2C }, /* HF_DK, */ +@@ -27,7 +27,7 @@ static struct SStandardParam m_StandardTable[] = { + { 0, 0, 0x00, 0x00 }, /* HF_DVBC (Unused) */ + }; + +-static struct SMap m_BP_Filter_Map[] = { ++struct SMap m_BP_Filter_Map[] = { + { 62000000, 0x00 }, + { 84000000, 0x01 }, + { 100000000, 0x02 }, +@@ -799,14 +799,14 @@ static struct SRFBandMap m_RF_Band_Map[7] = { + { 865000000, 489500000, 697500000, 842000000}, + }; + +-static u8 m_Thermometer_Map_1[16] = { ++u8 m_Thermometer_Map_1[16] = { + 60, 62, 66, 64, + 74, 72, 68, 70, + 90, 88, 84, 86, + 76, 78, 82, 80, + }; + +-static u8 m_Thermometer_Map_2[16] = { ++u8 m_Thermometer_Map_2[16] = { + 92, 94, 98, 96, + 106, 104, 100, 102, + 122, 120, 116, 118, diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index 44e5dc1..d283008 100644 --- a/drivers/media/pci/ddbridge/Kconfig @@ -22485,7 +22629,7 @@ index 7446c8b..2610161 100644 ccflags-y += -Idrivers/media/dvb-core/ diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c -index da8f848..9cd98a4 100644 +index da8f848..c2fc010 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1,7 +1,8 @@ @@ -23763,9 +23907,9 @@ index da8f848..9cd98a4 100644 + + if (enable) { + mutex_lock(&port->i2c_gate_lock); -+ status = dvb->gate_ctrl(fe, 1); ++ status = dvb->i2c_gate_ctrl(fe, 1); + } else { -+ status = dvb->gate_ctrl(fe, 0); ++ status = dvb->i2c_gate_ctrl(fe, 0); + mutex_unlock(&port->i2c_gate_lock); + } + return status; @@ -23773,37 +23917,28 @@ index da8f848..9cd98a4 100644 + +#if IS_ENABLED(CONFIG_DVB_DRXK) +static int demod_attach_drxk(struct ddb_input *input) - { - struct i2c_adapter *i2c = &input->port->i2c->adap; ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; - struct dvb_frontend *fe; ++ struct dvb_frontend *fe; + struct drxk_config config; + + memset(&config, 0, sizeof(config)); + config.adr = 0x29 + (input->nr & 1); + config.microcode_name = "drxk_a3.mc"; - -- if (input->fe->ops.i2c_gate_ctrl) -- input->fe->ops.i2c_gate_ctrl(input->fe, 1); -- fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60); ++ + fe = dvb->fe = dvb_attach(drxk_attach, &config, i2c); - if (!fe) { -- printk(KERN_ERR "No TDA18271 found!\n"); ++ if (!fe) { + pr_err("No DRXK found!\n"); - return -ENODEV; - } -- if (input->fe->ops.i2c_gate_ctrl) -- input->fe->ops.i2c_gate_ctrl(input->fe, 0); ++ return -ENODEV; ++ } + fe->sec_priv = input; -+ dvb->gate_ctrl = fe->ops.i2c_gate_ctrl; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; + fe->ops.i2c_gate_ctrl = locked_gate_ctrl; - return 0; - } ++ return 0; ++} +#endif - --/******************************************************************************/ --/******************************************************************************/ --/******************************************************************************/ ++ +#if 0 +struct stv0367_config stv0367_0 = { + .demod_address = 0x1f, @@ -23838,7 +23973,7 @@ index da8f848..9cd98a4 100644 + return -ENODEV; + } + fe->sec_priv = input; -+ dvb->gate_ctrl = fe->ops.i2c_gate_ctrl; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; + fe->ops.i2c_gate_ctrl = locked_gate_ctrl; + return 0; +} @@ -23881,7 +24016,7 @@ index da8f848..9cd98a4 100644 + return -ENODEV; + } + fe->sec_priv = input; -+ dvb->gate_ctrl = fe->ops.i2c_gate_ctrl; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; + fe->ops.i2c_gate_ctrl = locked_gate_ctrl; + return 0; +} @@ -23911,7 +24046,7 @@ index da8f848..9cd98a4 100644 + return -ENODEV; + } + fe->sec_priv = input; -+ dvb->gate_ctrl = fe->ops.i2c_gate_ctrl; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; + fe->ops.i2c_gate_ctrl = locked_gate_ctrl; + return 0; +} @@ -23959,22 +24094,31 @@ index da8f848..9cd98a4 100644 +}; + +static int tuner_attach_tda18212(struct ddb_input *input) -+{ -+ struct i2c_adapter *i2c = &input->port->i2c->adap; + { + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; -+ struct dvb_frontend *fe; + struct dvb_frontend *fe; + struct tda18212_config *cfg; -+ + +- if (input->fe->ops.i2c_gate_ctrl) +- input->fe->ops.i2c_gate_ctrl(input->fe, 1); +- fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60); + cfg = (input->nr & 1) ? &tda18212_1 : &tda18212_0; + fe = dvb_attach(tda18212_attach, dvb->fe, i2c, cfg); -+ if (!fe) { + if (!fe) { +- printk(KERN_ERR "No TDA18271 found!\n"); + pr_err("No TDA18212 found!\n"); -+ return -ENODEV; -+ } -+ return 0; -+} + return -ENODEV; + } +- if (input->fe->ops.i2c_gate_ctrl) +- input->fe->ops.i2c_gate_ctrl(input->fe, 0); + return 0; + } +#endif -+ + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ @@ -24052,10 +24196,14 @@ index da8f848..9cd98a4 100644 feconf->tuner_init = ctl->tuner_init; feconf->tuner_sleep = ctl->tuner_sleep; -@@ -715,10 +1243,51 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type) +@@ -715,331 +1243,919 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type) return 0; } +-static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, +- int (*start_feed)(struct dvb_demux_feed *), +- int (*stop_feed)(struct dvb_demux_feed *), +- void *priv) +static struct stv0910_cfg stv0910 = { + .adr = 0x68, + .parallel = 1, @@ -24064,11 +24212,20 @@ index da8f848..9cd98a4 100644 +}; + +static int demod_attach_stv0910(struct ddb_input *input, int type) -+{ + { +- dvbdemux->priv = priv; + struct i2c_adapter *i2c = &input->port->i2c->adap; -+ + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; -+ + +- dvbdemux->filternum = 256; +- dvbdemux->feednum = 256; +- dvbdemux->start_feed = start_feed; +- dvbdemux->stop_feed = stop_feed; +- dvbdemux->write_to_decoder = NULL; +- dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | +- DMX_SECTION_FILTERING | +- DMX_MEMORY_BASED_FILTERING); +- return dvb_dmx_init(dvbdemux); + dvb->fe = dvb_attach(stv0910_attach, i2c, &stv0910, (input->nr & 1)); + if (!dvb->fe) { + pr_err("No STV0910 found!\n"); @@ -24080,52 +24237,215 @@ index da8f848..9cd98a4 100644 + return -ENODEV; + } + return 0; -+} -+ + } + +-static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, +- struct dvb_demux *dvbdemux, +- struct dmx_frontend *hw_frontend, +- struct dmx_frontend *mem_frontend, +- struct dvb_adapter *dvb_adapter) +static int tuner_attach_stv6111(struct ddb_input *input) -+{ + { +- int ret; +- +- dmxdev->filternum = 256; +- dmxdev->demux = &dvbdemux->dmx; +- dmxdev->capabilities = 0; +- ret = dvb_dmxdev_init(dmxdev, dvb_adapter); +- if (ret < 0) +- return ret; + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct dvb_frontend *fe; -+ + +- hw_frontend->source = DMX_FRONTEND_0; +- dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); +- mem_frontend->source = DMX_MEMORY_FE; +- dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); +- return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); + fe = dvb_attach(stv6111_attach, dvb->fe, i2c, + (input->nr & 1) ? 0x63 : 0x60); + if (!fe) { + pr_err("No STV6111 found!\n"); + return -ENODEV; + } ++ return 0; + } + +-static int start_feed(struct dvb_demux_feed *dvbdmxfeed) ++static int lnb_command(struct ddb *dev, u32 lnb, u32 cmd) + { +- struct dvb_demux *dvbdmx = dvbdmxfeed->demux; +- struct ddb_input *input = dvbdmx->priv; +- +- if (!input->users) +- ddb_input_start(input); ++ u32 c, v = 0; + +- return ++input->users; ++ v = LNB_TONE & (dev->lnb_tone << (15 - lnb)); ++ pr_info("lnb_control[%u] = %08x\n", lnb, cmd | v); ++ ddbwritel(dev, cmd | v, LNB_CONTROL(lnb)); ++ for (c = 0; c < 10; c++) { ++ v = ddbreadl(dev, LNB_CONTROL(lnb)); ++ pr_info("ctrl = %08x\n", v); ++ if ((v & LNB_BUSY) == 0) ++ break; ++ msleep(20); ++ } ++ return 0; + } + +-static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) ++static int dd_send_master_cmd(struct dvb_frontend *fe, ++ struct dvb_diseqc_master_cmd *cmd) + { +- struct dvb_demux *dvbdmx = dvbdmxfeed->demux; +- struct ddb_input *input = dvbdmx->priv; +- +- if (--input->users) +- return input->users; ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int i; + +- ddb_input_stop(input); ++ mutex_lock(&dev->lnb_lock); ++ ddbwritel(dev, 0, LNB_BUF_LEVEL(dvb->input)); ++ for (i = 0; i < cmd->msg_len; i++) ++ ddbwritel(dev, cmd->msg[i], LNB_BUF_WRITE(dvb->input)); ++ lnb_command(dev, dvb->input, LNB_CMD_DISEQC); ++ mutex_unlock(&dev->lnb_lock); + return 0; + } + +- +-static void dvb_input_detach(struct ddb_input *input) ++static int dd_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) + { +- struct dvb_adapter *adap = &input->adap; +- struct dvb_demux *dvbdemux = &input->demux; +- +- switch (input->attached) { +- case 5: +- if (input->fe2) +- dvb_unregister_frontend(input->fe2); +- if (input->fe) { +- dvb_unregister_frontend(input->fe); +- dvb_frontend_detach(input->fe); +- input->fe = NULL; +- } +- case 4: +- dvb_net_release(&input->dvbnet); ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int s = 0; + +- case 3: +- dvbdemux->dmx.close(&dvbdemux->dmx); +- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, +- &input->hw_frontend); ++ mutex_lock(&dev->lnb_lock); ++ switch (tone) { ++ case SEC_TONE_OFF: ++ dev->lnb_tone &= ~(1ULL << dvb->input); ++ break; ++ case SEC_TONE_ON: ++ dev->lnb_tone |= (1ULL << dvb->input); ++ break; ++ default: ++ s = -EINVAL; ++ break; ++ }; ++ if (!s) ++ s = lnb_command(dev, dvb->input, LNB_CMD_NOP); ++ mutex_unlock(&dev->lnb_lock); + return 0; +} + - static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, -- int (*start_feed)(struct dvb_demux_feed *), -- int (*stop_feed)(struct dvb_demux_feed *), -- void *priv) ++static int dd_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) ++{ ++ ++ return 0; ++} ++ ++static int dd_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int s = 0; ++ ++ mutex_lock(&dev->lnb_lock); ++ switch (voltage) { ++ case SEC_VOLTAGE_OFF: ++ lnb_command(dev, dvb->input, LNB_CMD_OFF); ++ break; ++ case SEC_VOLTAGE_13: ++ lnb_command(dev, dvb->input, LNB_CMD_LOW); ++ break; ++ case SEC_VOLTAGE_18: ++ lnb_command(dev, dvb->input, LNB_CMD_HIGH); ++ break; ++ default: ++ s = -EINVAL; ++ break; ++ }; ++ mutex_unlock(&dev->lnb_lock); ++ return s; ++} ++ ++static int dd_set_input(struct dvb_frontend *fe) ++{ ++ ++ return 0; ++} ++ ++static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, + int (*start_feed)(struct dvb_demux_feed *), + int (*stop_feed)(struct dvb_demux_feed *), + void *priv) - { - dvbdemux->priv = priv; - -@@ -734,10 +1303,10 @@ static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, - } - - static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, -- struct dvb_demux *dvbdemux, -- struct dmx_frontend *hw_frontend, -- struct dmx_frontend *mem_frontend, -- struct dvb_adapter *dvb_adapter) ++{ ++ dvbdemux->priv = priv; ++ ++ dvbdemux->filternum = 256; ++ dvbdemux->feednum = 256; ++ dvbdemux->start_feed = start_feed; ++ dvbdemux->stop_feed = stop_feed; ++ dvbdemux->write_to_decoder = NULL; ++ dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | ++ DMX_SECTION_FILTERING | ++ DMX_MEMORY_BASED_FILTERING); ++ return dvb_dmx_init(dvbdemux); ++} ++ ++static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, + struct dvb_demux *dvbdemux, + struct dmx_frontend *hw_frontend, + struct dmx_frontend *mem_frontend, + struct dvb_adapter *dvb_adapter) - { - int ret; - -@@ -755,291 +1324,727 @@ static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, - return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); - } - ++{ ++ int ret; ++ ++ dmxdev->filternum = 256; ++ dmxdev->demux = &dvbdemux->dmx; ++ dmxdev->capabilities = 0; ++ ret = dvb_dmxdev_init(dmxdev, dvb_adapter); ++ if (ret < 0) ++ return ret; ++ ++ hw_frontend->source = DMX_FRONTEND_0; ++ dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); ++ mem_frontend->source = DMX_MEMORY_FE; ++ dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); ++ return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); ++} ++ +#if 0 +static int start_input(struct ddb_input *input) +{ @@ -24149,56 +24469,33 @@ index da8f848..9cd98a4 100644 +} +#endif + - static int start_feed(struct dvb_demux_feed *dvbdmxfeed) - { - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - struct ddb_input *input = dvbdmx->priv; ++static int start_feed(struct dvb_demux_feed *dvbdmxfeed) ++{ ++ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; ++ struct ddb_input *input = dvbdmx->priv; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; - -- if (!input->users) -- ddb_input_start(input); ++ + if (!dvb->users) + ddb_input_start_all(input); - -- return ++input->users; ++ + return ++dvb->users; - } - - static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) - { - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - struct ddb_input *input = dvbdmx->priv; ++} ++ ++static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) ++{ ++ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; ++ struct ddb_input *input = dvbdmx->priv; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; - -- if (--input->users) -- return input->users; ++ + if (--dvb->users) + return dvb->users; - -- ddb_input_stop(input); ++ + ddb_input_stop_all(input); - return 0; - } - -- - static void dvb_input_detach(struct ddb_input *input) - { -- struct dvb_adapter *adap = &input->adap; -- struct dvb_demux *dvbdemux = &input->demux; -- -- switch (input->attached) { -- case 5: -- if (input->fe2) -- dvb_unregister_frontend(input->fe2); -- if (input->fe) { -- dvb_unregister_frontend(input->fe); -- dvb_frontend_detach(input->fe); -- input->fe = NULL; -- } -- case 4: -- dvb_net_release(&input->dvbnet); -- -- case 3: ++ return 0; ++} ++ ++static void dvb_input_detach(struct ddb_input *input) ++{ + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct dvb_demux *dvbdemux = &dvb->demux; + @@ -24221,13 +24518,12 @@ index da8f848..9cd98a4 100644 + dvb_net_release(&dvb->dvbnet); + /* fallthrough */ + case 0x11: - dvbdemux->dmx.close(&dvbdemux->dmx); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, -- &input->hw_frontend); -+ &dvb->hw_frontend); ++ dvbdemux->dmx.close(&dvbdemux->dmx); dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, - &input->mem_frontend); - dvb_dmxdev_release(&input->dmxdev); ++ &dvb->hw_frontend); ++ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, + &dvb->mem_frontend); + dvb_dmxdev_release(&dvb->dmxdev); + /* fallthrough */ @@ -24239,7 +24535,9 @@ index da8f848..9cd98a4 100644 + } + dvb->attached = 0x00; +} -+ + +- case 2: +- dvb_dmx_release(&input->demux); +static int dvb_register_adapters(struct ddb *dev) +{ + int i, ret = 0; @@ -24262,7 +24560,9 @@ index da8f848..9cd98a4 100644 + } + return 0; + } -+ + +- case 1: +- dvb_unregister_adapter(adap); + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; + switch (port->class) { @@ -24289,9 +24589,7 @@ index da8f848..9cd98a4 100644 + return ret; + port->dvb[1].adap_registered = 1; + break; - -- case 2: -- dvb_dmx_release(&input->demux); ++ + case DDB_PORT_CI: + case DDB_PORT_LOOP: + adap = port->dvb[0].adap; @@ -24319,9 +24617,7 @@ index da8f848..9cd98a4 100644 + } + return ret; +} - -- case 1: -- dvb_unregister_adapter(adap); ++ +static void dvb_unregister_adapters(struct ddb *dev) +{ + int i; @@ -24414,6 +24710,7 @@ index da8f848..9cd98a4 100644 - } + break; + case DDB_TUNER_DVBS_STV0910: ++ case DDB_TUNER_DVBS_STV0910_P: + if (demod_attach_stv0910(input, 0) < 0) + return -ENODEV; + if (tuner_attach_stv6111(input) < 0) @@ -24449,14 +24746,6 @@ index da8f848..9cd98a4 100644 + case DDB_TUNER_ISDBT_SONY: + if (demod_attach_cxd2843(input, 0) < 0) + return -ENODEV; -+ if (tuner_attach_tda18212dd(input) < 0) -+ return -ENODEV; -+ break; -+ case DDB_TUNER_DVBCT2_SONY_P: -+ case DDB_TUNER_DVBC2T2_SONY_P: -+ case DDB_TUNER_ISDBT_SONY_P: -+ if (demod_attach_cxd2843(input, 1) < 0) -+ return -ENODEV; + if (tuner_attach_tda18212dd(input) < 0) return -ENODEV; - if (input->fe2) { @@ -24468,6 +24757,14 @@ index da8f848..9cd98a4 100644 - sizeof(struct dvb_tuner_ops)); - } break; ++ case DDB_TUNER_DVBCT2_SONY_P: ++ case DDB_TUNER_DVBC2T2_SONY_P: ++ case DDB_TUNER_ISDBT_SONY_P: ++ if (demod_attach_cxd2843(input, 1) < 0) ++ return -ENODEV; ++ if (tuner_attach_tda18212dd(input) < 0) ++ return -ENODEV; ++ break; + default: + return 0; } @@ -24520,7 +24817,6 @@ index da8f848..9cd98a4 100644 - return (left == count) ? -EAGAIN : (count - left); + if (!ret) + pr_info("[0x20]=0x%02x\n", val); -+ + return ret ? 0 : 1; } @@ -24600,10 +24896,9 @@ index da8f848..9cd98a4 100644 + return 1; +} + -+static int port_has_stv0900_aa(struct ddb_port *port) ++static int port_has_stv0900_aa(struct ddb_port *port, u8 *id) +{ -+ u8 val; -+ if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0) ++ if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, id) < 0) + return 0; + return 1; +} @@ -24647,9 +24942,7 @@ index da8f848..9cd98a4 100644 + res = i2c_read_reg(i2c, 0x10, 0x04, &val); + if (res < 0) + return res; - -- poll_wait(file, &read_queue, wait); -- poll_wait(file, &write_queue, wait); ++ + if (val != 0x02) { + pr_info("Port %d: invalid XO2\n", port->nr); + return -1; @@ -24669,7 +24962,9 @@ index da8f848..9cd98a4 100644 + usleep_range(2000, 3000); + /* Start XO2 PLL */ + i2c_write_reg(i2c, 0x10, 0x08, 0x87); -+ + +- poll_wait(file, &read_queue, wait); +- poll_wait(file, &write_queue, wait); + return 0; +} #endif @@ -24757,6 +25052,15 @@ index da8f848..9cd98a4 100644 + return; + } + ++ if (dev->info->type == DDB_OCTOPUS_MAX) { ++ port->name = "DUAL DVB-S2 MX"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_MXL5XX; ++ if (port->i2c) ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ return; ++ } ++ + if (port->nr > 1 && dev->info->type == DDB_OCTOPUS_CI) { + port->name = "CI internal"; + port->class = DDB_PORT_CI; @@ -24808,10 +25112,14 @@ index da8f848..9cd98a4 100644 + port->class = DDB_PORT_TUNER; + port->type = DDB_TUNER_DVBS_ST; + ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); -+ } else if (port_has_stv0900_aa(port)) { ++ } else if (port_has_stv0900_aa(port, &id)) { + port->name = "DUAL DVB-S2"; + port->class = DDB_PORT_TUNER; + port->type = DDB_TUNER_DVBS_ST_AA; ++ if (id == 0x51) ++ port->type = DDB_TUNER_DVBS_STV0910_P; ++ else ++ port->type = DDB_TUNER_DVBS_ST_AA; + ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); + } else if (port_has_drxks(port)) { + port->name = "DUAL DVB-C/T"; @@ -25035,7 +25343,7 @@ index da8f848..9cd98a4 100644 .adr = 0x40, .polarity = 1, .clock_mode = 1, -@@ -1047,28 +2052,21 @@ struct cxd2099_cfg cxd_cfg = { +@@ -1047,28 +2163,21 @@ struct cxd2099_cfg cxd_cfg = { static int ddb_ci_attach(struct ddb_port *port) { @@ -25078,7 +25386,7 @@ index da8f848..9cd98a4 100644 } static int ddb_port_attach(struct ddb_port *port) -@@ -1081,15 +2079,32 @@ static int ddb_port_attach(struct ddb_port *port) +@@ -1081,15 +2190,32 @@ static int ddb_port_attach(struct ddb_port *port) if (ret < 0) break; ret = dvb_input_attach(port->input[1]); @@ -25112,7 +25420,7 @@ index da8f848..9cd98a4 100644 return ret; } -@@ -1098,6 +2113,21 @@ static int ddb_ports_attach(struct ddb *dev) +@@ -1098,6 +2224,21 @@ static int ddb_ports_attach(struct ddb *dev) int i, ret = 0; struct ddb_port *port; @@ -25134,7 +25442,7 @@ index da8f848..9cd98a4 100644 for (i = 0; i < dev->info->port_num; i++) { port = &dev->port[i]; ret = ddb_port_attach(port); -@@ -1114,125 +2144,259 @@ static void ddb_ports_detach(struct ddb *dev) +@@ -1114,125 +2255,259 @@ static void ddb_ports_detach(struct ddb *dev) for (i = 0; i < dev->info->port_num; i++) { port = &dev->port[i]; @@ -25465,7 +25773,7 @@ index da8f848..9cd98a4 100644 } static void ddb_ports_init(struct ddb *dev) -@@ -1240,20 +2404,48 @@ static void ddb_ports_init(struct ddb *dev) +@@ -1240,20 +2515,53 @@ static void ddb_ports_init(struct ddb *dev) int i; struct ddb_port *port; @@ -25482,11 +25790,13 @@ index da8f848..9cd98a4 100644 port = &dev->port[i]; port->dev = dev; port->nr = i; - port->i2c = &dev->i2c[i]; +- port->i2c = &dev->i2c[i]; - port->input[0] = &dev->input[2 * i]; - port->input[1] = &dev->input[2 * i + 1]; - port->output = &dev->output[i]; - ++ if (dev->info->i2c_num > i) ++ port->i2c = &dev->i2c[i]; + port->gap = 4; + port->obr = ci_bitrate; mutex_init(&port->i2c_gate_lock); @@ -25512,6 +25822,10 @@ index da8f848..9cd98a4 100644 + } + ddb_output_init(port, i, i + 8); + } ++ if (dev->info->type == DDB_OCTOPUS_MAX) { ++ ddb_input_init(port, 2 * i, 0, 2 * i); ++ ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1); ++ } + if (dev->info->type == DDB_MOD) { + ddb_output_init(port, i, i); + dev->handler[i + 18] = ddbridge_mod_rate_handler; @@ -25521,7 +25835,7 @@ index da8f848..9cd98a4 100644 } } -@@ -1262,12 +2454,25 @@ static void ddb_ports_release(struct ddb *dev) +@@ -1262,12 +2570,25 @@ static void ddb_ports_release(struct ddb *dev) int i; struct ddb_port *port; @@ -25551,7 +25865,7 @@ index da8f848..9cd98a4 100644 } } -@@ -1275,90 +2480,306 @@ static void ddb_ports_release(struct ddb *dev) +@@ -1275,90 +2596,306 @@ static void ddb_ports_release(struct ddb *dev) /****************************************************************************/ /****************************************************************************/ @@ -25619,7 +25933,9 @@ index da8f848..9cd98a4 100644 - struct ddb_i2c *i2c = &dev->i2c[n]; + struct ddb *dev = (struct ddb *) dev_id; + u32 s = ddbreadl(dev, INTERRUPT_STATUS); -+ + +- i2c->done = 1; +- wake_up(&i2c->wq); + do { + if (s & 0x80000000) + return IRQ_NONE; @@ -25628,9 +25944,7 @@ index da8f848..9cd98a4 100644 + ddbwritel(dev, s, INTERRUPT_ACK); + irq_handle_msg(dev, s); + } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); - -- i2c->done = 1; -- wake_up(&i2c->wq); ++ + return IRQ_HANDLED; } @@ -25911,7 +26225,7 @@ index da8f848..9cd98a4 100644 data = 0; shift = ((4 - wlen) * 8); -@@ -1370,33 +2791,33 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) +@@ -1370,33 +2907,33 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) } if (shift) data <<= shift; @@ -25957,7 +26271,7 @@ index da8f848..9cd98a4 100644 if (rlen < 4) data <<= ((4 - rlen) * 8); -@@ -1410,6 +2831,35 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) +@@ -1410,6 +2947,35 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) return 0; } @@ -25993,7 +26307,7 @@ index da8f848..9cd98a4 100644 #define DDB_MAGIC 'd' struct ddb_flashio { -@@ -1419,19 +2869,69 @@ struct ddb_flashio { +@@ -1419,19 +2985,69 @@ struct ddb_flashio { __u32 read_len; }; @@ -26066,7 +26380,7 @@ index da8f848..9cd98a4 100644 file->private_data = dev; return 0; } -@@ -1450,7 +2950,6 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +@@ -1450,7 +3066,6 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (copy_from_user(&fio, parg, sizeof(fio))) return -EFAULT; @@ -26074,7 +26388,7 @@ index da8f848..9cd98a4 100644 if (fio.write_len > 1028 || fio.read_len > 1028) return -EINVAL; if (fio.write_len + fio.read_len > 1028) -@@ -1468,6 +2967,103 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +@@ -1468,6 +3083,107 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return -EFAULT; break; } @@ -26129,6 +26443,8 @@ index da8f848..9cd98a4 100644 + { + struct ddb_mdio mdio; + ++ if (!dev->info->mdio_num) ++ return -EIO; + if (copy_from_user(&mdio, parg, sizeof(mdio))) + return -EFAULT; + mdio.val = mdio_read(dev, mdio.adr, mdio.reg); @@ -26140,6 +26456,8 @@ index da8f848..9cd98a4 100644 + { + struct ddb_mdio mdio; + ++ if (!dev->info->mdio_num) ++ return -EIO; + if (copy_from_user(&mdio, parg, sizeof(mdio))) + return -EFAULT; + mdio_write(dev, mdio.adr, mdio.reg, mdio.val); @@ -26178,7 +26496,7 @@ index da8f848..9cd98a4 100644 default: return -ENOTTY; } -@@ -1477,284 +3073,494 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +@@ -1477,284 +3193,508 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations ddb_fops = { .unlocked_ioctl = ddb_ioctl, .open = ddb_open, @@ -26677,11 +26995,16 @@ index da8f848..9cd98a4 100644 + __ATTR_RO(ports), + __ATTR_RO(ts_irq), + __ATTR_RO(i2c_irq), ++ __ATTR(gap0, 0664, gap_show, gap_store), ++ __ATTR(gap1, 0664, gap_show, gap_store), ++ __ATTR(gap2, 0664, gap_show, gap_store), ++ __ATTR(gap3, 0664, gap_show, gap_store), + __ATTR_RO(hwid), + __ATTR_RO(regmap), +#if 0 + __ATTR_RO(qam), +#endif ++ __ATTR(redirect, 0664, redirect_show, redirect_store), + __ATTR_MRO(snr, bsnr_show), + __ATTR_NULL, }; @@ -26716,6 +27039,7 @@ index da8f848..9cd98a4 100644 - .name = "Digital Devices Octopus V3 DVB adapter", - .port_num = 4, +static struct device_attribute ddb_attrs_fan[] = { ++ __ATTR(fan, 0664, fan_show, fan_store), }; -#define DDVID 0xdd01 /* Digital Devices Vendor ID */ @@ -26739,10 +27063,18 @@ index da8f848..9cd98a4 100644 - DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - {0} +static struct device_attribute ddb_attrs_snr[] = { ++ __ATTR(snr0, 0664, snr_show, snr_store), ++ __ATTR(snr1, 0664, snr_show, snr_store), ++ __ATTR(snr2, 0664, snr_show, snr_store), ++ __ATTR(snr3, 0664, snr_show, snr_store), }; -MODULE_DEVICE_TABLE(pci, ddb_id_tbl); +static struct device_attribute ddb_attrs_led[] = { ++ __ATTR(led0, 0664, led_show, led_store), ++ __ATTR(led1, 0664, led_show, led_store), ++ __ATTR(led2, 0664, led_show, led_store), ++ __ATTR(led3, 0664, led_show, led_store), +}; -static struct pci_driver ddb_pci_driver = { @@ -26882,14 +27214,14 @@ index da8f848..9cd98a4 100644 +} diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c new file mode 100644 -index 0000000..88b2db8 +index 0000000..bd0d9b1 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c @@ -0,0 +1,257 @@ +/* + * ddbridge-i2c.c: Digital Devices bridge i2c driver + * -+ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH + * Ralph Metzler + * + * This program is free software; you can redistribute it and/or @@ -27145,14 +27477,14 @@ index 0000000..88b2db8 + diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.h b/drivers/media/pci/ddbridge/ddbridge-i2c.h new file mode 100644 -index 0000000..fc8e34f +index 0000000..4a9bc26 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.h @@ -0,0 +1,105 @@ +/* + * ddbridge-i2c.h: Digital Devices bridge i2c driver + * -+ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH + * Ralph Metzler + * + * This program is free software; you can redistribute it and/or @@ -27256,14 +27588,14 @@ index 0000000..fc8e34f +#endif diff --git a/drivers/media/pci/ddbridge/ddbridge-mod.c b/drivers/media/pci/ddbridge/ddbridge-mod.c new file mode 100644 -index 0000000..46b9394 +index 0000000..5a9c866 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-mod.c -@@ -0,0 +1,1131 @@ +@@ -0,0 +1,1148 @@ +/* + * ddbridge.c: Digital Devices PCIe bridge driver + * -+ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * @@ -28021,6 +28353,7 @@ index 0000000..46b9394 + dev->mod[chan].modulation = mod; + dev->mod[chan].obitrate = 0x0061072787900000 * (mod + 3); + dev->mod[chan].ibitrate = dev->mod[chan].obitrate; ++ ddbwritel(dev, qamtab[mod], CHANNEL_SETTINGS(chan)); + return 0; +} + @@ -28151,6 +28484,16 @@ index 0000000..46b9394 + return stat; +} + ++#define PACKET_CLOCKS (27000000ULL*1504) ++#define FACTOR (1ULL << 22) ++ ++/* ++ double Increment = FACTOR*PACKET_CLOCKS/double(m_OutputBitrate); ++ double Decrement = FACTOR*PACKET_CLOCKS/double(m_InputBitrate); ++ ++ 27000000 * 1504 * 2^22 / (6900000 * 188 / 204) = 26785190066.1 ++*/ ++ +void ddbridge_mod_rate_handler(unsigned long data) +{ + struct ddb_output *output = (struct ddb_output *) data; @@ -28208,39 +28551,40 @@ index 0000000..46b9394 + case CM_STARTUP: + if (mod->StateCounter) { + if (mod->StateCounter == 1) { -+ mul = (0x1000000 * (u64) (OutPacketDiff - -+ InPacketDiff - -+ InPacketDiff/1000)); -+ if (OutPacketDiff) -+ mod->rate_inc = -+ div_u64(mul, OutPacketDiff); -+ else -+ mod->rate_inc = 0; -+ mod_set_rateinc(dev, output->nr); -+/* -+#define PACKET_CLOCKS (27000000ULL*1504) -+#define FACTOR (1<<22) -+double Increment = FACTOR*PACKET_CLOCKS/double(m_OutputBitrate); -+double Decrement = FACTOR*PACKET_CLOCKS/double(m_InputBitrate); -+ -+27000000 * 1504 * 2^22 / (6900000 * 188 / 204) = 26785190066.1 -+*/ -+ mod->PCRIncrement = -+ div_u64(26785190066ULL, -+ mod->modulation + 3); -+ if (InPacketDiff) ++ if (mod->ibitrate == 0) { ++ mul = (0x1000000 * (u64) (OutPacketDiff - ++ InPacketDiff - ++ InPacketDiff/1000)); ++ if (OutPacketDiff) ++ mod->rate_inc = ++ div_u64(mul, OutPacketDiff); ++ else ++ mod->rate_inc = 0; ++ mod_set_rateinc(dev, output->nr); ++ mod->PCRIncrement = ++ div_u64(26785190066ULL, ++ mod->modulation + 3); ++ if (InPacketDiff) ++ mod->PCRDecrement = ++ div_u64(mod->PCRIncrement * ++ (u64) OutPacketDiff, ++ InPacketDiff); ++ else ++ mod->PCRDecrement = 0; ++ mod_set_incs(output); ++ } else { ++ mod->PCRIncrement = ++ div_u64(26785190066ULL, ++ mod->modulation + 3); + mod->PCRDecrement = -+ div_u64(mod->PCRIncrement * -+ (u64) OutPacketDiff, -+ InPacketDiff); -+ else -+ mod->PCRDecrement = 0; -+ mod_set_incs(output); ++ div_u64(FACTOR*PACKET_CLOCKS, ++ mod->ibitrate >> 32); ++ mod_set_incs(output); ++ } + } + mod->StateCounter--; + break; -+ } -+ if (InPacketDiff >= mod->MinInputPackets) { ++ } else if (InPacketDiff >= mod->MinInputPackets) { + mod->State = CM_ADJUST; + mod->Control |= CHANNEL_CONTROL_ENABLE_PCRADJUST; + mod->InPacketsSum = 0; @@ -28341,9 +28685,11 @@ index 0000000..46b9394 + { + struct dvb_mod_params *mp = parg; + ++ pr_info("set base freq\n"); + if (mp->base_frequency != dev->mod_base.frequency) + if (set_base_frequency(dev, mp->base_frequency)) + return -EINVAL; ++ pr_info("set attenuator\n"); + mod_set_attenuator(dev, mp->attenuator); + break; + } @@ -28353,6 +28699,7 @@ index 0000000..46b9394 + int res; + u32 ri; + ++ pr_info("set modulation\n"); + res = mod_set_modulation(dev, output->nr, cp->modulation); + if (res) + return res; @@ -28362,6 +28709,8 @@ index 0000000..46b9394 + dev->mod[output->nr].ibitrate = cp->input_bitrate; + dev->mod[output->nr].pcr_correction = cp->pcr_correction; + ++ pr_info("ibitrate %llu\n", dev->mod[output->nr].ibitrate); ++ pr_info("obitrate %llu\n", dev->mod[output->nr].obitrate); + if (cp->input_bitrate != 0) { + u64 d = dev->mod[output->nr].obitrate - + dev->mod[output->nr].ibitrate; @@ -28393,14 +28742,14 @@ index 0000000..46b9394 +} diff --git a/drivers/media/pci/ddbridge/ddbridge-ns.c b/drivers/media/pci/ddbridge/ddbridge-ns.c new file mode 100644 -index 0000000..b538f12 +index 0000000..9d86cba --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-ns.c @@ -0,0 +1,489 @@ +/* + * ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming + * -+ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH + * Ralph Metzler + * + * This program is free software; you can redistribute it and/or @@ -28887,7 +29236,7 @@ index 0000000..b538f12 + return res; +} diff --git a/drivers/media/pci/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h -index a3ccb31..0c064ae 100644 +index a3ccb31..eca8574 100644 --- a/drivers/media/pci/ddbridge/ddbridge-regs.h +++ b/drivers/media/pci/ddbridge/ddbridge-regs.h @@ -1,7 +1,7 @@ @@ -28895,7 +29244,7 @@ index a3ccb31..0c064ae 100644 * ddbridge-regs.h: Digital Devices PCIe bridge driver * - * Copyright (C) 2010-2011 Digital Devices GmbH -+ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -28931,12 +29280,12 @@ index a3ccb31..0c064ae 100644 +#define MDIO_ADR 0x24 +#define MDIO_REG 0x28 +#define MDIO_VAL 0x2C ++ ++/* ------------------------------------------------------------------------- */ -/* Interrupt controller */ -/* How many MSI's are available depends on HW (Min 2 max 8) */ -/* How many are usable also depends on Host platform */ -+/* ------------------------------------------------------------------------- */ -+ +#define BOARD_CONTROL 0x30 + +/* ------------------------------------------------------------------------- */ @@ -28991,7 +29340,7 @@ index a3ccb31..0c064ae 100644 /* ------------------------------------------------------------------------- */ /* I2C Master Controller */ -@@ -90,18 +139,12 @@ +@@ -90,19 +139,14 @@ #define I2C_TIMING (0x04) #define I2C_TASKLENGTH (0x08) /* High read, low write */ #define I2C_TASKADDRESS (0x0C) /* High read, low write */ @@ -29009,9 +29358,11 @@ index a3ccb31..0c064ae 100644 -#define I2C_TASKMEM_SIZE (0x1000) +#define I2C_TASKMEM_SIZE (0x0800) ++#define I2C_SPEED_666 (0x02010202) #define I2C_SPEED_400 (0x04030404) #define I2C_SPEED_200 (0x09080909) -@@ -117,35 +160,252 @@ + #define I2C_SPEED_154 (0x0C0B0C0C) +@@ -117,35 +161,276 @@ #define DMA_BASE_WRITE (0x100) #define DMA_BASE_READ (0x140) @@ -29066,6 +29417,30 @@ index a3ccb31..0c064ae 100644 #define DMA_BASE_ADDRESS_TABLE (0x2000) #define DMA_BASE_ADDRESS_TABLE_ENTRIES (512) ++ ++/* ------------------------------------------------------------------------- */ ++ ++#define LNB_BASE (0x400) ++#define LNB_CONTROL(i) (LNB_BASE + (i) * 0x20 + 0x00) ++#define LNB_CMD (7ULL << 0) ++#define LNB_CMD_NOP 0 ++#define LNB_CMD_INIT 1 ++#define LNB_CMD_STATUS 2 ++#define LNB_CMD_LOW 3 ++#define LNB_CMD_HIGH 4 ++#define LNB_CMD_OFF 5 ++#define LNB_CMD_DISEQC 6 ++#define LNB_CMD_UNI 7 ++ ++#define LNB_BUSY (1ULL << 4) ++#define LNB_TONE (1ULL << 15) ++ ++#define LNB_STATUS(i) (LNB_BASE + (i) * 0x20 + 0x04) ++#define LNB_VOLTAGE(i) (LNB_BASE + (i) * 0x20 + 0x08) ++#define LNB_CONFIG(i) (LNB_BASE + (i) * 0x20 + 0x0c) ++#define LNB_BUF_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10) ++#define LNB_BUF_WRITE(i) (LNB_BASE + (i) * 0x20 + 0x14) ++ +/* ------------------------------------------------------------------------- */ +/* CI Interface (only CI-Bridge) */ + @@ -29283,15 +29658,16 @@ index a3ccb31..0c064ae 100644 + diff --git a/drivers/media/pci/ddbridge/ddbridge.c b/drivers/media/pci/ddbridge/ddbridge.c new file mode 100644 -index 0000000..a2c3c43 +index 0000000..9784f10 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge.c -@@ -0,0 +1,449 @@ +@@ -0,0 +1,470 @@ +/* + * ddbridge.c: Digital Devices PCIe bridge driver + * + * Copyright (C) 2010-2013 Digital Devices GmbH + * Ralph Metzler ++ * Marcus Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License @@ -29434,7 +29810,16 @@ index 0000000..a2c3c43 + +#ifdef CONFIG_PCI_MSI + if (msi && pci_msi_enabled()) { -+ stat = pci_enable_msi_exact(dev->pdev, 2); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) // OE ++ stat = pci_enable_msi_range(dev->pdev, 1, 2); ++ if (stat >= 1) { ++ dev->msi = stat; ++ pr_info(": Using %d MSI interrupts\n", dev->msi); ++ irq_flag = 0; ++ } else ++ pr_info(": MSI not available.\n"); ++#else ++ stat = pci_enable_msi_block(dev->pdev, 2); + if (stat == 0) { + dev->msi = 1; + pr_info("DDBrige using 2 MSI interrupts\n"); @@ -29447,6 +29832,7 @@ index 0000000..a2c3c43 + irq_flag = 0; + dev->msi++; + } ++#endif + } + if (dev->msi == 2) { + stat = request_irq(dev->pdev->irq, irq_handler0, @@ -29486,6 +29872,7 @@ index 0000000..a2c3c43 + ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); + ddbwritel(dev, 0x00000000, MSI1_ENABLE); + } ++ mutex_init(&dev->lnb_lock); + if (ddb_i2c_init(dev) < 0) + goto fail1; + ddb_ports_init(dev); @@ -29616,6 +30003,14 @@ index 0000000..a2c3c43 + .board_control = 2, +}; + ++static struct ddb_info ddb_s2_48 = { ++ .type = DDB_OCTOPUS_MAX, ++ .name = "Digital Devices Cine S2 4/8", ++ .port_num = 4, ++ .i2c_num = 1, ++ .board_control = 1, ++}; ++ +static struct ddb_info ddb_ctv7 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine CT V7 DVB adapter", @@ -29681,6 +30076,7 @@ index 0000000..a2c3c43 + DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), + DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), + DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), ++ DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48), + DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci), + DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis), + DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod), @@ -29735,9 +30131,9 @@ index 0000000..a2c3c43 +MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); +MODULE_AUTHOR("Ralph Metzler, Metzler Brothers Systementwicklung"); +MODULE_LICENSE("GPL"); -+MODULE_VERSION(DDBRIDGE_VERSION); ++MODULE_VERSION(DDBRIDGE_VERSION); diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h -index 8b1b41d..46b30b0 100644 +index 8b1b41d..a02e91a 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -1,7 +1,8 @@ @@ -29803,7 +30199,7 @@ index 8b1b41d..46b30b0 100644 #include "dmxdev.h" #include "dvbdev.h" #include "dvb_demux.h" -@@ -41,95 +77,161 @@ +@@ -41,95 +77,167 @@ #include "dvb_ringbuffer.h" #include "dvb_ca_en50221.h" #include "dvb_net.h" @@ -29868,6 +30264,7 @@ index 8b1b41d..46b30b0 100644 +#define DDB_OCTOPUS_CI 2 +#define DDB_MOD 3 +#define DDB_OCTONET 4 ++#define DDB_OCTOPUS_MAX 5 char *name; - int port_num; - u32 port_type[DDB_MAX_PORT]; @@ -29879,6 +30276,7 @@ index 8b1b41d..46b30b0 100644 + u8 temp_bus; + u8 board_control; + u8 ns_num; ++ u8 mdio_num; + struct ddb_regmap *regmap; }; @@ -29948,8 +30346,13 @@ index 8b1b41d..46b30b0 100644 struct dmx_frontend hw_frontend; struct dmx_frontend mem_frontend; int users; - int (*gate_ctrl)(struct dvb_frontend *, int); -+ int attached; +- int (*gate_ctrl)(struct dvb_frontend *, int); ++ u32 attached; ++ u8 input; ++ ++ int (*i2c_gate_ctrl)(struct dvb_frontend *, int); ++ int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); ++ int (*set_input)(struct dvb_frontend *fe); }; -struct ddb_output { @@ -29998,28 +30401,34 @@ index 8b1b41d..46b30b0 100644 }; struct ddb_port { -@@ -141,45 +243,246 @@ struct ddb_port { +@@ -141,45 +249,250 @@ struct ddb_port { #define DDB_PORT_NONE 0 #define DDB_PORT_CI 1 #define DDB_PORT_TUNER 2 -+#define DDB_PORT_LOOP 3 -+#define DDB_PORT_MOD 4 -+ char *name; - u32 type; - #define DDB_TUNER_NONE 0 - #define DDB_TUNER_DVBS_ST 1 - #define DDB_TUNER_DVBS_ST_AA 2 +- u32 type; +-#define DDB_TUNER_NONE 0 +-#define DDB_TUNER_DVBS_ST 1 +-#define DDB_TUNER_DVBS_ST_AA 2 -#define DDB_TUNER_DVBCT_TR 16 -#define DDB_TUNER_DVBCT_ST 17 - u32 adr; -+#define DDB_TUNER_DVBCT_TR 3 -+#define DDB_TUNER_DVBCT_ST 4 -+#define DDB_CI_INTERNAL 5 -+#define DDB_CI_EXTERNAL_SONY 6 -+#define DDB_TUNER_DVBCT2_SONY_P 7 ++#define DDB_PORT_LOOP 3 ++#define DDB_PORT_MOD 4 ++ char *name; ++ u32 type; ++#define DDB_TUNER_NONE 0 ++#define DDB_TUNER_DVBS_ST 1 ++#define DDB_TUNER_DVBS_ST_AA 2 ++#define DDB_TUNER_DVBCT_TR 3 ++#define DDB_TUNER_DVBCT_ST 4 ++#define DDB_CI_INTERNAL 5 ++#define DDB_CI_EXTERNAL_SONY 6 ++#define DDB_TUNER_DVBCT2_SONY_P 7 +#define DDB_TUNER_DVBC2T2_SONY_P 8 -+#define DDB_TUNER_ISDBT_SONY_P 9 -+ ++#define DDB_TUNER_ISDBT_SONY_P 9 ++#define DDB_TUNER_DVBS_STV0910_P 10 ++#define DDB_TUNER_MXL5XX 11 + +#define DDB_TUNER_XO2 16 +#define DDB_TUNER_DVBS_STV0910 16 +#define DDB_TUNER_DVBCT2_SONY 17 @@ -30027,7 +30436,7 @@ index 8b1b41d..46b30b0 100644 +#define DDB_TUNER_DVBC2T2_SONY 19 +#define DDB_TUNER_ATSC_ST 20 +#define DDB_TUNER_DVBC2T2_ST 21 - ++ + u32 adr; struct ddb_input *input[2]; struct ddb_output *output; @@ -30082,7 +30491,7 @@ index 8b1b41d..46b30b0 100644 +#define CM_STARTUP 1 +#define CM_ADJUST 2 + -+#define TS_CAPTURE_LEN (21*188) ++#define TS_CAPTURE_LEN (4096) + +/* net streaming hardware block */ + @@ -30146,6 +30555,8 @@ index 8b1b41d..46b30b0 100644 + struct mod_state mod[10]; + + struct mutex octonet_i2c_lock; ++ struct mutex lnb_lock; ++ u32 lnb_tone; }; + @@ -30255,15 +30666,15 @@ index 8b1b41d..46b30b0 100644 + +int ddbridge_flashread(struct ddb *dev, u8 *buf, u32 addr, u32 len); + -+#define DDBRIDGE_VERSION "0.9.14" ++#define DDBRIDGE_VERSION "0.9.15" + #endif diff --git a/drivers/media/pci/ddbridge/octonet.c b/drivers/media/pci/ddbridge/octonet.c new file mode 100644 -index 0000000..e6c9b92 +index 0000000..e803e73 --- /dev/null +++ b/drivers/media/pci/ddbridge/octonet.c -@@ -0,0 +1,191 @@ +@@ -0,0 +1,199 @@ +/* + * octonet.c: Digital Devices network tuner driver + * @@ -30308,6 +30719,7 @@ index 0000000..e6c9b92 + .port_num = 4, + .i2c_num = 4, + .ns_num = 12, ++ .mdio_num = 1, +}; + +static void octonet_unmap(struct ddb *dev) @@ -30320,9 +30732,9 @@ index 0000000..e6c9b92 +static int __exit octonet_remove(struct platform_device *pdev) +{ + struct ddb *dev; -+ ++ + dev = platform_get_drvdata(pdev); -+ ++ + ddb_nsd_detach(dev); + ddb_ports_detach(dev); + ddb_i2c_release(dev); @@ -30342,6 +30754,7 @@ index 0000000..e6c9b92 +{ + struct ddb *dev; + struct resource *regs; ++ int i; + + dev = vzalloc(sizeof(struct ddb)); + if (!dev) @@ -30377,12 +30790,18 @@ index 0000000..e6c9b92 + pr_info("HW %08x REGMAP %08x\n", dev->ids.hwid, dev->ids.regmapid); + pr_info("MAC %08x DEVID %08x\n", dev->ids.mac, dev->ids.devid); + ++ ddbwritel(dev, 0, ETHER_CONTROL); + ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE); -+ ++ ddbwritel(dev, 0xffffffff, INTERRUPT_STATUS); ++ for (i = 0; i < 16; i++) ++ ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i)); ++ usleep_range(5000, 6000); ++ + if (request_irq(platform_get_irq(dev->pfdev, 0), irq_handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "octonet-dvb", (void *) dev) < 0) + goto fail; ++ + ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); + ddbwritel(dev, 0x1, ETHER_CONTROL); + ddbwritel(dev, 14 + (vlan ? 4 : 0), ETHER_LENGTH); @@ -30452,14 +30871,14 @@ index 0000000..e6c9b92 +module_exit(exit_octonet); + +MODULE_DESCRIPTION("GPL"); -+MODULE_AUTHOR("Ralph Metzler, Metzler Brothers Systementwicklung"); ++MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.5"); diff --git a/drivers/media/pci/ngene/Kconfig b/drivers/media/pci/ngene/Kconfig -index 637d506..c6577e7 100644 +index 637d506..3896c12 100644 --- a/drivers/media/pci/ngene/Kconfig +++ b/drivers/media/pci/ngene/Kconfig -@@ -1,12 +1,15 @@ +@@ -1,12 +1,16 @@ config DVB_NGENE tristate "Micronas nGene support" depends on DVB_CORE && PCI && I2C @@ -30472,6 +30891,7 @@ index 637d506..c6577e7 100644 select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT + select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT ---help--- Support for Micronas PCI express cards with nGene bridge. @@ -30844,10 +31264,10 @@ index 0000000..a86459e +}; +#endif diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c -index 9e82d21..c9b1bd4 100644 +index 9e82d21..a8a1a03 100644 --- a/drivers/media/pci/ngene/ngene-cards.c +++ b/drivers/media/pci/ngene/ngene-cards.c -@@ -42,8 +42,8 @@ +@@ -42,8 +42,18 @@ #include "mt2131.h" #include "tda18271c2dd.h" #include "drxk.h" @@ -30855,10 +31275,20 @@ index 9e82d21..c9b1bd4 100644 -#include "dvb-pll.h" +#include "tda18212dd.h" +#include "stv0367dd.h" ++#include "cxd2843.h" ++ ++ ++enum DEMOD_TYPE { ++ DMD_NONE = 0, ++ DMD_STV0900, ++ DMD_DRXK, ++ DMD_STV0367, ++ DMD_CXD28xx, ++}; /****************************************************************************/ -@@ -86,8 +86,98 @@ static int tuner_attach_stv6110(struct ngene_channel *chan) +@@ -86,8 +96,98 @@ static int tuner_attach_stv6110(struct ngene_channel *chan) return 0; } @@ -30958,7 +31388,7 @@ index 9e82d21..c9b1bd4 100644 { struct ngene_channel *chan = fe->sec_priv; int status; -@@ -121,12 +211,29 @@ static int tuner_attach_tda18271(struct ngene_channel *chan) +@@ -121,12 +221,41 @@ static int tuner_attach_tda18271(struct ngene_channel *chan) return 0; } @@ -30966,10 +31396,12 @@ index 9e82d21..c9b1bd4 100644 +{ + struct i2c_adapter *i2c; + struct dvb_frontend *fe; ++ u8 addr = (chan->number & 1) ? 0x63 : 0x60; + ++ if (chan->demod_type == DMD_CXD28xx && chan->number < 2) ++ addr ^= 0x04; + i2c = &chan->dev->channel[0].i2c_adapter; -+ fe = dvb_attach(tda18212dd_attach, chan->fe, i2c, -+ (chan->number & 1) ? 0x63 : 0x60); ++ fe = dvb_attach(tda18212dd_attach, chan->fe, i2c, addr); + if (!fe) { + printk(KERN_ERR "No TDA18212 found!\n"); + return -ENODEV; @@ -30979,16 +31411,71 @@ index 9e82d21..c9b1bd4 100644 + static int tuner_attach_probe(struct ngene_channel *chan) { - if (chan->demod_type == 0) +- if (chan->demod_type == 0) ++ switch(chan->demod_type) ++ { ++ case DMD_STV0900: return tuner_attach_stv6110(chan); - if (chan->demod_type == 1) +- if (chan->demod_type == 1) ++ ++ case DMD_DRXK: return tuner_attach_tda18271(chan); -+ if (chan->demod_type == 2) ++ ++ case DMD_STV0367: ++ case DMD_CXD28xx: + return tuner_attach_tda18212dd(chan); ++ ++ default: ++ pr_err("Unknown demod %x\n", chan->demod_type); ++ break; ++ } return -EINVAL; } -@@ -218,18 +325,51 @@ static int demod_attach_drxk(struct ngene_channel *chan, +@@ -184,6 +313,26 @@ static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) + return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; + } + ++static int i2c_read_regs(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 *val, u8 len) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, ++ u8 reg, u8 *val) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1} }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ + static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, + u16 reg, u8 *val) + { +@@ -195,6 +344,15 @@ static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, + return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; + } + ++static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr, ++ u8 reg, u8 val) ++{ ++ u8 msg[2] = {reg, val}; ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2 } }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ + static int port_has_stv0900(struct i2c_adapter *i2c, int port) + { + u8 val; +@@ -218,18 +376,154 @@ static int demod_attach_drxk(struct ngene_channel *chan, struct drxk_config config; memset(&config, 0, sizeof(config)); @@ -31039,21 +31526,177 @@ index 9e82d21..c9b1bd4 100644 + } + chan->fe->sec_priv = chan; + chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; ++ chan->fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++static int port_has_xo2(struct i2c_adapter *i2c, int port, u8 *id) ++{ ++ u8 addr = (port < 2) ? 0x14 : 0x10; ++ u8 val; ++ u8 probe[1] = { 0x00 }, data[4]; ++ struct i2c_msg msgs[2] = {{ .addr = addr, .flags = 0, ++ .buf = probe, .len = 1 }, ++ { .addr = addr, .flags = I2C_M_RD, ++ .buf = data, .len = 4 } }; ++#if 0 ++ u8 cfg[] = { 0x79, 0x00, 0x00 }; ++ struct i2c_msg cmsg = { .addr = 0x44, .flags = 0, ++ .buf = cfg, .len = 3 }; ++ if (port == 0) ++ i2c_transfer(i2c, &cmsg, 1); ++ pr_info("chan %d addr %x\n", port, addr); ++ msleep(1000); ++#endif ++ val = i2c_transfer(i2c, msgs, 2); ++ if (val != 2) ++ return 0; ++ ++ if (data[0] != 'D' || data[1] != 'F') ++ return 0; ++ ++ *id = data[2]; ++ return 1; ++} ++ ++static int init_xo2(struct i2c_adapter *i2c, int port) ++{ ++ u8 addr = (port < 2) ? 0x14 : 0x10; ++ u8 val, data[2]; ++ int res; ++ ++ if (port & 1) ++ return 0; ++ ++ res = i2c_read_regs(i2c, addr, 0x04, data, 2); ++ if (res < 0) ++ return res; ++ ++ if (data[0] != 0x01) { ++ pr_info("Invalid XO2\n"); ++ return -1; ++ } ++ ++ i2c_read_reg(i2c, addr, 0x08, &val); ++ if (val != 0) { ++ i2c_write_reg(i2c, addr, 0x08, 0x00); ++ msleep(100); ++ } ++ /* Enable tuner power, disable pll, reset demods */ ++ i2c_write_reg(i2c, addr, 0x08, 0x04); ++ usleep_range(2000, 3000); ++ /* Release demod resets */ ++ i2c_write_reg(i2c, addr, 0x08, 0x07); ++ usleep_range(2000, 3000); ++ /* Start XO2 PLL */ ++ i2c_write_reg(i2c, addr, 0x08, 0x87); ++ ++ return 0; ++} ++ ++#define DDB_TUNER_XO2 16 ++#define DDB_TUNER_DVBS_STV0910 16 ++#define DDB_TUNER_DVBCT2_SONY 17 ++#define DDB_TUNER_ISDBT_SONY 18 ++#define DDB_TUNER_DVBC2T2_SONY 19 ++#define DDB_TUNER_ATSC_ST 20 ++#define DDB_TUNER_DVBC2T2_ST 21 ++ ++static char *xo2names[] = { ++ "DUAL DVB-S2", ++ "DUAL DVB-C/T/T2", ++ "DUAL DVB-ISDBT", ++ "DUAL DVB-C/C2/T/T2", ++ "DUAL ATSC", ++ "DUAL DVB-C/C2/T/T2", ++ "", "" ++}; ++ ++struct cxd2843_cfg cxd2843[] = { ++ { .adr = 0x68, }, ++ { .adr = 0x69, }, ++ { .adr = 0x6c, }, ++ { .adr = 0x6d, }, ++}; ++ ++static int demod_attach_cxd2843(struct ngene_channel *chan, ++ struct i2c_adapter *i2c) ++{ ++ chan->fe = dvb_attach(cxd2843_attach, i2c, cxd2843+chan->number); ++ if (!chan->fe) { ++ pr_err("No cxd2837/38/43 found!\n"); ++ return -ENODEV; ++ } ++ chan->fe->sec_priv = chan; ++ chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; + chan->fe->ops.i2c_gate_ctrl = locked_gate_ctrl; return 0; } -@@ -279,6 +419,9 @@ static int cineS2_probe(struct ngene_channel *chan) +@@ -240,6 +534,7 @@ static int cineS2_probe(struct ngene_channel *chan) + u8 buf[3]; + struct i2c_msg i2c_msg = { .flags = 0, .buf = buf }; + int rc; ++ u8 id; + + /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ + if (chan->number < 2) +@@ -247,8 +542,33 @@ static int cineS2_probe(struct ngene_channel *chan) + else + i2c = &chan->dev->channel[1].i2c_adapter; + +- if (port_has_stv0900(i2c, chan->number)) { +- chan->demod_type = 0; ++ if (port_has_xo2(i2c, chan->number, &id)) { ++ id >>= 2; ++ if (id > 5) { ++ pr_info("Channel %d: Unknown XO2 DuoFlex %u\n", ++ chan->number, id); ++ return -ENODEV; ++ } ++ init_xo2(i2c, chan->number); ++ switch(DDB_TUNER_XO2 + id) ++ { ++ case DDB_TUNER_DVBCT2_SONY: ++ case DDB_TUNER_ISDBT_SONY: ++ case DDB_TUNER_DVBC2T2_SONY: ++ chan->demod_type = DMD_CXD28xx; ++ pr_info("Channel %d: %s\n", chan->number, xo2names[id]); ++ demod_attach_cxd2843(chan, i2c); ++ break; ++ default: ++ pr_info("Channel %d: %s not supported yet\n", ++ chan->number, xo2names[id]); ++ return -ENODEV; ++ } ++ ++ } else if (chan->dev->channel[0].demod_type != DMD_CXD28xx && ++ port_has_stv0900(i2c, chan->number)) { ++ chan->demod_type = DMD_STV0900; ++ pr_info("Channel %d: STV0900\n", chan->number); + fe_conf = chan->dev->card_info->fe_config[chan->number]; + /* demod found, attach it */ + rc = demod_attach_stv0900(chan); +@@ -276,9 +596,17 @@ static int cineS2_probe(struct ngene_channel *chan) + printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n"); + return -EIO; + } ++ } else if (port_has_drxk(i2c, chan->number^2)) { - chan->demod_type = 1; +- chan->demod_type = 1; ++ chan->demod_type = DMD_DRXK; ++ pr_info("Channel %d: DRXK\n", chan->number); demod_attach_drxk(chan, i2c); ++ + } else if (port_has_stv0367(i2c, chan->number)) { -+ chan->demod_type = 2; ++ chan->demod_type = DMD_STV0367; ++ pr_info("Channel %d: STV0367\n", chan->number); + demod_attach_stv0367dd(chan, i2c); ++ } else { printk(KERN_ERR "No demod found on chan %d\n", chan->number); return -ENODEV; -@@ -315,249 +458,140 @@ static int demod_attach_lg330x(struct ngene_channel *chan) +@@ -315,249 +643,140 @@ static int demod_attach_lg330x(struct ngene_channel *chan) return (chan->fe) ? 0 : -ENODEV; } @@ -31102,8 +31745,7 @@ index 9e82d21..c9b1bd4 100644 - -#define MICNG_EE_START 0x0100 -#define MICNG_EE_END 0x0FF0 -+/* Viper expander: sw11,sw12,sw21,sw22,i2csw1,i2csw2,tsen1,tsen2 */ - +- -#define MICNG_EETAG_END0 0x0000 -#define MICNG_EETAG_END1 0xFFFF - @@ -31118,7 +31760,8 @@ index 9e82d21..c9b1bd4 100644 - -#define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */ -#define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */ -- ++/* Viper expander: sw11,sw12,sw21,sw22,i2csw1,i2csw2,tsen1,tsen2 */ + -/* Tag range for OEMs */ +static int exp_set(struct ngene *dev) +{ @@ -31400,7 +32043,7 @@ index 9e82d21..c9b1bd4 100644 static struct stv090x_config fe_cineS2 = { .device = STV0900, -@@ -705,14 +739,18 @@ static struct ngene_info ngene_info_m780 = { +@@ -705,14 +924,18 @@ static struct ngene_info ngene_info_m780 = { .fw_version = 15, }; @@ -31420,7 +32063,7 @@ index 9e82d21..c9b1bd4 100644 .osc_deviation = osc_deviation, }; -@@ -722,8 +760,9 @@ static struct drxd_config fe_terratec_dvbt_1 = { +@@ -722,8 +945,9 @@ static struct drxd_config fe_terratec_dvbt_1 = { .demod_revision = 0xa2, .demoda_address = 0x00, .pll_address = 0x60, @@ -31431,7 +32074,7 @@ index 9e82d21..c9b1bd4 100644 .osc_deviation = osc_deviation, }; -@@ -732,13 +771,293 @@ static struct ngene_info ngene_info_terratec = { +@@ -732,13 +956,293 @@ static struct ngene_info ngene_info_terratec = { .name = "Terratec Integra/Cinergy2400i Dual DVB-T", .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, .demod_attach = {demod_attach_drxd, demod_attach_drxd}, @@ -31726,7 +32369,7 @@ index 9e82d21..c9b1bd4 100644 /****************************************************************************/ -@@ -753,6 +1072,8 @@ static struct ngene_info ngene_info_terratec = { +@@ -753,6 +1257,8 @@ static struct ngene_info ngene_info_terratec = { /****************************************************************************/ static const struct pci_device_id ngene_id_tbl[] = { @@ -31735,7 +32378,7 @@ index 9e82d21..c9b1bd4 100644 NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2), NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2), NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), -@@ -761,7 +1082,32 @@ static const struct pci_device_id ngene_id_tbl[] = { +@@ -761,7 +1267,32 @@ static const struct pci_device_id ngene_id_tbl[] = { NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex), NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex), NGENE_ID(0x1461, 0x062e, ngene_info_m780), @@ -31768,7 +32411,7 @@ index 9e82d21..c9b1bd4 100644 {0} }; MODULE_DEVICE_TABLE(pci, ngene_id_tbl); -@@ -798,7 +1144,7 @@ static void ngene_resume(struct pci_dev *dev) +@@ -798,7 +1329,7 @@ static void ngene_resume(struct pci_dev *dev) printk(KERN_INFO DEVICE_NAME ": resume\n"); }