⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dst.c

📁 linux_dvb的驱动程序:linuxtv-dvb-1.1.1.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
			use_dst_type = dsp->dst_type;			printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr);			break;		}	}	if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) {		printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]);		printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);		use_dst_type = DST_TYPE_IS_SAT;		use_type_flags = DST_TYPE_HAS_SYMDIV;	}	switch (dst_type[dst_cur_no]) {		case (-1U):			/* not used */			break;		case DST_TYPE_IS_SAT:		case DST_TYPE_IS_TERR:		case DST_TYPE_IS_CABLE:			use_dst_type = (u8)(dst_type[dst_cur_no]);			break;		default:			printk("%s: invalid user override dst type %d, not used\n",				__FUNCTION__, dst_type[dst_cur_no]);			break;	}	dst_type_print(use_dst_type);	if (dst_type_flags[dst_cur_no] != (-1U)) {		printk("%s: user override dst type flags 0x%x\n",				__FUNCTION__, dst_type_flags[dst_cur_no]);		use_type_flags = dst_type_flags[dst_cur_no];	}	dst->type_flags = use_type_flags;	dst->dst_type= use_dst_type;	dst_type_flags_print(dst->type_flags);	if (dst->type_flags & DST_TYPE_HAS_TS204) {		dst_packsize(dst, 204);	}	return 0;}static int dst_command (struct dst_data *dst, u8 *data, u8 len){	int retval;	u8 reply;	dst_i2c_enable(dst);	dst_reset8820(dst);	retval = write_dst (dst, data, len);	if (retval < 0) {		dst_i2c_disable(dst);		dprintk("%s: write not successful\n", __FUNCTION__);		return retval;	}	dvb_delay(33);	retval = read_dst (dst, &reply, 1);	dst_i2c_disable(dst);	if (retval < 0) {		dprintk("%s: read verify  not successful\n", __FUNCTION__);		return retval;	}	if (reply != 0xff) {		dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);		return 0;	}	if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))		return 0;	if (!dst_wait_dst_ready(dst))		return 0;	// dst_i2c_enable(i2c); Per dimitri	retval = read_dst (dst, dst->rxbuffer, 8);	dst_i2c_disable(dst);	if (retval < 0) {		dprintk("%s: read not successful\n", __FUNCTION__);		return 0;	}	if (dst->rxbuffer[7] != dst_check_sum (dst->rxbuffer, 7)) {		dprintk("%s: checksum failure\n", __FUNCTION__);		return 0;	}	return 0;}static int dst_get_signal(struct dst_data *dst){	int retval;	u8 get_signal[] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};	if ((dst->diseq_flags & ATTEMPT_TUNE) == 0) {		dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;		return 0;	}	if (0 == (dst->diseq_flags & HAS_LOCK)) {		dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;		return 0;	}	if (time_after_eq(jiffies, dst->cur_jiff + (HZ/5))) {		retval =  dst_command(dst, get_signal, 8);		if (retval < 0)			return retval;		if (dst->dst_type == DST_TYPE_IS_SAT) {			dst->decode_lock = ((dst->rxbuffer[6] & 0x10) == 0) ?					1 : 0;			dst->decode_strength = dst->rxbuffer[5] << 8;			dst->decode_snr = dst->rxbuffer[2] << 8 |				dst->rxbuffer[3];		} else if ((dst->dst_type == DST_TYPE_IS_TERR) ||				(dst->dst_type == DST_TYPE_IS_CABLE)) {			dst->decode_lock = (dst->rxbuffer[1]) ?					1 : 0;			dst->decode_strength = dst->rxbuffer[4] << 8;			dst->decode_snr = dst->rxbuffer[3] << 8;		}		dst->cur_jiff = jiffies;	}	return 0;}/* * line22k0    0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00 * line22k1    0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00 * line22k2    0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00 * tone        0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00 * data        0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00 * power_off   0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 * power_on    0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 * Diseqc 1    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec * Diseqc 2    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8  * Diseqc 3    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4  * Diseqc 4    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0  */static int dst_set_diseqc (struct dst_data *dst, u8 *cmd, u8 len){	u8 paket[8] =  {0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };	if (dst->dst_type == DST_TYPE_IS_TERR)		return 0;	if (len == 0 || len > 4)		return -EINVAL;	memcpy(&paket[3], cmd, len);	paket[7] = dst_check_sum (&paket[0], 7);	dst_command(dst, paket, 8);	return 0;}static int dst_tone_power_cmd (struct dst_data *dst){	u8 paket[8] =  {0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00};	if (dst->dst_type == DST_TYPE_IS_TERR)		return 0;	if (dst->voltage == SEC_VOLTAGE_OFF) 		paket[4] = 0;	else		paket[4] = 1;	if (dst->tone == SEC_TONE_ON)		paket[2] = dst->k22;	else		paket[2] = 0;	paket[7] = dst_check_sum (&paket[0], 7);	dst_command(dst, paket, 8);	return 0;}static int dst_set_voltage (struct dst_data *dst, fe_sec_voltage_t voltage){	u8 *val;	int need_cmd;	dst->voltage = voltage;	if (dst->dst_type == DST_TYPE_IS_TERR)		return 0;	need_cmd = 0;	val = &dst->tx_tuna[0];	val[8] &= ~0x40;	switch (voltage) {	case SEC_VOLTAGE_13:		if ((dst->diseq_flags & HAS_POWER) == 0)			need_cmd = 1;		dst->diseq_flags |= HAS_POWER;		break;	case SEC_VOLTAGE_18:		if ((dst->diseq_flags & HAS_POWER) == 0)			need_cmd = 1;		dst->diseq_flags |= HAS_POWER;		val[8] |= 0x40;		break;	case SEC_VOLTAGE_OFF:		need_cmd = 1;		dst->diseq_flags &= ~(HAS_POWER|HAS_LOCK|ATTEMPT_TUNE);		break;	default:		return -EINVAL;	}	if (need_cmd) {		dst_tone_power_cmd(dst);	}	return 0;}static int dst_set_tone (struct dst_data *dst, fe_sec_tone_mode_t tone){	u8 *val;	dst->tone = tone;	if (dst->dst_type == DST_TYPE_IS_TERR)		return 0;	val = &dst->tx_tuna[0];	val[8] &= ~0x1;	switch (tone) {	case SEC_TONE_OFF:		break;	case SEC_TONE_ON:		val[8] |= 1;		break;	default:		return -EINVAL;	}	dst_tone_power_cmd(dst);	return 0;}static int dst_get_tuna (struct dst_data *dst){int retval;	if ((dst->diseq_flags & ATTEMPT_TUNE) == 0)		return 0;	dst->diseq_flags &= ~(HAS_LOCK);	if (!dst_wait_dst_ready(dst))		return 0;	if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {		/* how to get variable length reply ???? */		retval = read_dst (dst, dst->rx_tuna, 10);	} else {		retval = read_dst (dst, &dst->rx_tuna[2], 8);	}	if (retval < 0) {		dprintk("%s: read not successful\n", __FUNCTION__);		return 0;	}	if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {		if (dst->rx_tuna[9] != dst_check_sum (&dst->rx_tuna[0], 9)) {			dprintk("%s: checksum failure?\n", __FUNCTION__);			return 0;		}	} else {		if (dst->rx_tuna[9] != dst_check_sum (&dst->rx_tuna[2], 7)) {			dprintk("%s: checksum failure?\n", __FUNCTION__);			return 0;		}	}	if (dst->rx_tuna[2] == 0 && dst->rx_tuna[3] == 0)		return 0;	dst->decode_freq = ((dst->rx_tuna[2] & 0x7f) << 8) +  dst->rx_tuna[3];	dst->decode_lock = 1;	/*	dst->decode_n1 = (dst->rx_tuna[4] << 8) +  			(dst->rx_tuna[5]);	dst->decode_n2 = (dst->rx_tuna[8] << 8) +  			(dst->rx_tuna[7]);	*/	dst->diseq_flags |= HAS_LOCK;	/* dst->cur_jiff = jiffies; */	return 1;}static int dst_write_tuna (struct dst_data *dst){	int retval;	u8 reply;	dprintk("%s: type_flags 0x%x \n", __FUNCTION__, dst->type_flags);	dst->decode_freq = 0;	dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;	if (dst->dst_type == DST_TYPE_IS_SAT) {		if (!(dst->diseq_flags & HAS_POWER))			dst_set_voltage (dst, SEC_VOLTAGE_13);	}	dst->diseq_flags &= ~(HAS_LOCK|ATTEMPT_TUNE);	dst_i2c_enable(dst);	if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {		dst_reset8820(dst);		dst->tx_tuna[9] = dst_check_sum (&dst->tx_tuna[0], 9);		retval = write_dst (dst, &dst->tx_tuna[0], 10);	} else {		dst->tx_tuna[9] = dst_check_sum (&dst->tx_tuna[2], 7);		retval = write_dst (dst, &dst->tx_tuna[2], 8);	}	if (retval < 0) {		dst_i2c_disable(dst);		dprintk("%s: write not successful\n", __FUNCTION__);		return retval;	}	dvb_delay(3);	retval = read_dst (dst, &reply, 1);	dst_i2c_disable(dst);	if (retval < 0) {		dprintk("%s: read verify  not successful\n", __FUNCTION__);		return retval;	}	if (reply != 0xff) {		dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);		return 0;	}	dst->diseq_flags |= ATTEMPT_TUNE;	return dst_get_tuna(dst);}static void dst_init (struct dst_data *dst){static u8 ini_satci_tuna[] = {  9, 0, 3, 0xb6, 1, 0,    0x73, 0x21, 0, 0 };static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };static u8 ini_tvfta_tuna[] = { 0, 0,  3, 0xb6, 1, 7,    0x0,   0x0, 0, 0 };static u8 ini_tvci_tuna[] = { 9, 0,  3, 0xb6, 1, 7,    0x0,   0x0, 0, 0 };static u8 ini_cabfta_tuna[] = { 0, 0,  3, 0xb6, 1, 7,    0x0,   0x0, 0, 0 };static u8 ini_cabci_tuna[] = { 9, 0,  3, 0xb6, 1, 7,    0x0,   0x0, 0, 0 };	dst->inversion = INVERSION_ON;	dst->voltage = SEC_VOLTAGE_13;	dst->tone = SEC_TONE_OFF;	dst->symbol_rate = 29473000;	dst->fec = FEC_AUTO;	dst->diseq_flags = 0;	dst->k22 = 0x02;	dst->bandwidth = BANDWIDTH_7_MHZ;	dst->cur_jiff = jiffies;	if (dst->dst_type == DST_TYPE_IS_SAT) {		dst->frequency = 950000;		memcpy(dst->tx_tuna, ((dst->type_flags &  DST_TYPE_HAS_NEWTUNE )? 					ini_satci_tuna : ini_satfta_tuna),				sizeof(ini_satfta_tuna));	} else if (dst->dst_type == DST_TYPE_IS_TERR) {		dst->frequency = 137000000;		memcpy(dst->tx_tuna, ((dst->type_flags &  DST_TYPE_HAS_NEWTUNE )? 					ini_tvci_tuna : ini_tvfta_tuna),				sizeof(ini_tvfta_tuna));	} else if (dst->dst_type == DST_TYPE_IS_CABLE) {		dst->frequency = 51000000;		memcpy(dst->tx_tuna, ((dst->type_flags &  DST_TYPE_HAS_NEWTUNE )? 					ini_cabci_tuna : ini_cabfta_tuna),				sizeof(ini_cabfta_tuna));	}}struct lkup {	unsigned int cmd;	char *desc;} looker[] = {	{FE_GET_INFO,                "FE_GET_INFO:"},	{FE_READ_STATUS,             "FE_READ_STATUS:" },	{FE_READ_BER,                "FE_READ_BER:" },	{FE_READ_SIGNAL_STRENGTH,    "FE_READ_SIGNAL_STRENGTH:" },	{FE_READ_SNR,                "FE_READ_SNR:" },	{FE_READ_UNCORRECTED_BLOCKS, "FE_READ_UNCORRECTED_BLOCKS:" },	{FE_SET_FRONTEND,            "FE_SET_FRONTEND:" },	{FE_GET_FRONTEND,            "FE_GET_FRONTEND:" },	{FE_SLEEP,                   "FE_SLEEP:" },	{FE_INIT,                    "FE_INIT:" },	{FE_RESET,                   "FE_RESET:" },	{FE_SET_TONE,                "FE_SET_TONE:" },	{FE_SET_VOLTAGE,             "FE_SET_VOLTAGE:" },	};static int dst_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg){	struct dst_data *dst = fe->data;	int retval;	/*	char  *cc;                	cc = "FE_UNSUPP:";	for(retval = 0; retval < sizeof(looker) / sizeof(looker[0]); retval++) {		if (looker[retval].cmd == cmd) {			cc = looker[retval].desc;			break;		}	}	dprintk("%s cmd %s (0x%x)\n",__FUNCTION__, cc, cmd);	*/	// printk("%s: dst %8.8x bt %8.8x i2c %8.8x\n", __FUNCTION__, dst, dst->bt, dst->i2c);	/* should be set by attach, but just in case */	dst->i2c = fe->i2c;        switch (cmd) {        case FE_GET_INFO: 	{	     struct dvb_frontend_info *info;		info = &dst_info_sat;		if (dst->dst_type == DST_TYPE_IS_TERR)			info = &dst_info_tv;		else if (dst->dst_type == DST_TYPE_IS_CABLE)			info = &dst_info_cable;		memcpy (arg, info, sizeof(struct dvb_frontend_info));		break;	}        case FE_READ_STATUS:	{		fe_status_t *status = arg;		*status = 0;		if (dst->diseq_flags & HAS_LOCK) {			dst_get_signal(dst);			if (dst->decode_lock)				*status |= FE_HAS_LOCK 					| FE_HAS_SIGNAL 					| FE_HAS_CARRIER					| FE_HAS_SYNC					| FE_HAS_VITERBI;		}		break;	}        case FE_READ_BER:	{		/* guess */		// *(u32*) arg = dst->decode_n1;		*(u32*) arg = 0;		return -EOPNOTSUPP; 	}        case FE_READ_SIGNAL_STRENGTH:	{		dst_get_signal(dst);		*((u16*) arg) = dst->decode_strength;		break;	}        case FE_READ_SNR:	{		dst_get_signal(dst);		*((u16*) arg) = dst->decode_snr;		break;	}	case FE_READ_UNCORRECTED_BLOCKS: 	{		*((u32*) arg) = 0;    /* the stv0299 can't measure BER and */		return -EOPNOTSUPP;   /* errors at the same time.... */	}        case FE_SET_FRONTEND:        {		struct dvb_frontend_parameters *p = arg;		dst_set_freq (dst, p->frequency);		dst_set_inversion (dst, p->inversion);		if (dst->dst_type == DST_TYPE_IS_SAT) {			dst_set_fec (dst, p->u.qpsk.fec_inner);			dst_set_symbolrate (dst, p->u.qpsk.symbol_rate);		} else if (dst->dst_type == DST_TYPE_IS_TERR) {			dst_set_bandwidth(dst, p->u.ofdm.bandwidth);		} else if (dst->dst_type == DST_TYPE_IS_CABLE) {			dst_set_fec (dst, p->u.qam.fec_inner);			dst_set_symbolrate (dst, p->u.qam.symbol_rate);		}		dst_write_tuna (dst);                break;        }	case FE_GET_FRONTEND:	{		struct dvb_frontend_parameters *p = arg;		p->frequency = dst->decode_freq;		p->inversion = dst->inversion;		if (dst->dst_type == DST_TYPE_IS_SAT) {			p->u.qpsk.symbol_rate = dst->symbol_rate;			p->u.qpsk.fec_inner = dst_get_fec (dst);		} else if (dst->dst_type == DST_TYPE_IS_TERR) {			p->u.ofdm.bandwidth = dst->bandwidth;		} else if (dst->dst_type == DST_TYPE_IS_CABLE) {			p->u.qam.symbol_rate = dst->symbol_rate;			p->u.qam.fec_inner = dst_get_fec (dst);			p->u.qam.modulation = QAM_AUTO;		}		break;	}        case FE_SLEEP:		return 0;        case FE_INIT:		dst_init(dst);		break;	case FE_RESET:		break;	case FE_DISEQC_SEND_MASTER_CMD:	{		struct dvb_diseqc_master_cmd *cmd = (struct dvb_diseqc_master_cmd *)arg;		retval = dst_set_diseqc (dst, cmd->msg, cmd->msg_len);		if (retval < 0)			return retval;		break;	}	case FE_SET_TONE:		retval = dst_set_tone (dst, (fe_sec_tone_mode_t) arg);		if (retval < 0)			return retval;		break;	case FE_SET_VOLTAGE:		retval = dst_set_voltage (dst, (fe_sec_voltage_t) arg);		if (retval < 0)			return retval;		break;	default:		return -EOPNOTSUPP;        };                return 0;} static int dst_attach (struct dvb_i2c_bus *i2c, void **data){	struct dst_data *dst;	struct bt878 *bt;	struct dvb_frontend_info *info;	dprintk("%s: check ci\n", __FUNCTION__);	if (dst_cur_no >= DST_MAX_CARDS) {		dprintk("%s: can't have more than %d cards\n", __FUNCTION__, DST_MAX_CARDS);		return -ENODEV;	}	bt = bt878_find_by_dvb_adap(i2c->adapter);	if (!bt)		return -ENODEV;	dst = kmalloc(sizeof(struct dst_data), GFP_KERNEL);	if (dst == NULL) {		printk(KERN_INFO "%s: Out of memory.\n", __FUNCTION__);		return -ENOMEM;	}	memset(dst, 0, sizeof(*dst));	*data = dst;	dst->bt = bt;	dst->i2c = i2c;	if (dst_check_ci(dst) < 0) {		kfree(dst);		return -ENODEV;	}	dst_init (dst);	dprintk("%s: register dst %8.8x bt %8.8x i2c %8.8x\n", __FUNCTION__, 			(u32)dst, (u32)(dst->bt), (u32)(dst->i2c));	info = &dst_info_sat;	if (dst->dst_type == DST_TYPE_IS_TERR)		info = &dst_info_tv;	else if (dst->dst_type == DST_TYPE_IS_CABLE)		info = &dst_info_cable;	dvb_register_frontend (dst_ioctl, i2c, dst, info);	dst_cur_no++;	return 0;}static void dst_detach (struct dvb_i2c_bus *i2c, void *data){	dvb_unregister_frontend (dst_ioctl, i2c);	dprintk("%s: unregister dst %8.8x\n", __FUNCTION__, (u32)(data));	if (data)		kfree(data);}static int __init init_dst (void){	return dvb_register_i2c_device (THIS_MODULE, dst_attach, dst_detach);}static void __exit exit_dst (void){	dvb_unregister_i2c_device (dst_attach);}module_init(init_dst);module_exit(exit_dst);MODULE_DESCRIPTION("DST DVB-S Frontend");MODULE_AUTHOR("Jamie Honan");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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