blob: 8f8a5b0c7f3f13ffdcc35bd5713c4db6530fa439 [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;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300385 int i, ret, len;
Thomas Mair82041c02012-05-18 14:47:40 -0300386 u8 en_bbin;
387 u64 pset_iffreq;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300388 const struct rtl2832_reg_value *init;
Thomas Mair82041c02012-05-18 14:47:40 -0300389
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},
Thomas Mair82041c02012-05-18 14:47:40 -0300435 };
436
Thomas Mair82041c02012-05-18 14:47:40 -0300437 dbg("%s", __func__);
438
439 en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
440
441 /*
442 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
443 * / CrystalFreqHz)
444 */
445 pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
446 pset_iffreq *= 0x400000;
447 pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
448 pset_iffreq = pset_iffreq & 0x3fffff;
449
Thomas Mair82041c02012-05-18 14:47:40 -0300450 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
451 ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
452 rtl2832_initial_regs[i].value);
453 if (ret)
454 goto err;
455 }
456
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300457 /* load tuner specific settings */
458 dbg("%s: load settings for tuner=%02x", __func__, priv->cfg.tuner);
459 switch (priv->cfg.tuner) {
460 case RTL2832_TUNER_FC0012:
461 case RTL2832_TUNER_FC0013:
462 len = ARRAY_SIZE(rtl2832_tuner_init_fc0012);
463 init = rtl2832_tuner_init_fc0012;
464 break;
Antti Palosaari5db41872012-09-11 22:27:08 -0300465 case RTL2832_TUNER_TUA9001:
466 len = ARRAY_SIZE(rtl2832_tuner_init_tua9001);
467 init = rtl2832_tuner_init_tua9001;
468 break;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300469 default:
470 ret = -EINVAL;
471 goto err;
472 }
473
474 for (i = 0; i < len; i++) {
Antti Palosaari5db41872012-09-11 22:27:08 -0300475 ret = rtl2832_wr_demod_reg(priv, init[i].reg, init[i].value);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300476 if (ret)
477 goto err;
478 }
479
Thomas Mair82041c02012-05-18 14:47:40 -0300480 /* if frequency settings */
481 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
482 if (ret)
483 goto err;
484
485 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
486 if (ret)
487 goto err;
488
489 priv->sleeping = false;
490
491 return ret;
492
493err:
494 dbg("%s: failed=%d", __func__, ret);
495 return ret;
496}
497
498static int rtl2832_sleep(struct dvb_frontend *fe)
499{
500 struct rtl2832_priv *priv = fe->demodulator_priv;
501
502 dbg("%s", __func__);
503 priv->sleeping = true;
504 return 0;
505}
506
507int rtl2832_get_tune_settings(struct dvb_frontend *fe,
508 struct dvb_frontend_tune_settings *s)
509{
510 dbg("%s", __func__);
511 s->min_delay_ms = 1000;
512 s->step_size = fe->ops.info.frequency_stepsize * 2;
513 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
514 return 0;
515}
516
517static int rtl2832_set_frontend(struct dvb_frontend *fe)
518{
519 struct rtl2832_priv *priv = fe->demodulator_priv;
520 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
521 int ret, i, j;
522 u64 bw_mode, num, num2;
523 u32 resamp_ratio, cfreq_off_ratio;
524
525
526 static u8 bw_params[3][32] = {
527 /* 6 MHz bandwidth */
528 {
529 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
530 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
531 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
532 0x19, 0xe0,
533 },
534
535 /* 7 MHz bandwidth */
536 {
537 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
538 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
539 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
540 0x19, 0x10,
541 },
542
543 /* 8 MHz bandwidth */
544 {
545 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
546 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
547 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
548 0x19, 0xe0,
549 },
550 };
551
552
553 dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
554 c->frequency, c->bandwidth_hz, c->inversion);
555
556
557 /* program tuner */
558 if (fe->ops.tuner_ops.set_params)
559 fe->ops.tuner_ops.set_params(fe);
560
561
562 switch (c->bandwidth_hz) {
563 case 6000000:
564 i = 0;
565 bw_mode = 48000000;
566 break;
567 case 7000000:
568 i = 1;
569 bw_mode = 56000000;
570 break;
571 case 8000000:
572 i = 2;
573 bw_mode = 64000000;
574 break;
575 default:
576 dbg("invalid bandwidth");
577 return -EINVAL;
578 }
579
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300580 for (j = 0; j < sizeof(bw_params[0]); j++) {
Thomas Mair82041c02012-05-18 14:47:40 -0300581 ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
582 if (ret)
583 goto err;
584 }
585
586 /* calculate and set resample ratio
587 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
588 * / ConstWithBandwidthMode)
589 */
590 num = priv->cfg.xtal * 7;
591 num *= 0x400000;
592 num = div_u64(num, bw_mode);
593 resamp_ratio = num & 0x3ffffff;
594 ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
595 if (ret)
596 goto err;
597
598 /* calculate and set cfreq off ratio
599 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
600 * / (CrystalFreqHz * 7))
601 */
602 num = bw_mode << 20;
603 num2 = priv->cfg.xtal * 7;
604 num = div_u64(num, num2);
605 num = -num;
606 cfreq_off_ratio = num & 0xfffff;
607 ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
608 if (ret)
609 goto err;
610
611
612 /* soft reset */
613 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
614 if (ret)
615 goto err;
616
617 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
618 if (ret)
619 goto err;
620
621 return ret;
622err:
623 info("%s: failed=%d", __func__, ret);
624 return ret;
625}
626
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300627static int rtl2832_get_frontend(struct dvb_frontend *fe)
628{
629 struct rtl2832_priv *priv = fe->demodulator_priv;
630 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
631 int ret;
632 u8 buf[3];
633
634 if (priv->sleeping)
635 return 0;
636
637 ret = rtl2832_rd_regs(priv, 0x3c, 3, buf, 2);
638 if (ret)
639 goto err;
640
641 ret = rtl2832_rd_reg(priv, 0x51, 3, &buf[2]);
642 if (ret)
643 goto err;
644
645 dbg("%s: TPS=%*ph", __func__, 3, buf);
646
647 switch ((buf[0] >> 2) & 3) {
648 case 0:
649 c->modulation = QPSK;
650 break;
651 case 1:
652 c->modulation = QAM_16;
653 break;
654 case 2:
655 c->modulation = QAM_64;
656 break;
657 }
658
659 switch ((buf[2] >> 2) & 1) {
660 case 0:
661 c->transmission_mode = TRANSMISSION_MODE_2K;
662 break;
663 case 1:
664 c->transmission_mode = TRANSMISSION_MODE_8K;
665 }
666
667 switch ((buf[2] >> 0) & 3) {
668 case 0:
669 c->guard_interval = GUARD_INTERVAL_1_32;
670 break;
671 case 1:
672 c->guard_interval = GUARD_INTERVAL_1_16;
673 break;
674 case 2:
675 c->guard_interval = GUARD_INTERVAL_1_8;
676 break;
677 case 3:
678 c->guard_interval = GUARD_INTERVAL_1_4;
679 break;
680 }
681
682 switch ((buf[0] >> 4) & 7) {
683 case 0:
684 c->hierarchy = HIERARCHY_NONE;
685 break;
686 case 1:
687 c->hierarchy = HIERARCHY_1;
688 break;
689 case 2:
690 c->hierarchy = HIERARCHY_2;
691 break;
692 case 3:
693 c->hierarchy = HIERARCHY_4;
694 break;
695 }
696
697 switch ((buf[1] >> 3) & 7) {
698 case 0:
699 c->code_rate_HP = FEC_1_2;
700 break;
701 case 1:
702 c->code_rate_HP = FEC_2_3;
703 break;
704 case 2:
705 c->code_rate_HP = FEC_3_4;
706 break;
707 case 3:
708 c->code_rate_HP = FEC_5_6;
709 break;
710 case 4:
711 c->code_rate_HP = FEC_7_8;
712 break;
713 }
714
715 switch ((buf[1] >> 0) & 7) {
716 case 0:
717 c->code_rate_LP = FEC_1_2;
718 break;
719 case 1:
720 c->code_rate_LP = FEC_2_3;
721 break;
722 case 2:
723 c->code_rate_LP = FEC_3_4;
724 break;
725 case 3:
726 c->code_rate_LP = FEC_5_6;
727 break;
728 case 4:
729 c->code_rate_LP = FEC_7_8;
730 break;
731 }
732
733 return 0;
734err:
735 dbg("%s: failed=%d", __func__, ret);
736 return ret;
737}
738
Thomas Mair82041c02012-05-18 14:47:40 -0300739static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
740{
741 struct rtl2832_priv *priv = fe->demodulator_priv;
742 int ret;
743 u32 tmp;
744 *status = 0;
745
746
747 dbg("%s", __func__);
748 if (priv->sleeping)
749 return 0;
750
751 ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
752 if (ret)
753 goto err;
754
755 if (tmp == 11) {
756 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
757 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
758 }
759 /* TODO find out if this is also true for rtl2832? */
760 /*else if (tmp == 10) {
761 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
762 FE_HAS_VITERBI;
763 }*/
764
765 return ret;
766err:
767 info("%s: failed=%d", __func__, ret);
768 return ret;
769}
770
Antti Palosaari73983492012-08-21 19:56:21 -0300771static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
772{
773 struct rtl2832_priv *priv = fe->demodulator_priv;
774 int ret, hierarchy, constellation;
775 u8 buf[2], tmp;
776 u16 tmp16;
777#define CONSTELLATION_NUM 3
778#define HIERARCHY_NUM 4
779 static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
780 { 85387325, 85387325, 85387325, 85387325 },
781 { 86676178, 86676178, 87167949, 87795660 },
782 { 87659938, 87659938, 87885178, 88241743 },
783 };
784
785 /* reports SNR in resolution of 0.1 dB */
786
787 ret = rtl2832_rd_reg(priv, 0x3c, 3, &tmp);
788 if (ret)
789 goto err;
790
791 constellation = (tmp >> 2) & 0x03; /* [3:2] */
792 if (constellation > CONSTELLATION_NUM - 1)
793 goto err;
794
795 hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
796 if (hierarchy > HIERARCHY_NUM - 1)
797 goto err;
798
799 ret = rtl2832_rd_regs(priv, 0x0c, 4, buf, 2);
800 if (ret)
801 goto err;
802
803 tmp16 = buf[0] << 8 | buf[1];
804
805 if (tmp16)
806 *snr = (snr_constant[constellation][hierarchy] -
807 intlog10(tmp16)) / ((1 << 24) / 100);
808 else
809 *snr = 0;
810
811 return 0;
812err:
813 dbg("%s: failed=%d", __func__, ret);
814 return ret;
815}
816
Antti Palosaaridb32d742012-08-21 19:56:22 -0300817static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
818{
819 struct rtl2832_priv *priv = fe->demodulator_priv;
820 int ret;
821 u8 buf[2];
822
823 ret = rtl2832_rd_regs(priv, 0x4e, 3, buf, 2);
824 if (ret)
825 goto err;
826
827 *ber = buf[0] << 8 | buf[1];
828
829 return 0;
830err:
831 dbg("%s: failed=%d", __func__, ret);
832 return ret;
833}
834
Thomas Mair82041c02012-05-18 14:47:40 -0300835static struct dvb_frontend_ops rtl2832_ops;
836
837static void rtl2832_release(struct dvb_frontend *fe)
838{
839 struct rtl2832_priv *priv = fe->demodulator_priv;
840
841 dbg("%s", __func__);
842 kfree(priv);
843}
844
845struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
846 struct i2c_adapter *i2c)
847{
848 struct rtl2832_priv *priv = NULL;
849 int ret = 0;
850 u8 tmp;
851
852 dbg("%s", __func__);
853
854 /* allocate memory for the internal state */
855 priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
856 if (priv == NULL)
857 goto err;
858
859 /* setup the priv */
860 priv->i2c = i2c;
861 priv->tuner = cfg->tuner;
862 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
863
864 /* check if the demod is there */
865 ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
866 if (ret)
867 goto err;
868
869 /* create dvb_frontend */
870 memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
871 priv->fe.demodulator_priv = priv;
872
873 /* TODO implement sleep mode */
874 priv->sleeping = true;
875
876 return &priv->fe;
877err:
878 dbg("%s: failed=%d", __func__, ret);
879 kfree(priv);
880 return NULL;
881}
882EXPORT_SYMBOL(rtl2832_attach);
883
884static struct dvb_frontend_ops rtl2832_ops = {
885 .delsys = { SYS_DVBT },
886 .info = {
887 .name = "Realtek RTL2832 (DVB-T)",
888 .frequency_min = 174000000,
889 .frequency_max = 862000000,
890 .frequency_stepsize = 166667,
891 .caps = FE_CAN_FEC_1_2 |
892 FE_CAN_FEC_2_3 |
893 FE_CAN_FEC_3_4 |
894 FE_CAN_FEC_5_6 |
895 FE_CAN_FEC_7_8 |
896 FE_CAN_FEC_AUTO |
897 FE_CAN_QPSK |
898 FE_CAN_QAM_16 |
899 FE_CAN_QAM_64 |
900 FE_CAN_QAM_AUTO |
901 FE_CAN_TRANSMISSION_MODE_AUTO |
902 FE_CAN_GUARD_INTERVAL_AUTO |
903 FE_CAN_HIERARCHY_AUTO |
904 FE_CAN_RECOVER |
905 FE_CAN_MUTE_TS
906 },
907
908 .release = rtl2832_release,
909
910 .init = rtl2832_init,
911 .sleep = rtl2832_sleep,
912
913 .get_tune_settings = rtl2832_get_tune_settings,
914
915 .set_frontend = rtl2832_set_frontend,
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300916 .get_frontend = rtl2832_get_frontend,
Thomas Mair82041c02012-05-18 14:47:40 -0300917
918 .read_status = rtl2832_read_status,
Antti Palosaari73983492012-08-21 19:56:21 -0300919 .read_snr = rtl2832_read_snr,
Antti Palosaaridb32d742012-08-21 19:56:22 -0300920 .read_ber = rtl2832_read_ber,
Antti Palosaari73983492012-08-21 19:56:21 -0300921
Thomas Mair82041c02012-05-18 14:47:40 -0300922 .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
923};
924
925MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
926MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
927MODULE_LICENSE("GPL");
928MODULE_VERSION("0.5");