blob: 4d40b4f42a1fc3a2be04588419c7e1873d63a313 [file] [log] [blame]
Thomas Mair82041c02012-05-18 14:47:40 -03001/*
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"
Antti Palosaari73983492012-08-21 19:56:21 -030022#include "dvb_math.h"
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -030023#include <linux/bitops.h>
Thomas Mair82041c02012-05-18 14:47:40 -030024
25int rtl2832_debug;
26module_param_named(debug, rtl2832_debug, int, 0644);
27MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
28
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -030029#define REG_MASK(b) (BIT(b + 1) - 1)
Thomas Mair82041c02012-05-18 14:47:40 -030030
31static const struct rtl2832_reg_entry registers[] = {
32 [DVBT_SOFT_RST] = {0x1, 0x1, 2, 2},
33 [DVBT_IIC_REPEAT] = {0x1, 0x1, 3, 3},
34 [DVBT_TR_WAIT_MIN_8K] = {0x1, 0x88, 11, 2},
35 [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
36 [DVBT_EN_BK_TRK] = {0x1, 0xa6, 7, 7},
37 [DVBT_AD_EN_REG] = {0x0, 0x8, 7, 7},
38 [DVBT_AD_EN_REG1] = {0x0, 0x8, 6, 6},
39 [DVBT_EN_BBIN] = {0x1, 0xb1, 0, 0},
40 [DVBT_MGD_THD0] = {0x1, 0x95, 7, 0},
41 [DVBT_MGD_THD1] = {0x1, 0x96, 7, 0},
42 [DVBT_MGD_THD2] = {0x1, 0x97, 7, 0},
43 [DVBT_MGD_THD3] = {0x1, 0x98, 7, 0},
44 [DVBT_MGD_THD4] = {0x1, 0x99, 7, 0},
45 [DVBT_MGD_THD5] = {0x1, 0x9a, 7, 0},
46 [DVBT_MGD_THD6] = {0x1, 0x9b, 7, 0},
47 [DVBT_MGD_THD7] = {0x1, 0x9c, 7, 0},
48 [DVBT_EN_CACQ_NOTCH] = {0x1, 0x61, 4, 4},
49 [DVBT_AD_AV_REF] = {0x0, 0x9, 6, 0},
50 [DVBT_REG_PI] = {0x0, 0xa, 2, 0},
51 [DVBT_PIP_ON] = {0x0, 0x21, 3, 3},
52 [DVBT_SCALE1_B92] = {0x2, 0x92, 7, 0},
53 [DVBT_SCALE1_B93] = {0x2, 0x93, 7, 0},
54 [DVBT_SCALE1_BA7] = {0x2, 0xa7, 7, 0},
55 [DVBT_SCALE1_BA9] = {0x2, 0xa9, 7, 0},
56 [DVBT_SCALE1_BAA] = {0x2, 0xaa, 7, 0},
57 [DVBT_SCALE1_BAB] = {0x2, 0xab, 7, 0},
58 [DVBT_SCALE1_BAC] = {0x2, 0xac, 7, 0},
59 [DVBT_SCALE1_BB0] = {0x2, 0xb0, 7, 0},
60 [DVBT_SCALE1_BB1] = {0x2, 0xb1, 7, 0},
61 [DVBT_KB_P1] = {0x1, 0x64, 3, 1},
62 [DVBT_KB_P2] = {0x1, 0x64, 6, 4},
63 [DVBT_KB_P3] = {0x1, 0x65, 2, 0},
64 [DVBT_OPT_ADC_IQ] = {0x0, 0x6, 5, 4},
65 [DVBT_AD_AVI] = {0x0, 0x9, 1, 0},
66 [DVBT_AD_AVQ] = {0x0, 0x9, 3, 2},
67 [DVBT_K1_CR_STEP12] = {0x2, 0xad, 9, 4},
68 [DVBT_TRK_KS_P2] = {0x1, 0x6f, 2, 0},
69 [DVBT_TRK_KS_I2] = {0x1, 0x70, 5, 3},
70 [DVBT_TR_THD_SET2] = {0x1, 0x72, 3, 0},
71 [DVBT_TRK_KC_P2] = {0x1, 0x73, 5, 3},
72 [DVBT_TRK_KC_I2] = {0x1, 0x75, 2, 0},
73 [DVBT_CR_THD_SET2] = {0x1, 0x76, 7, 6},
74 [DVBT_PSET_IFFREQ] = {0x1, 0x19, 21, 0},
75 [DVBT_SPEC_INV] = {0x1, 0x15, 0, 0},
76 [DVBT_RSAMP_RATIO] = {0x1, 0x9f, 27, 2},
77 [DVBT_CFREQ_OFF_RATIO] = {0x1, 0x9d, 23, 4},
78 [DVBT_FSM_STAGE] = {0x3, 0x51, 6, 3},
79 [DVBT_RX_CONSTEL] = {0x3, 0x3c, 3, 2},
80 [DVBT_RX_HIER] = {0x3, 0x3c, 6, 4},
81 [DVBT_RX_C_RATE_LP] = {0x3, 0x3d, 2, 0},
82 [DVBT_RX_C_RATE_HP] = {0x3, 0x3d, 5, 3},
83 [DVBT_GI_IDX] = {0x3, 0x51, 1, 0},
84 [DVBT_FFT_MODE_IDX] = {0x3, 0x51, 2, 2},
85 [DVBT_RSD_BER_EST] = {0x3, 0x4e, 15, 0},
86 [DVBT_CE_EST_EVM] = {0x4, 0xc, 15, 0},
87 [DVBT_RF_AGC_VAL] = {0x3, 0x5b, 13, 0},
88 [DVBT_IF_AGC_VAL] = {0x3, 0x59, 13, 0},
89 [DVBT_DAGC_VAL] = {0x3, 0x5, 7, 0},
90 [DVBT_SFREQ_OFF] = {0x3, 0x18, 13, 0},
91 [DVBT_CFREQ_OFF] = {0x3, 0x5f, 17, 0},
92 [DVBT_POLAR_RF_AGC] = {0x0, 0xe, 1, 1},
93 [DVBT_POLAR_IF_AGC] = {0x0, 0xe, 0, 0},
94 [DVBT_AAGC_HOLD] = {0x1, 0x4, 5, 5},
95 [DVBT_EN_RF_AGC] = {0x1, 0x4, 6, 6},
96 [DVBT_EN_IF_AGC] = {0x1, 0x4, 7, 7},
97 [DVBT_IF_AGC_MIN] = {0x1, 0x8, 7, 0},
98 [DVBT_IF_AGC_MAX] = {0x1, 0x9, 7, 0},
99 [DVBT_RF_AGC_MIN] = {0x1, 0xa, 7, 0},
100 [DVBT_RF_AGC_MAX] = {0x1, 0xb, 7, 0},
101 [DVBT_IF_AGC_MAN] = {0x1, 0xc, 6, 6},
102 [DVBT_IF_AGC_MAN_VAL] = {0x1, 0xc, 13, 0},
103 [DVBT_RF_AGC_MAN] = {0x1, 0xe, 6, 6},
104 [DVBT_RF_AGC_MAN_VAL] = {0x1, 0xe, 13, 0},
105 [DVBT_DAGC_TRG_VAL] = {0x1, 0x12, 7, 0},
106 [DVBT_AGC_TARG_VAL_0] = {0x1, 0x2, 0, 0},
107 [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3, 7, 0},
108 [DVBT_AAGC_LOOP_GAIN] = {0x1, 0xc7, 5, 1},
109 [DVBT_LOOP_GAIN2_3_0] = {0x1, 0x4, 4, 1},
110 [DVBT_LOOP_GAIN2_4] = {0x1, 0x5, 7, 7},
111 [DVBT_LOOP_GAIN3] = {0x1, 0xc8, 4, 0},
112 [DVBT_VTOP1] = {0x1, 0x6, 5, 0},
113 [DVBT_VTOP2] = {0x1, 0xc9, 5, 0},
114 [DVBT_VTOP3] = {0x1, 0xca, 5, 0},
115 [DVBT_KRF1] = {0x1, 0xcb, 7, 0},
116 [DVBT_KRF2] = {0x1, 0x7, 7, 0},
117 [DVBT_KRF3] = {0x1, 0xcd, 7, 0},
118 [DVBT_KRF4] = {0x1, 0xce, 7, 0},
119 [DVBT_EN_GI_PGA] = {0x1, 0xe5, 0, 0},
120 [DVBT_THD_LOCK_UP] = {0x1, 0xd9, 8, 0},
121 [DVBT_THD_LOCK_DW] = {0x1, 0xdb, 8, 0},
122 [DVBT_THD_UP1] = {0x1, 0xdd, 7, 0},
123 [DVBT_THD_DW1] = {0x1, 0xde, 7, 0},
124 [DVBT_INTER_CNT_LEN] = {0x1, 0xd8, 3, 0},
125 [DVBT_GI_PGA_STATE] = {0x1, 0xe6, 3, 3},
126 [DVBT_EN_AGC_PGA] = {0x1, 0xd7, 0, 0},
127 [DVBT_CKOUTPAR] = {0x1, 0x7b, 5, 5},
128 [DVBT_CKOUT_PWR] = {0x1, 0x7b, 6, 6},
129 [DVBT_SYNC_DUR] = {0x1, 0x7b, 7, 7},
130 [DVBT_ERR_DUR] = {0x1, 0x7c, 0, 0},
131 [DVBT_SYNC_LVL] = {0x1, 0x7c, 1, 1},
132 [DVBT_ERR_LVL] = {0x1, 0x7c, 2, 2},
133 [DVBT_VAL_LVL] = {0x1, 0x7c, 3, 3},
134 [DVBT_SERIAL] = {0x1, 0x7c, 4, 4},
135 [DVBT_SER_LSB] = {0x1, 0x7c, 5, 5},
136 [DVBT_CDIV_PH0] = {0x1, 0x7d, 3, 0},
137 [DVBT_CDIV_PH1] = {0x1, 0x7d, 7, 4},
138 [DVBT_MPEG_IO_OPT_2_2] = {0x0, 0x6, 7, 7},
139 [DVBT_MPEG_IO_OPT_1_0] = {0x0, 0x7, 7, 6},
140 [DVBT_CKOUTPAR_PIP] = {0x0, 0xb7, 4, 4},
141 [DVBT_CKOUT_PWR_PIP] = {0x0, 0xb7, 3, 3},
142 [DVBT_SYNC_LVL_PIP] = {0x0, 0xb7, 2, 2},
143 [DVBT_ERR_LVL_PIP] = {0x0, 0xb7, 1, 1},
144 [DVBT_VAL_LVL_PIP] = {0x0, 0xb7, 0, 0},
145 [DVBT_CKOUTPAR_PID] = {0x0, 0xb9, 4, 4},
146 [DVBT_CKOUT_PWR_PID] = {0x0, 0xb9, 3, 3},
147 [DVBT_SYNC_LVL_PID] = {0x0, 0xb9, 2, 2},
148 [DVBT_ERR_LVL_PID] = {0x0, 0xb9, 1, 1},
149 [DVBT_VAL_LVL_PID] = {0x0, 0xb9, 0, 0},
150 [DVBT_SM_PASS] = {0x1, 0x93, 11, 0},
151 [DVBT_AD7_SETTING] = {0x0, 0x11, 15, 0},
152 [DVBT_RSSI_R] = {0x3, 0x1, 6, 0},
153 [DVBT_ACI_DET_IND] = {0x3, 0x12, 0, 0},
154 [DVBT_REG_MON] = {0x0, 0xd, 1, 0},
155 [DVBT_REG_MONSEL] = {0x0, 0xd, 2, 2},
156 [DVBT_REG_GPE] = {0x0, 0xd, 7, 7},
157 [DVBT_REG_GPO] = {0x0, 0x10, 0, 0},
158 [DVBT_REG_4MSEL] = {0x0, 0x13, 0, 0},
159};
160
161/* write multiple hardware registers */
162static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
163{
164 int ret;
165 u8 buf[1+len];
166 struct i2c_msg msg[1] = {
167 {
168 .addr = priv->cfg.i2c_addr,
169 .flags = 0,
170 .len = 1+len,
171 .buf = buf,
172 }
173 };
174
175 buf[0] = reg;
176 memcpy(&buf[1], val, len);
177
178 ret = i2c_transfer(priv->i2c, msg, 1);
179 if (ret == 1) {
180 ret = 0;
181 } else {
182 warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
183 ret = -EREMOTEIO;
184 }
185 return ret;
186}
187
188/* read multiple hardware registers */
189static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
190{
191 int ret;
192 struct i2c_msg msg[2] = {
193 {
194 .addr = priv->cfg.i2c_addr,
195 .flags = 0,
196 .len = 1,
197 .buf = &reg,
198 }, {
199 .addr = priv->cfg.i2c_addr,
200 .flags = I2C_M_RD,
201 .len = len,
202 .buf = val,
203 }
204 };
205
206 ret = i2c_transfer(priv->i2c, msg, 2);
207 if (ret == 2) {
208 ret = 0;
209 } else {
210 warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
211 ret = -EREMOTEIO;
212}
213return ret;
214}
215
216/* write multiple registers */
217static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
218 int len)
219{
220 int ret;
221
222
223 /* switch bank if needed */
224 if (page != priv->page) {
225 ret = rtl2832_wr(priv, 0x00, &page, 1);
226 if (ret)
227 return ret;
228
229 priv->page = page;
230}
231
232return rtl2832_wr(priv, reg, val, len);
233}
234
235/* read multiple registers */
236static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
237 int len)
238{
239 int ret;
240
241 /* switch bank if needed */
242 if (page != priv->page) {
243 ret = rtl2832_wr(priv, 0x00, &page, 1);
244 if (ret)
245 return ret;
246
247 priv->page = page;
248 }
249
250 return rtl2832_rd(priv, reg, val, len);
251}
252
253#if 0 /* currently not used */
254/* write single register */
255static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
256{
257 return rtl2832_wr_regs(priv, reg, page, &val, 1);
258}
259#endif
260
261/* read single register */
262static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
263{
264 return rtl2832_rd_regs(priv, reg, page, val, 1);
265}
266
267int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
268{
269 int ret;
270
271 u8 reg_start_addr;
272 u8 msb, lsb;
273 u8 page;
274 u8 reading[4];
275 u32 reading_tmp;
276 int i;
277
278 u8 len;
279 u32 mask;
280
281 reg_start_addr = registers[reg].start_address;
282 msb = registers[reg].msb;
283 lsb = registers[reg].lsb;
284 page = registers[reg].page;
285
286 len = (msb >> 3) + 1;
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -0300287 mask = REG_MASK(msb - lsb);
Thomas Mair82041c02012-05-18 14:47:40 -0300288
289 ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
290 if (ret)
291 goto err;
292
293 reading_tmp = 0;
294 for (i = 0; i < len; i++)
295 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
296
297 *val = (reading_tmp >> lsb) & mask;
298
299 return ret;
300
301err:
302 dbg("%s: failed=%d", __func__, ret);
303 return ret;
304
305}
306
307int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
308{
309 int ret, i;
310 u8 len;
311 u8 reg_start_addr;
312 u8 msb, lsb;
313 u8 page;
314 u32 mask;
315
316
317 u8 reading[4];
318 u8 writing[4];
319 u32 reading_tmp;
320 u32 writing_tmp;
321
322
323 reg_start_addr = registers[reg].start_address;
324 msb = registers[reg].msb;
325 lsb = registers[reg].lsb;
326 page = registers[reg].page;
327
328 len = (msb >> 3) + 1;
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -0300329 mask = REG_MASK(msb - lsb);
Thomas Mair82041c02012-05-18 14:47:40 -0300330
331
332 ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
333 if (ret)
334 goto err;
335
336 reading_tmp = 0;
337 for (i = 0; i < len; i++)
338 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
339
340 writing_tmp = reading_tmp & ~(mask << lsb);
341 writing_tmp |= ((val & mask) << lsb);
342
343
344 for (i = 0; i < len; i++)
345 writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
346
347 ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len);
348 if (ret)
349 goto err;
350
351 return ret;
352
353err:
354 dbg("%s: failed=%d", __func__, ret);
355 return ret;
356
357}
358
Thomas Mair82041c02012-05-18 14:47:40 -0300359static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
360{
361 int ret;
362 struct rtl2832_priv *priv = fe->demodulator_priv;
363
364 dbg("%s: enable=%d", __func__, enable);
365
366 /* gate already open or close */
367 if (priv->i2c_gate_state == enable)
368 return 0;
369
370 ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0));
371 if (ret)
372 goto err;
373
374 priv->i2c_gate_state = enable;
375
376 return ret;
377err:
378 dbg("%s: failed=%d", __func__, ret);
379 return ret;
380}
381
Thomas Mair82041c02012-05-18 14:47:40 -0300382static int rtl2832_init(struct dvb_frontend *fe)
383{
384 struct rtl2832_priv *priv = fe->demodulator_priv;
385 int i, ret;
386
387 u8 en_bbin;
388 u64 pset_iffreq;
389
390 /* initialization values for the demodulator registers */
391 struct rtl2832_reg_value rtl2832_initial_regs[] = {
392 {DVBT_AD_EN_REG, 0x1},
393 {DVBT_AD_EN_REG1, 0x1},
394 {DVBT_RSD_BER_FAIL_VAL, 0x2800},
395 {DVBT_MGD_THD0, 0x10},
396 {DVBT_MGD_THD1, 0x20},
397 {DVBT_MGD_THD2, 0x20},
398 {DVBT_MGD_THD3, 0x40},
399 {DVBT_MGD_THD4, 0x22},
400 {DVBT_MGD_THD5, 0x32},
401 {DVBT_MGD_THD6, 0x37},
402 {DVBT_MGD_THD7, 0x39},
403 {DVBT_EN_BK_TRK, 0x0},
404 {DVBT_EN_CACQ_NOTCH, 0x0},
405 {DVBT_AD_AV_REF, 0x2a},
406 {DVBT_REG_PI, 0x6},
407 {DVBT_PIP_ON, 0x0},
408 {DVBT_CDIV_PH0, 0x8},
409 {DVBT_CDIV_PH1, 0x8},
410 {DVBT_SCALE1_B92, 0x4},
411 {DVBT_SCALE1_B93, 0xb0},
412 {DVBT_SCALE1_BA7, 0x78},
413 {DVBT_SCALE1_BA9, 0x28},
414 {DVBT_SCALE1_BAA, 0x59},
415 {DVBT_SCALE1_BAB, 0x83},
416 {DVBT_SCALE1_BAC, 0xd4},
417 {DVBT_SCALE1_BB0, 0x65},
418 {DVBT_SCALE1_BB1, 0x43},
419 {DVBT_KB_P1, 0x1},
420 {DVBT_KB_P2, 0x4},
421 {DVBT_KB_P3, 0x7},
422 {DVBT_K1_CR_STEP12, 0xa},
423 {DVBT_REG_GPE, 0x1},
424 {DVBT_SERIAL, 0x0},
425 {DVBT_CDIV_PH0, 0x9},
426 {DVBT_CDIV_PH1, 0x9},
427 {DVBT_MPEG_IO_OPT_2_2, 0x0},
428 {DVBT_MPEG_IO_OPT_1_0, 0x0},
429 {DVBT_TRK_KS_P2, 0x4},
430 {DVBT_TRK_KS_I2, 0x7},
431 {DVBT_TR_THD_SET2, 0x6},
432 {DVBT_TRK_KC_I2, 0x5},
433 {DVBT_CR_THD_SET2, 0x1},
434 {DVBT_SPEC_INV, 0x0},
435 {DVBT_DAGC_TRG_VAL, 0x5a},
436 {DVBT_AGC_TARG_VAL_0, 0x0},
437 {DVBT_AGC_TARG_VAL_8_1, 0x5a},
438 {DVBT_AAGC_LOOP_GAIN, 0x16},
439 {DVBT_LOOP_GAIN2_3_0, 0x6},
440 {DVBT_LOOP_GAIN2_4, 0x1},
441 {DVBT_LOOP_GAIN3, 0x16},
442 {DVBT_VTOP1, 0x35},
443 {DVBT_VTOP2, 0x21},
444 {DVBT_VTOP3, 0x21},
445 {DVBT_KRF1, 0x0},
446 {DVBT_KRF2, 0x40},
447 {DVBT_KRF3, 0x10},
448 {DVBT_KRF4, 0x10},
449 {DVBT_IF_AGC_MIN, 0x80},
450 {DVBT_IF_AGC_MAX, 0x7f},
451 {DVBT_RF_AGC_MIN, 0x80},
452 {DVBT_RF_AGC_MAX, 0x7f},
453 {DVBT_POLAR_RF_AGC, 0x0},
454 {DVBT_POLAR_IF_AGC, 0x0},
455 {DVBT_AD7_SETTING, 0xe9bf},
456 {DVBT_EN_GI_PGA, 0x0},
457 {DVBT_THD_LOCK_UP, 0x0},
458 {DVBT_THD_LOCK_DW, 0x0},
459 {DVBT_THD_UP1, 0x11},
460 {DVBT_THD_DW1, 0xef},
461 {DVBT_INTER_CNT_LEN, 0xc},
462 {DVBT_GI_PGA_STATE, 0x0},
463 {DVBT_EN_AGC_PGA, 0x1},
464 {DVBT_IF_AGC_MAN, 0x0},
465 };
466
467
468 dbg("%s", __func__);
469
470 en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
471
472 /*
473 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
474 * / CrystalFreqHz)
475 */
476 pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
477 pset_iffreq *= 0x400000;
478 pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
479 pset_iffreq = pset_iffreq & 0x3fffff;
480
481
482
483 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
484 ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
485 rtl2832_initial_regs[i].value);
486 if (ret)
487 goto err;
488 }
489
490 /* if frequency settings */
491 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
492 if (ret)
493 goto err;
494
495 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
496 if (ret)
497 goto err;
498
499 priv->sleeping = false;
500
501 return ret;
502
503err:
504 dbg("%s: failed=%d", __func__, ret);
505 return ret;
506}
507
508static int rtl2832_sleep(struct dvb_frontend *fe)
509{
510 struct rtl2832_priv *priv = fe->demodulator_priv;
511
512 dbg("%s", __func__);
513 priv->sleeping = true;
514 return 0;
515}
516
517int rtl2832_get_tune_settings(struct dvb_frontend *fe,
518 struct dvb_frontend_tune_settings *s)
519{
520 dbg("%s", __func__);
521 s->min_delay_ms = 1000;
522 s->step_size = fe->ops.info.frequency_stepsize * 2;
523 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
524 return 0;
525}
526
527static int rtl2832_set_frontend(struct dvb_frontend *fe)
528{
529 struct rtl2832_priv *priv = fe->demodulator_priv;
530 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
531 int ret, i, j;
532 u64 bw_mode, num, num2;
533 u32 resamp_ratio, cfreq_off_ratio;
534
535
536 static u8 bw_params[3][32] = {
537 /* 6 MHz bandwidth */
538 {
539 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
540 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
541 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
542 0x19, 0xe0,
543 },
544
545 /* 7 MHz bandwidth */
546 {
547 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
548 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
549 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
550 0x19, 0x10,
551 },
552
553 /* 8 MHz bandwidth */
554 {
555 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
556 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
557 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
558 0x19, 0xe0,
559 },
560 };
561
562
563 dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
564 c->frequency, c->bandwidth_hz, c->inversion);
565
566
567 /* program tuner */
568 if (fe->ops.tuner_ops.set_params)
569 fe->ops.tuner_ops.set_params(fe);
570
571
572 switch (c->bandwidth_hz) {
573 case 6000000:
574 i = 0;
575 bw_mode = 48000000;
576 break;
577 case 7000000:
578 i = 1;
579 bw_mode = 56000000;
580 break;
581 case 8000000:
582 i = 2;
583 bw_mode = 64000000;
584 break;
585 default:
586 dbg("invalid bandwidth");
587 return -EINVAL;
588 }
589
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300590 for (j = 0; j < sizeof(bw_params[0]); j++) {
Thomas Mair82041c02012-05-18 14:47:40 -0300591 ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
592 if (ret)
593 goto err;
594 }
595
596 /* calculate and set resample ratio
597 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
598 * / ConstWithBandwidthMode)
599 */
600 num = priv->cfg.xtal * 7;
601 num *= 0x400000;
602 num = div_u64(num, bw_mode);
603 resamp_ratio = num & 0x3ffffff;
604 ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
605 if (ret)
606 goto err;
607
608 /* calculate and set cfreq off ratio
609 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
610 * / (CrystalFreqHz * 7))
611 */
612 num = bw_mode << 20;
613 num2 = priv->cfg.xtal * 7;
614 num = div_u64(num, num2);
615 num = -num;
616 cfreq_off_ratio = num & 0xfffff;
617 ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
618 if (ret)
619 goto err;
620
621
622 /* soft reset */
623 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
624 if (ret)
625 goto err;
626
627 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
628 if (ret)
629 goto err;
630
631 return ret;
632err:
633 info("%s: failed=%d", __func__, ret);
634 return ret;
635}
636
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300637static int rtl2832_get_frontend(struct dvb_frontend *fe)
638{
639 struct rtl2832_priv *priv = fe->demodulator_priv;
640 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
641 int ret;
642 u8 buf[3];
643
644 if (priv->sleeping)
645 return 0;
646
647 ret = rtl2832_rd_regs(priv, 0x3c, 3, buf, 2);
648 if (ret)
649 goto err;
650
651 ret = rtl2832_rd_reg(priv, 0x51, 3, &buf[2]);
652 if (ret)
653 goto err;
654
655 dbg("%s: TPS=%*ph", __func__, 3, buf);
656
657 switch ((buf[0] >> 2) & 3) {
658 case 0:
659 c->modulation = QPSK;
660 break;
661 case 1:
662 c->modulation = QAM_16;
663 break;
664 case 2:
665 c->modulation = QAM_64;
666 break;
667 }
668
669 switch ((buf[2] >> 2) & 1) {
670 case 0:
671 c->transmission_mode = TRANSMISSION_MODE_2K;
672 break;
673 case 1:
674 c->transmission_mode = TRANSMISSION_MODE_8K;
675 }
676
677 switch ((buf[2] >> 0) & 3) {
678 case 0:
679 c->guard_interval = GUARD_INTERVAL_1_32;
680 break;
681 case 1:
682 c->guard_interval = GUARD_INTERVAL_1_16;
683 break;
684 case 2:
685 c->guard_interval = GUARD_INTERVAL_1_8;
686 break;
687 case 3:
688 c->guard_interval = GUARD_INTERVAL_1_4;
689 break;
690 }
691
692 switch ((buf[0] >> 4) & 7) {
693 case 0:
694 c->hierarchy = HIERARCHY_NONE;
695 break;
696 case 1:
697 c->hierarchy = HIERARCHY_1;
698 break;
699 case 2:
700 c->hierarchy = HIERARCHY_2;
701 break;
702 case 3:
703 c->hierarchy = HIERARCHY_4;
704 break;
705 }
706
707 switch ((buf[1] >> 3) & 7) {
708 case 0:
709 c->code_rate_HP = FEC_1_2;
710 break;
711 case 1:
712 c->code_rate_HP = FEC_2_3;
713 break;
714 case 2:
715 c->code_rate_HP = FEC_3_4;
716 break;
717 case 3:
718 c->code_rate_HP = FEC_5_6;
719 break;
720 case 4:
721 c->code_rate_HP = FEC_7_8;
722 break;
723 }
724
725 switch ((buf[1] >> 0) & 7) {
726 case 0:
727 c->code_rate_LP = FEC_1_2;
728 break;
729 case 1:
730 c->code_rate_LP = FEC_2_3;
731 break;
732 case 2:
733 c->code_rate_LP = FEC_3_4;
734 break;
735 case 3:
736 c->code_rate_LP = FEC_5_6;
737 break;
738 case 4:
739 c->code_rate_LP = FEC_7_8;
740 break;
741 }
742
743 return 0;
744err:
745 dbg("%s: failed=%d", __func__, ret);
746 return ret;
747}
748
Thomas Mair82041c02012-05-18 14:47:40 -0300749static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
750{
751 struct rtl2832_priv *priv = fe->demodulator_priv;
752 int ret;
753 u32 tmp;
754 *status = 0;
755
756
757 dbg("%s", __func__);
758 if (priv->sleeping)
759 return 0;
760
761 ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
762 if (ret)
763 goto err;
764
765 if (tmp == 11) {
766 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
767 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
768 }
769 /* TODO find out if this is also true for rtl2832? */
770 /*else if (tmp == 10) {
771 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
772 FE_HAS_VITERBI;
773 }*/
774
775 return ret;
776err:
777 info("%s: failed=%d", __func__, ret);
778 return ret;
779}
780
Antti Palosaari73983492012-08-21 19:56:21 -0300781static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
782{
783 struct rtl2832_priv *priv = fe->demodulator_priv;
784 int ret, hierarchy, constellation;
785 u8 buf[2], tmp;
786 u16 tmp16;
787#define CONSTELLATION_NUM 3
788#define HIERARCHY_NUM 4
789 static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
790 { 85387325, 85387325, 85387325, 85387325 },
791 { 86676178, 86676178, 87167949, 87795660 },
792 { 87659938, 87659938, 87885178, 88241743 },
793 };
794
795 /* reports SNR in resolution of 0.1 dB */
796
797 ret = rtl2832_rd_reg(priv, 0x3c, 3, &tmp);
798 if (ret)
799 goto err;
800
801 constellation = (tmp >> 2) & 0x03; /* [3:2] */
802 if (constellation > CONSTELLATION_NUM - 1)
803 goto err;
804
805 hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
806 if (hierarchy > HIERARCHY_NUM - 1)
807 goto err;
808
809 ret = rtl2832_rd_regs(priv, 0x0c, 4, buf, 2);
810 if (ret)
811 goto err;
812
813 tmp16 = buf[0] << 8 | buf[1];
814
815 if (tmp16)
816 *snr = (snr_constant[constellation][hierarchy] -
817 intlog10(tmp16)) / ((1 << 24) / 100);
818 else
819 *snr = 0;
820
821 return 0;
822err:
823 dbg("%s: failed=%d", __func__, ret);
824 return ret;
825}
826
Antti Palosaaridb32d742012-08-21 19:56:22 -0300827static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
828{
829 struct rtl2832_priv *priv = fe->demodulator_priv;
830 int ret;
831 u8 buf[2];
832
833 ret = rtl2832_rd_regs(priv, 0x4e, 3, buf, 2);
834 if (ret)
835 goto err;
836
837 *ber = buf[0] << 8 | buf[1];
838
839 return 0;
840err:
841 dbg("%s: failed=%d", __func__, ret);
842 return ret;
843}
844
Thomas Mair82041c02012-05-18 14:47:40 -0300845static struct dvb_frontend_ops rtl2832_ops;
846
847static void rtl2832_release(struct dvb_frontend *fe)
848{
849 struct rtl2832_priv *priv = fe->demodulator_priv;
850
851 dbg("%s", __func__);
852 kfree(priv);
853}
854
855struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
856 struct i2c_adapter *i2c)
857{
858 struct rtl2832_priv *priv = NULL;
859 int ret = 0;
860 u8 tmp;
861
862 dbg("%s", __func__);
863
864 /* allocate memory for the internal state */
865 priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
866 if (priv == NULL)
867 goto err;
868
869 /* setup the priv */
870 priv->i2c = i2c;
871 priv->tuner = cfg->tuner;
872 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
873
874 /* check if the demod is there */
875 ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
876 if (ret)
877 goto err;
878
879 /* create dvb_frontend */
880 memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
881 priv->fe.demodulator_priv = priv;
882
883 /* TODO implement sleep mode */
884 priv->sleeping = true;
885
886 return &priv->fe;
887err:
888 dbg("%s: failed=%d", __func__, ret);
889 kfree(priv);
890 return NULL;
891}
892EXPORT_SYMBOL(rtl2832_attach);
893
894static struct dvb_frontend_ops rtl2832_ops = {
895 .delsys = { SYS_DVBT },
896 .info = {
897 .name = "Realtek RTL2832 (DVB-T)",
898 .frequency_min = 174000000,
899 .frequency_max = 862000000,
900 .frequency_stepsize = 166667,
901 .caps = FE_CAN_FEC_1_2 |
902 FE_CAN_FEC_2_3 |
903 FE_CAN_FEC_3_4 |
904 FE_CAN_FEC_5_6 |
905 FE_CAN_FEC_7_8 |
906 FE_CAN_FEC_AUTO |
907 FE_CAN_QPSK |
908 FE_CAN_QAM_16 |
909 FE_CAN_QAM_64 |
910 FE_CAN_QAM_AUTO |
911 FE_CAN_TRANSMISSION_MODE_AUTO |
912 FE_CAN_GUARD_INTERVAL_AUTO |
913 FE_CAN_HIERARCHY_AUTO |
914 FE_CAN_RECOVER |
915 FE_CAN_MUTE_TS
916 },
917
918 .release = rtl2832_release,
919
920 .init = rtl2832_init,
921 .sleep = rtl2832_sleep,
922
923 .get_tune_settings = rtl2832_get_tune_settings,
924
925 .set_frontend = rtl2832_set_frontend,
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300926 .get_frontend = rtl2832_get_frontend,
Thomas Mair82041c02012-05-18 14:47:40 -0300927
928 .read_status = rtl2832_read_status,
Antti Palosaari73983492012-08-21 19:56:21 -0300929 .read_snr = rtl2832_read_snr,
Antti Palosaaridb32d742012-08-21 19:56:22 -0300930 .read_ber = rtl2832_read_ber,
Antti Palosaari73983492012-08-21 19:56:21 -0300931
Thomas Mair82041c02012-05-18 14:47:40 -0300932 .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
933};
934
935MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
936MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
937MODULE_LICENSE("GPL");
938MODULE_VERSION("0.5");