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:
parent
4b68bcad91
commit
32f46389be
@ -27,24 +27,376 @@
|
||||
#include "ddbridge-mci.h"
|
||||
|
||||
struct m4_base {
|
||||
struct mci_base mci_base;
|
||||
struct mci_base mci_base;
|
||||
|
||||
};
|
||||
|
||||
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 = {
|
||||
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2, SYS_DVBC2, SYS_ISDBT,
|
||||
SYS_DVBS, SYS_DVBS2, },
|
||||
.info = {
|
||||
.name = "M4",
|
||||
.frequency_min = 47000000, /* DVB-T: 47125000 */
|
||||
.frequency_min = 950000, /* DVB-T: 47125000 */
|
||||
.frequency_max = 865000000, /* DVB-C: 862000000 */
|
||||
.symbol_rate_min = 870000,
|
||||
.symbol_rate_max = 11700000,
|
||||
.symbol_rate_min = 100000,
|
||||
.symbol_rate_max = 100000000,
|
||||
.frequency_stepsize = 0,
|
||||
.frequency_tolerance = 0,
|
||||
.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_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
|
||||
},
|
||||
#if 0
|
||||
.get_frontend_algo = get_algo,
|
||||
.tune = tune,
|
||||
.release = release,
|
||||
.get_frontend_algo = get_algo,
|
||||
.read_status = read_status,
|
||||
.set_input = set_input,
|
||||
.tune = tune,
|
||||
.sleep = sleep,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int init(struct mci *mci)
|
||||
|
@ -60,6 +60,24 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
|
||||
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,
|
||||
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)
|
||||
return 0;
|
||||
|
||||
if (fmode == 4)
|
||||
max_emulate_switch(fe, cmd->msg, cmd->msg_len);
|
||||
|
||||
if (dvb->diseqc_send_master_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;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -416,7 +439,7 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input)
|
||||
|
||||
demod = input->nr;
|
||||
tuner = demod & 3;
|
||||
if (fmode == 3)
|
||||
if (fmode >= 3)
|
||||
tuner = 0;
|
||||
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner);
|
||||
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];
|
||||
int demod, tuner;
|
||||
struct mci_cfg cfg;
|
||||
int fm = fmode;
|
||||
|
||||
demod = input->nr;
|
||||
tuner = demod & 3;
|
||||
switch (type) {
|
||||
case DDB_TUNER_MCI_SX8:
|
||||
cfg = ddb_max_sx8_cfg;
|
||||
if (fmode == 3)
|
||||
if (fm >= 3)
|
||||
tuner = 0;
|
||||
break;
|
||||
case DDB_TUNER_MCI_M4:
|
||||
fm = 0;
|
||||
cfg = ddb_max_m4_cfg;
|
||||
break;
|
||||
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_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.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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -149,6 +149,52 @@ static int ddb_mci_get_iq(struct mci *mci, u32 demod, s16 *i, s16 *q)
|
||||
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)
|
||||
{
|
||||
struct mci_base *base = (struct mci_base *)priv;
|
||||
|
@ -97,8 +97,6 @@
|
||||
#define SX8_DEMOD_IQ_MODE (1)
|
||||
#define SX8_DEMOD_WAIT_SIGNAL (2)
|
||||
#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_LOCKED (15)
|
||||
|
||||
@ -116,19 +114,24 @@
|
||||
#define MCI_CMD_SEARCH_DVBC (0x20)
|
||||
#define MCI_CMD_SEARCH_DVBT (0x21)
|
||||
#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_BANDWIDTH_1_7MHZ (0)
|
||||
#define MCI_BANDWIDTH_5MHZ (1)
|
||||
#define MCI_BANDWIDTH_6MHZ (2)
|
||||
#define MCI_BANDWIDTH_7MHZ (3)
|
||||
#define MCI_BANDWIDTH_8MHZ (4)
|
||||
#define MCI_BANDWIDTH_UNKNOWN (0)
|
||||
#define MCI_BANDWIDTH_1_7MHZ (1)
|
||||
#define MCI_BANDWIDTH_5MHZ (5)
|
||||
#define MCI_BANDWIDTH_6MHZ (6)
|
||||
#define MCI_BANDWIDTH_7MHZ (7)
|
||||
#define MCI_BANDWIDTH_8MHZ (8)
|
||||
|
||||
#define M4_MODE_SX (2)
|
||||
#define M4_MODE_C (3)
|
||||
#define M4_MODE_T (4)
|
||||
#define M4_MODE_T2 (5)
|
||||
#define M4_MODE_DVBSX (2)
|
||||
#define M4_MODE_DVBC (3)
|
||||
#define M4_MODE_DVBT (4)
|
||||
#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_DISABLE (0x41)
|
||||
@ -138,6 +141,8 @@
|
||||
#define SX8_CMD_DISABLE_IQOUTPUT (0x45)
|
||||
|
||||
#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_UNSUPPORTED (0x80)
|
||||
@ -175,52 +180,85 @@ struct mci_command {
|
||||
u32 scrambling_sequence_index;
|
||||
u32 frequency_range;
|
||||
} dvbs2_search;
|
||||
|
||||
struct {
|
||||
uint8_t flags;
|
||||
uint8_t bandwidth;
|
||||
uint8_t rsvd1;
|
||||
uint8_t retry;
|
||||
uint32_t frequency;
|
||||
u8 flags;
|
||||
u8 bandwidth;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
} dvbc_search;
|
||||
|
||||
struct {
|
||||
uint8_t flags; /* Bit 0: LP Stream */
|
||||
uint8_t bandwidth;
|
||||
uint8_t rsvd1;
|
||||
uint8_t retry;
|
||||
uint32_t frequency;
|
||||
u8 flags; /* Bit 0: LP Stream */
|
||||
u8 bandwidth;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
} dvbt_search;
|
||||
|
||||
struct {
|
||||
uint8_t flags; /* Bit 0: T2 Lite Profile, 7: PLP, */
|
||||
uint8_t bandwidth;
|
||||
uint8_t rsvd1;
|
||||
uint8_t retry;
|
||||
uint32_t frequency;
|
||||
uint32_t reserved;
|
||||
uint8_t plp;
|
||||
uint8_t rsvd2[3];
|
||||
u8 flags; /* Bit 0: T2 Lite Profile, 7: PLP, */
|
||||
u8 bandwidth;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
u32 reserved;
|
||||
u8 plp;
|
||||
u8 rsvd2[3];
|
||||
} dvbt2_search;
|
||||
|
||||
struct {
|
||||
uint8_t Tap;
|
||||
uint8_t Rsvd;
|
||||
uint16_t Point;
|
||||
u8 flags;
|
||||
u8 bandwidth;
|
||||
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;
|
||||
|
||||
struct {
|
||||
uint8_t flags; /* Bit 0 : 0 = VTM, 1 = SCAN. Bit 1: Set Gain */
|
||||
uint8_t roll_off;
|
||||
uint8_t rsvd1;
|
||||
uint8_t rsvd2;
|
||||
uint32_t frequency;
|
||||
uint32_t symbol_rate; /* Only in VTM mode. */
|
||||
uint16_t gain;
|
||||
u8 flags; /* Bit 0 : 0 = VTM, 1 = SCAN. Bit 1: Set Gain */
|
||||
u8 roll_off;
|
||||
u8 rsvd1;
|
||||
u8 rsvd2;
|
||||
u32 frequency;
|
||||
u32 symbol_rate; /* Only in VTM mode. */
|
||||
u16 gain;
|
||||
} sx8_start_iq;
|
||||
|
||||
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;
|
||||
|
||||
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_denominator;
|
||||
} dvbs2_signal_info;
|
||||
|
||||
struct {
|
||||
u8 modulation;
|
||||
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 rsvd2;
|
||||
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;
|
||||
} dvbc_signal_info;
|
||||
|
||||
struct {
|
||||
u8 tps_25_32; /* Constellation (2), Hierarchy (3), Coderate HP (3) */
|
||||
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 rsvd2;
|
||||
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;
|
||||
} dvbt_signal_info;
|
||||
|
||||
struct {
|
||||
u32 rsvd0;
|
||||
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 rsvd2;
|
||||
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;
|
||||
} 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 {
|
||||
s16 i;
|
||||
s16 q;
|
||||
@ -299,6 +371,61 @@ struct mci_result {
|
||||
u8 t2_l1_post_d[19];
|
||||
u8 t2_l1_post_c[19];
|
||||
} 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];
|
||||
};
|
||||
@ -391,11 +518,26 @@ struct mci {
|
||||
int nr;
|
||||
int demod;
|
||||
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_raw(struct mci *state, struct mci_command *command, u32 command_len,
|
||||
struct mci_result *result, u32 result_len);
|
||||
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
|
||||
|
@ -52,7 +52,6 @@ struct sx8 {
|
||||
|
||||
int first_time_lock;
|
||||
int started;
|
||||
struct mci_result signal_info;
|
||||
|
||||
u32 bb_mode;
|
||||
u32 local_frequency;
|
||||
@ -108,64 +107,23 @@ static void release(struct dvb_frontend *fe)
|
||||
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)
|
||||
{
|
||||
int stat;
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct mci_command cmd;
|
||||
u32 val;
|
||||
struct mci_result *res = (struct mci_result *)&val;
|
||||
struct mci_result res;
|
||||
|
||||
cmd.command = MCI_CMD_GETSTATUS;
|
||||
cmd.demod = state->mci.demod;
|
||||
stat = ddb_mci_cmd_raw(&state->mci, &cmd, 1, res, 1);
|
||||
stat = ddb_mci_get_status(&state->mci, &res);
|
||||
if (stat)
|
||||
return stat;
|
||||
*status = 0x00;
|
||||
get_info(fe);
|
||||
get_strength(fe);
|
||||
if (res->status == SX8_DEMOD_WAIT_MATYPE)
|
||||
ddb_mci_get_info(&state->mci);
|
||||
ddb_mci_get_strength(fe);
|
||||
if (res.status == SX8_DEMOD_WAIT_MATYPE)
|
||||
*status = 0x0f;
|
||||
if (res->status == SX8_DEMOD_LOCKED) {
|
||||
if (res.status == SX8_DEMOD_LOCKED) {
|
||||
*status = 0x1f;
|
||||
get_snr(fe);
|
||||
ddb_mci_get_snr(fe);
|
||||
}
|
||||
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 mci_base *mci_base = state->mci.base;
|
||||
@ -408,7 +367,7 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
}
|
||||
if (iq_mode)
|
||||
ts_config = (SX8_TSCONFIG_TSHEADER | SX8_TSCONFIG_MODE_IQ);
|
||||
if (iq_mode < 3) {
|
||||
if (iq_mode < 2) {
|
||||
u32 mask;
|
||||
|
||||
switch (p->modulation) {
|
||||
@ -433,14 +392,12 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
}
|
||||
stat = start(fe, 3, mask, ts_config);
|
||||
} else {
|
||||
u32 flags = (iq_mode == 2) ? 1 : 0;
|
||||
|
||||
stat = start_iq(fe, flags, 4, ts_config);
|
||||
stat = start_iq(fe, iq_mode & 1, 4, ts_config);
|
||||
}
|
||||
if (!stat) {
|
||||
state->started = 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;
|
||||
}
|
||||
@ -489,8 +446,6 @@ static int set_input(struct dvb_frontend *fe, int input)
|
||||
|
||||
static int sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
|
||||
stop(fe);
|
||||
return 0;
|
||||
}
|
||||
|
@ -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,
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user