1
0
mirror of https://github.com/DigitalDevices/dddvb.git synced 2023-10-10 13:37:43 +02:00

adjust to latest MCI upstream drivers

This commit is contained in:
Ralph Metzler 2018-06-23 16:52:22 +02:00
parent 4b68bcad91
commit 32f46389be
6 changed files with 632 additions and 125 deletions

View File

@ -27,24 +27,376 @@
#include "ddbridge-mci.h" #include "ddbridge-mci.h"
struct m4_base { struct m4_base {
struct mci_base mci_base; struct mci_base mci_base;
}; };
struct m4 { struct m4 {
struct mci mci; struct mci mci;
int started;
int t2_signalling_valid;
int iq_constellation_point;
int iq_constellation_point_max;
int iq_constellation_tap;
int first_time_lock;
}; };
static int stop(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
struct mci_command cmd;
struct mci_base *mci_base = state->mci.base;
if (!state->started)
return -1;
state->started = 0;
state->t2_signalling_valid = 0;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_STOP;
cmd.demod = state->mci.demod;
ddb_mci_cmd(&state->mci, &cmd, NULL);
return 0;
}
static int search_s2(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
struct mci_base *mci_base = state->mci.base;
struct m4_base *m4_base = (struct m4_base *) mci_base;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct mci_command cmd;
int stat;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_SEARCH_DVBS;
cmd.dvbs2_search.flags = 3;
cmd.dvbs2_search.s2_modulation_mask = 3;
cmd.dvbs2_search.retry = 2;
cmd.dvbs2_search.frequency = p->frequency * 1000;
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
cmd.dvbs2_search.scrambling_sequence_index = 0; //p->scrambling_sequence_index;
cmd.dvbs2_search.input_stream_id = p->stream_id;
cmd.tuner = state->mci.nr;
cmd.demod = state->mci.tuner;
cmd.output = state->mci.nr;
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
if (stat)
stop(fe);
return stat;
}
static int search_c(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
struct mci_base *mci_base = state->mci.base;
struct m4_base *m4_base = (struct m4_base *) mci_base;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct mci_command cmd;
int stat;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_SEARCH_DVBC;
switch (p->bandwidth_hz) {
case 6000000:
cmd.dvbc_search.bandwidth = MCI_BANDWIDTH_6MHZ;
break;
case 7000000:
cmd.dvbc_search.bandwidth = MCI_BANDWIDTH_7MHZ;
break;
default:
cmd.dvbc_search.bandwidth = MCI_BANDWIDTH_8MHZ;
break;
}
cmd.dvbc_search.retry = 2;
cmd.dvbc_search.frequency = p->frequency;
cmd.tuner = state->mci.tuner;
cmd.demod = state->mci.demod;
cmd.output = state->mci.nr;
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
if (stat)
stop(fe);
return stat;
}
static int search_t(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
struct mci_base *mci_base = state->mci.base;
struct m4_base *m4_base = (struct m4_base *) mci_base;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct mci_command cmd;
int stat;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_SEARCH_DVBT;
switch (p->bandwidth_hz) {
case 5000000:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_5MHZ;
break;
case 6000000:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_6MHZ;
break;
case 7000000:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_7MHZ;
break;
default:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_8MHZ;
break;
}
cmd.dvbt_search.retry = 2;
cmd.dvbt_search.frequency = p->frequency;
cmd.tuner = state->mci.tuner;
cmd.demod = state->mci.demod;
cmd.output = state->mci.nr;
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
if (stat)
stop(fe);
return stat;
}
static int search_t2(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
struct mci_base *mci_base = state->mci.base;
struct m4_base *m4_base = (struct m4_base *) mci_base;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct mci_command cmd;
int stat;
u32 flags = 0;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_SEARCH_DVBT2;
switch (p->bandwidth_hz) {
case 1700000:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_1_7MHZ;
break;
case 5000000:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_5MHZ;
break;
case 6000000:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_6MHZ;
break;
case 7000000:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_7MHZ;
break;
default:
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_8MHZ;
break;
}
cmd.dvbt2_search.retry = 2;
cmd.dvbt2_search.frequency = p->frequency;
if (p->stream_id != NO_STREAM_ID_FILTER) {
cmd.dvbt2_search.plp = p->stream_id & 0xff;
cmd.dvbt2_search.flags |= 0x80;
cmd.dvbt2_search.flags |= (p->stream_id >> 8) & 1;
}
cmd.tuner = state->mci.tuner;
cmd.demod = state->mci.demod;
cmd.output = state->mci.nr;
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
if (stat)
stop(fe);
return stat;
}
static int search_c2(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
struct mci_base *mci_base = state->mci.base;
struct m4_base *m4_base = (struct m4_base *) mci_base;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct mci_command cmd;
int stat;
u32 flags = 0;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_SEARCH_DVBC2;
switch (p->bandwidth_hz) {
case 6000000:
cmd.dvbc2_search.bandwidth = MCI_BANDWIDTH_6MHZ;
break;
default:
cmd.dvbc2_search.bandwidth = MCI_BANDWIDTH_8MHZ;
break;
}
cmd.dvbc2_search.retry = 2;
cmd.dvbc2_search.frequency = p->frequency;
if (p->stream_id != NO_STREAM_ID_FILTER) {
cmd.dvbc2_search.plp = p->stream_id & 0xff;
cmd.dvbc2_search.data_slice = (p->stream_id >> 8) & 0xff;
}
cmd.tuner = state->mci.tuner;
cmd.demod = state->mci.demod;
cmd.output = state->mci.nr;
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
if (stat)
stop(fe);
return stat;
}
static int search_isdbt(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
struct mci_base *mci_base = state->mci.base;
struct m4_base *m4_base = (struct m4_base *) mci_base;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct mci_command cmd;
int stat;
u32 flags = 0;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_SEARCH_ISDBT;
switch (p->bandwidth_hz) {
case 8000000:
cmd.isdbt_search.bandwidth = MCI_BANDWIDTH_8MHZ;
break;
case 7000000:
cmd.isdbt_search.bandwidth = MCI_BANDWIDTH_7MHZ;
break;
default:
cmd.isdbt_search.bandwidth = MCI_BANDWIDTH_6MHZ;
break;
}
cmd.isdbt_search.retry = 2;
cmd.isdbt_search.frequency = p->frequency;
cmd.tuner = state->mci.tuner;
cmd.demod = state->mci.demod;
cmd.output = state->mci.nr;
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
if (stat)
stop(fe);
return stat;
}
static int set_parameters(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
int res;
stop(fe);
state->t2_signalling_valid = 0;
state->iq_constellation_point = 0;
state->iq_constellation_point_max = 0;
state->iq_constellation_tap = 0;
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBS:
case SYS_DVBS2:
res = search_s2(fe);
break;
case SYS_DVBC_ANNEX_A:
res = search_c(fe);
break;
case SYS_DVBT:
state->iq_constellation_tap = 5;
res = search_t(fe);
break;
case SYS_DVBT2:
res = search_t2(fe);
break;
case SYS_DVBC2:
res = search_c2(fe);
break;
case SYS_ISDBT:
res = search_isdbt(fe);
break;
default:
return -EINVAL;
}
if (!res) {
state->started = 1;
state->first_time_lock = 1;
}
return res;
}
static int read_status(struct dvb_frontend *fe, enum fe_status *status)
{
int stat;
struct m4 *state = fe->demodulator_priv;
struct mci_result res;
stat = ddb_mci_get_status(&state->mci, &res);
if (stat)
return stat;
*status = 0x00;
ddb_mci_get_info(&state->mci);
ddb_mci_get_strength(fe);
if (res.status == M4_DEMOD_WAIT_SIGNAL)
*status = 0x01;
if (res.status == M4_DEMOD_LOCKED) {
*status = 0x1f;
ddb_mci_get_snr(fe);
}
return stat;
}
static int tune(struct dvb_frontend *fe, bool re_tune,
unsigned int mode_flags,
unsigned int *delay, enum fe_status *status)
{
int r;
if (re_tune) {
r = set_parameters(fe);
if (r)
return r;
}
r = read_status(fe, status);
if (r)
return r;
if (*status & FE_HAS_LOCK)
return 0;
*delay = HZ / 10;
return 0;
}
static int sleep(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
if (state->started)
stop(fe);
return 0;
}
static void release(struct dvb_frontend *fe)
{
struct m4 *state = fe->demodulator_priv;
struct mci_base *mci_base = state->mci.base;
mci_base->count--;
if (mci_base->count == 0) {
list_del(&mci_base->mci_list);
kfree(mci_base);
}
kfree(state);
}
static int get_algo(struct dvb_frontend *fe)
{
return DVBFE_ALGO_HW;
}
static struct dvb_frontend_ops m4_ops = { static struct dvb_frontend_ops m4_ops = {
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2, SYS_DVBC2, SYS_ISDBT, .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2, SYS_DVBC2, SYS_ISDBT,
SYS_DVBS, SYS_DVBS2, }, SYS_DVBS, SYS_DVBS2, },
.info = { .info = {
.name = "M4", .name = "M4",
.frequency_min = 47000000, /* DVB-T: 47125000 */ .frequency_min = 950000, /* DVB-T: 47125000 */
.frequency_max = 865000000, /* DVB-C: 862000000 */ .frequency_max = 865000000, /* DVB-C: 862000000 */
.symbol_rate_min = 870000, .symbol_rate_min = 100000,
.symbol_rate_max = 11700000, .symbol_rate_max = 100000000,
.frequency_stepsize = 0, .frequency_stepsize = 0,
.frequency_tolerance = 0, .frequency_tolerance = 0,
.caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | .caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
@ -57,14 +409,11 @@ static struct dvb_frontend_ops m4_ops = {
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
}, },
#if 0
.get_frontend_algo = get_algo,
.tune = tune,
.release = release, .release = release,
.get_frontend_algo = get_algo,
.read_status = read_status, .read_status = read_status,
.set_input = set_input, .tune = tune,
.sleep = sleep, .sleep = sleep,
#endif
}; };
static int init(struct mci *mci) static int init(struct mci *mci)

View File

@ -60,6 +60,24 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
return 0; return 0;
} }
static int max_set_input_unlocked(struct dvb_frontend *fe, int in);
static int max_emulate_switch(struct dvb_frontend *fe,
u8 *cmd, u32 len)
{
int input;
if (len !=4)
return -1;
if ((cmd[0] != 0xe0) || (cmd[1] != 0x10) || (cmd[2] != 0x39))
return -1;
input = cmd[3] & 3;
max_set_input_unlocked(fe, input);
return 0;
}
static int max_send_master_cmd(struct dvb_frontend *fe, static int max_send_master_cmd(struct dvb_frontend *fe,
struct dvb_diseqc_master_cmd *cmd) struct dvb_diseqc_master_cmd *cmd)
{ {
@ -73,6 +91,10 @@ static int max_send_master_cmd(struct dvb_frontend *fe,
if (fmode == 2 || fmode == 1) if (fmode == 2 || fmode == 1)
return 0; return 0;
if (fmode == 4)
max_emulate_switch(fe, cmd->msg, cmd->msg_len);
if (dvb->diseqc_send_master_cmd) if (dvb->diseqc_send_master_cmd)
dvb->diseqc_send_master_cmd(fe, cmd); dvb->diseqc_send_master_cmd(fe, cmd);
@ -181,7 +203,8 @@ static int max_set_input_unlocked(struct dvb_frontend *fe, int in)
dvb->input = in; dvb->input = in;
dev->link[port->lnr].lnb.voltage[dvb->input] |= obit; dev->link[port->lnr].lnb.voltage[dvb->input] |= obit;
} }
res = dvb->set_input(fe, in); if (dvb->set_input)
res = dvb->set_input(fe, in);
return res; return res;
} }
@ -416,7 +439,7 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input)
demod = input->nr; demod = input->nr;
tuner = demod & 3; tuner = demod & 3;
if (fmode == 3) if (fmode >= 3)
tuner = 0; tuner = 0;
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner); dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner);
if (!dvb->fe) { if (!dvb->fe) {
@ -456,16 +479,18 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
struct ddb_link *link = &dev->link[port->lnr]; struct ddb_link *link = &dev->link[port->lnr];
int demod, tuner; int demod, tuner;
struct mci_cfg cfg; struct mci_cfg cfg;
int fm = fmode;
demod = input->nr; demod = input->nr;
tuner = demod & 3; tuner = demod & 3;
switch (type) { switch (type) {
case DDB_TUNER_MCI_SX8: case DDB_TUNER_MCI_SX8:
cfg = ddb_max_sx8_cfg; cfg = ddb_max_sx8_cfg;
if (fmode == 3) if (fm >= 3)
tuner = 0; tuner = 0;
break; break;
case DDB_TUNER_MCI_M4: case DDB_TUNER_MCI_M4:
fm = 0;
cfg = ddb_max_m4_cfg; cfg = ddb_max_m4_cfg;
break; break;
default: default:
@ -480,7 +505,7 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT); lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF); lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
} }
ddb_lnb_init_fmode(dev, link, fmode); ddb_lnb_init_fmode(dev, link, fm);
dvb->fe->ops.set_voltage = max_set_voltage; dvb->fe->ops.set_voltage = max_set_voltage;
dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage; dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage;
@ -494,4 +519,3 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
dvb->input = tuner; dvb->input = tuner;
return 0; return 0;
} }

