📄 dst.c
字号:
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; } up(&state->dst_mutex); return 0;error: up(&state->dst_mutex); return -EIO;}EXPORT_SYMBOL(dst_command);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", __FUNCTION__); 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; } 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_TERR) return 0; 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); dst_command(state, paket, 8); return 0;}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_NEWTUNE) /* how to get variable length reply ???? */ 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_NEWTUNE) { 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); down(&state->dst_mutex); if ((dst_comm_init(state)) < 0) { dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); goto error; } if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); retval = write_dst(state, &state->tx_tuna[0], 10); } else { state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM); } if (retval < 0) { dst_pio_disable(state); dprintk(verbose, DST_DEBUG, 1, "write not successful"); goto werr; } if ((dst_pio_disable(state)) < 0) { dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); goto error; } if ((read_dst(state, &reply, GET_ACK) < 0)) { dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); goto error; } if (reply != ACK) { dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); goto error; } state->diseq_flags |= ATTEMPT_TUNE; retval = dst_get_tuna(state);werr: up(&state->dst_mutex); return retval;error: up(&state->dst_mutex); return -EIO;}/* * 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 dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd){ struct dst_state *state = fe->demodulator_priv; u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; if (state->dst_type != DST_TYPE_IS_SAT) return 0; if (cmd->msg_len == 0 || cmd->msg_len > 4) return -EINVAL; memcpy(&paket[3], cmd->msg, cmd->msg_len); paket[7] = dst_check_sum(&paket[0], 7); dst_command(state, paket, 8); return 0;}static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage){ int need_cmd; struct dst_state *state = fe->demodulator_priv; state->voltage = voltage; if (state->dst_type != DST_TYPE_IS_SAT) return 0; need_cmd = 0; switch (voltage) { case SEC_VOLTAGE_13: case SEC_VOLTAGE_18: if ((state->diseq_flags & HAS_POWER) == 0) need_cmd = 1; state->diseq_flags |= HAS_POWER; state->tx_tuna[4] = 0x01; break; case SEC_VOLTAGE_OFF: need_cmd = 1; state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); state->tx_tuna[4] = 0x00; break; default: return -EINVAL; } if (need_cmd) dst_tone_power_cmd(state); return 0;}static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone){ struct dst_state *state = fe->demodulator_priv; state->tone = tone; if (state->dst_type != DST_TYPE_IS_SAT) return 0; switch (tone) { case SEC_TONE_OFF: if (state->type_flags & DST_TYPE_HAS_OBS_REGS) state->tx_tuna[2] = 0x00; else state->tx_tuna[2] = 0xff; break; case SEC_TONE_ON: state->tx_tuna[2] = 0x02; break; default: return -EINVAL; } dst_tone_power_cmd(state); return 0;}static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd){ struct dst_state *state = fe->demodulator_priv; if (state->dst_type != DST_TYPE_IS_SAT) return 0; state->minicmd = minicmd; switch (minicmd) { case SEC_MINI_A: state->tx_tuna[3] = 0x02; break; case SEC_MINI_B: state->tx_tuna[3] = 0xff; break; } dst_tone_power_cmd(state); return 0;}static int dst_init(struct dvb_frontend *fe){ struct dst_state *state = fe->demodulator_priv; static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 }; static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; state->inversion = INVERSION_OFF; state->voltage = SEC_VOLTAGE_13; state->tone = SEC_TONE_OFF; state->diseq_flags = 0; state->k22 = 0x02; state->bandwidth = BANDWIDTH_7_MHZ; state->cur_jiff = jiffies; if (state->dst_type == DST_TYPE_IS_SAT) memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); else if (state->dst_type == DST_TYPE_IS_TERR) memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); else if (state->dst_type == DST_TYPE_IS_CABLE) memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); return 0;}static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status){ struct dst_state *state = fe->demodulator_priv; *status = 0; if (state->diseq_flags & HAS_LOCK) {// dst_get_signal(state); // don't require(?) to ask MCU if (state->decode_lock) *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI; } return 0;}static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength){ struct dst_state *state = fe->demodulator_priv; dst_get_signal(state); *strength = state->decode_strength; return 0;}static int dst_read_snr(struct dvb_frontend *fe, u16 *snr){ struct dst_state *state = fe->demodulator_priv; dst_get_signal(state); *snr = state->decode_snr; return 0;}static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p){ struct dst_state *state = fe->demodulator_priv; dst_set_freq(state, p->frequency); dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); if (state->dst_type == DST_TYPE_IS_SAT) { if (state->type_flags & DST_TYPE_HAS_OBS_REGS) dst_set_inversion(state, p->inversion); dst_set_fec(state, p->u.qpsk.fec_inner); dst_set_symbolrate(state, p->u.qpsk.symbol_rate); dst_set_polarization(state); dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); } else if (state->dst_type == DST_TYPE_IS_TERR) dst_set_bandwidth(state, p->u.ofdm.bandwidth); else if (state->dst_type == DST_TYPE_IS_CABLE) { dst_set_fec(state, p->u.qam.fec_inner); dst_set_symbolrate(state, p->u.qam.symbol_rate); dst_set_modulation(state, p->u.qam.modulation); } dst_write_tuna(fe); return 0;}static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p){ struct dst_state *state = fe->demodulator_priv; p->frequency = state->decode_freq; if (state->dst_type == DST_TYPE_IS_SAT) { if (state->type_flags & DST_TYPE_HAS_OBS_REGS) p->inversion = state->inversion; p->u.qpsk.symbol_rate = state->symbol_rate; p->u.qpsk.fec_inner = dst_get_fec(state); } else if (state->dst_type == DST_TYPE_IS_TERR) { p->u.ofdm.bandwidth = state->bandwidth; } else if (state->dst_type == DST_TYPE_IS_CABLE) { p->u.qam.symbol_rate = state->symbol_rate; p->u.qam.fec_inner = dst_get_fec(state); p->u.qam.modulation = dst_get_modulation(state); } return 0;}static void dst_release(struct dvb_frontend *fe){ struct dst_state *state = fe->demodulator_priv; kfree(state);}static struct dvb_frontend_ops dst_dvbt_ops;static struct dvb_frontend_ops dst_dvbs_ops;static struct dvb_frontend_ops dst_dvbc_ops;struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter){ /* check if the ASIC is there */ if (dst_probe(state) < 0) { kfree(state); return NULL; } /* determine settings based on type */ switch (state->dst_type) { case DST_TYPE_IS_TERR: memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); break; case DST_TYPE_IS_CABLE: memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); break; case DST_TYPE_IS_SAT: memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); break; default: dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); kfree(state); return NULL; } /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return state; /* Manu (DST is a card not a frontend) */}EXPORT_SYMBOL(dst_attach);static struct dvb_frontend_ops dst_dvbt_ops = { .info = { .name = "DST DVB-T", .type = FE_OFDM, .frequency_min = 137000000, .frequency_max = 858000000, .frequency_stepsize = 166667, .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO }, .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr,};static struct dvb_frontend_ops dst_dvbs_ops = { .info = { .name = "DST DVB-S", .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 1000, /* kHz for QPSK frontends */ .frequency_tolerance = 29500, .symbol_rate_min = 1000000, .symbol_rate_max = 45000000, /* . symbol_rate_tolerance = ???,*/ .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK }, .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr, .diseqc_send_burst = dst_send_burst, .diseqc_send_master_cmd = dst_set_diseqc, .set_voltage = dst_set_voltage, .set_tone = dst_set_tone,};static struct dvb_frontend_ops dst_dvbc_ops = { .info = { .name = "DST DVB-C", .type = FE_QAM, .frequency_stepsize = 62500, .frequency_min = 51000000, .frequency_max = 858000000, .symbol_rate_min = 1000000, .symbol_rate_max = 45000000, /* . symbol_rate_tolerance = ???,*/ .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO }, .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr,};MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");MODULE_AUTHOR("Jamie Honan, Manu Abraham");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -