mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2023-10-10 13:37:43 +02:00
adapt to latest MCI interface changes
This commit is contained in:
parent
c5b45cdbac
commit
4ebb3ca938
@ -47,6 +47,7 @@ struct mci_base {
|
||||
u8 assigned_demod[8];
|
||||
u32 used_ldpc_bitrate[8];
|
||||
u8 demod_in_use[8];
|
||||
u32 iq_mode;
|
||||
};
|
||||
|
||||
struct mci {
|
||||
@ -58,6 +59,8 @@ struct mci {
|
||||
int first_time_lock;
|
||||
int started;
|
||||
struct mci_result signal_info;
|
||||
|
||||
u32 bb_mode;
|
||||
};
|
||||
|
||||
|
||||
@ -87,6 +90,17 @@ static int mci_reset(struct mci *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mci_config(struct mci *state, u32 config)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
|
||||
if (link->ids.device != 0x0009)
|
||||
return -EINVAL;
|
||||
ddblwritel(link, config, SX8_TSCONFIG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _mci_cmd_unlocked(struct mci *state,
|
||||
u32 *cmd, u32 cmd_len,
|
||||
u32 *res, u32 res_len)
|
||||
@ -217,7 +231,7 @@ static int get_info(struct dvb_frontend *fe)
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct mci_command cmd;
|
||||
|
||||
cmd.command = SX8_CMD_GETSIGNALINFO;
|
||||
cmd.command = MCI_CMD_GETSIGNALINFO;
|
||||
cmd.demod = state->demod;
|
||||
stat = mci_cmd(state, &cmd, &state->signal_info);
|
||||
return stat;
|
||||
@ -231,7 +245,7 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
u32 val;
|
||||
struct mci_result *res = (struct mci_result *)&val;
|
||||
|
||||
cmd.command = SX8_CMD_GETSTATUS;
|
||||
cmd.command = MCI_CMD_GETSTATUS;
|
||||
cmd.demod = state->demod;
|
||||
stat = _mci_cmd(state, &cmd, 1, res, 1);
|
||||
if (stat)
|
||||
@ -250,7 +264,7 @@ static int mci_set_tuner(struct dvb_frontend *fe, u32 tuner, u32 on)
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.tuner = state->tuner;
|
||||
cmd.command = on ? SX8_CMD_TUNER_ENABLE : SX8_CMD_TUNER_DISABLE;
|
||||
cmd.command = on ? SX8_CMD_INPUT_ENABLE : SX8_CMD_INPUT_DISABLE;
|
||||
return mci_cmd(state, &cmd, NULL);
|
||||
}
|
||||
|
||||
@ -260,11 +274,18 @@ static int stop(struct dvb_frontend *fe)
|
||||
struct mci_command cmd;
|
||||
u32 input = state->tuner;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
if (state->demod != 0xff) {
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_STOP;
|
||||
cmd.demod = state->demod;
|
||||
cmd.command = SX8_CMD_STOP;
|
||||
mci_cmd(state, &cmd, NULL);
|
||||
if (state->base->iq_mode) {
|
||||
cmd.command = MCI_CMD_STOP;
|
||||
cmd.demod = state->demod;
|
||||
cmd.output = 0;
|
||||
mci_cmd(state, &cmd, NULL);
|
||||
mci_config(state, SX8_TSCONFIG_MODE_NORMAL);
|
||||
}
|
||||
}
|
||||
mutex_lock(&state->base->tuner_lock);
|
||||
state->base->tuner_use_count[input]--;
|
||||
@ -274,26 +295,52 @@ static int stop(struct dvb_frontend *fe)
|
||||
state->base->used_ldpc_bitrate[state->nr] = 0;
|
||||
state->demod = 0xff;
|
||||
state->base->assigned_demod[state->nr] = 0xff;
|
||||
state->base->iq_mode = 0;
|
||||
mutex_unlock(&state->base->tuner_lock);
|
||||
state->started = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int start(struct dvb_frontend *fe)
|
||||
static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
static const u32 MAX_DEMOD_LDPC_BITRATE = (1550000000 / 6);
|
||||
u32 used_ldpc_bitrate = 0, free_ldpc_bitrate;
|
||||
u32 used_demods = 0;
|
||||
struct mci_command cmd;
|
||||
u32 input = state->tuner;
|
||||
u32 bits_per_symbol = 3;
|
||||
u32 bits_per_symbol = 0;
|
||||
int i, stat = 0;
|
||||
|
||||
if (p->symbol_rate >= MCLK / 2)
|
||||
flags &= ~1;
|
||||
if ((flags & 3) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (flags & 2) {
|
||||
u32 tmp = modmask;
|
||||
|
||||
bits_per_symbol = 1;
|
||||
while (tmp & 1) {
|
||||
tmp >>= 1;
|
||||
bits_per_symbol++;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&state->base->tuner_lock);
|
||||
for (i = 0; i < 8; i++)
|
||||
if (state->base->iq_mode) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
used_ldpc_bitrate += state->base->used_ldpc_bitrate[i];
|
||||
if (used_ldpc_bitrate >= MAX_LDPC_BITRATE) {
|
||||
if (state->base->demod_in_use[i])
|
||||
used_demods++;
|
||||
}
|
||||
if ((used_ldpc_bitrate >= MAX_LDPC_BITRATE) ||
|
||||
((ts_config & SX8_TSCONFIG_MODE_MASK) >
|
||||
SX8_TSCONFIG_MODE_NORMAL && used_demods > 0)) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@ -301,10 +348,9 @@ static int start(struct dvb_frontend *fe)
|
||||
if (free_ldpc_bitrate > MAX_DEMOD_LDPC_BITRATE)
|
||||
free_ldpc_bitrate = MAX_DEMOD_LDPC_BITRATE;
|
||||
|
||||
while (p->symbol_rate * bits_per_symbol > MAX_DEMOD_LDPC_BITRATE)
|
||||
while (p->symbol_rate * bits_per_symbol > free_ldpc_bitrate)
|
||||
bits_per_symbol--;
|
||||
|
||||
if (bits_per_symbol < 2) {
|
||||
if (bits_per_symbol < 2) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
@ -322,28 +368,84 @@ static int start(struct dvb_frontend *fe)
|
||||
if (!state->base->tuner_use_count[input])
|
||||
mci_set_tuner(fe, input, 1);
|
||||
state->base->tuner_use_count[input]++;
|
||||
state->base->iq_mode = (ts_config > 1);
|
||||
unlock:
|
||||
mutex_unlock(&state->base->tuner_lock);
|
||||
if (stat)
|
||||
return stat;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
if (state->base->iq_mode) {
|
||||
cmd.command = SX8_CMD_SELECT_IQOUT;
|
||||
cmd.demod = state->demod;
|
||||
cmd.output = 0;
|
||||
mci_cmd(state, &cmd, NULL);
|
||||
mci_config(state, ts_config);
|
||||
}
|
||||
printk("frontend %u: tuner=%u demod=%u\n", state->nr, state->tuner, state->demod);
|
||||
cmd.command = MCI_CMD_SEARCH_DVBS;
|
||||
cmd.dvbs2_search.flags = flags;
|
||||
cmd.dvbs2_search.s2_modulation_mask = modmask & ((1 << (bits_per_symbol - 1)) - 1);
|
||||
cmd.dvbs2_search.retry = 255; /* forever */
|
||||
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
||||
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
||||
cmd.dvbs2_search.scrambling_sequence_index =
|
||||
(p->pls != NO_SCRAMBLING_CODE) ? p->pls : 0;
|
||||
cmd.dvbs2_search.input_stream_id =
|
||||
(p->stream_id != NO_STREAM_ID_FILTER) ? p->stream_id : 0;
|
||||
cmd.tuner = state->tuner;
|
||||
cmd.demod = state->demod;
|
||||
cmd.output = state->nr;
|
||||
stat = mci_cmd(state, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
static int start_iq(struct dvb_frontend *fe, u32 ts_config)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
static const u32 MAX_DEMOD_LDPC_BITRATE = (1550000000 / 6);
|
||||
u32 used_ldpc_bitrate = 0, free_ldpc_bitrate;
|
||||
u32 used_demods = 0;
|
||||
struct mci_command cmd;
|
||||
u32 input = state->tuner;
|
||||
int i, stat = 0;
|
||||
|
||||
mutex_lock(&state->base->tuner_lock);
|
||||
if (state->base->iq_mode) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
for (i = 0; i < 8; i++)
|
||||
if (state->base->demod_in_use[i])
|
||||
used_demods++;
|
||||
if (used_demods > 0) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
state->demod = state->base->assigned_demod[state->nr] = 0;
|
||||
if (!state->base->tuner_use_count[input])
|
||||
mci_set_tuner(fe, input, 1);
|
||||
state->base->tuner_use_count[input]++;
|
||||
state->base->iq_mode = (ts_config > 1);
|
||||
unlock:
|
||||
mutex_unlock(&state->base->tuner_lock);
|
||||
if (stat)
|
||||
return stat;
|
||||
|
||||
printk("frontend %u: tuner=%u demod=%u\n", state->nr, state->tuner, state->demod);
|
||||
cmd.command = SX8_CMD_SEARCH;
|
||||
cmd.dvbs2_search.flags = 3; /* S1 + S2 */
|
||||
#if 1
|
||||
/* Enable all Modcods up to bits_per_symbol */
|
||||
cmd.dvbs2_search.s2_modulation_mask = (1 << (bits_per_symbol - 1)) - 1;
|
||||
#else
|
||||
/* Enable Modcods matching bits_per_symbol */
|
||||
cmd.dvbs2_search.s2_modulation_mask = (1 << (bits_per_symbol - 2));
|
||||
#endif
|
||||
cmd.dvbs2_search.retry = 255; /* forever */
|
||||
cmd.command = SX8_CMD_START_IQ;
|
||||
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
||||
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
||||
cmd.tuner = state->tuner;
|
||||
cmd.demod = state->demod;
|
||||
cmd.output = state->nr;
|
||||
cmd.output = 7;
|
||||
mci_config(state, ts_config);
|
||||
stat = mci_cmd(state, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -351,10 +453,39 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
{
|
||||
int stat = 0;
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 ts_config, iq_mode = 0, isi;
|
||||
|
||||
if (state->started)
|
||||
stop(fe);
|
||||
stat = start(fe);
|
||||
isi = p->stream_id;
|
||||
if (isi != NO_STREAM_ID_FILTER) {
|
||||
iq_mode = (isi & 0x30000000) >> 28;
|
||||
}
|
||||
switch (iq_mode) {
|
||||
case 1:
|
||||
ts_config = (SX8_TSCONFIG_TSHEADER|SX8_TSCONFIG_MODE_IQ);
|
||||
break;
|
||||
case 2:
|
||||
ts_config = (SX8_TSCONFIG_TSHEADER|SX8_TSCONFIG_MODE_IQ);
|
||||
break;
|
||||
default:
|
||||
ts_config = SX8_TSCONFIG_MODE_NORMAL;
|
||||
break;
|
||||
}
|
||||
if (iq_mode != 2) {
|
||||
u32 flags = 3;
|
||||
u32 mask = 3;
|
||||
|
||||
if (p->modulation == APSK_16 ||
|
||||
p->modulation == APSK_32) {
|
||||
flags = 2;
|
||||
mask = 15;
|
||||
}
|
||||
stat = start(fe, flags, mask, ts_config);
|
||||
} else {
|
||||
stat = start_iq(fe, ts_config);
|
||||
}
|
||||
if (!stat) {
|
||||
state->started = 1;
|
||||
state->first_time_lock = 1;
|
||||
|
@ -43,32 +43,49 @@
|
||||
#define SX8_TSCONFIG_MODE_NORMAL (0x00000001)
|
||||
#define SX8_TSCONFIG_MODE_IQ (0x00000003)
|
||||
|
||||
#define SX8_TSCONFIG_TSHEADER (0x00000004)
|
||||
#define SX8_TSCONFIG_BURST (0x00000008)
|
||||
|
||||
#define SX8_TSCONFIG_BURSTSIZE_MASK (0x00000030)
|
||||
#define SX8_TSCONFIG_BURSTSIZE_2K (0x00000000)
|
||||
#define SX8_TSCONFIG_BURSTSIZE_4K (0x00000010)
|
||||
#define SX8_TSCONFIG_BURSTSIZE_8K (0x00000020)
|
||||
#define SX8_TSCONFIG_BURSTSIZE_16K (0x00000030)
|
||||
|
||||
#define SX8_DEMOD_STOPPED (0)
|
||||
#define SX8_DEMOD_IQ_MODE (1)
|
||||
#define SX8_DEMOD_WAIT_SIGNAL (2)
|
||||
#define SX8_DEMOD_WAIT_MATYPE (3)
|
||||
#define SX8_DEMOD_TIMEOUT (14)
|
||||
#define SX8_DEMOD_LOCKED (15)
|
||||
|
||||
#define SX8_CMD_TUNER_ENABLE (0x01)
|
||||
#define SX8_CMD_TUNER_DISABLE (0x02)
|
||||
#define SX8_CMD_SEARCH (0x03)
|
||||
#define SX8_CMD_GETSTATUS (0x04)
|
||||
#define SX8_CMD_STOP (0x05)
|
||||
#define SX8_CMD_GETSIGNALINFO (0x07)
|
||||
#define MCI_CMD_STOP (0x01)
|
||||
#define MCI_CMD_GETSTATUS (0x02)
|
||||
#define MCI_CMD_GETSIGNALINFO (0x03)
|
||||
#define MCI_CMD_RFPOWER (0x04)
|
||||
|
||||
#define SX8_CMD_SELECT_IQOUT (0x10)
|
||||
#define SX8_CMD_SELECT_TSOUT (0x11)
|
||||
#define MCI_CMD_SEARCH_DVBS (0x10)
|
||||
|
||||
#define SX8_CMD_GET_IQSYMBOL (0x30)
|
||||
#define MCI_CMD_GET_IQSYMBOL (0x30)
|
||||
|
||||
#define SX8_CMD_INPUT_ENABLE (0x40)
|
||||
#define SX8_CMD_INPUT_DISABLE (0x41)
|
||||
#define SX8_CMD_START_IQ (0x42)
|
||||
#define SX8_CMD_STOP_IQ (0x43)
|
||||
#define SX8_CMD_SELECT_IQOUT (0x44)
|
||||
#define SX8_CMD_SELECT_TSOUT (0x45)
|
||||
|
||||
#define SX8_ERROR_UNSUPPORTED (0x80)
|
||||
|
||||
#define SX8_SUCCESS(status) (status < SX8_ERROR_UNSUPPORTED)
|
||||
|
||||
#define SX8_CMD_DIAG_READ8 (0xE0)
|
||||
#define SX8_CMD_DIAG_READ32 (0xE1)
|
||||
#define SX8_CMD_DIAG_WRITE8 (0xE2)
|
||||
#define SX8_CMD_DIAG_WRITE32 (0xE3)
|
||||
|
||||
#define SX8_CMD_DIAG_READV (0xE8)
|
||||
#define SX8_CMD_DIAG_WRITEV (0xE9)
|
||||
|
||||
#define M4_CMD_DIAG_READRF (0xE8)
|
||||
#define M4_CMD_DIAG_WRITERF (0xE9)
|
||||
|
||||
#define M4_CMD_DIAG_READX (0xE0)
|
||||
#define M4_CMD_DIAG_READT (0xE1)
|
||||
@ -79,9 +96,6 @@
|
||||
#define M4_CMD_DIAG_WRITERF (0xE9)
|
||||
|
||||
|
||||
#define SX8_ERROR_UNSUPPORTED (0x80)
|
||||
#define SX8_SUCCESS(status) (status < SX8_ERROR_UNSUPPORTED)
|
||||
|
||||
struct mci_command {
|
||||
union {
|
||||
u32 command_word;
|
||||
@ -97,10 +111,13 @@ struct mci_command {
|
||||
struct {
|
||||
u8 flags;
|
||||
u8 s2_modulation_mask;
|
||||
u8 rsvd;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
u32 symbol_rate;
|
||||
u8 input_stream_id;
|
||||
u8 rsvd2[3];
|
||||
u32 scrambling_sequence_index;
|
||||
} dvbs2_search;
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user