View File

@ -149,6 +149,52 @@ static int ddb_mci_get_iq(struct mci *mci, u32 demod, s16 *i, s16 *q)
return stat; return stat;
} }
int ddb_mci_get_status(struct mci *mci, struct mci_result *res)
{
struct mci_command cmd;
cmd.command = MCI_CMD_GETSTATUS;
cmd.demod = mci->demod;
return ddb_mci_cmd_raw(mci, &cmd, 1, res, 1);
}
int ddb_mci_get_snr(struct dvb_frontend *fe)
{
struct mci *mci = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
p->cnr.len = 1;
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
p->cnr.stat[0].svalue = (s64) mci->
signal_info.dvbs2_signal_info.signal_to_noise * 10;
return 0;
}
int ddb_mci_get_strength(struct dvb_frontend *fe)
{
struct mci *mci = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
s32 str;
str = mci->signal_info.dvbs2_signal_info.channel_power * 10;
p->strength.len = 1;
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
p->strength.stat[0].svalue = str;
return 0;
}
int ddb_mci_get_info(struct mci *mci)
{
int stat;
struct mci_command cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_GETSIGNALINFO;
cmd.demod = mci->demod;
stat = ddb_mci_cmd(mci, &cmd, &mci->signal_info);
return stat;
}
static void mci_handler(void *priv) static void mci_handler(void *priv)
{ {
struct mci_base *base = (struct mci_base *)priv; struct mci_base *base = (struct mci_base *)priv;

View File

@ -97,8 +97,6 @@
#define SX8_DEMOD_IQ_MODE (1) #define SX8_DEMOD_IQ_MODE (1)
#define SX8_DEMOD_WAIT_SIGNAL (2) #define SX8_DEMOD_WAIT_SIGNAL (2)
#define SX8_DEMOD_WAIT_MATYPE (3) #define SX8_DEMOD_WAIT_MATYPE (3)
#define SX8_DEMOD_WAIT_FEC (4)
#define SX8_DEMOD_WAIT_FEC_S1 (5)
#define SX8_DEMOD_TIMEOUT (14) #define SX8_DEMOD_TIMEOUT (14)
#define SX8_DEMOD_LOCKED (15) #define SX8_DEMOD_LOCKED (15)
@ -116,19 +114,24 @@
#define MCI_CMD_SEARCH_DVBC (0x20) #define MCI_CMD_SEARCH_DVBC (0x20)
#define MCI_CMD_SEARCH_DVBT (0x21) #define MCI_CMD_SEARCH_DVBT (0x21)
#define MCI_CMD_SEARCH_DVBT2 (0x22) #define MCI_CMD_SEARCH_DVBT2 (0x22)
#define MCI_CMD_SEARCH_DVBC2 (0x23)
#define MCI_CMD_SEARCH_ISDBT (0x24)
#define MCI_CMD_GET_IQSYMBOL (0x30) #define MCI_CMD_GET_IQSYMBOL (0x30)
#define MCI_BANDWIDTH_1_7MHZ (0) #define MCI_BANDWIDTH_UNKNOWN (0)
#define MCI_BANDWIDTH_5MHZ (1) #define MCI_BANDWIDTH_1_7MHZ (1)
#define MCI_BANDWIDTH_6MHZ (2) #define MCI_BANDWIDTH_5MHZ (5)
#define MCI_BANDWIDTH_7MHZ (3) #define MCI_BANDWIDTH_6MHZ (6)
#define MCI_BANDWIDTH_8MHZ (4) #define MCI_BANDWIDTH_7MHZ (7)
#define MCI_BANDWIDTH_8MHZ (8)
#define M4_MODE_SX (2) #define M4_MODE_DVBSX (2)
#define M4_MODE_C (3) #define M4_MODE_DVBC (3)
#define M4_MODE_T (4) #define M4_MODE_DVBT (4)
#define M4_MODE_T2 (5) #define M4_MODE_DVBT2 (5)
#define M4_MODE_DVBC2 (6)
#define M4_MODE_ISDBT (7)
#define SX8_CMD_INPUT_ENABLE (0x40) #define SX8_CMD_INPUT_ENABLE (0x40)
#define SX8_CMD_INPUT_DISABLE (0x41) #define SX8_CMD_INPUT_DISABLE (0x41)
@ -138,6 +141,8 @@
#define SX8_CMD_DISABLE_IQOUTPUT (0x45) #define SX8_CMD_DISABLE_IQOUTPUT (0x45)
#define M4_CMD_GET_T2_L1INFO (0x50) #define M4_CMD_GET_T2_L1INFO (0x50)
#define M4_CMD_GET_C2_L1P2 (0x50)
#define M4_CMD_GET_IDS (0x51)
#define MCI_STATUS_OK (0x00) #define MCI_STATUS_OK (0x00)
#define MCI_STATUS_UNSUPPORTED (0x80) #define MCI_STATUS_UNSUPPORTED (0x80)
@ -175,52 +180,85 @@ struct mci_command {
u32 scrambling_sequence_index; u32 scrambling_sequence_index;
u32 frequency_range; u32 frequency_range;
} dvbs2_search; } dvbs2_search;
struct { struct {
uint8_t flags; u8 flags;
uint8_t bandwidth; u8 bandwidth;
uint8_t rsvd1; u8 rsvd1;
uint8_t retry; u8 retry;
uint32_t frequency; u32 frequency;
} dvbc_search; } dvbc_search;
struct { struct {
uint8_t flags; /* Bit 0: LP Stream */ u8 flags; /* Bit 0: LP Stream */
uint8_t bandwidth; u8 bandwidth;
uint8_t rsvd1; u8 rsvd1;
uint8_t retry; u8 retry;
uint32_t frequency; u32 frequency;
} dvbt_search; } dvbt_search;
struct { struct {
uint8_t flags; /* Bit 0: T2 Lite Profile, 7: PLP, */ u8 flags; /* Bit 0: T2 Lite Profile, 7: PLP, */
uint8_t bandwidth; u8 bandwidth;
uint8_t rsvd1; u8 rsvd1;
uint8_t retry; u8 retry;
uint32_t frequency; u32 frequency;
uint32_t reserved; u32 reserved;
uint8_t plp; u8 plp;
uint8_t rsvd2[3]; u8 rsvd2[3];
} dvbt2_search; } dvbt2_search;
struct { struct {
uint8_t Tap; u8 flags;
uint8_t Rsvd; u8 bandwidth;
uint16_t Point; u8 rsvd1;
u8 retry;
u32 frequency;
u32 reserved;
u8 plp;
u8 data_slice;
u8 rsvd2[2];
} dvbc2_search;
struct {
u8 flags;
u8 bandwidth;
u8 rsvd1;
u8 retry;
u32 frequency;
} isdbt_search;
struct {
u8 tap;
u8 rsvd;
u16 point;
} get_iq_symbol; } get_iq_symbol;
struct { struct {
uint8_t flags; /* Bit 0 : 0 = VTM, 1 = SCAN. Bit 1: Set Gain */ u8 flags; /* Bit 0 : 0 = VTM, 1 = SCAN. Bit 1: Set Gain */
uint8_t roll_off; u8 roll_off;
uint8_t rsvd1; u8 rsvd1;
uint8_t rsvd2; u8 rsvd2;
uint32_t frequency; u32 frequency;
uint32_t symbol_rate; /* Only in VTM mode. */ u32 symbol_rate; /* Only in VTM mode. */
uint16_t gain; u16 gain;
} sx8_start_iq; } sx8_start_iq;
struct { struct {
uint8_t flags; /* Bit 1:0 = STVVGLNA Gain. 0 = AGC, 1 = 0dB, 2 = Minimum, 3 = Maximum */ u8 flags; /* Bit 1:0 = STVVGLNA Gain. 0 = AGC, 1 = 0dB, 2 = Minimum, 3 = Maximum */
} sx8_input_enable; } sx8_input_enable;
struct {
u8 Offset; // Offset into list, must be multiple of 64
u8 Select; // 0 = Slices, 1 = PLPs (C2 Only)
u8 DataSlice; // DataSlice to get PLPList (C2 Only)
} Get_IDs;
struct {
u8 Select; // 0 = Base, 1 = DataSilce, 2 = PLP, Bit 7: Set new ID
u8 ID; // DataSliceID, PLPId
} Get_L1Info;
}; };
}; };
@ -250,6 +288,7 @@ struct mci_result {
u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */
u32 ber_denominator; u32 ber_denominator;
} dvbs2_signal_info; } dvbs2_signal_info;
struct { struct {
u8 modulation; u8 modulation;
u8 rsvd1[3]; u8 rsvd1[3];
@ -260,9 +299,10 @@ struct mci_result {
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */ s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
s16 rsvd2; s16 rsvd2;
u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */ u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */
u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ u32 ber_numerator; /* Bit error rate: PreRS */
u32 ber_denominator; u32 ber_denominator;
} dvbc_signal_info; } dvbc_signal_info;
struct { struct {
u8 tps_25_32; /* Constellation (2), Hierarchy (3), Coderate HP (3) */ u8 tps_25_32; /* Constellation (2), Hierarchy (3), Coderate HP (3) */
u8 tps_33_39; /* Coderate LP (3), Guardinterval (2), FFT (2), 0 (1) */ u8 tps_33_39; /* Coderate LP (3), Guardinterval (2), FFT (2), 0 (1) */
@ -274,9 +314,10 @@ struct mci_result {
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */ s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
s16 rsvd2; s16 rsvd2;
u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */ u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */
u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ u32 ber_numerator; /* Bit error rate: PreRS */
u32 ber_denominator; u32 ber_denominator;
} dvbt_signal_info; } dvbt_signal_info;
struct { struct {
u32 rsvd0; u32 rsvd0;
u32 frequency; /* actual frequency in Hz */ u32 frequency; /* actual frequency in Hz */
@ -286,9 +327,40 @@ struct mci_result {
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */ s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
s16 rsvd2; s16 rsvd2;
u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */ u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */
u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ u32 ber_numerator; /* Bit error rate: PreRS */
u32 ber_denominator; u32 ber_denominator;
} dvbt2_signal_info; } dvbt2_signal_info;
struct { // Work in Progress
u32 rsvd0 ; // Cell Identifier
u32 frequency; // actual frequency in Hz
u32 rsvd1; //
s16 channel_power; // channel power in dBm x 100
s16 band_power; // band power in dBm x 100
s16 signal_to_noise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2
s16 rsvd2;
u32 packet_errors; // Counter for packet errors. (set to 0 on Start command)
u32 ber_numerator; // Bit error rate: PreBCH
u32 ber_denominator;
} DVBC2_SignalInfo;
struct {
u32 rsvd0;
u32 frequency; // actual frequency in Hz
u32 rsvd1; //
s16 channel_power; // channel power in dBm x 100
s16 band_power; // band power in dBm x 100
s16 signal_to_noise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2
s16 rsvd2;
u32 packet_errors; // Counter for packet errors. (set to 0 on Start command)
u32 ber_numerator; // Bit error rate: PreRS
u32 ber_denominator;
u8 tmcc_info[13]; // TMCC B20 - B121
} isdbt_signal_info;
struct { struct {
s16 i; s16 i;
s16 q; s16 q;
@ -299,6 +371,61 @@ struct mci_result {
u8 t2_l1_post_d[19]; u8 t2_l1_post_d[19];
u8 t2_l1_post_c[19]; u8 t2_l1_post_c[19];
} dvbt2_l1_info; } dvbt2_l1_info;
struct {
u8 NetworkID[2];
u8 C2SystemID[2];
u8 StartFrequency[3];
u8 C2BandWidth[2];
u8 GuardInterval;
u8 C2FrameLength[2];
u8 L1P2ChangeCounter;
u8 NumDataSlices;
u8 NumNotches;
struct {
u8 Start[2];
u8 Width[2];
u8 Reserved3;
} NotchData[15];
u8 ReservedTone;
u8 Reserved4[2]; // EWS 1 bit, C2_Version 4 bit, Rsvd 11 bit
} DVBC2_L1Part2;
struct {
u8 NumIDs;
u8 Offset;
u8 IDs[64];
} DVBC2_IDList;
struct {
u8 SliceID;
u8 TunePosition[2];
u8 OffsetLeft[2];
u8 OffsetRight[2];
u8 TIDepth;
u8 Type;
u8 FECHeaderType;
u8 ConstConf;
u8 LeftNotch;
u8 NumPLP;
u8 Reserved2;
} DVBC2_SliceInfo;
struct {
u8 PLPID;
u8 Bundled;
u8 Type;
u8 PayloadType;
u8 GroupID;
u8 Start[2];
u8 FEC_Type;
u8 Mod;
u8 Cod;
u8 PSISIReprocessing;
u8 TransportstreamID[2];
u8 OrginalNetworkID[2];
u8 Reserved1;
} DVBC2_PLPInfo;
}; };
u32 version[4]; u32 version[4];
}; };
@ -391,11 +518,26 @@ struct mci {
int nr; int nr;
int demod; int demod;
int tuner; int tuner;
struct mci_result signal_info;
};
struct mci_cfg {
int type;
struct dvb_frontend_ops *fe_ops;
u32 base_size;
u32 state_size;
int (*init)(struct mci *mci);
int (*base_init)(struct mci_base *mci_base);
}; };
int ddb_mci_cmd(struct mci *state, struct mci_command *command, struct mci_result *result); int ddb_mci_cmd(struct mci *state, struct mci_command *command, struct mci_result *result);
int ddb_mci_cmd_raw(struct mci *state, struct mci_command *command, u32 command_len, int ddb_mci_cmd_raw(struct mci *state, struct mci_command *command, u32 command_len,
struct mci_result *result, u32 result_len); struct mci_result *result, u32 result_len);
int ddb_mci_config(struct mci *state, u32 config); int ddb_mci_config(struct mci *state, u32 config);
int ddb_mci_get_status(struct mci *mci, struct mci_result *res);
int ddb_mci_get_snr(struct dvb_frontend *fe);
int ddb_mci_get_info(struct mci *mci);
int ddb_mci_get_strength(struct dvb_frontend *fe);
#endif #endif

View File

@ -52,7 +52,6 @@ struct sx8 {
int first_time_lock; int first_time_lock;
int started; int started;
struct mci_result signal_info;
u32 bb_mode; u32 bb_mode;
u32 local_frequency; u32 local_frequency;
@ -108,64 +107,23 @@ static void release(struct dvb_frontend *fe)
kfree(state); kfree(state);
} }
static int get_info(struct dvb_frontend *fe)
{
int stat;
struct sx8 *state = fe->demodulator_priv;
struct mci_command cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.command = MCI_CMD_GETSIGNALINFO;
cmd.demod = state->mci.demod;
stat = ddb_mci_cmd(&state->mci, &cmd, &state->signal_info);
return stat;
}
static int get_snr(struct dvb_frontend *fe)
{
struct sx8 *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
p->cnr.len = 1;
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
p->cnr.stat[0].svalue = (s64) state->signal_info.dvbs2_signal_info.signal_to_noise * 10;
return 0;
}
static int get_strength(struct dvb_frontend *fe)
{
struct sx8 *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
s32 str;
str = state->signal_info.dvbs2_signal_info.channel_power * 10;
p->strength.len = 1;
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
p->strength.stat[0].svalue = str;
return 0;
}
static int read_status(struct dvb_frontend *fe, enum fe_status *status) static int read_status(struct dvb_frontend *fe, enum fe_status *status)
{ {
int stat; int stat;
struct sx8 *state = fe->demodulator_priv; struct sx8 *state = fe->demodulator_priv;
struct mci_command cmd; struct mci_result res;
u32 val;
struct mci_result *res = (struct mci_result *)&val;
cmd.command = MCI_CMD_GETSTATUS; stat = ddb_mci_get_status(&state->mci, &res);
cmd.demod = state->mci.demod;
stat = ddb_mci_cmd_raw(&state->mci, &cmd, 1, res, 1);
if (stat) if (stat)
return stat; return stat;
*status = 0x00; *status = 0x00;
get_info(fe); ddb_mci_get_info(&state->mci);
get_strength(fe); ddb_mci_get_strength(fe);
if (res->status == SX8_DEMOD_WAIT_MATYPE) if (res.status == SX8_DEMOD_WAIT_MATYPE)
*status = 0x0f; *status = 0x0f;
if (res->status == SX8_DEMOD_LOCKED) { if (res.status == SX8_DEMOD_LOCKED) {
*status = 0x1f; *status = 0x1f;
get_snr(fe); ddb_mci_get_snr(fe);
} }
return stat; return stat;
} }
@ -346,7 +304,8 @@ unlock:
} }
static int start_iq(struct dvb_frontend *fe, u32 flags, u32 roll_off, u32 ts_config) static int start_iq(struct dvb_frontend *fe, u32 flags,
u32 roll_off, u32 ts_config)
{ {
struct sx8 *state = fe->demodulator_priv; struct sx8 *state = fe->demodulator_priv;
struct mci_base *mci_base = state->mci.base; struct mci_base *mci_base = state->mci.base;
@ -408,7 +367,7 @@ static int set_parameters(struct dvb_frontend *fe)
} }
if (iq_mode) if (iq_mode)
ts_config = (SX8_TSCONFIG_TSHEADER | SX8_TSCONFIG_MODE_IQ); ts_config = (SX8_TSCONFIG_TSHEADER | SX8_TSCONFIG_MODE_IQ);
if (iq_mode < 3) { if (iq_mode < 2) {
u32 mask; u32 mask;
switch (p->modulation) { switch (p->modulation) {
@ -433,14 +392,12 @@ static int set_parameters(struct dvb_frontend *fe)
} }
stat = start(fe, 3, mask, ts_config); stat = start(fe, 3, mask, ts_config);
} else { } else {
u32 flags = (iq_mode == 2) ? 1 : 0; stat = start_iq(fe, iq_mode & 1, 4, ts_config);
stat = start_iq(fe, flags, 4, ts_config);
} }
if (!stat) { if (!stat) {
state->started = 1; state->started = 1;
state->first_time_lock = 1; state->first_time_lock = 1;
state->signal_info.status = SX8_DEMOD_WAIT_SIGNAL; state->mci.signal_info.status = SX8_DEMOD_WAIT_SIGNAL;
} }
return stat; return stat;
} }
@ -489,8 +446,6 @@ static int set_input(struct dvb_frontend *fe, int input)
static int sleep(struct dvb_frontend *fe) static int sleep(struct dvb_frontend *fe)
{ {
struct sx8 *state = fe->demodulator_priv;
stop(fe); stop(fe);
return 0; return 0;
} }

View File

@ -567,15 +567,6 @@ int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm);
struct ddb_irq *ddb_irq_set(struct ddb *dev, u32 link, u32 nr, struct ddb_irq *ddb_irq_set(struct ddb *dev, u32 link, u32 nr,
void (*handler)(void *), void *data); void (*handler)(void *), void *data);
struct mci_cfg {
int type;
struct dvb_frontend_ops *fe_ops;
u32 base_size;
u32 state_size;
int (*init)(struct mci *mci);
int (*base_init)(struct mci_base *mci_base);
};
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr, int tuner); struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr, int tuner);
#endif #endif