📄 nxt6000.c
字号:
printk(" VITERBI CODERATE: 2/3,"); break; case 0x02: printk(" VITERBI CODERATE: 3/4,"); break; case 0x03: printk(" VITERBI CODERATE: 5/6,"); break; case 0x04: printk(" VITERBI CODERATE: 7/8,"); break; default: printk(" VITERBI CODERATE: Reserved,"); } val = nxt6000_readreg(fe, OFDM_COR_STAT); printk(" CHCTrack: %d,", (val >> 7) & 0x01); printk(" TPSLock: %d,", (val >> 6) & 0x01); printk(" SYRLock: %d,", (val >> 5) & 0x01); printk(" AGCLock: %d,", (val >> 4) & 0x01); switch (val & 0x0F) { case 0x00: printk(" CoreState: IDLE,"); break; case 0x02: printk(" CoreState: WAIT_AGC,"); break; case 0x03: printk(" CoreState: WAIT_SYR,"); break; case 0x04: printk(" CoreState: WAIT_PPM,"); break; case 0x01: printk(" CoreState: WAIT_TRL,"); break; case 0x05: printk(" CoreState: WAIT_TPS,"); break; case 0x06: printk(" CoreState: MONITOR_TPS,"); break; default: printk(" CoreState: Reserved,"); } val = nxt6000_readreg(fe, OFDM_SYR_STAT); printk(" SYRLock: %d,", (val >> 4) & 0x01); printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K"); switch ((val >> 4) & 0x03) { case 0x00: printk(" SYRGuard: 1/32,"); break; case 0x01: printk(" SYRGuard: 1/16,"); break; case 0x02: printk(" SYRGuard: 1/8,"); break; case 0x03: printk(" SYRGuard: 1/4,"); break; } val = nxt6000_readreg(fe, OFDM_TPS_RCVD_3); switch ((val >> 4) & 0x07) { case 0x00: printk(" TPSLP: 1/2,"); break; case 0x01: printk(" TPSLP: 2/3,"); break; case 0x02: printk(" TPSLP: 3/4,"); break; case 0x03: printk(" TPSLP: 5/6,"); break; case 0x04: printk(" TPSLP: 7/8,"); break; default: printk(" TPSLP: Reserved,"); } switch (val & 0x07) { case 0x00: printk(" TPSHP: 1/2,"); break; case 0x01: printk(" TPSHP: 2/3,"); break; case 0x02: printk(" TPSHP: 3/4,"); break; case 0x03: printk(" TPSHP: 5/6,"); break; case 0x04: printk(" TPSHP: 7/8,"); break; default: printk(" TPSHP: Reserved,"); } val = nxt6000_readreg(fe, OFDM_TPS_RCVD_4); printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K"); switch ((val >> 4) & 0x03) { case 0x00: printk(" TPSGuard: 1/32,"); break; case 0x01: printk(" TPSGuard: 1/16,"); break; case 0x02: printk(" TPSGuard: 1/8,"); break; case 0x03: printk(" TPSGuard: 1/4,"); break; } /* Strange magic required to gain access to RF_AGC_STATUS */ nxt6000_readreg(fe, RF_AGC_VAL_1); val = nxt6000_readreg(fe, RF_AGC_STATUS); val = nxt6000_readreg(fe, RF_AGC_STATUS); printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01); printk("\n");}static int nxt6000_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg){ switch (cmd) { case FE_GET_INFO: memcpy(arg, &nxt6000_info, sizeof(struct dvb_frontend_info)); return 0; case FE_READ_STATUS: { fe_status_t *status = (fe_status_t *) arg; u8 core_status; *status = 0; core_status = nxt6000_readreg(fe, OFDM_COR_STAT); if (core_status & AGCLOCKED) *status |= FE_HAS_SIGNAL; if (nxt6000_readreg(fe, OFDM_SYR_STAT) & GI14_SYR_LOCK) *status |= FE_HAS_CARRIER; if (nxt6000_readreg(fe, VIT_SYNC_STATUS) & VITINSYNC) *status |= FE_HAS_VITERBI; if (nxt6000_readreg(fe, RS_COR_STAT) & RSCORESTATUS) *status |= FE_HAS_SYNC; if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))) *status |= FE_HAS_LOCK; if (debug) nxt6000_dump_status(fe); return 0; } case FE_READ_BER: { u32 *ber = (u32 *) arg; *ber = 0; return 0; } case FE_READ_SIGNAL_STRENGTH: { s16 *signal = (s16 *) arg;/* *signal=(((signed char)readreg(client, 0x16))+128)<<8;*/ *signal = 0; return 0; } case FE_READ_SNR: { s16 *snr = (s16 *) arg;/* *snr=readreg(client, 0x24)<<8; *snr|=readreg(client, 0x25);*/ *snr = 0; break; } case FE_READ_UNCORRECTED_BLOCKS: { u32 *ublocks = (u32 *) arg; *ublocks = 0; break; } case FE_INIT: nxt6000_reset(fe); nxt6000_setup(fe); break; case FE_RESET: break; case FE_SET_FRONTEND: { struct nxt6000_config *nxt = FE2NXT(fe); struct dvb_frontend_parameters *param = (struct dvb_frontend_parameters *) arg; int result; switch (nxt->tuner_type) { case TUNER_TYPE_ALP510: if ((result = alp510_set_tv_freq(fe, param->frequency)) < 0) return result; break; case TUNER_TYPE_SP5659: if ((result = sp5659_set_tv_freq(fe, param->frequency)) < 0) return result; break; case TUNER_TYPE_SP5730: if ((result = sp5730_set_tv_freq(fe, param->frequency)) < 0) return result; break; default: return -EFAULT; } if ((result = nxt6000_set_bandwidth(fe, param->u.ofdm.bandwidth)) < 0) return result; if ((result = nxt6000_set_guard_interval(fe, param->u.ofdm.guard_interval)) < 0) return result; if ((result = nxt6000_set_transmission_mode(fe, param->u.ofdm.transmission_mode)) < 0) return result; if ((result = nxt6000_set_inversion(fe, param->inversion)) < 0) return result; break; } default: return -EOPNOTSUPP; } return 0;}static u8 demod_addr_tbl[] = { 0x14, 0x18, 0x24, 0x28 };static int nxt6000_attach(struct dvb_i2c_bus *i2c, void **data){ u8 addr_nr; u8 fe_count = 0; struct nxt6000_config *pnxt; dprintk("nxt6000: attach\n"); pnxt = kmalloc(sizeof(demod_addr_tbl)*sizeof(struct nxt6000_config), GFP_KERNEL); if (NULL == pnxt) { dprintk("nxt6000: no memory for private data.\n"); return -ENOMEM; } *data = pnxt; for (addr_nr = 0; addr_nr < sizeof(demod_addr_tbl); addr_nr++) { struct nxt6000_config *nxt = &pnxt[addr_nr]; if (nxt6000_read(i2c, demod_addr_tbl[addr_nr], OFDM_MSC_REV) != NXT6000ASICDEVICE) continue; if (pll_test(i2c, demod_addr_tbl[addr_nr], 0xC0) == 0) { nxt->tuner_addr = 0xC0; nxt->tuner_type = TUNER_TYPE_ALP510; nxt->clock_inversion = 1; dprintk("nxt6000: detected TI ALP510 tuner at 0x%02X\n", nxt->tuner_addr); } else if (pll_test(i2c, demod_addr_tbl[addr_nr], 0xC2) == 0) { nxt->tuner_addr = 0xC2; nxt->tuner_type = TUNER_TYPE_SP5659; nxt->clock_inversion = 0; dprintk("nxt6000: detected MITEL SP5659 tuner at 0x%02X\n", nxt->tuner_addr); } else if (pll_test(i2c, demod_addr_tbl[addr_nr], 0xC0) == 0) { nxt->tuner_addr = 0xC0; nxt->tuner_type = TUNER_TYPE_SP5730; nxt->clock_inversion = 0; dprintk("nxt6000: detected SP5730 tuner at 0x%02X\n", nxt->tuner_addr); } else { printk("nxt6000: unable to detect tuner\n"); continue; } nxt->demod_addr = demod_addr_tbl[addr_nr]; dprintk("nxt6000: attached at %d:%d\n", i2c->adapter->num, i2c->id); dvb_register_frontend(nxt6000_ioctl, i2c, (void *)nxt, &nxt6000_info); fe_count++; } if (fe_count == 0) { kfree(pnxt); return -ENODEV; } return 0;}static void nxt6000_detach(struct dvb_i2c_bus *i2c, void *data){ struct nxt6000_config *pnxt = (struct nxt6000_config *)data; dprintk("nxt6000: detach\n"); dvb_unregister_frontend(nxt6000_ioctl, i2c); kfree(pnxt);}static __init int nxt6000_init(void){ dprintk("nxt6000: init\n"); return dvb_register_i2c_device(THIS_MODULE, nxt6000_attach, nxt6000_detach);}static __exit void nxt6000_exit(void){ dprintk("nxt6000: cleanup\n"); dvb_unregister_i2c_device(nxt6000_attach);}module_init(nxt6000_init);module_exit(nxt6000_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -