dst.c
来自「trident tm5600的linux驱动」· C语言 代码 · 共 1,866 行 · 第 1/4 页
C
1,866 行
dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); goto error; }// if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { if ((state->type_flags & DST_TYPE_HAS_VLF) && (!(state->dst_type == DST_TYPE_IS_ATSC))) { 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: mutex_unlock(&state->dst_mutex); return retval;error: mutex_unlock(&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 -EOPNOTSUPP; if (cmd->msg_len > 0 && cmd->msg_len < 5) memcpy(&paket[3], cmd->msg, cmd->msg_len); else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) memcpy(&paket[2], cmd->msg, cmd->msg_len); else return -EINVAL; paket[7] = dst_check_sum(&paket[0], 7); return dst_command(state, paket, 8);}static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage){ int need_cmd, retval = 0; struct dst_state *state = fe->demodulator_priv; state->voltage = voltage; if (state->dst_type != DST_TYPE_IS_SAT) return -EOPNOTSUPP; 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) retval = dst_tone_power_cmd(state); return retval;}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 -EOPNOTSUPP; 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; } return dst_tone_power_cmd(state);}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 -EOPNOTSUPP; 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; } return dst_tone_power_cmd(state);}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_188[] = { 0x09, 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 atsc_tuner[] = { 0x00, 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_VLF) ? 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_VLF) ? 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_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); else if (state->dst_type == DST_TYPE_IS_ATSC) memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner)); 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; int retval = dst_get_signal(state); *strength = state->decode_strength; return retval;}static int dst_read_snr(struct dvb_frontend *fe, u16 *snr){ struct dst_state *state = fe->demodulator_priv; int retval = dst_get_signal(state); *snr = state->decode_snr; return retval;}static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p){ int retval = -EINVAL; struct dst_state *state = fe->demodulator_priv; if (p != NULL) { retval = dst_set_freq(state, p->frequency); if(retval != 0) return retval; 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); } retval = dst_write_tuna(fe); } return retval;}static int dst_tune_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* p, unsigned int mode_flags, unsigned int *delay, fe_status_t *status){ struct dst_state *state = fe->demodulator_priv; if (p != NULL) { 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); } if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) dst_read_status(fe, status); *delay = HZ/10; return 0;}static int dst_get_tuning_algo(struct dvb_frontend *fe){ return dst_algo;}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; if (state->dst_ca) { dvb_unregister_device(state->dst_ca);#ifdef CONFIG_MEDIA_ATTACH symbol_put(dst_ca_attach);#endif } 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;static struct dvb_frontend_ops dst_atsc_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 */ /* create dvb_frontend */ switch (state->dst_type) { case DST_TYPE_IS_TERR: memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); break; case DST_TYPE_IS_CABLE: memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); break; case DST_TYPE_IS_SAT: memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); break; case DST_TYPE_IS_ATSC: memcpy(&state->frontend.ops, &dst_atsc_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; } 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, .tune = dst_tune_frontend, .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .get_frontend_algo = dst_get_tuning_algo, .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, .tune = dst_tune_frontend, .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .get_frontend_algo = dst_get_tuning_algo, .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, .tune = dst_tune_frontend, .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .get_frontend_algo = dst_get_tuning_algo, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr,};static struct dvb_frontend_ops dst_atsc_ops = { .info = { .name = "DST ATSC", .type = FE_ATSC, .frequency_stepsize = 62500, .frequency_min = 510000000, .frequency_max = 858000000, .symbol_rate_min = 1000000, .symbol_rate_max = 45000000, .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB }, .release = dst_release, .init = dst_init, .tune = dst_tune_frontend, .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .get_frontend_algo = dst_get_tuning_algo, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr,};MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");MODULE_AUTHOR("Jamie Honan, Manu Abraham");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?