dst.c

来自「trident tm5600的linux驱动」· C语言 代码 · 共 1,866 行 · 第 1/4 页

C
1,866
字号
	memset(&state->fw_version, '\0', 8);	memcpy(&state->fw_version, &state->rxbuffer, 8);	dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",		state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,		state->fw_version[1],		state->fw_version[5], state->fw_version[6],		state->fw_version[4], state->fw_version[3], state->fw_version[2]);	return 0;}static int dst_card_type(struct dst_state *state){	int j;	struct tuner_types *p_tuner_list = NULL;	u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };	get_type[7] = dst_check_sum(get_type, 7);	if (dst_command(state, get_type, 8) < 0) {		dprintk(verbose, DST_INFO, 1, "Unsupported Command");		return -1;	}	memset(&state->card_info, '\0', 8);	memcpy(&state->card_info, &state->rxbuffer, 7);	dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);	for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {		if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {			state->tuner_type = p_tuner_list->tuner_type;			dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]",				p_tuner_list->tuner_name, p_tuner_list->tuner_type);		}	}	return 0;}static int dst_get_vendor(struct dst_state *state){	u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };	get_vendor[7] = dst_check_sum(get_vendor, 7);	if (dst_command(state, get_vendor, 8) < 0) {		dprintk(verbose, DST_INFO, 1, "Unsupported Command");		return -1;	}	memset(&state->vendor, '\0', 8);	memcpy(&state->vendor, &state->rxbuffer, 7);	dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);	return 0;}static void debug_dst_buffer(struct dst_state *state){	int i;	if (verbose > 2) {		printk("%s: [", __func__);		for (i = 0; i < 8; i++)			printk(" %02x", state->rxbuffer[i]);		printk("]\n");	}}static int dst_check_stv0299(struct dst_state *state){	u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };	check_stv0299[7] = dst_check_sum(check_stv0299, 7);	if (dst_command(state, check_stv0299, 8) < 0) {		dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed");		return -1;	}	debug_dst_buffer(state);	if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {		dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM");		state->tuner_type = TUNER_TYPE_STV0299;		return 0;	}	return -1;}static int dst_check_mb86a15(struct dst_state *state){	u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };	check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);	if (dst_command(state, check_mb86a15, 8) < 0) {		dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed");		return -1;	}	debug_dst_buffer(state);	if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {		dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM");		state->tuner_type = TUNER_TYPE_MB86A15;		return 0;	}	return -1;}static int dst_get_tuner_info(struct dst_state *state){	u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };	u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };	get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);	get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);	dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE");	if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {		if (dst_command(state, get_tuner_1, 8) < 0) {			dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported");			goto force;		}	} else {		if (dst_command(state, get_tuner_2, 8) < 0) {			dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported");			goto force;		}	}	memset(&state->board_info, '\0', 8);	memcpy(&state->board_info, &state->rxbuffer, 8);	if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {		dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");	}	if (state->board_info[0] == 0xbc) {		if (state->type_flags != DST_TYPE_IS_ATSC)			state->type_flags |= DST_TYPE_HAS_TS188;		else			state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;		if (state->board_info[1] == 0x01) {			state->dst_hw_cap |= DST_TYPE_HAS_DBOARD;			dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard");		}	}	return 0;force:	if (!strncmp(state->fw_name, "DCT-CI", 6)) {		state->type_flags |= DST_TYPE_HAS_TS204;		dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name);	}	return -1;}static int dst_get_device_id(struct dst_state *state){	u8 reply;	int i, j;	struct dst_types *p_dst_type = NULL;	struct tuner_types *p_tuner_list = NULL;	u8 use_dst_type = 0;	u32 use_type_flags = 0;	static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};	state->tuner_type = 0;	device_type[7] = dst_check_sum(device_type, 7);	if (write_dst(state, device_type, FIXED_COMM))		return -1;		/*	Write failed		*/	if ((dst_pio_disable(state)) < 0)		return -1;	if (read_dst(state, &reply, GET_ACK))		return -1;		/*	Read failure		*/	if (reply != ACK) {		dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);		return -1;		/*	Unack'd write		*/	}	if (!dst_wait_dst_ready(state, DEVICE_INIT))		return -1;		/*	DST not ready yet	*/	if (read_dst(state, state->rxbuffer, FIXED_COMM))		return -1;	dst_pio_disable(state);	if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {		dprintk(verbose, DST_INFO, 1, "Checksum failure!");		return -1;		/*	Checksum failure	*/	}	state->rxbuffer[7] = '\0';	for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {		if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {			use_type_flags = p_dst_type->type_flags;			use_dst_type = p_dst_type->dst_type;			/*	Card capabilities	*/			state->dst_hw_cap = p_dst_type->dst_feature;			dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id);			strncpy(&state->fw_name[0], p_dst_type->device_id, 6);			/*	Multiple tuners		*/			if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {				switch (use_dst_type) {				case DST_TYPE_IS_SAT:					/*	STV0299 check	*/					if (dst_check_stv0299(state) < 0) {						dprintk(verbose, DST_ERROR, 1, "Unsupported");						state->tuner_type = TUNER_TYPE_MB86A15;					}					break;				default:					break;				}				if (dst_check_mb86a15(state) < 0)					dprintk(verbose, DST_ERROR, 1, "Unsupported");			/*	Single tuner		*/			} else {				state->tuner_type = p_dst_type->tuner_type;			}			for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {				if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&					p_tuner_list->tuner_type == state->tuner_type) {					dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]",						p_dst_type->device_id, p_tuner_list->tuner_name);				}			}			break;		}	}	if (i >= ARRAY_SIZE(dst_tlist)) {		dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);		dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");		use_dst_type = DST_TYPE_IS_SAT;		use_type_flags = DST_TYPE_HAS_SYMDIV;	}	dst_type_print(state, use_dst_type);	state->type_flags = use_type_flags;	state->dst_type = use_dst_type;	dst_type_flags_print(state);	return 0;}static int dst_probe(struct dst_state *state){	mutex_init(&state->dst_mutex);	if (dst_addons & DST_TYPE_HAS_CA) {		if ((rdc_8820_reset(state)) < 0) {			dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");			return -1;		}		msleep(4000);	} else {		msleep(100);	}	if ((dst_comm_init(state)) < 0) {		dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");		return -1;	}	msleep(100);	if (dst_get_device_id(state) < 0) {		dprintk(verbose, DST_ERROR, 1, "unknown device.");		return -1;	}	if (dst_get_mac(state) < 0) {		dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");	}	if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {		if (dst_get_tuner_info(state) < 0)			dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");	}	if (state->type_flags & DST_TYPE_HAS_TS204) {		dst_packsize(state, 204);	}	if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {		if (dst_fw_ver(state) < 0) {			dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");			return 0;		}		if (dst_card_type(state) < 0) {			dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");			return 0;		}		if (dst_get_vendor(state) < 0) {			dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");			return 0;		}	}	return 0;}static int dst_command(struct dst_state *state, u8 *data, u8 len){	u8 reply;	mutex_lock(&state->dst_mutex);	if ((dst_comm_init(state)) < 0) {		dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");		goto error;	}	if (write_dst(state, data, len)) {		dprintk(verbose, DST_INFO, 1, "Trying to recover.. ");		if ((dst_error_recovery(state)) < 0) {			dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");			goto error;		}		goto error;	}	if ((dst_pio_disable(state)) < 0) {		dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");		goto error;	}	if (state->type_flags & DST_TYPE_HAS_FW_1)		mdelay(3);	if (read_dst(state, &reply, GET_ACK)) {		dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");		if ((dst_error_recovery(state)) < 0) {			dprintk(verbose, DST_INFO, 1, "Recovery Failed.");			goto error;		}		goto error;	}	if (reply != ACK) {		dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);		goto error;	}	if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))		goto error;	if (state->type_flags & DST_TYPE_HAS_FW_1)		mdelay(3);	else		udelay(2000);	if (!dst_wait_dst_ready(state, NO_DELAY))		goto error;	if (read_dst(state, state->rxbuffer, FIXED_COMM)) {		dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");		if ((dst_error_recovery(state)) < 0) {			dprintk(verbose, DST_INFO, 1, "Recovery failed.");			goto error;		}		goto error;	}	if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {		dprintk(verbose, DST_INFO, 1, "checksum failure");		goto error;	}	mutex_unlock(&state->dst_mutex);	return 0;error:	mutex_unlock(&state->dst_mutex);	return -EIO;}static int dst_get_signal(struct dst_state *state){	int retval;	u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };	//dprintk("%s: Getting Signal strength and other parameters\n", __func__);	if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {		state->decode_lock = state->decode_strength = state->decode_snr = 0;		return 0;	}	if (0 == (state->diseq_flags & HAS_LOCK)) {		state->decode_lock = state->decode_strength = state->decode_snr = 0;		return 0;	}	if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {		retval = dst_command(state, get_signal, 8);		if (retval < 0)			return retval;		if (state->dst_type == DST_TYPE_IS_SAT) {			state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;			state->decode_strength = state->rxbuffer[5] << 8;			state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];		} else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {			state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;			state->decode_strength = state->rxbuffer[4] << 8;			state->decode_snr = state->rxbuffer[3] << 8;		} else if (state->dst_type == DST_TYPE_IS_ATSC) {			state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;			state->decode_strength = state->rxbuffer[4] << 8;			state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];		}		state->cur_jiff = jiffies;	}	return 0;}static int dst_tone_power_cmd(struct dst_state *state){	u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };	if (state->dst_type != DST_TYPE_IS_SAT)		return -EOPNOTSUPP;	paket[4] = state->tx_tuna[4];	paket[2] = state->tx_tuna[2];	paket[3] = state->tx_tuna[3];	paket[7] = dst_check_sum (paket, 7);	return dst_command(state, paket, 8);}static int dst_get_tuna(struct dst_state *state){	int retval;	if ((state->diseq_flags & ATTEMPT_TUNE) == 0)		return 0;	state->diseq_flags &= ~(HAS_LOCK);	if (!dst_wait_dst_ready(state, NO_DELAY))		return -EIO;	if ((state->type_flags & DST_TYPE_HAS_VLF) &&		!(state->dst_type == DST_TYPE_IS_ATSC))		retval = read_dst(state, state->rx_tuna, 10);	else		retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);	if (retval < 0) {		dprintk(verbose, DST_DEBUG, 1, "read not successful");		return retval;	}	if ((state->type_flags & DST_TYPE_HAS_VLF) &&		!(state->dst_type == DST_TYPE_IS_CABLE) &&		!(state->dst_type == DST_TYPE_IS_ATSC)) {		if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {			dprintk(verbose, DST_INFO, 1, "checksum failure ? ");			return -EIO;		}	} else {		if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {			dprintk(verbose, DST_INFO, 1, "checksum failure? ");			return -EIO;		}	}	if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)		return 0;	if (state->dst_type == DST_TYPE_IS_SAT) {		state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];	} else {		state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];	}	state->decode_freq = state->decode_freq * 1000;	state->decode_lock = 1;	state->diseq_flags |= HAS_LOCK;	return 1;}static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);static int dst_write_tuna(struct dvb_frontend *fe){	struct dst_state *state = fe->demodulator_priv;	int retval;	u8 reply;	dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);	state->decode_freq = 0;	state->decode_lock = state->decode_strength = state->decode_snr = 0;	if (state->dst_type == DST_TYPE_IS_SAT) {		if (!(state->diseq_flags & HAS_POWER))			dst_set_voltage(fe, SEC_VOLTAGE_13);	}	state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);	mutex_lock(&state->dst_mutex);	if ((dst_comm_init(state)) < 0) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?