📄 stv0299.c
字号:
else if (((first_ZF >= 1350) && (first_ZF < 1420)) || ((first_ZF >= 1950) && (first_ZF < 2150))) reg0[1] = 0x0B; else if ((first_ZF >= 1420) && (first_ZF < 1455)) reg0[1] = 0x0F; } if (first_ZF > 1525) reg1[1] |= 0x80; else reg1[1] &= 0x7F; if (_fband == 2) { if (first_ZF > 1430) { /* 1430MHZ */ reg1[1] &= 0xCF; /* N2 */ reg2[1] &= 0xCF; /* R2 */ reg2[1] |= 0x10; } else { reg1[1] &= 0xCF; /* N2 */ reg1[1] |= 0x20; reg2[1] &= 0xCF; /* R2 */ reg2[1] |= 0x10; } } if (_fband == 3) { if ((first_ZF >= 1455) && (first_ZF < 1630)) { reg1[1] &= 0xCF; /* N2 */ reg1[1] |= 0x20; reg2[1] &= 0xCF; /* R2 */ } else { if (first_ZF < 1455) { reg1[1] &= 0xCF; /* N2 */ reg1[1] |= 0x20; reg2[1] &= 0xCF; /* R2 */ reg2[1] |= 0x10; } else { if (first_ZF >= 1630) { reg1[1] &= 0xCF; /* N2 */ reg2[1] &= 0xCF; /* R2 */ reg2[1] |= 0x10; } } } } /* set ports, enable P0 for symbol rates > 4Ms/s */ if (srate >= 4000000) reg1[1] |= 0x0c; else reg1[1] |= 0x04; reg2[1] |= 0x0c; R = 64; A = 64; P = 64; //32 M = (freq * R) / 4; /* in Mhz */ N = (M - A * 1000) / (P * 1000); reg1[1] |= (N >> 9) & 0x03; reg1[2] = (N >> 1) & 0xff; reg1[3] = (N << 7) & 0x80; reg2[1] |= (R >> 8) & 0x03; reg2[2] = R & 0xFF; /* R */ reg1[3] |= A & 0x7f; /* A */ if (P == 64) reg1[1] |= 0x40; /* Prescaler 64/65 */ reg0[1] |= 0x03; if ((err = pll_write(i2c, 0x60, reg0, sizeof(reg0)))) return err; if ((err = pll_write(i2c, 0x60, reg1, sizeof(reg1)))) return err; if ((err = pll_write(i2c, 0x60, reg2, sizeof(reg2)))) return err; return 0;}static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate){ switch(ftype) { case SAMSUNG_TBMU24112IMB: return sl1935_set_tv_freq(i2c, freq, ftype); case LG_TDQF_S001F: return sl1935_set_tv_freq(i2c, freq, ftype); case PHILIPS_SU1278_TUA: return tua6100_set_tv_freq(i2c, freq, ftype, srate); default: return tsa5059_set_tv_freq(i2c, freq, ftype, srate); }}#if 0static int tsa5059_read_status (struct dvb_i2c_bus *i2c){ int ret; u8 rpt1 [] = { 0x05, 0xb5 }; u8 stat [] = { 0 }; struct i2c_msg msg [] = {{ .addr = 0x68, .flags = 0, .buf = rpt1, .len = 2 }, { .addr = 0x60, .flags = I2C_M_RD, .buf = stat, .len = 1 }}; dprintk ("%s\n", __FUNCTION__); ret = i2c->xfer (i2c, msg, 2); if (ret != 2) dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); return stat[0];}#endifstatic int stv0299_init (struct dvb_i2c_bus *i2c, int ftype){ int i; dprintk("stv0299: init chip\n"); switch(ftype) { case SAMSUNG_TBMU24112IMB: dprintk("%s: init stv0299 chip for Samsung TBMU24112IMB\n", __FUNCTION__); for (i=0; i<sizeof(init_tab_samsung); i+=2) { dprintk("%s: reg == 0x%02x, val == 0x%02x\n", __FUNCTION__, init_tab_samsung[i], init_tab_samsung[i+1]); stv0299_writereg (i2c, init_tab_samsung[i], init_tab_samsung[i+1]); } break; case PHILIPS_SU1278_TSA_TT: for (i=0; i<sizeof(init_tab_su1278_tsa_tt); i+=2) { stv0299_writereg (i2c, init_tab_su1278_tsa_tt[i], init_tab_su1278_tsa_tt[i+1]); } break; default: stv0299_writereg (i2c, 0x01, 0x15); stv0299_writereg (i2c, 0x02, ftype == PHILIPS_SU1278_TUA ? 0x00 : 0x30); stv0299_writereg (i2c, 0x03, 0x00); for (i=0; i<sizeof(init_tab); i+=2) stv0299_writereg (i2c, init_tab[i], init_tab[i+1]); /* AGC1 reference register setup */ if (ftype == PHILIPS_SU1278_TSA) stv0299_writereg (i2c, 0x0f, 0x92); /* Iagc = Inverse, m1 = 18 */ else if (ftype == PHILIPS_SU1278_TUA) stv0299_writereg (i2c, 0x0f, 0x94); /* Iagc = Inverse, m1 = 20 */ else stv0299_writereg (i2c, 0x0f, 0x52); /* Iagc = Normal, m1 = 18 */ break; } switch(stv0299_status) { case STATUS_BER: stv0299_writereg(i2c, 0x34, 0x93); break; case STATUS_UCBLOCKS: stv0299_writereg(i2c, 0x34, 0xB3); break; } return 0;}static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec){ dprintk ("%s\n", __FUNCTION__); switch (fec) { case FEC_AUTO: { dprintk ("%s : FEC_AUTO\n", __FUNCTION__); return stv0299_writereg (i2c, 0x31, 0x1f); } case FEC_1_2: { dprintk ("%s : FEC_1_2\n", __FUNCTION__); return stv0299_writereg (i2c, 0x31, 0x01); } case FEC_2_3: { dprintk ("%s : FEC_2_3\n", __FUNCTION__); return stv0299_writereg (i2c, 0x31, 0x02); } case FEC_3_4: { dprintk ("%s : FEC_3_4\n", __FUNCTION__); return stv0299_writereg (i2c, 0x31, 0x04); } case FEC_5_6: { dprintk ("%s : FEC_5_6\n", __FUNCTION__); return stv0299_writereg (i2c, 0x31, 0x08); } case FEC_7_8: { dprintk ("%s : FEC_7_8\n", __FUNCTION__); return stv0299_writereg (i2c, 0x31, 0x10); } default: { dprintk ("%s : FEC invalid\n", __FUNCTION__); return -EINVAL; } }}static fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c){ static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_1_2 }; u8 index; dprintk ("%s\n", __FUNCTION__); index = stv0299_readreg (i2c, 0x1b); index &= 0x7; if (index > 4) return FEC_AUTO; return fec_tab [index];}static int stv0299_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout){ unsigned long start = jiffies; dprintk ("%s\n", __FUNCTION__); while (stv0299_readreg(i2c, 0x0a) & 1) { if (jiffies - start > timeout) { dprintk ("%s: timeout!!\n", __FUNCTION__); return -ETIMEDOUT; } dvb_delay(10); }; return 0;}static int stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c, int timeout){ unsigned long start = jiffies; dprintk ("%s\n", __FUNCTION__); while ((stv0299_readreg(i2c, 0x0a) & 3) != 2 ) { if (jiffies - start > timeout) { dprintk ("%s: timeout!!\n", __FUNCTION__); return -ETIMEDOUT; } dvb_delay(10); }; return 0;}static int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c, struct dvb_diseqc_master_cmd *m){ u8 val; int i; dprintk ("%s\n", __FUNCTION__); if (stv0299_wait_diseqc_idle (i2c, 100) < 0) return -ETIMEDOUT; val = stv0299_readreg (i2c, 0x08); if (stv0299_writereg (i2c, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */ return -EREMOTEIO; for (i=0; i<m->msg_len; i++) { if (stv0299_wait_diseqc_fifo (i2c, 100) < 0) return -ETIMEDOUT; if (stv0299_writereg (i2c, 0x09, m->msg[i])) return -EREMOTEIO; } if (stv0299_wait_diseqc_idle (i2c, 100) < 0) return -ETIMEDOUT; return 0;}static int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst){ u8 val; dprintk ("%s\n", __FUNCTION__); if (stv0299_wait_diseqc_idle (i2c, 100) < 0) return -ETIMEDOUT; val = stv0299_readreg (i2c, 0x08); if (stv0299_writereg (i2c, 0x08, (val & ~0x7) | 0x2)) /* burst mode */ return -EREMOTEIO; if (stv0299_writereg (i2c, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff)) return -EREMOTEIO; if (stv0299_wait_diseqc_idle (i2c, 100) < 0) return -ETIMEDOUT; if (stv0299_writereg (i2c, 0x08, val)) return -EREMOTEIO; return 0;}static int stv0299_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone){ u8 val; dprintk("%s: %s\n", __FUNCTION__, tone == SEC_TONE_ON ? "SEC_TONE_ON" : tone == SEC_TONE_OFF ? "SEC_TONE_OFF" : "??"); if (stv0299_wait_diseqc_idle (i2c, 100) < 0) return -ETIMEDOUT; val = stv0299_readreg (i2c, 0x08); switch (tone) { case SEC_TONE_ON: { dprintk("%s: TONE_ON\n", __FUNCTION__); return stv0299_writereg (i2c, 0x08, val | 0x3); } case SEC_TONE_OFF: { dprintk("%s: TONE_OFF\n", __FUNCTION__); return stv0299_writereg (i2c, 0x08, (val & ~0x3) | 0x02); } default: { dprintk("%s: TONE INVALID\n", __FUNCTION__); return -EINVAL; } };}static int stv0299_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage){ u8 reg0x08; u8 reg0x0c; dprintk("%s: %s\n", __FUNCTION__, voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); reg0x08 = stv0299_readreg (i2c, 0x08); reg0x0c = stv0299_readreg (i2c, 0x0c); /** * H/V switching over OP0, OP1 and OP2 are LNB power enable bits */ reg0x0c &= 0x0f; if (voltage == SEC_VOLTAGE_OFF) { stv0299_writereg (i2c, 0x08, reg0x08 & ~0x40); return stv0299_writereg (i2c, 0x0c, reg0x0c & ~0x40); } else { stv0299_writereg (i2c, 0x08, reg0x08 | 0x40); reg0x0c |= 0x40; /* LNB power on */ switch (voltage) { case SEC_VOLTAGE_13: return stv0299_writereg (i2c, 0x0c, reg0x0c); case SEC_VOLTAGE_18: return stv0299_writereg (i2c, 0x0c, reg0x0c | 0x10); default: return -EINVAL; }; }}static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner_type){ u64 big = srate; u32 ratio; u8 aclk = 0; u8 bclk = 0; u8 m1; int Mclk = M_CLK; // check rate is within limits if ((srate < 1000000) || (srate > 45000000)) return -EINVAL; // calculate value to program if (tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT; big = big << 20; big += (Mclk-1); // round correctly do_div(big, Mclk); ratio = big << 4; // program registers switch(tuner_type) { case PHILIPS_SU1278_TSA_TT: stv0299_writereg (i2c, 0x0e, 0x44); if (srate >= 10000000) { stv0299_writereg (i2c, 0x13, 0x97); stv0299_writereg (i2c, 0x14, 0x95); stv0299_writereg (i2c, 0x15, 0xc9); stv0299_writereg (i2c, 0x17, 0x8c); stv0299_writereg (i2c, 0x1a, 0xfe); stv0299_writereg (i2c, 0x1c, 0x7f); stv0299_writereg (i2c, 0x2d, 0x09); } else { stv0299_writereg (i2c, 0x13, 0x99); stv0299_writereg (i2c, 0x14, 0x8d); stv0299_writereg (i2c, 0x15, 0xce); stv0299_writereg (i2c, 0x17, 0x43);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -