2 * Realtek RTL2832 DVB-T demodulator driver
4 * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "rtl2832_priv.h"
25 module_param_named(debug, rtl2832_debug, int, 0644);
26 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
29 static const int reg_mask[32] = {
64 static const struct rtl2832_reg_entry registers[] = {
65 [DVBT_SOFT_RST] = {0x1, 0x1, 2, 2},
66 [DVBT_IIC_REPEAT] = {0x1, 0x1, 3, 3},
67 [DVBT_TR_WAIT_MIN_8K] = {0x1, 0x88, 11, 2},
68 [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
69 [DVBT_EN_BK_TRK] = {0x1, 0xa6, 7, 7},
70 [DVBT_AD_EN_REG] = {0x0, 0x8, 7, 7},
71 [DVBT_AD_EN_REG1] = {0x0, 0x8, 6, 6},
72 [DVBT_EN_BBIN] = {0x1, 0xb1, 0, 0},
73 [DVBT_MGD_THD0] = {0x1, 0x95, 7, 0},
74 [DVBT_MGD_THD1] = {0x1, 0x96, 7, 0},
75 [DVBT_MGD_THD2] = {0x1, 0x97, 7, 0},
76 [DVBT_MGD_THD3] = {0x1, 0x98, 7, 0},
77 [DVBT_MGD_THD4] = {0x1, 0x99, 7, 0},
78 [DVBT_MGD_THD5] = {0x1, 0x9a, 7, 0},
79 [DVBT_MGD_THD6] = {0x1, 0x9b, 7, 0},
80 [DVBT_MGD_THD7] = {0x1, 0x9c, 7, 0},
81 [DVBT_EN_CACQ_NOTCH] = {0x1, 0x61, 4, 4},
82 [DVBT_AD_AV_REF] = {0x0, 0x9, 6, 0},
83 [DVBT_REG_PI] = {0x0, 0xa, 2, 0},
84 [DVBT_PIP_ON] = {0x0, 0x21, 3, 3},
85 [DVBT_SCALE1_B92] = {0x2, 0x92, 7, 0},
86 [DVBT_SCALE1_B93] = {0x2, 0x93, 7, 0},
87 [DVBT_SCALE1_BA7] = {0x2, 0xa7, 7, 0},
88 [DVBT_SCALE1_BA9] = {0x2, 0xa9, 7, 0},
89 [DVBT_SCALE1_BAA] = {0x2, 0xaa, 7, 0},
90 [DVBT_SCALE1_BAB] = {0x2, 0xab, 7, 0},
91 [DVBT_SCALE1_BAC] = {0x2, 0xac, 7, 0},
92 [DVBT_SCALE1_BB0] = {0x2, 0xb0, 7, 0},
93 [DVBT_SCALE1_BB1] = {0x2, 0xb1, 7, 0},
94 [DVBT_KB_P1] = {0x1, 0x64, 3, 1},
95 [DVBT_KB_P2] = {0x1, 0x64, 6, 4},
96 [DVBT_KB_P3] = {0x1, 0x65, 2, 0},
97 [DVBT_OPT_ADC_IQ] = {0x0, 0x6, 5, 4},
98 [DVBT_AD_AVI] = {0x0, 0x9, 1, 0},
99 [DVBT_AD_AVQ] = {0x0, 0x9, 3, 2},
100 [DVBT_K1_CR_STEP12] = {0x2, 0xad, 9, 4},
101 [DVBT_TRK_KS_P2] = {0x1, 0x6f, 2, 0},
102 [DVBT_TRK_KS_I2] = {0x1, 0x70, 5, 3},
103 [DVBT_TR_THD_SET2] = {0x1, 0x72, 3, 0},
104 [DVBT_TRK_KC_P2] = {0x1, 0x73, 5, 3},
105 [DVBT_TRK_KC_I2] = {0x1, 0x75, 2, 0},
106 [DVBT_CR_THD_SET2] = {0x1, 0x76, 7, 6},
107 [DVBT_PSET_IFFREQ] = {0x1, 0x19, 21, 0},
108 [DVBT_SPEC_INV] = {0x1, 0x15, 0, 0},
109 [DVBT_RSAMP_RATIO] = {0x1, 0x9f, 27, 2},
110 [DVBT_CFREQ_OFF_RATIO] = {0x1, 0x9d, 23, 4},
111 [DVBT_FSM_STAGE] = {0x3, 0x51, 6, 3},
112 [DVBT_RX_CONSTEL] = {0x3, 0x3c, 3, 2},
113 [DVBT_RX_HIER] = {0x3, 0x3c, 6, 4},
114 [DVBT_RX_C_RATE_LP] = {0x3, 0x3d, 2, 0},
115 [DVBT_RX_C_RATE_HP] = {0x3, 0x3d, 5, 3},
116 [DVBT_GI_IDX] = {0x3, 0x51, 1, 0},
117 [DVBT_FFT_MODE_IDX] = {0x3, 0x51, 2, 2},
118 [DVBT_RSD_BER_EST] = {0x3, 0x4e, 15, 0},
119 [DVBT_CE_EST_EVM] = {0x4, 0xc, 15, 0},
120 [DVBT_RF_AGC_VAL] = {0x3, 0x5b, 13, 0},
121 [DVBT_IF_AGC_VAL] = {0x3, 0x59, 13, 0},
122 [DVBT_DAGC_VAL] = {0x3, 0x5, 7, 0},
123 [DVBT_SFREQ_OFF] = {0x3, 0x18, 13, 0},
124 [DVBT_CFREQ_OFF] = {0x3, 0x5f, 17, 0},
125 [DVBT_POLAR_RF_AGC] = {0x0, 0xe, 1, 1},
126 [DVBT_POLAR_IF_AGC] = {0x0, 0xe, 0, 0},
127 [DVBT_AAGC_HOLD] = {0x1, 0x4, 5, 5},
128 [DVBT_EN_RF_AGC] = {0x1, 0x4, 6, 6},
129 [DVBT_EN_IF_AGC] = {0x1, 0x4, 7, 7},
130 [DVBT_IF_AGC_MIN] = {0x1, 0x8, 7, 0},
131 [DVBT_IF_AGC_MAX] = {0x1, 0x9, 7, 0},
132 [DVBT_RF_AGC_MIN] = {0x1, 0xa, 7, 0},
133 [DVBT_RF_AGC_MAX] = {0x1, 0xb, 7, 0},
134 [DVBT_IF_AGC_MAN] = {0x1, 0xc, 6, 6},
135 [DVBT_IF_AGC_MAN_VAL] = {0x1, 0xc, 13, 0},
136 [DVBT_RF_AGC_MAN] = {0x1, 0xe, 6, 6},
137 [DVBT_RF_AGC_MAN_VAL] = {0x1, 0xe, 13, 0},
138 [DVBT_DAGC_TRG_VAL] = {0x1, 0x12, 7, 0},
139 [DVBT_AGC_TARG_VAL_0] = {0x1, 0x2, 0, 0},
140 [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3, 7, 0},
141 [DVBT_AAGC_LOOP_GAIN] = {0x1, 0xc7, 5, 1},
142 [DVBT_LOOP_GAIN2_3_0] = {0x1, 0x4, 4, 1},
143 [DVBT_LOOP_GAIN2_4] = {0x1, 0x5, 7, 7},
144 [DVBT_LOOP_GAIN3] = {0x1, 0xc8, 4, 0},
145 [DVBT_VTOP1] = {0x1, 0x6, 5, 0},
146 [DVBT_VTOP2] = {0x1, 0xc9, 5, 0},
147 [DVBT_VTOP3] = {0x1, 0xca, 5, 0},
148 [DVBT_KRF1] = {0x1, 0xcb, 7, 0},
149 [DVBT_KRF2] = {0x1, 0x7, 7, 0},
150 [DVBT_KRF3] = {0x1, 0xcd, 7, 0},
151 [DVBT_KRF4] = {0x1, 0xce, 7, 0},
152 [DVBT_EN_GI_PGA] = {0x1, 0xe5, 0, 0},
153 [DVBT_THD_LOCK_UP] = {0x1, 0xd9, 8, 0},
154 [DVBT_THD_LOCK_DW] = {0x1, 0xdb, 8, 0},
155 [DVBT_THD_UP1] = {0x1, 0xdd, 7, 0},
156 [DVBT_THD_DW1] = {0x1, 0xde, 7, 0},
157 [DVBT_INTER_CNT_LEN] = {0x1, 0xd8, 3, 0},
158 [DVBT_GI_PGA_STATE] = {0x1, 0xe6, 3, 3},
159 [DVBT_EN_AGC_PGA] = {0x1, 0xd7, 0, 0},
160 [DVBT_CKOUTPAR] = {0x1, 0x7b, 5, 5},
161 [DVBT_CKOUT_PWR] = {0x1, 0x7b, 6, 6},
162 [DVBT_SYNC_DUR] = {0x1, 0x7b, 7, 7},
163 [DVBT_ERR_DUR] = {0x1, 0x7c, 0, 0},
164 [DVBT_SYNC_LVL] = {0x1, 0x7c, 1, 1},
165 [DVBT_ERR_LVL] = {0x1, 0x7c, 2, 2},
166 [DVBT_VAL_LVL] = {0x1, 0x7c, 3, 3},
167 [DVBT_SERIAL] = {0x1, 0x7c, 4, 4},
168 [DVBT_SER_LSB] = {0x1, 0x7c, 5, 5},
169 [DVBT_CDIV_PH0] = {0x1, 0x7d, 3, 0},
170 [DVBT_CDIV_PH1] = {0x1, 0x7d, 7, 4},
171 [DVBT_MPEG_IO_OPT_2_2] = {0x0, 0x6, 7, 7},
172 [DVBT_MPEG_IO_OPT_1_0] = {0x0, 0x7, 7, 6},
173 [DVBT_CKOUTPAR_PIP] = {0x0, 0xb7, 4, 4},
174 [DVBT_CKOUT_PWR_PIP] = {0x0, 0xb7, 3, 3},
175 [DVBT_SYNC_LVL_PIP] = {0x0, 0xb7, 2, 2},
176 [DVBT_ERR_LVL_PIP] = {0x0, 0xb7, 1, 1},
177 [DVBT_VAL_LVL_PIP] = {0x0, 0xb7, 0, 0},
178 [DVBT_CKOUTPAR_PID] = {0x0, 0xb9, 4, 4},
179 [DVBT_CKOUT_PWR_PID] = {0x0, 0xb9, 3, 3},
180 [DVBT_SYNC_LVL_PID] = {0x0, 0xb9, 2, 2},
181 [DVBT_ERR_LVL_PID] = {0x0, 0xb9, 1, 1},
182 [DVBT_VAL_LVL_PID] = {0x0, 0xb9, 0, 0},
183 [DVBT_SM_PASS] = {0x1, 0x93, 11, 0},
184 [DVBT_AD7_SETTING] = {0x0, 0x11, 15, 0},
185 [DVBT_RSSI_R] = {0x3, 0x1, 6, 0},
186 [DVBT_ACI_DET_IND] = {0x3, 0x12, 0, 0},
187 [DVBT_REG_MON] = {0x0, 0xd, 1, 0},
188 [DVBT_REG_MONSEL] = {0x0, 0xd, 2, 2},
189 [DVBT_REG_GPE] = {0x0, 0xd, 7, 7},
190 [DVBT_REG_GPO] = {0x0, 0x10, 0, 0},
191 [DVBT_REG_4MSEL] = {0x0, 0x13, 0, 0},
194 /* write multiple hardware registers */
195 static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
199 struct i2c_msg msg[1] = {
201 .addr = priv->cfg.i2c_addr,
209 memcpy(&buf[1], val, len);
211 ret = i2c_transfer(priv->i2c, msg, 1);
215 warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
221 /* read multiple hardware registers */
222 static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
225 struct i2c_msg msg[2] = {
227 .addr = priv->cfg.i2c_addr,
232 .addr = priv->cfg.i2c_addr,
239 ret = i2c_transfer(priv->i2c, msg, 2);
243 warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
249 /* write multiple registers */
250 static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
256 /* switch bank if needed */
257 if (page != priv->page) {
258 ret = rtl2832_wr(priv, 0x00, &page, 1);
265 return rtl2832_wr(priv, reg, val, len);
268 /* read multiple registers */
269 static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
274 /* switch bank if needed */
275 if (page != priv->page) {
276 ret = rtl2832_wr(priv, 0x00, &page, 1);
283 return rtl2832_rd(priv, reg, val, len);
286 #if 0 /* currently not used */
287 /* write single register */
288 static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
290 return rtl2832_wr_regs(priv, reg, page, &val, 1);
294 /* read single register */
295 static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
297 return rtl2832_rd_regs(priv, reg, page, val, 1);
300 int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
314 reg_start_addr = registers[reg].start_address;
315 msb = registers[reg].msb;
316 lsb = registers[reg].lsb;
317 page = registers[reg].page;
319 len = (msb >> 3) + 1;
320 mask = reg_mask[msb - lsb];
322 ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
327 for (i = 0; i < len; i++)
328 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
330 *val = (reading_tmp >> lsb) & mask;
335 dbg("%s: failed=%d", __func__, ret);
340 int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
356 reg_start_addr = registers[reg].start_address;
357 msb = registers[reg].msb;
358 lsb = registers[reg].lsb;
359 page = registers[reg].page;
361 len = (msb >> 3) + 1;
362 mask = reg_mask[msb - lsb];
365 ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
370 for (i = 0; i < len; i++)
371 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
373 writing_tmp = reading_tmp & ~(mask << lsb);
374 writing_tmp |= ((val & mask) << lsb);
377 for (i = 0; i < len; i++)
378 writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
380 ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len);
387 dbg("%s: failed=%d", __func__, ret);
393 static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
396 struct rtl2832_priv *priv = fe->demodulator_priv;
398 dbg("%s: enable=%d", __func__, enable);
400 /* gate already open or close */
401 if (priv->i2c_gate_state == enable)
404 ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0));
408 priv->i2c_gate_state = enable;
412 dbg("%s: failed=%d", __func__, ret);
418 static int rtl2832_init(struct dvb_frontend *fe)
420 struct rtl2832_priv *priv = fe->demodulator_priv;
426 /* initialization values for the demodulator registers */
427 struct rtl2832_reg_value rtl2832_initial_regs[] = {
428 {DVBT_AD_EN_REG, 0x1},
429 {DVBT_AD_EN_REG1, 0x1},
430 {DVBT_RSD_BER_FAIL_VAL, 0x2800},
431 {DVBT_MGD_THD0, 0x10},
432 {DVBT_MGD_THD1, 0x20},
433 {DVBT_MGD_THD2, 0x20},
434 {DVBT_MGD_THD3, 0x40},
435 {DVBT_MGD_THD4, 0x22},
436 {DVBT_MGD_THD5, 0x32},
437 {DVBT_MGD_THD6, 0x37},
438 {DVBT_MGD_THD7, 0x39},
439 {DVBT_EN_BK_TRK, 0x0},
440 {DVBT_EN_CACQ_NOTCH, 0x0},
441 {DVBT_AD_AV_REF, 0x2a},
444 {DVBT_CDIV_PH0, 0x8},
445 {DVBT_CDIV_PH1, 0x8},
446 {DVBT_SCALE1_B92, 0x4},
447 {DVBT_SCALE1_B93, 0xb0},
448 {DVBT_SCALE1_BA7, 0x78},
449 {DVBT_SCALE1_BA9, 0x28},
450 {DVBT_SCALE1_BAA, 0x59},
451 {DVBT_SCALE1_BAB, 0x83},
452 {DVBT_SCALE1_BAC, 0xd4},
453 {DVBT_SCALE1_BB0, 0x65},
454 {DVBT_SCALE1_BB1, 0x43},
458 {DVBT_K1_CR_STEP12, 0xa},
461 {DVBT_CDIV_PH0, 0x9},
462 {DVBT_CDIV_PH1, 0x9},
463 {DVBT_MPEG_IO_OPT_2_2, 0x0},
464 {DVBT_MPEG_IO_OPT_1_0, 0x0},
465 {DVBT_TRK_KS_P2, 0x4},
466 {DVBT_TRK_KS_I2, 0x7},
467 {DVBT_TR_THD_SET2, 0x6},
468 {DVBT_TRK_KC_I2, 0x5},
469 {DVBT_CR_THD_SET2, 0x1},
470 {DVBT_SPEC_INV, 0x0},
471 {DVBT_DAGC_TRG_VAL, 0x5a},
472 {DVBT_AGC_TARG_VAL_0, 0x0},
473 {DVBT_AGC_TARG_VAL_8_1, 0x5a},
474 {DVBT_AAGC_LOOP_GAIN, 0x16},
475 {DVBT_LOOP_GAIN2_3_0, 0x6},
476 {DVBT_LOOP_GAIN2_4, 0x1},
477 {DVBT_LOOP_GAIN3, 0x16},
485 {DVBT_IF_AGC_MIN, 0x80},
486 {DVBT_IF_AGC_MAX, 0x7f},
487 {DVBT_RF_AGC_MIN, 0x80},
488 {DVBT_RF_AGC_MAX, 0x7f},
489 {DVBT_POLAR_RF_AGC, 0x0},
490 {DVBT_POLAR_IF_AGC, 0x0},
491 {DVBT_AD7_SETTING, 0xe9bf},
492 {DVBT_EN_GI_PGA, 0x0},
493 {DVBT_THD_LOCK_UP, 0x0},
494 {DVBT_THD_LOCK_DW, 0x0},
495 {DVBT_THD_UP1, 0x11},
496 {DVBT_THD_DW1, 0xef},
497 {DVBT_INTER_CNT_LEN, 0xc},
498 {DVBT_GI_PGA_STATE, 0x0},
499 {DVBT_EN_AGC_PGA, 0x1},
500 {DVBT_IF_AGC_MAN, 0x0},
506 en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
509 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
512 pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
513 pset_iffreq *= 0x400000;
514 pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
515 pset_iffreq = pset_iffreq & 0x3fffff;
519 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
520 ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
521 rtl2832_initial_regs[i].value);
526 /* if frequency settings */
527 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
531 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
535 priv->sleeping = false;
540 dbg("%s: failed=%d", __func__, ret);
544 static int rtl2832_sleep(struct dvb_frontend *fe)
546 struct rtl2832_priv *priv = fe->demodulator_priv;
549 priv->sleeping = true;
553 int rtl2832_get_tune_settings(struct dvb_frontend *fe,
554 struct dvb_frontend_tune_settings *s)
557 s->min_delay_ms = 1000;
558 s->step_size = fe->ops.info.frequency_stepsize * 2;
559 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
563 static int rtl2832_set_frontend(struct dvb_frontend *fe)
565 struct rtl2832_priv *priv = fe->demodulator_priv;
566 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
568 u64 bw_mode, num, num2;
569 u32 resamp_ratio, cfreq_off_ratio;
572 static u8 bw_params[3][32] = {
573 /* 6 MHz bandwidth */
575 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
576 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
577 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
581 /* 7 MHz bandwidth */
583 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
584 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
585 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
589 /* 8 MHz bandwidth */
591 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
592 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
593 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
599 dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
600 c->frequency, c->bandwidth_hz, c->inversion);
604 if (fe->ops.tuner_ops.set_params)
605 fe->ops.tuner_ops.set_params(fe);
608 switch (c->bandwidth_hz) {
622 dbg("invalid bandwidth");
626 for (j = 0; j < sizeof(bw_params[j]); j++) {
627 ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
632 /* calculate and set resample ratio
633 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
634 * / ConstWithBandwidthMode)
636 num = priv->cfg.xtal * 7;
638 num = div_u64(num, bw_mode);
639 resamp_ratio = num & 0x3ffffff;
640 ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
644 /* calculate and set cfreq off ratio
645 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
646 * / (CrystalFreqHz * 7))
649 num2 = priv->cfg.xtal * 7;
650 num = div_u64(num, num2);
652 cfreq_off_ratio = num & 0xfffff;
653 ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
659 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
663 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
669 info("%s: failed=%d", __func__, ret);
673 static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
675 struct rtl2832_priv *priv = fe->demodulator_priv;
685 ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
690 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
691 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
693 /* TODO find out if this is also true for rtl2832? */
694 /*else if (tmp == 10) {
695 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
701 info("%s: failed=%d", __func__, ret);
705 static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
711 static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
717 static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
724 static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
730 static struct dvb_frontend_ops rtl2832_ops;
732 static void rtl2832_release(struct dvb_frontend *fe)
734 struct rtl2832_priv *priv = fe->demodulator_priv;
740 struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
741 struct i2c_adapter *i2c)
743 struct rtl2832_priv *priv = NULL;
749 /* allocate memory for the internal state */
750 priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
756 priv->tuner = cfg->tuner;
757 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
759 /* check if the demod is there */
760 ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
764 /* create dvb_frontend */
765 memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
766 priv->fe.demodulator_priv = priv;
768 /* TODO implement sleep mode */
769 priv->sleeping = true;
773 dbg("%s: failed=%d", __func__, ret);
777 EXPORT_SYMBOL(rtl2832_attach);
779 static struct dvb_frontend_ops rtl2832_ops = {
780 .delsys = { SYS_DVBT },
782 .name = "Realtek RTL2832 (DVB-T)",
783 .frequency_min = 174000000,
784 .frequency_max = 862000000,
785 .frequency_stepsize = 166667,
786 .caps = FE_CAN_FEC_1_2 |
796 FE_CAN_TRANSMISSION_MODE_AUTO |
797 FE_CAN_GUARD_INTERVAL_AUTO |
798 FE_CAN_HIERARCHY_AUTO |
803 .release = rtl2832_release,
805 .init = rtl2832_init,
806 .sleep = rtl2832_sleep,
808 .get_tune_settings = rtl2832_get_tune_settings,
810 .set_frontend = rtl2832_set_frontend,
812 .read_status = rtl2832_read_status,
813 .read_snr = rtl2832_read_snr,
814 .read_ber = rtl2832_read_ber,
815 .read_ucblocks = rtl2832_read_ucblocks,
816 .read_signal_strength = rtl2832_read_signal_strength,
817 .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
820 MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
821 MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
822 MODULE_LICENSE("GPL");
823 MODULE_VERSION("0.5");