mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2023-10-10 13:37:43 +02:00
add per demod lock for more fine-grained locking
This commit is contained in:
parent
4b0a0c4ff2
commit
fc9a89c870
@ -56,6 +56,7 @@ struct sx8_base {
|
|||||||
|
|
||||||
struct sx8 {
|
struct sx8 {
|
||||||
struct mci mci;
|
struct mci mci;
|
||||||
|
struct mutex lock;
|
||||||
|
|
||||||
int first_time_lock;
|
int first_time_lock;
|
||||||
int started;
|
int started;
|
||||||
@ -123,38 +124,45 @@ static int ddb_mci_tsconfig(struct mci *state, u32 config)
|
|||||||
|
|
||||||
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 = 0;
|
||||||
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;
|
||||||
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
||||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||||
struct mci_result res;
|
struct mci_result res;
|
||||||
|
|
||||||
|
*status = 0x00;
|
||||||
|
mutex_lock(&state->lock);
|
||||||
|
if (!state->started && !state->iq_started)
|
||||||
|
goto unlock;
|
||||||
stat = ddb_mci_get_status(&state->mci, &res);
|
stat = ddb_mci_get_status(&state->mci, &res);
|
||||||
if (stat)
|
if (stat)
|
||||||
return stat;
|
goto unlock;
|
||||||
if (sx8_base->iq_mode >= 2) {
|
|
||||||
*status = 0x1f;
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
*status = 0x00;
|
|
||||||
ddb_mci_get_info(&state->mci);
|
ddb_mci_get_info(&state->mci);
|
||||||
if (res.status == SX8_DEMOD_WAIT_MATYPE)
|
if (stat)
|
||||||
*status = 0x0f;
|
goto unlock;
|
||||||
|
if (res.status == MCI_DEMOD_LOCKED || res.status == SX8_DEMOD_IQ_MODE) {
|
||||||
|
*status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI |
|
||||||
|
FE_HAS_CARRIER | FE_HAS_SIGNAL;
|
||||||
if (res.status == MCI_DEMOD_LOCKED) {
|
if (res.status == MCI_DEMOD_LOCKED) {
|
||||||
*status = 0x1f;
|
|
||||||
if (state->mci.signal_info.dvbs2_signal_info.standard == 2) {
|
|
||||||
mutex_lock(&mci_base->tuner_lock);
|
mutex_lock(&mci_base->tuner_lock);
|
||||||
if (state->started)
|
if (state->first_time_lock && state->started) {
|
||||||
|
if (state->mci.signal_info.dvbs2_signal_info.standard == 2) {
|
||||||
sx8_base->used_ldpc_bitrate[state->mci.nr] =
|
sx8_base->used_ldpc_bitrate[state->mci.nr] =
|
||||||
p->symbol_rate *
|
p->symbol_rate *
|
||||||
dvbs2_bits_per_symbol[
|
dvbs2_bits_per_symbol[
|
||||||
state->mci.signal_info.
|
state->mci.signal_info.
|
||||||
dvbs2_signal_info.pls_code];
|
dvbs2_signal_info.pls_code];
|
||||||
mutex_unlock(&mci_base->tuner_lock);
|
|
||||||
} else
|
} else
|
||||||
sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;
|
sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;
|
||||||
|
state->first_time_lock = 0;
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&mci_base->tuner_lock);
|
||||||
|
}
|
||||||
|
else if (res.status >= SX8_DEMOD_WAIT_MATYPE)
|
||||||
|
*status = FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&state->lock);
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,9 +205,9 @@ static int stop_iq(struct dvb_frontend *fe)
|
|||||||
state->mci.demod = SX8_DEMOD_NONE;
|
state->mci.demod = SX8_DEMOD_NONE;
|
||||||
}
|
}
|
||||||
sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;
|
sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;
|
||||||
|
mutex_unlock(&mci_base->tuner_lock);
|
||||||
sx8_base->iq_mode = 0;
|
sx8_base->iq_mode = 0;
|
||||||
state->iq_started = 0;
|
state->iq_started = 0;
|
||||||
mutex_unlock(&mci_base->tuner_lock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,12 +217,13 @@ static int stop(struct dvb_frontend *fe)
|
|||||||
struct mci_base *mci_base = state->mci.base;
|
struct mci_base *mci_base = state->mci.base;
|
||||||
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
||||||
struct mci_command cmd;
|
struct mci_command cmd;
|
||||||
u32 input = state->mci.tuner;
|
u32 input;
|
||||||
|
|
||||||
|
input = state->mci.tuner;
|
||||||
if (!state->started)
|
if (!state->started)
|
||||||
return -1;
|
return -1;
|
||||||
memset(&cmd, 0, sizeof(cmd));
|
|
||||||
if (state->mci.demod != SX8_DEMOD_NONE) {
|
if (state->mci.demod != SX8_DEMOD_NONE) {
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
cmd.command = MCI_CMD_STOP;
|
cmd.command = MCI_CMD_STOP;
|
||||||
cmd.demod = state->mci.demod;
|
cmd.demod = state->mci.demod;
|
||||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||||
@ -236,8 +245,8 @@ static int stop(struct dvb_frontend *fe)
|
|||||||
}
|
}
|
||||||
sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;
|
sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;
|
||||||
sx8_base->iq_mode = 0;
|
sx8_base->iq_mode = 0;
|
||||||
mutex_unlock(&mci_base->tuner_lock);
|
|
||||||
state->started = 0;
|
state->started = 0;
|
||||||
|
mutex_unlock(&mci_base->tuner_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +324,6 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
|
|||||||
stat = -EBUSY;
|
stat = -EBUSY;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
modmask &= ((1 << (bits_per_symbol - 1)) - 1);
|
modmask &= ((1 << (bits_per_symbol - 1)) - 1);
|
||||||
if (((flags & 0x02) != 0) && (modmask == 0)) {
|
if (((flags & 0x02) != 0) && (modmask == 0)) {
|
||||||
stat = -EBUSY;
|
stat = -EBUSY;
|
||||||
@ -343,11 +351,10 @@ unlock:
|
|||||||
if (stat)
|
if (stat)
|
||||||
return stat;
|
return stat;
|
||||||
memset(&cmd, 0, sizeof(cmd));
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
|
||||||
if (sx8_base->iq_mode) {
|
if (sx8_base->iq_mode) {
|
||||||
cmd.command = SX8_CMD_ENABLE_IQOUTPUT;
|
cmd.command = SX8_CMD_ENABLE_IQOUTPUT;
|
||||||
cmd.demod = state->mci.demod;
|
cmd.demod = state->mci.demod;
|
||||||
cmd.output = p->stream_id & 7;
|
cmd.output = p->stream_id & 0x0f;
|
||||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||||
ddb_mci_tsconfig(&state->mci, ts_config);
|
ddb_mci_tsconfig(&state->mci, ts_config);
|
||||||
}
|
}
|
||||||
@ -377,6 +384,9 @@ unlock:
|
|||||||
(p->stream_id & 0x80000000))
|
(p->stream_id & 0x80000000))
|
||||||
cmd.output |= 0x80;
|
cmd.output |= 0x80;
|
||||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||||
|
state->started = 1;
|
||||||
|
state->first_time_lock = 1;
|
||||||
|
state->mci.signal_info.status = MCI_DEMOD_WAIT_SIGNAL;
|
||||||
if (stat)
|
if (stat)
|
||||||
stop(fe);
|
stop(fe);
|
||||||
return stat;
|
return stat;
|
||||||
@ -395,8 +405,8 @@ static int start_iq(struct dvb_frontend *fe, u32 flags,
|
|||||||
u32 input = state->mci.tuner;
|
u32 input = state->mci.tuner;
|
||||||
int i, stat = 0;
|
int i, stat = 0;
|
||||||
|
|
||||||
if (!state->iq_started) {
|
|
||||||
mutex_lock(&mci_base->tuner_lock);
|
mutex_lock(&mci_base->tuner_lock);
|
||||||
|
if (!state->iq_started) {
|
||||||
if (sx8_base->iq_mode) {
|
if (sx8_base->iq_mode) {
|
||||||
stat = -EBUSY;
|
stat = -EBUSY;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
@ -409,17 +419,18 @@ static int start_iq(struct dvb_frontend *fe, u32 flags,
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
state->mci.demod = 0;
|
state->mci.demod = 0;
|
||||||
/*
|
|
||||||
if (!sx8_base->tuner_use_count[input])
|
|
||||||
mci_set_tuner(fe, input, 1);
|
|
||||||
*/
|
|
||||||
sx8_base->tuner_use_count[input]++;
|
sx8_base->tuner_use_count[input]++;
|
||||||
sx8_base->iq_mode = 2;
|
sx8_base->iq_mode = 2;
|
||||||
|
} else {
|
||||||
|
if ((state->iq_started & 0x07) != state->mci.nr) {
|
||||||
|
stat = -EBUSY;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&mci_base->tuner_lock);
|
mutex_unlock(&mci_base->tuner_lock);
|
||||||
if (stat)
|
if (stat)
|
||||||
return stat;
|
return stat;
|
||||||
}
|
|
||||||
mci_set_tuner(fe, input, 1, flags & 0xff, 0);
|
mci_set_tuner(fe, input, 1, flags & 0xff, 0);
|
||||||
memset(&cmd, 0, sizeof(cmd));
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
cmd.command = SX8_CMD_START_IQ;
|
cmd.command = SX8_CMD_START_IQ;
|
||||||
@ -431,6 +442,9 @@ static int start_iq(struct dvb_frontend *fe, u32 flags,
|
|||||||
cmd.tuner = state->mci.tuner;
|
cmd.tuner = state->mci.tuner;
|
||||||
cmd.demod = state->mci.demod;
|
cmd.demod = state->mci.demod;
|
||||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||||
|
state->iq_started = 8 | state->mci.nr;
|
||||||
|
state->first_time_lock = 1;
|
||||||
|
state->mci.signal_info.status = MCI_DEMOD_WAIT_SIGNAL;
|
||||||
if (stat)
|
if (stat)
|
||||||
stop_iq(fe);
|
stop_iq(fe);
|
||||||
ddb_mci_tsconfig(&state->mci, ts_config);
|
ddb_mci_tsconfig(&state->mci, ts_config);
|
||||||
@ -443,7 +457,6 @@ static int set_lna(struct dvb_frontend *fe)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int set_parameters(struct dvb_frontend *fe)
|
static int set_parameters(struct dvb_frontend *fe)
|
||||||
{
|
{
|
||||||
int stat = 0;
|
int stat = 0;
|
||||||
@ -459,6 +472,7 @@ static int set_parameters(struct dvb_frontend *fe)
|
|||||||
state->mci.input->con = ts_mode << 8;
|
state->mci.input->con = ts_mode << 8;
|
||||||
if (iq_mode)
|
if (iq_mode)
|
||||||
ts_config = (SX8_TSCONFIG_TSHEADER | SX8_TSCONFIG_MODE_IQ);
|
ts_config = (SX8_TSCONFIG_TSHEADER | SX8_TSCONFIG_MODE_IQ);
|
||||||
|
mutex_lock(&state->lock);
|
||||||
stop(fe);
|
stop(fe);
|
||||||
if (iq_mode < 2) {
|
if (iq_mode < 2) {
|
||||||
u32 mask;
|
u32 mask;
|
||||||
@ -485,19 +499,10 @@ static int set_parameters(struct dvb_frontend *fe)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
stat = start(fe, 3, mask, ts_config);
|
stat = start(fe, 3, mask, ts_config);
|
||||||
if (!stat) {
|
|
||||||
state->started = 1;
|
|
||||||
state->first_time_lock = 1;
|
|
||||||
state->mci.signal_info.status = MCI_DEMOD_WAIT_SIGNAL;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
stat = start_iq(fe, isi & 0xffffff, 4, ts_config);
|
stat = start_iq(fe, isi & 0xffffff, 4, ts_config);
|
||||||
if (!stat) {
|
|
||||||
state->iq_started = 1;
|
|
||||||
state->first_time_lock = 1;
|
|
||||||
state->mci.signal_info.status = MCI_DEMOD_WAIT_SIGNAL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&state->lock);
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,16 +541,22 @@ static int set_input(struct dvb_frontend *fe, int input)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (state->mci.tuner == input)
|
if (state->mci.tuner == input)
|
||||||
return 0;
|
return 0;
|
||||||
|
mutex_lock(&state->lock);
|
||||||
stop_iq(fe);
|
stop_iq(fe);
|
||||||
stop(fe);
|
stop(fe);
|
||||||
state->mci.tuner = p->input = input;
|
state->mci.tuner = p->input = input;
|
||||||
|
mutex_unlock(&state->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sleep(struct dvb_frontend *fe)
|
static int sleep(struct dvb_frontend *fe)
|
||||||
{
|
{
|
||||||
|
struct sx8 *state = fe->demodulator_priv;
|
||||||
|
|
||||||
|
mutex_lock(&state->lock);
|
||||||
stop_iq(fe);
|
stop_iq(fe);
|
||||||
stop(fe);
|
stop(fe);
|
||||||
|
mutex_unlock(&state->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,6 +602,7 @@ static int init(struct mci *mci)
|
|||||||
state->mci.demod = SX8_DEMOD_NONE;
|
state->mci.demod = SX8_DEMOD_NONE;
|
||||||
mci->fe.ops.xbar[1] = mci->nr;
|
mci->fe.ops.xbar[1] = mci->nr;
|
||||||
mci->fe.dtv_property_cache.input = mci->tuner;
|
mci->fe.dtv_property_cache.input = mci->tuner;
|
||||||
|
mutex_init(&state->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user