#include "stv0367_priv.h"
 #include "cxd2841er.h"
 #include "tda18212.h"
+#include "stv0910.h"
+#include "stv6111.h"
+#include "lnbh25.h"
 
 static int xo2_speed = 2;
 module_param(xo2_speed, int, 0444);
        return 0;
 }
 
+static struct stv0910_cfg stv0910_p = {
+       .adr      = 0x68,
+       .parallel = 1,
+       .rptlvl   = 4,
+       .clk      = 30000000,
+};
+
+static struct lnbh25_config lnbh25_cfg = {
+       .i2c_address = 0x0c << 1,
+       .data2_config = LNBH25_TEN
+};
+
+static int demod_attach_stv0910(struct ddb_input *input, int type)
+{
+       struct i2c_adapter *i2c = &input->port->i2c->adap;
+       struct device *dev = &input->port->dev->pdev->dev;
+       struct stv0910_cfg cfg = stv0910_p;
+       struct lnbh25_config lnbcfg = lnbh25_cfg;
+
+       if (type)
+               cfg.parallel = 2;
+       input->fe = dvb_attach(stv0910_attach, i2c, &cfg, (input->nr & 1));
+       if (!input->fe) {
+               cfg.adr = 0x6c;
+               input->fe = dvb_attach(stv0910_attach, i2c,
+                                       &cfg, (input->nr & 1));
+       }
+       if (!input->fe) {
+               dev_err(dev, "No STV0910 found!\n");
+               return -ENODEV;
+       }
+
+       /* attach lnbh25 - leftshift by one as the lnbh25 driver expects 8bit
+        * i2c addresses
+        */
+       lnbcfg.i2c_address = (((input->nr & 1) ? 0x0d : 0x0c) << 1);
+       if (!dvb_attach(lnbh25_attach, input->fe, &lnbcfg, i2c)) {
+               lnbcfg.i2c_address = (((input->nr & 1) ? 0x09 : 0x08) << 1);
+               if (!dvb_attach(lnbh25_attach, input->fe, &lnbcfg, i2c)) {
+                       dev_err(dev, "No LNBH25 found!\n");
+                       return -ENODEV;
+               }
+       }
+
+       return 0;
+}
+
+static int tuner_attach_stv6111(struct ddb_input *input, int type)
+{
+       struct i2c_adapter *i2c = &input->port->i2c->adap;
+       struct device *dev = &input->port->dev->pdev->dev;
+       struct dvb_frontend *fe;
+       u8 adr = (type ? 0 : 4) + ((input->nr & 1) ? 0x63 : 0x60);
+
+       fe = dvb_attach(stv6111_attach, input->fe, i2c, adr);
+       if (!fe) {
+               fe = dvb_attach(stv6111_attach, input->fe, i2c, adr & ~4);
+               if (!fe) {
+                       dev_err(dev, "No STV6111 found at 0x%02x!\n", adr);
+                       return -ENODEV;
+               }
+       }
+       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 *),
                                return -ENODEV;
                }
                break;
+       case DDB_TUNER_XO2_DVBS_STV0910:
+               if (demod_attach_stv0910(input, 0) < 0)
+                       return -ENODEV;
+               if (tuner_attach_stv6111(input, 0) < 0)
+                       return -ENODEV;
+               if (input->fe) {
+                       if (dvb_register_frontend(adap, input->fe) < 0)
+                               return -ENODEV;
+               }
+               break;
+       case DDB_TUNER_DVBS_STV0910_PR:
+               if (demod_attach_stv0910(input, 1) < 0)
+                       return -ENODEV;
+               if (tuner_attach_stv6111(input, 1) < 0)
+                       return -ENODEV;
+               if (input->fe) {
+                       if (dvb_register_frontend(adap, input->fe) < 0)
+                               return -ENODEV;
+               }
+               break;
+       case DDB_TUNER_DVBS_STV0910_P:
+               if (demod_attach_stv0910(input, 0) < 0)
+                       return -ENODEV;
+               if (tuner_attach_stv6111(input, 1) < 0)
+                       return -ENODEV;
+               if (input->fe) {
+                       if (dvb_register_frontend(adap, input->fe) < 0)
+                               return -ENODEV;
+               }
+               break;
        case DDB_TUNER_DVBCT_TR:
                if (demod_attach_drxk(input) < 0)
                        return -ENODEV;
                        init_xo2(port);
                        switch (xo2_id >> 2) {
                        case 0:
-                               modname = "DUAL DVB-S2 (unsupported)";
-                               port->class = DDB_PORT_NONE;
+                               modname = "DUAL DVB-S2";
+                               port->class = DDB_PORT_TUNER;
                                port->type = DDB_TUNER_XO2_DVBS_STV0910;
                                break;
                        case 1:
        } else if (port_has_stv0900_aa(port, &stv_id)) {
                modname = "DUAL DVB-S2";
                port->class = DDB_PORT_TUNER;
-               port->type = DDB_TUNER_DVBS_ST_AA;
+               switch (stv_id) {
+               case 0x51:
+                       if (dev->info->ts_quirks & TS_QUIRK_REVERSED &&
+                                       port->nr == 0)
+                               port->type = DDB_TUNER_DVBS_STV0910_PR;
+                       else
+                               port->type = DDB_TUNER_DVBS_STV0910_P;
+                       break;
+               default:
+                       port->type = DDB_TUNER_DVBS_ST_AA;
+                       break;
+               }
                ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING);
        } else if (port_has_drxks(port)) {
                modname = "DUAL DVB-C/T";
        .port_num = 4,
 };
 
+static const struct ddb_info ddb_v7 = {
+       .type     = DDB_OCTOPUS,
+       .name     = "Digital Devices Cine S2 V7 DVB adapter",
+       .port_num = 4,
+       .board_control   = 2,
+       .board_control_2 = 4,
+       .ts_quirks = TS_QUIRK_REVERSED,
+};
+
+static const struct ddb_info ddb_v7a = {
+       .type     = DDB_OCTOPUS,
+       .name     = "Digital Devices Cine S2 V7 Advanced DVB adapter",
+       .port_num = 4,
+       .board_control   = 2,
+       .board_control_2 = 4,
+       .ts_quirks = TS_QUIRK_REVERSED,
+};
+
 static const struct ddb_info ddb_dvbct = {
        .type     = DDB_OCTOPUS,
        .name     = "Digital Devices DVBCT V6.1 DVB adapter",
        DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini),
        DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6),
        DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5),
+       DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7),
+       DDB_ID(DDVID, 0x0006, DDVID, 0x0024, ddb_v7a),
        DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct),
        DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3),
        DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7),