aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/rtl2832.c
diff options
context:
space:
mode:
authorThomas Mair <thomas.mair86@googlemail.com>2012-05-18 13:47:40 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-05 11:05:37 -0400
commit82041c0a15fdd45336f11c893c4ff69d48dcc4f1 (patch)
tree87ad4d65c7bd997bc33dd604513e21699fd3b9ef /drivers/media/dvb/frontends/rtl2832.c
parentb31b021988fed9e3741a46918f14ba9b063811db (diff)
[media] RTL2832 DVB-T demodulator driver
Changelog for ver. 0.5: - fixed code style and naming errors Changelog for ver. 0.4: - removed statistics as their calculation was wrong - fixed bug in Makefile - indentation and code style improvements Signed-off-by: Thomas Mair <thomas.mair86@googlemail.com> Reviewed-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends/rtl2832.c')
-rw-r--r--drivers/media/dvb/frontends/rtl2832.c823
1 files changed, 823 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/rtl2832.c b/drivers/media/dvb/frontends/rtl2832.c
new file mode 100644
index 000000000000..d0cbe27f979e
--- /dev/null
+++ b/drivers/media/dvb/frontends/rtl2832.c
@@ -0,0 +1,823 @@
1/*
2 * Realtek RTL2832 DVB-T demodulator driver
3 *
4 * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
5 *
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.
10 *
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.
15 *
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.
19 */
20
21#include "rtl2832_priv.h"
22
23
24int rtl2832_debug;
25module_param_named(debug, rtl2832_debug, int, 0644);
26MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
27
28
29static const int reg_mask[32] = {
30 0x00000001,
31 0x00000003,
32 0x00000007,
33 0x0000000f,
34 0x0000001f,
35 0x0000003f,
36 0x0000007f,
37 0x000000ff,
38 0x000001ff,
39 0x000003ff,
40 0x000007ff,
41 0x00000fff,
42 0x00001fff,
43 0x00003fff,
44 0x00007fff,
45 0x0000ffff,
46 0x0001ffff,
47 0x0003ffff,
48 0x0007ffff,
49 0x000fffff,
50 0x001fffff,
51 0x003fffff,
52 0x007fffff,
53 0x00ffffff,
54 0x01ffffff,
55 0x03ffffff,
56 0x07ffffff,
57 0x0fffffff,
58 0x1fffffff,
59 0x3fffffff,
60 0x7fffffff,
61 0xffffffff
62};
63
64static 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},
192};
193
194/* write multiple hardware registers */
195static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
196{
197 int ret;
198 u8 buf[1+len];
199 struct i2c_msg msg[1] = {
200 {
201 .addr = priv->cfg.i2c_addr,
202 .flags = 0,
203 .len = 1+len,
204 .buf = buf,
205 }
206 };
207
208 buf[0] = reg;
209 memcpy(&buf[1], val, len);
210
211 ret = i2c_transfer(priv->i2c, msg, 1);
212 if (ret == 1) {
213 ret = 0;
214 } else {
215 warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
216 ret = -EREMOTEIO;
217 }
218 return ret;
219}
220
221/* read multiple hardware registers */
222static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
223{
224 int ret;
225 struct i2c_msg msg[2] = {
226 {
227 .addr = priv->cfg.i2c_addr,
228 .flags = 0,
229 .len = 1,
230 .buf = &reg,
231 }, {
232 .addr = priv->cfg.i2c_addr,
233 .flags = I2C_M_RD,
234 .len = len,
235 .buf = val,
236 }
237 };
238
239 ret = i2c_transfer(priv->i2c, msg, 2);
240 if (ret == 2) {
241 ret = 0;
242 } else {
243 warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
244 ret = -EREMOTEIO;
245}
246return ret;
247}
248
249/* write multiple registers */
250static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
251 int len)
252{
253 int ret;
254
255
256 /* switch bank if needed */
257 if (page != priv->page) {
258 ret = rtl2832_wr(priv, 0x00, &page, 1);
259 if (ret)
260 return ret;
261
262 priv->page = page;
263}
264
265return rtl2832_wr(priv, reg, val, len);
266}
267
268/* read multiple registers */
269static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
270 int len)
271{
272 int ret;
273
274 /* switch bank if needed */
275 if (page != priv->page) {
276 ret = rtl2832_wr(priv, 0x00, &page, 1);
277 if (ret)
278 return ret;
279
280 priv->page = page;
281 }
282
283 return rtl2832_rd(priv, reg, val, len);
284}
285
286#if 0 /* currently not used */
287/* write single register */
288static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
289{
290 return rtl2832_wr_regs(priv, reg, page, &val, 1);
291}
292#endif
293
294/* read single register */
295static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
296{
297 return rtl2832_rd_regs(priv, reg, page, val, 1);
298}
299
300int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
301{
302 int ret;
303
304 u8 reg_start_addr;
305 u8 msb, lsb;
306 u8 page;
307 u8 reading[4];
308 u32 reading_tmp;
309 int i;
310
311 u8 len;
312 u32 mask;
313
314 reg_start_addr = registers[reg].start_address;
315 msb = registers[reg].msb;
316 lsb = registers[reg].lsb;
317 page = registers[reg].page;
318
319 len = (msb >> 3) + 1;
320 mask = reg_mask[msb - lsb];
321
322 ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
323 if (ret)
324 goto err;
325
326 reading_tmp = 0;
327 for (i = 0; i < len; i++)
328 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
329
330 *val = (reading_tmp >> lsb) & mask;
331
332 return ret;
333
334err:
335 dbg("%s: failed=%d", __func__, ret);
336 return ret;
337
338}
339
340int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
341{
342 int ret, i;
343 u8 len;
344 u8 reg_start_addr;
345 u8 msb, lsb;
346 u8 page;
347 u32 mask;
348
349
350 u8 reading[4];
351 u8 writing[4];
352 u32 reading_tmp;
353 u32 writing_tmp;
354
355
356 reg_start_addr = registers[reg].start_address;
357 msb = registers[reg].msb;
358 lsb = registers[reg].lsb;
359 page = registers[reg].page;
360
361 len = (msb >> 3) + 1;
362 mask = reg_mask[msb - lsb];
363
364
365 ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
366 if (ret)
367 goto err;
368
369 reading_tmp = 0;
370 for (i = 0; i < len; i++)
371 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
372
373 writing_tmp = reading_tmp & ~(mask << lsb);
374 writing_tmp |= ((val & mask) << lsb);
375
376
377 for (i = 0; i < len; i++)
378 writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
379
380 ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len);
381 if (ret)
382 goto err;
383
384 return ret;
385
386err:
387 dbg("%s: failed=%d", __func__, ret);
388 return ret;
389
390}
391
392
393static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
394{
395 int ret;
396 struct rtl2832_priv *priv = fe->demodulator_priv;
397
398 dbg("%s: enable=%d", __func__, enable);
399
400 /* gate already open or close */
401 if (priv->i2c_gate_state == enable)
402 return 0;
403
404 ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0));
405 if (ret)
406 goto err;
407
408 priv->i2c_gate_state = enable;
409
410 return ret;
411err:
412 dbg("%s: failed=%d", __func__, ret);
413 return ret;
414}
415
416
417
418static int rtl2832_init(struct dvb_frontend *fe)
419{
420 struct rtl2832_priv *priv = fe->demodulator_priv;
421 int i, ret;
422
423 u8 en_bbin;
424 u64 pset_iffreq;
425
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},
442 {DVBT_REG_PI, 0x6},
443 {DVBT_PIP_ON, 0x0},
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},
455 {DVBT_KB_P1, 0x1},
456 {DVBT_KB_P2, 0x4},
457 {DVBT_KB_P3, 0x7},
458 {DVBT_K1_CR_STEP12, 0xa},
459 {DVBT_REG_GPE, 0x1},
460 {DVBT_SERIAL, 0x0},
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},
478 {DVBT_VTOP1, 0x35},
479 {DVBT_VTOP2, 0x21},
480 {DVBT_VTOP3, 0x21},
481 {DVBT_KRF1, 0x0},
482 {DVBT_KRF2, 0x40},
483 {DVBT_KRF3, 0x10},
484 {DVBT_KRF4, 0x10},
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},
501 };
502
503
504 dbg("%s", __func__);
505
506 en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
507
508 /*
509 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
510 * / CrystalFreqHz)
511 */
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;
516
517
518
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);
522 if (ret)
523 goto err;
524 }
525
526 /* if frequency settings */
527 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
528 if (ret)
529 goto err;
530
531 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
532 if (ret)
533 goto err;
534
535 priv->sleeping = false;
536
537 return ret;
538
539err:
540 dbg("%s: failed=%d", __func__, ret);
541 return ret;
542}
543
544static int rtl2832_sleep(struct dvb_frontend *fe)
545{
546 struct rtl2832_priv *priv = fe->demodulator_priv;
547
548 dbg("%s", __func__);
549 priv->sleeping = true;
550 return 0;
551}
552
553int rtl2832_get_tune_settings(struct dvb_frontend *fe,
554 struct dvb_frontend_tune_settings *s)
555{
556 dbg("%s", __func__);
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;
560 return 0;
561}
562
563static int rtl2832_set_frontend(struct dvb_frontend *fe)
564{
565 struct rtl2832_priv *priv = fe->demodulator_priv;
566 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
567 int ret, i, j;
568 u64 bw_mode, num, num2;
569 u32 resamp_ratio, cfreq_off_ratio;
570
571
572 static u8 bw_params[3][32] = {
573 /* 6 MHz bandwidth */
574 {
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,
578 0x19, 0xe0,
579 },
580
581 /* 7 MHz bandwidth */
582 {
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,
586 0x19, 0x10,
587 },
588
589 /* 8 MHz bandwidth */
590 {
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,
594 0x19, 0xe0,
595 },
596 };
597
598
599 dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
600 c->frequency, c->bandwidth_hz, c->inversion);
601
602
603 /* program tuner */
604 if (fe->ops.tuner_ops.set_params)
605 fe->ops.tuner_ops.set_params(fe);
606
607
608 switch (c->bandwidth_hz) {
609 case 6000000:
610 i = 0;
611 bw_mode = 48000000;
612 break;
613 case 7000000:
614 i = 1;
615 bw_mode = 56000000;
616 break;
617 case 8000000:
618 i = 2;
619 bw_mode = 64000000;
620 break;
621 default:
622 dbg("invalid bandwidth");
623 return -EINVAL;
624 }
625
626 for (j = 0; j < sizeof(bw_params[j]); j++) {
627 ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
628 if (ret)
629 goto err;
630 }
631
632 /* calculate and set resample ratio
633 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
634 * / ConstWithBandwidthMode)
635 */
636 num = priv->cfg.xtal * 7;
637 num *= 0x400000;
638 num = div_u64(num, bw_mode);
639 resamp_ratio = num & 0x3ffffff;
640 ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
641 if (ret)
642 goto err;
643
644 /* calculate and set cfreq off ratio
645 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
646 * / (CrystalFreqHz * 7))
647 */
648 num = bw_mode << 20;
649 num2 = priv->cfg.xtal * 7;
650 num = div_u64(num, num2);
651 num = -num;
652 cfreq_off_ratio = num & 0xfffff;
653 ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
654 if (ret)
655 goto err;
656
657
658 /* soft reset */
659 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
660 if (ret)
661 goto err;
662
663 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
664 if (ret)
665 goto err;
666
667 return ret;
668err:
669 info("%s: failed=%d", __func__, ret);
670 return ret;
671}
672
673static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
674{
675 struct rtl2832_priv *priv = fe->demodulator_priv;
676 int ret;
677 u32 tmp;
678 *status = 0;
679
680
681 dbg("%s", __func__);
682 if (priv->sleeping)
683 return 0;
684
685 ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
686 if (ret)
687 goto err;
688
689 if (tmp == 11) {
690 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
691 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
692 }
693 /* TODO find out if this is also true for rtl2832? */
694 /*else if (tmp == 10) {
695 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
696 FE_HAS_VITERBI;
697 }*/
698
699 return ret;
700err:
701 info("%s: failed=%d", __func__, ret);
702 return ret;
703}
704
705static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
706{
707 *snr = 0;
708 return 0;
709}
710
711static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
712{
713 *ber = 0;
714 return 0;
715}
716
717static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
718{
719 *ucblocks = 0;
720 return 0;
721}
722
723
724static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
725{
726 *strength = 0;
727 return 0;
728}
729
730static struct dvb_frontend_ops rtl2832_ops;
731
732static void rtl2832_release(struct dvb_frontend *fe)
733{
734 struct rtl2832_priv *priv = fe->demodulator_priv;
735
736 dbg("%s", __func__);
737 kfree(priv);
738}
739
740struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
741 struct i2c_adapter *i2c)
742{
743 struct rtl2832_priv *priv = NULL;
744 int ret = 0;
745 u8 tmp;
746
747 dbg("%s", __func__);
748
749 /* allocate memory for the internal state */
750 priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
751 if (priv == NULL)
752 goto err;
753
754 /* setup the priv */
755 priv->i2c = i2c;
756 priv->tuner = cfg->tuner;
757 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
758
759 /* check if the demod is there */
760 ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
761 if (ret)
762 goto err;
763
764 /* create dvb_frontend */
765 memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
766 priv->fe.demodulator_priv = priv;
767
768 /* TODO implement sleep mode */
769 priv->sleeping = true;
770
771 return &priv->fe;
772err:
773 dbg("%s: failed=%d", __func__, ret);
774 kfree(priv);
775 return NULL;
776}
777EXPORT_SYMBOL(rtl2832_attach);
778
779static struct dvb_frontend_ops rtl2832_ops = {
780 .delsys = { SYS_DVBT },
781 .info = {
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 |
787 FE_CAN_FEC_2_3 |
788 FE_CAN_FEC_3_4 |
789 FE_CAN_FEC_5_6 |
790 FE_CAN_FEC_7_8 |
791 FE_CAN_FEC_AUTO |
792 FE_CAN_QPSK |
793 FE_CAN_QAM_16 |
794 FE_CAN_QAM_64 |
795 FE_CAN_QAM_AUTO |
796 FE_CAN_TRANSMISSION_MODE_AUTO |
797 FE_CAN_GUARD_INTERVAL_AUTO |
798 FE_CAN_HIERARCHY_AUTO |
799 FE_CAN_RECOVER |
800 FE_CAN_MUTE_TS
801 },
802
803 .release = rtl2832_release,
804
805 .init = rtl2832_init,
806 .sleep = rtl2832_sleep,
807
808 .get_tune_settings = rtl2832_get_tune_settings,
809
810 .set_frontend = rtl2832_set_frontend,
811
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,
818};
819
820MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
821MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
822MODULE_LICENSE("GPL");
823MODULE_VERSION("0.5");