diff --git a/ddbridge/ddbridge-core.c b/ddbridge/ddbridge-core.c index 2726887..0bbaa56 100644 --- a/ddbridge/ddbridge-core.c +++ b/ddbridge/ddbridge-core.c @@ -1838,6 +1838,9 @@ static int dvb_input_attach(struct ddb_input *input) break; case DDB_TUNER_MCI_SX8: case DDB_TUNER_MCI_M4: + case DDB_TUNER_MCI_M8: + case DDB_TUNER_MCI_M8A: + case DDB_TUNER_MCI_M2: if (ddb_fe_attach_mci(input, port->type) < 0) return -ENODEV; break; diff --git a/ddbridge/ddbridge-hw.c b/ddbridge/ddbridge-hw.c index c4e8291..63e2cd4 100644 --- a/ddbridge/ddbridge-hw.c +++ b/ddbridge/ddbridge-hw.c @@ -731,8 +731,48 @@ static const struct ddb_info ddb_m4 = { .i2c_mask = 0x00, .tempmon_irq = 24, .mci_ports = 2, - .mci_type = 1, + .mci_type = DDB_TUNER_MCI_M4, .temp_num = 1, + .lnb_base = 0x400, +}; + +static const struct ddb_info ddb_m8 = { + .type = DDB_OCTOPUS_MCI, + .name = "Digital Devices MAX M8", + .regmap = &octopus_mci_map, + .port_num = 4, + .i2c_mask = 0x00, + .tempmon_irq = 24, + .mci_ports = 4, + .mci_type = DDB_TUNER_MCI_M8, + .temp_num = 1, + .lnb_base = 0x400, +}; + +static const struct ddb_info ddb_m8a = { + .type = DDB_OCTOPUS_MCI, + .name = "Digital Devices MAX M8A", + .regmap = &octopus_mci_map, + .port_num = 4, + .tempmon_irq = 24, + .mci_ports = 4, + .mci_type = DDB_TUNER_MCI_M8A, + .temp_num = 1, + .lnb_base = 0x400, +}; + +static const struct ddb_info ddb_ci_m2 = { + .type = DDB_OCTOPUS_MCI, + .name = "Digital Devices Octopus CI M2", + .regmap = &octopus_mci_map, + .port_num = 4, + .tempmon_irq = 24, + .mci_ports = 1, + .mci_type = DDB_TUNER_MCI_M2, + .temp_num = 1, + .ci_mask = 0x0c, + .ci_base = 0x400, + .lnb_base = 0x480, }; /****************************************************************************/ @@ -865,7 +905,10 @@ static const struct ddb_device_id ddb_device_ids[] = { DDB_DEVID(0x0012, 0x0042, ddb_ci), DDB_DEVID(0x0013, 0x0043, ddb_ci_s2_pro), DDB_DEVID(0x0013, 0x0044, ddb_ci_s2_pro_a), + DDB_DEVID(0x0014, 0x0045, ddb_ci_m2), DDB_DEVID(0x0020, 0x0012, ddb_gtl_mini), + DDB_DEVID(0x0022, 0x0052, ddb_m8), + DDB_DEVID(0x0024, 0x0053, ddb_m8a), /* Modulators */ DDB_DEVID(0x0201, 0x0001, ddb_mod), diff --git a/ddbridge/ddbridge-m4.c b/ddbridge/ddbridge-m4.c index 74ccc77..7489540 100644 --- a/ddbridge/ddbridge-m4.c +++ b/ddbridge/ddbridge-m4.c @@ -529,7 +529,134 @@ static struct mci_cfg ddb_max_m4_cfg = { .base_init = base_init, }; -struct dvb_frontend *ddb_m4_attach(struct ddb_input *input, int nr, int tuner) +static struct dvb_frontend_ops m_ops = { + .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_C, + SYS_ISDBC, + SYS_DVBT, SYS_DVBT2, SYS_ISDBT, + SYS_DVBS, SYS_DVBS2, SYS_ISDBS, }, + .info = { + .name = "M_AS", + .frequency_min_hz = 47125000, /* DVB-T: 47125000 */ + .frequency_max_hz = 2150000000, /* DVB-C: 862000000 */ + .symbol_rate_min = 100000, + .symbol_rate_max = 100000000, + .frequency_stepsize_hz = 0, + .frequency_tolerance_hz = 0, + .caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | + FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_4_5 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION + }, + .release = release, + .get_frontend_algo = get_algo, + .get_frontend = get_frontend, + .read_status = read_status, + .tune = tune, + .sleep = sleep, +}; + +static struct mci_cfg ddb_max_m_cfg = { + .type = 0, + .fe_ops = &m_ops, + .base_size = sizeof(struct m4_base), + .state_size = sizeof(struct m4), + .init = init, + .base_init = base_init, +}; + +static struct dvb_frontend_ops m_s_ops = { + .delsys = { SYS_DVBS, SYS_DVBS2, SYS_ISDBS }, + .info = { + .name = "M_S", + .frequency_min_hz = 47125000, /* DVB-T: 47125000 */ + .frequency_max_hz = 2150000000, /* DVB-C: 862000000 */ + .symbol_rate_min = 100000, + .symbol_rate_max = 100000000, + .frequency_stepsize_hz = 0, + .frequency_tolerance_hz = 0, + .caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | + FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_4_5 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION + }, + .release = release, + .get_frontend_algo = get_algo, + .get_frontend = get_frontend, + .read_status = read_status, + .tune = tune, + .sleep = sleep, +}; + +static struct mci_cfg ddb_max_m_s_cfg = { + .type = 0, + .fe_ops = &m_s_ops, + .base_size = sizeof(struct m4_base), + .state_size = sizeof(struct m4), + .init = init, + .base_init = base_init, +}; + +static struct dvb_frontend_ops m_a_ops = { + .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_C, + SYS_ISDBC, + SYS_DVBT, SYS_DVBT2, SYS_ISDBT, + }, + .info = { + .name = "M_A", + .frequency_min_hz = 47125000, /* DVB-T: 47125000 */ + .frequency_max_hz = 2150000000, /* DVB-C: 862000000 */ + .symbol_rate_min = 100000, + .symbol_rate_max = 100000000, + .frequency_stepsize_hz = 0, + .frequency_tolerance_hz = 0, + .caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | + FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_4_5 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION + }, + .release = release, + .get_frontend_algo = get_algo, + .get_frontend = get_frontend, + .read_status = read_status, + .tune = tune, + .sleep = sleep, +}; + +static struct mci_cfg ddb_max_m_a_cfg = { + .type = 0, + .fe_ops = &m_a_ops, + .base_size = sizeof(struct m4_base), + .state_size = sizeof(struct m4), + .init = init, + .base_init = base_init, +}; + +static struct mci_cfg *ddb_max_cfgs [] = { + &ddb_max_m4_cfg, + &ddb_max_m_a_cfg, + &ddb_max_m_s_cfg, + &ddb_max_m_cfg, +}; + +struct dvb_frontend *ddb_mx_attach(struct ddb_input *input, int nr, int tuner, int type) { - return ddb_mci_attach(input, &ddb_max_m4_cfg, nr, tuner); + return ddb_mci_attach(input, ddb_max_cfgs[type], nr, tuner); } + +EXPORT_SYMBOL(ddb_mx_attach); + diff --git a/ddbridge/ddbridge-main.c b/ddbridge/ddbridge-main.c index d60c7f7..a03b58a 100644 --- a/ddbridge/ddbridge-main.c +++ b/ddbridge/ddbridge-main.c @@ -417,7 +417,10 @@ static const struct pci_device_id ddb_id_table[] __devinitconst = { DDB_DEVICE_ANY(0x0011), DDB_DEVICE_ANY(0x0012), DDB_DEVICE_ANY(0x0013), + DDB_DEVICE_ANY(0x0014), DDB_DEVICE_ANY(0x0020), + DDB_DEVICE_ANY(0x0022), + DDB_DEVICE_ANY(0x0024), DDB_DEVICE_ANY(0x0201), DDB_DEVICE_ANY(0x0203), DDB_DEVICE_ANY(0x0210), diff --git a/ddbridge/ddbridge-max.c b/ddbridge/ddbridge-max.c index dcbdea6..df72e90 100644 --- a/ddbridge/ddbridge-max.c +++ b/ddbridge/ddbridge-max.c @@ -28,6 +28,10 @@ /* MAX LNB interface related module parameters */ +static int delmode; +module_param(delmode, int, 0444); +MODULE_PARM_DESC(delmode, "frontend delivery system mode"); + static int fmode; module_param(fmode, int, 0444); MODULE_PARM_DESC(fmode, "frontend emulation mode"); @@ -505,7 +509,8 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input) /* MAX MCI related functions */ struct dvb_frontend *ddb_sx8_attach(struct ddb_input *input, int nr, int tuner, int (**fn_set_input)(struct dvb_frontend *fe, int input)); -struct dvb_frontend *ddb_m4_attach(struct ddb_input *input, int nr, int tuner); +struct dvb_frontend *ddb_mx_attach(struct ddb_input *input, int nr, int tuner, int type); + int ddb_fe_attach_mci(struct ddb_input *input, u32 type) { @@ -523,11 +528,46 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type) if (fm >= 3) tuner = 0; dvb->fe = ddb_sx8_attach(input, demod, tuner, &dvb->set_input); + dvb->input = tuner; break; case DDB_TUNER_MCI_M4: fm = 0; - dvb->fe = ddb_m4_attach(input, demod, tuner); + dvb->fe = ddb_mx_attach(input, demod, tuner, 0); + dvb->input = tuner; break; + case DDB_TUNER_MCI_M8: + fm = 3; + dvb->fe = ddb_mx_attach(input, demod, tuner, 1); + dvb->input = 0; + break; + case DDB_TUNER_MCI_M8A: + fm = 3; + dvb->fe = ddb_mx_attach(input, demod, tuner, 2); + dvb->input = 0; + break; + case DDB_TUNER_MCI_M2: + { + u32 mode, mmode; + + // delmode: 0 - sat,sat 1-cable,cable/sat + switch (delmode & 1) { + case 0: + mode = 2; + mmode = 2; + break; + case 1: + mode = 1; + mmode = demod ? 3 : 1; + break; + } + if (!demod) + ddb_mci_cmd_link_simple(link, MCI_CMD_SET_INPUT_CONFIG, + 0xff, mode | (delmode & 0x10)); + dvb->fe = ddb_mx_attach(input, demod, tuner, mmode); + dvb->input = 0; + fm = 0; + break; + } default: return -EINVAL; } @@ -535,7 +575,7 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type) dev_err(dev->dev, "No MCI card found!\n"); return -ENODEV; } - if (input->nr < 4) { + if (!input->nr || (input->nr < 4 && type != DDB_TUNER_MCI_M8)) { lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT); lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF); } @@ -548,15 +588,10 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type) dvb->fe->ops.diseqc_send_master_cmd = max_send_master_cmd; dvb->fe->ops.diseqc_send_burst = max_send_burst; dvb->fe->sec_priv = input; - switch (type) { - case DDB_TUNER_MCI_M4: - break; - default: + if (type == DDB_TUNER_MCI_SX8) { #ifndef KERNEL_DVB_CORE dvb->fe->ops.set_input = max_set_input; #endif - break; } - dvb->input = tuner; return 0; } diff --git a/ddbridge/ddbridge.h b/ddbridge/ddbridge.h index 75030f7..e9d24ba 100644 --- a/ddbridge/ddbridge.h +++ b/ddbridge/ddbridge.h @@ -321,6 +321,9 @@ struct ddb_port { #define DDB_TUNER_MCI 48 #define DDB_TUNER_MCI_SX8 (DDB_TUNER_MCI + 0) #define DDB_TUNER_MCI_M4 (DDB_TUNER_MCI + 1) +#define DDB_TUNER_MCI_M8 (DDB_TUNER_MCI + 2) +#define DDB_TUNER_MCI_M8A (DDB_TUNER_MCI + 3) +#define DDB_TUNER_MCI_M2 (DDB_TUNER_MCI + 4) struct ddb_input *input[2]; struct ddb_output *output;