mirror of
				https://github.com/DigitalDevices/dddvb.git
				synced 2025-03-01 10:35:23 +00:00 
			
		
		
		
	add per demod lock for more fine-grained locking
This commit is contained in:
		| @@ -56,6 +56,7 @@ struct sx8_base { | ||||
|  | ||||
| struct sx8 { | ||||
| 	struct mci           mci; | ||||
| 	struct mutex         lock; | ||||
|  | ||||
| 	int                  first_time_lock; | ||||
| 	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) | ||||
| { | ||||
| 	int stat; | ||||
| 	int stat = 0; | ||||
| 	struct sx8 *state = fe->demodulator_priv; | ||||
| 	struct mci_base *mci_base = state->mci.base; | ||||
| 	struct sx8_base *sx8_base = (struct sx8_base *) mci_base; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	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); | ||||
| 	if (stat) | ||||
| 		return stat; | ||||
| 	if (sx8_base->iq_mode >= 2) { | ||||
| 		*status = 0x1f; | ||||
| 		return stat; | ||||
| 	} | ||||
| 	*status = 0x00; | ||||
| 		goto unlock; | ||||
| 	ddb_mci_get_info(&state->mci); | ||||
| 	if (res.status == SX8_DEMOD_WAIT_MATYPE) | ||||
| 		*status = 0x0f; | ||||
| 	if (res.status == MCI_DEMOD_LOCKED) { | ||||
| 		*status = 0x1f; | ||||
| 		if (state->mci.signal_info.dvbs2_signal_info.standard == 2) { | ||||
| 	if (stat) | ||||
| 		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) { | ||||
| 			mutex_lock(&mci_base->tuner_lock); | ||||
| 			if (state->started) | ||||
| 				sx8_base->used_ldpc_bitrate[state->mci.nr] = | ||||
| 					p->symbol_rate * | ||||
| 					dvbs2_bits_per_symbol[ | ||||
| 						state->mci.signal_info. | ||||
| 						dvbs2_signal_info.pls_code]; | ||||
| 			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] = | ||||
| 						p->symbol_rate * | ||||
| 						dvbs2_bits_per_symbol[ | ||||
| 							state->mci.signal_info. | ||||
| 							dvbs2_signal_info.pls_code]; | ||||
| 				} else | ||||
| 					sx8_base->used_ldpc_bitrate[state->mci.nr] = 0; | ||||
| 				state->first_time_lock = 0; | ||||
| 			} | ||||
| 			mutex_unlock(&mci_base->tuner_lock); | ||||
| 		} else  | ||||
| 			sx8_base->used_ldpc_bitrate[state->mci.nr] = 0; | ||||
| 	} | ||||
| 		} | ||||
| 	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; | ||||
| } | ||||
|  | ||||
| @@ -197,9 +205,9 @@ static int stop_iq(struct dvb_frontend *fe) | ||||
| 		state->mci.demod = SX8_DEMOD_NONE; | ||||
| 	} | ||||
| 	sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;	 | ||||
| 	mutex_unlock(&mci_base->tuner_lock); | ||||
| 	sx8_base->iq_mode = 0; | ||||
| 	state->iq_started = 0; | ||||
| 	mutex_unlock(&mci_base->tuner_lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -209,12 +217,13 @@ static int stop(struct dvb_frontend *fe) | ||||
| 	struct mci_base *mci_base = state->mci.base; | ||||
| 	struct sx8_base *sx8_base = (struct sx8_base *) mci_base; | ||||
| 	struct mci_command cmd; | ||||
| 	u32 input = state->mci.tuner; | ||||
| 	u32 input; | ||||
|  | ||||
| 	input = state->mci.tuner; | ||||
| 	if (!state->started) | ||||
| 		return -1; | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	if (state->mci.demod != SX8_DEMOD_NONE) { | ||||
| 		memset(&cmd, 0, sizeof(cmd)); | ||||
| 		cmd.command = MCI_CMD_STOP; | ||||
| 		cmd.demod = state->mci.demod; | ||||
| 		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->iq_mode = 0; | ||||
| 	mutex_unlock(&mci_base->tuner_lock); | ||||
| 	state->started = 0; | ||||
| 	mutex_unlock(&mci_base->tuner_lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -308,16 +317,15 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config) | ||||
| 		free_ldpc_bitrate = MAX_LDPC_BITRATE - used_ldpc_bitrate; | ||||
| 		if (free_ldpc_bitrate > MAX_DEMOD_LDPC_BITRATE)  | ||||
| 			free_ldpc_bitrate = MAX_DEMOD_LDPC_BITRATE; | ||||
| 		 | ||||
|  | ||||
| 		while (p->symbol_rate * bits_per_symbol > free_ldpc_bitrate) | ||||
| 			bits_per_symbol--; | ||||
| 		if (bits_per_symbol < 2) { | ||||
| 			stat = -EBUSY; | ||||
| 			goto unlock; | ||||
| 		} | ||||
| 		 | ||||
| 		modmask &= ((1 << (bits_per_symbol - 1)) - 1); | ||||
| 		if( ((flags & 0x02) != 0)  &&  (modmask == 0)) { | ||||
| 		if (((flags & 0x02) != 0) && (modmask == 0)) { | ||||
| 			stat = -EBUSY; | ||||
| 			goto unlock; | ||||
| 		} | ||||
| @@ -343,11 +351,10 @@ unlock: | ||||
| 	if (stat) | ||||
| 		return stat; | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	 | ||||
| 	if (sx8_base->iq_mode) { | ||||
| 		cmd.command = SX8_CMD_ENABLE_IQOUTPUT; | ||||
| 		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_tsconfig(&state->mci, ts_config); | ||||
| 	} | ||||
| @@ -377,6 +384,9 @@ unlock: | ||||
| 	    (p->stream_id & 0x80000000)) | ||||
| 		cmd.output |= 0x80; | ||||
| 	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) | ||||
| 		stop(fe); | ||||
| 	return stat; | ||||
| @@ -395,8 +405,8 @@ static int start_iq(struct dvb_frontend *fe, u32 flags, | ||||
| 	u32 input = state->mci.tuner; | ||||
| 	int i, stat = 0; | ||||
|  | ||||
| 	mutex_lock(&mci_base->tuner_lock); | ||||
| 	if (!state->iq_started) { | ||||
| 		mutex_lock(&mci_base->tuner_lock); | ||||
| 		if (sx8_base->iq_mode) { | ||||
| 			stat = -EBUSY; | ||||
| 			goto unlock; | ||||
| @@ -409,17 +419,18 @@ static int start_iq(struct dvb_frontend *fe, u32 flags, | ||||
| 			goto unlock; | ||||
| 		} | ||||
| 		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->iq_mode = 2; | ||||
| 	unlock: | ||||
| 		mutex_unlock(&mci_base->tuner_lock); | ||||
| 		if (stat) | ||||
| 			return stat; | ||||
| 	} else { | ||||
| 		if ((state->iq_started & 0x07) != state->mci.nr) { | ||||
| 			stat = -EBUSY; | ||||
| 			goto unlock; | ||||
| 		} | ||||
| 	} | ||||
| unlock: | ||||
| 	mutex_unlock(&mci_base->tuner_lock); | ||||
| 	if (stat) | ||||
| 		return stat; | ||||
| 	mci_set_tuner(fe, input, 1, flags & 0xff, 0); | ||||
| 	memset(&cmd, 0, sizeof(cmd)); | ||||
| 	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.demod = state->mci.demod; | ||||
| 	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) | ||||
| 		stop_iq(fe); | ||||
| 	ddb_mci_tsconfig(&state->mci, ts_config); | ||||
| @@ -443,7 +457,6 @@ static int set_lna(struct dvb_frontend *fe) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int set_parameters(struct dvb_frontend *fe) | ||||
| { | ||||
| 	int stat = 0; | ||||
| @@ -459,6 +472,7 @@ static int set_parameters(struct dvb_frontend *fe) | ||||
| 	state->mci.input->con = ts_mode << 8; | ||||
| 	if (iq_mode) | ||||
| 		ts_config = (SX8_TSCONFIG_TSHEADER | SX8_TSCONFIG_MODE_IQ); | ||||
| 	mutex_lock(&state->lock); | ||||
| 	stop(fe); | ||||
| 	if (iq_mode < 2) { | ||||
| 		u32 mask; | ||||
| @@ -485,19 +499,10 @@ static int set_parameters(struct dvb_frontend *fe) | ||||
| 			break; | ||||
| 		} | ||||
| 		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 { | ||||
| 		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; | ||||
| } | ||||
|  | ||||
| @@ -536,16 +541,22 @@ static int set_input(struct dvb_frontend *fe, int input) | ||||
| 		return -EINVAL; | ||||
| 	if (state->mci.tuner == input) | ||||
| 		return 0; | ||||
| 	mutex_lock(&state->lock); | ||||
| 	stop_iq(fe); | ||||
| 	stop(fe); | ||||
| 	state->mci.tuner = p->input = input; | ||||
| 	mutex_unlock(&state->lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int sleep(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct sx8 *state = fe->demodulator_priv; | ||||
|  | ||||
| 	mutex_lock(&state->lock); | ||||
| 	stop_iq(fe); | ||||
| 	stop(fe); | ||||
| 	mutex_unlock(&state->lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -591,6 +602,7 @@ static int init(struct mci *mci) | ||||
| 	state->mci.demod = SX8_DEMOD_NONE; | ||||
| 	mci->fe.ops.xbar[1] = mci->nr; | ||||
| 	mci->fe.dtv_property_cache.input = mci->tuner; | ||||
| 	mutex_init(&state->lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user