blob: facb84841518e66cd274308af34009a16a8a7390 [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 {
Antti Palosaari298efdd2012-09-11 22:27:11 -0300182 dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
183 "len=%d\n", KBUILD_MODNAME, ret, reg, len);
Thomas Mair82041c02012-05-18 14:47:40 -0300184 ret = -EREMOTEIO;
185 }
186 return ret;
187}
188
189/* read multiple hardware registers */
190static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
191{
192 int ret;
193 struct i2c_msg msg[2] = {
194 {
195 .addr = priv->cfg.i2c_addr,
196 .flags = 0,
197 .len = 1,
198 .buf = &reg,
199 }, {
200 .addr = priv->cfg.i2c_addr,
201 .flags = I2C_M_RD,
202 .len = len,
203 .buf = val,
204 }
205 };
206
207 ret = i2c_transfer(priv->i2c, msg, 2);
208 if (ret == 2) {
209 ret = 0;
210 } else {
Antti Palosaari298efdd2012-09-11 22:27:11 -0300211 dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
212 "len=%d\n", KBUILD_MODNAME, ret, reg, len);
Thomas Mair82041c02012-05-18 14:47:40 -0300213 ret = -EREMOTEIO;
Antti Palosaari298efdd2012-09-11 22:27:11 -0300214 }
215 return ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300216}
217
218/* write multiple registers */
219static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
220 int len)
221{
222 int ret;
223
Thomas Mair82041c02012-05-18 14:47:40 -0300224 /* switch bank if needed */
225 if (page != priv->page) {
226 ret = rtl2832_wr(priv, 0x00, &page, 1);
227 if (ret)
228 return ret;
229
230 priv->page = page;
231}
232
233return rtl2832_wr(priv, reg, val, len);
234}
235
236/* read multiple registers */
237static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
238 int len)
239{
240 int ret;
241
242 /* switch bank if needed */
243 if (page != priv->page) {
244 ret = rtl2832_wr(priv, 0x00, &page, 1);
245 if (ret)
246 return ret;
247
248 priv->page = page;
249 }
250
251 return rtl2832_rd(priv, reg, val, len);
252}
253
254#if 0 /* currently not used */
255/* write single register */
256static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
257{
258 return rtl2832_wr_regs(priv, reg, page, &val, 1);
259}
260#endif
261
262/* read single register */
263static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
264{
265 return rtl2832_rd_regs(priv, reg, page, val, 1);
266}
267
Mauro Carvalho Chehabb0944ea2012-10-27 11:24:37 -0300268static int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
Thomas Mair82041c02012-05-18 14:47:40 -0300269{
270 int ret;
271
272 u8 reg_start_addr;
273 u8 msb, lsb;
274 u8 page;
275 u8 reading[4];
276 u32 reading_tmp;
277 int i;
278
279 u8 len;
280 u32 mask;
281
282 reg_start_addr = registers[reg].start_address;
283 msb = registers[reg].msb;
284 lsb = registers[reg].lsb;
285 page = registers[reg].page;
286
287 len = (msb >> 3) + 1;
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -0300288 mask = REG_MASK(msb - lsb);
Thomas Mair82041c02012-05-18 14:47:40 -0300289
290 ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
291 if (ret)
292 goto err;
293
294 reading_tmp = 0;
295 for (i = 0; i < len; i++)
296 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
297
298 *val = (reading_tmp >> lsb) & mask;
299
300 return ret;
301
302err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300303 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300304 return ret;
305
306}
307
Mauro Carvalho Chehabb0944ea2012-10-27 11:24:37 -0300308static int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
Thomas Mair82041c02012-05-18 14:47:40 -0300309{
310 int ret, i;
311 u8 len;
312 u8 reg_start_addr;
313 u8 msb, lsb;
314 u8 page;
315 u32 mask;
316
317
318 u8 reading[4];
319 u8 writing[4];
320 u32 reading_tmp;
321 u32 writing_tmp;
322
323
324 reg_start_addr = registers[reg].start_address;
325 msb = registers[reg].msb;
326 lsb = registers[reg].lsb;
327 page = registers[reg].page;
328
329 len = (msb >> 3) + 1;
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -0300330 mask = REG_MASK(msb - lsb);
Thomas Mair82041c02012-05-18 14:47:40 -0300331
332
333 ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
334 if (ret)
335 goto err;
336
337 reading_tmp = 0;
338 for (i = 0; i < len; i++)
339 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
340
341 writing_tmp = reading_tmp & ~(mask << lsb);
342 writing_tmp |= ((val & mask) << lsb);
343
344
345 for (i = 0; i < len; i++)
346 writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
347
348 ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len);
349 if (ret)
350 goto err;
351
352 return ret;
353
354err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300355 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300356 return ret;
357
358}
359
Thomas Mair82041c02012-05-18 14:47:40 -0300360static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
361{
362 int ret;
363 struct rtl2832_priv *priv = fe->demodulator_priv;
364
Antti Palosaari298efdd2012-09-11 22:27:11 -0300365 dev_dbg(&priv->i2c->dev, "%s: enable=%d\n", __func__, enable);
Thomas Mair82041c02012-05-18 14:47:40 -0300366
367 /* gate already open or close */
368 if (priv->i2c_gate_state == enable)
369 return 0;
370
371 ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0));
372 if (ret)
373 goto err;
374
375 priv->i2c_gate_state = enable;
376
377 return ret;
378err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300379 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300380 return ret;
381}
382
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300383
384static int rtl2832_set_if(struct dvb_frontend *fe, u32 if_freq)
385{
386 struct rtl2832_priv *priv = fe->demodulator_priv;
387 int ret;
388 u64 pset_iffreq;
389 u8 en_bbin = (if_freq == 0 ? 0x1 : 0x0);
390
391 /*
392 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
393 * / CrystalFreqHz)
394 */
395
396 pset_iffreq = if_freq % priv->cfg.xtal;
397 pset_iffreq *= 0x400000;
398 pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
Mauro Carvalho Chehabc8832e82013-04-15 19:44:39 -0300399 pset_iffreq = -pset_iffreq;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300400 pset_iffreq = pset_iffreq & 0x3fffff;
Mauro Carvalho Chehabc8832e82013-04-15 19:44:39 -0300401 dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d pset_iffreq=%08x\n",
402 __func__, if_freq, (unsigned)pset_iffreq);
403
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300404 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
405 if (ret)
406 return ret;
407
408 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
409
410 return (ret);
411}
412
Thomas Mair82041c02012-05-18 14:47:40 -0300413static int rtl2832_init(struct dvb_frontend *fe)
414{
415 struct rtl2832_priv *priv = fe->demodulator_priv;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300416 const struct rtl2832_reg_value *init;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300417 int i, ret, len;
Thomas Mair82041c02012-05-18 14:47:40 -0300418
419 /* initialization values for the demodulator registers */
420 struct rtl2832_reg_value rtl2832_initial_regs[] = {
421 {DVBT_AD_EN_REG, 0x1},
422 {DVBT_AD_EN_REG1, 0x1},
423 {DVBT_RSD_BER_FAIL_VAL, 0x2800},
424 {DVBT_MGD_THD0, 0x10},
425 {DVBT_MGD_THD1, 0x20},
426 {DVBT_MGD_THD2, 0x20},
427 {DVBT_MGD_THD3, 0x40},
428 {DVBT_MGD_THD4, 0x22},
429 {DVBT_MGD_THD5, 0x32},
430 {DVBT_MGD_THD6, 0x37},
431 {DVBT_MGD_THD7, 0x39},
432 {DVBT_EN_BK_TRK, 0x0},
433 {DVBT_EN_CACQ_NOTCH, 0x0},
434 {DVBT_AD_AV_REF, 0x2a},
435 {DVBT_REG_PI, 0x6},
436 {DVBT_PIP_ON, 0x0},
437 {DVBT_CDIV_PH0, 0x8},
438 {DVBT_CDIV_PH1, 0x8},
439 {DVBT_SCALE1_B92, 0x4},
440 {DVBT_SCALE1_B93, 0xb0},
441 {DVBT_SCALE1_BA7, 0x78},
442 {DVBT_SCALE1_BA9, 0x28},
443 {DVBT_SCALE1_BAA, 0x59},
444 {DVBT_SCALE1_BAB, 0x83},
445 {DVBT_SCALE1_BAC, 0xd4},
446 {DVBT_SCALE1_BB0, 0x65},
447 {DVBT_SCALE1_BB1, 0x43},
448 {DVBT_KB_P1, 0x1},
449 {DVBT_KB_P2, 0x4},
450 {DVBT_KB_P3, 0x7},
451 {DVBT_K1_CR_STEP12, 0xa},
452 {DVBT_REG_GPE, 0x1},
453 {DVBT_SERIAL, 0x0},
454 {DVBT_CDIV_PH0, 0x9},
455 {DVBT_CDIV_PH1, 0x9},
456 {DVBT_MPEG_IO_OPT_2_2, 0x0},
457 {DVBT_MPEG_IO_OPT_1_0, 0x0},
458 {DVBT_TRK_KS_P2, 0x4},
459 {DVBT_TRK_KS_I2, 0x7},
460 {DVBT_TR_THD_SET2, 0x6},
461 {DVBT_TRK_KC_I2, 0x5},
462 {DVBT_CR_THD_SET2, 0x1},
Thomas Mair82041c02012-05-18 14:47:40 -0300463 };
464
Antti Palosaari298efdd2012-09-11 22:27:11 -0300465 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300466
Thomas Mair82041c02012-05-18 14:47:40 -0300467 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
468 ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
469 rtl2832_initial_regs[i].value);
470 if (ret)
471 goto err;
472 }
473
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300474 /* load tuner specific settings */
Antti Palosaari298efdd2012-09-11 22:27:11 -0300475 dev_dbg(&priv->i2c->dev, "%s: load settings for tuner=%02x\n",
476 __func__, priv->cfg.tuner);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300477 switch (priv->cfg.tuner) {
478 case RTL2832_TUNER_FC0012:
479 case RTL2832_TUNER_FC0013:
480 len = ARRAY_SIZE(rtl2832_tuner_init_fc0012);
481 init = rtl2832_tuner_init_fc0012;
482 break;
Antti Palosaari5db41872012-09-11 22:27:08 -0300483 case RTL2832_TUNER_TUA9001:
484 len = ARRAY_SIZE(rtl2832_tuner_init_tua9001);
485 init = rtl2832_tuner_init_tua9001;
486 break;
Antti Palosaari7e688de2012-09-17 17:53:04 -0300487 case RTL2832_TUNER_E4000:
488 len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
489 init = rtl2832_tuner_init_e4000;
490 break;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300491 case RTL2832_TUNER_R820T:
492 len = ARRAY_SIZE(rtl2832_tuner_init_r820t);
493 init = rtl2832_tuner_init_r820t;
494 break;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300495 default:
496 ret = -EINVAL;
497 goto err;
498 }
499
500 for (i = 0; i < len; i++) {
Antti Palosaari5db41872012-09-11 22:27:08 -0300501 ret = rtl2832_wr_demod_reg(priv, init[i].reg, init[i].value);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300502 if (ret)
503 goto err;
504 }
505
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300506 if (!fe->ops.tuner_ops.get_if_frequency) {
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300507 ret = rtl2832_set_if(fe, priv->cfg.if_dvbt);
508 if (ret)
509 goto err;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300510 }
511
512 /*
513 * r820t NIM code does a software reset here at the demod -
514 * may not be needed, as there's already a software reset at set_params()
515 */
516#if 1
517 /* soft reset */
518 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
519 if (ret)
520 goto err;
521
522 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
523 if (ret)
524 goto err;
525#endif
Thomas Mair82041c02012-05-18 14:47:40 -0300526
527 priv->sleeping = false;
528
529 return ret;
530
531err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300532 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300533 return ret;
534}
535
536static int rtl2832_sleep(struct dvb_frontend *fe)
537{
538 struct rtl2832_priv *priv = fe->demodulator_priv;
539
Antti Palosaari298efdd2012-09-11 22:27:11 -0300540 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300541 priv->sleeping = true;
542 return 0;
543}
544
Mauro Carvalho Chehabb0944ea2012-10-27 11:24:37 -0300545static int rtl2832_get_tune_settings(struct dvb_frontend *fe,
Thomas Mair82041c02012-05-18 14:47:40 -0300546 struct dvb_frontend_tune_settings *s)
547{
Antti Palosaari298efdd2012-09-11 22:27:11 -0300548 struct rtl2832_priv *priv = fe->demodulator_priv;
549
550 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300551 s->min_delay_ms = 1000;
552 s->step_size = fe->ops.info.frequency_stepsize * 2;
553 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
554 return 0;
555}
556
557static int rtl2832_set_frontend(struct dvb_frontend *fe)
558{
559 struct rtl2832_priv *priv = fe->demodulator_priv;
560 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
561 int ret, i, j;
562 u64 bw_mode, num, num2;
563 u32 resamp_ratio, cfreq_off_ratio;
Thomas Mair82041c02012-05-18 14:47:40 -0300564 static u8 bw_params[3][32] = {
565 /* 6 MHz bandwidth */
566 {
567 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
568 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
569 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
570 0x19, 0xe0,
571 },
572
573 /* 7 MHz bandwidth */
574 {
575 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
576 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
577 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
578 0x19, 0x10,
579 },
580
581 /* 8 MHz bandwidth */
582 {
583 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
584 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
585 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
586 0x19, 0xe0,
587 },
588 };
589
590
Antti Palosaari298efdd2012-09-11 22:27:11 -0300591 dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
592 "inversion=%d\n", __func__, c->frequency,
593 c->bandwidth_hz, c->inversion);
Thomas Mair82041c02012-05-18 14:47:40 -0300594
595 /* program tuner */
596 if (fe->ops.tuner_ops.set_params)
597 fe->ops.tuner_ops.set_params(fe);
598
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300599 /* If the frontend has get_if_frequency(), use it */
600 if (fe->ops.tuner_ops.get_if_frequency) {
601 u32 if_freq;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300602
603 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
604 if (ret)
605 goto err;
606
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300607 ret = rtl2832_set_if(fe, if_freq);
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300608 if (ret)
609 goto err;
610 }
611
Thomas Mair82041c02012-05-18 14:47:40 -0300612 switch (c->bandwidth_hz) {
613 case 6000000:
614 i = 0;
615 bw_mode = 48000000;
616 break;
617 case 7000000:
618 i = 1;
619 bw_mode = 56000000;
620 break;
621 case 8000000:
622 i = 2;
623 bw_mode = 64000000;
624 break;
625 default:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300626 dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300627 return -EINVAL;
628 }
629
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300630 for (j = 0; j < sizeof(bw_params[0]); j++) {
Thomas Mair82041c02012-05-18 14:47:40 -0300631 ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
632 if (ret)
633 goto err;
634 }
635
636 /* calculate and set resample ratio
637 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
638 * / ConstWithBandwidthMode)
639 */
640 num = priv->cfg.xtal * 7;
641 num *= 0x400000;
642 num = div_u64(num, bw_mode);
643 resamp_ratio = num & 0x3ffffff;
644 ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
645 if (ret)
646 goto err;
647
648 /* calculate and set cfreq off ratio
649 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
650 * / (CrystalFreqHz * 7))
651 */
652 num = bw_mode << 20;
653 num2 = priv->cfg.xtal * 7;
654 num = div_u64(num, num2);
655 num = -num;
656 cfreq_off_ratio = num & 0xfffff;
657 ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
658 if (ret)
659 goto err;
660
661
662 /* soft reset */
663 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
664 if (ret)
665 goto err;
666
667 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
668 if (ret)
669 goto err;
670
671 return ret;
672err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300673 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300674 return ret;
675}
676
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300677static int rtl2832_get_frontend(struct dvb_frontend *fe)
678{
679 struct rtl2832_priv *priv = fe->demodulator_priv;
680 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
681 int ret;
682 u8 buf[3];
683
684 if (priv->sleeping)
685 return 0;
686
687 ret = rtl2832_rd_regs(priv, 0x3c, 3, buf, 2);
688 if (ret)
689 goto err;
690
691 ret = rtl2832_rd_reg(priv, 0x51, 3, &buf[2]);
692 if (ret)
693 goto err;
694
Antti Palosaari298efdd2012-09-11 22:27:11 -0300695 dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300696
697 switch ((buf[0] >> 2) & 3) {
698 case 0:
699 c->modulation = QPSK;
700 break;
701 case 1:
702 c->modulation = QAM_16;
703 break;
704 case 2:
705 c->modulation = QAM_64;
706 break;
707 }
708
709 switch ((buf[2] >> 2) & 1) {
710 case 0:
711 c->transmission_mode = TRANSMISSION_MODE_2K;
712 break;
713 case 1:
714 c->transmission_mode = TRANSMISSION_MODE_8K;
715 }
716
717 switch ((buf[2] >> 0) & 3) {
718 case 0:
719 c->guard_interval = GUARD_INTERVAL_1_32;
720 break;
721 case 1:
722 c->guard_interval = GUARD_INTERVAL_1_16;
723 break;
724 case 2:
725 c->guard_interval = GUARD_INTERVAL_1_8;
726 break;
727 case 3:
728 c->guard_interval = GUARD_INTERVAL_1_4;
729 break;
730 }
731
732 switch ((buf[0] >> 4) & 7) {
733 case 0:
734 c->hierarchy = HIERARCHY_NONE;
735 break;
736 case 1:
737 c->hierarchy = HIERARCHY_1;
738 break;
739 case 2:
740 c->hierarchy = HIERARCHY_2;
741 break;
742 case 3:
743 c->hierarchy = HIERARCHY_4;
744 break;
745 }
746
747 switch ((buf[1] >> 3) & 7) {
748 case 0:
749 c->code_rate_HP = FEC_1_2;
750 break;
751 case 1:
752 c->code_rate_HP = FEC_2_3;
753 break;
754 case 2:
755 c->code_rate_HP = FEC_3_4;
756 break;
757 case 3:
758 c->code_rate_HP = FEC_5_6;
759 break;
760 case 4:
761 c->code_rate_HP = FEC_7_8;
762 break;
763 }
764
765 switch ((buf[1] >> 0) & 7) {
766 case 0:
767 c->code_rate_LP = FEC_1_2;
768 break;
769 case 1:
770 c->code_rate_LP = FEC_2_3;
771 break;
772 case 2:
773 c->code_rate_LP = FEC_3_4;
774 break;
775 case 3:
776 c->code_rate_LP = FEC_5_6;
777 break;
778 case 4:
779 c->code_rate_LP = FEC_7_8;
780 break;
781 }
782
783 return 0;
784err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300785 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300786 return ret;
787}
788
Thomas Mair82041c02012-05-18 14:47:40 -0300789static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
790{
791 struct rtl2832_priv *priv = fe->demodulator_priv;
792 int ret;
793 u32 tmp;
794 *status = 0;
795
Antti Palosaari298efdd2012-09-11 22:27:11 -0300796 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300797 if (priv->sleeping)
798 return 0;
799
800 ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
801 if (ret)
802 goto err;
803
804 if (tmp == 11) {
805 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
806 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
807 }
808 /* TODO find out if this is also true for rtl2832? */
809 /*else if (tmp == 10) {
810 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
811 FE_HAS_VITERBI;
812 }*/
813
814 return ret;
815err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300816 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300817 return ret;
818}
819
Antti Palosaari73983492012-08-21 19:56:21 -0300820static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
821{
822 struct rtl2832_priv *priv = fe->demodulator_priv;
823 int ret, hierarchy, constellation;
824 u8 buf[2], tmp;
825 u16 tmp16;
826#define CONSTELLATION_NUM 3
827#define HIERARCHY_NUM 4
828 static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
829 { 85387325, 85387325, 85387325, 85387325 },
830 { 86676178, 86676178, 87167949, 87795660 },
831 { 87659938, 87659938, 87885178, 88241743 },
832 };
833
834 /* reports SNR in resolution of 0.1 dB */
835
836 ret = rtl2832_rd_reg(priv, 0x3c, 3, &tmp);
837 if (ret)
838 goto err;
839
840 constellation = (tmp >> 2) & 0x03; /* [3:2] */
841 if (constellation > CONSTELLATION_NUM - 1)
842 goto err;
843
844 hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
845 if (hierarchy > HIERARCHY_NUM - 1)
846 goto err;
847
848 ret = rtl2832_rd_regs(priv, 0x0c, 4, buf, 2);
849 if (ret)
850 goto err;
851
852 tmp16 = buf[0] << 8 | buf[1];
853
854 if (tmp16)
855 *snr = (snr_constant[constellation][hierarchy] -
856 intlog10(tmp16)) / ((1 << 24) / 100);
857 else
858 *snr = 0;
859
860 return 0;
861err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300862 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari73983492012-08-21 19:56:21 -0300863 return ret;
864}
865
Antti Palosaaridb32d742012-08-21 19:56:22 -0300866static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
867{
868 struct rtl2832_priv *priv = fe->demodulator_priv;
869 int ret;
870 u8 buf[2];
871
872 ret = rtl2832_rd_regs(priv, 0x4e, 3, buf, 2);
873 if (ret)
874 goto err;
875
876 *ber = buf[0] << 8 | buf[1];
877
878 return 0;
879err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300880 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaaridb32d742012-08-21 19:56:22 -0300881 return ret;
882}
883
Thomas Mair82041c02012-05-18 14:47:40 -0300884static struct dvb_frontend_ops rtl2832_ops;
885
886static void rtl2832_release(struct dvb_frontend *fe)
887{
888 struct rtl2832_priv *priv = fe->demodulator_priv;
889
Antti Palosaari298efdd2012-09-11 22:27:11 -0300890 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300891 kfree(priv);
892}
893
894struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
895 struct i2c_adapter *i2c)
896{
897 struct rtl2832_priv *priv = NULL;
898 int ret = 0;
899 u8 tmp;
900
Antti Palosaari298efdd2012-09-11 22:27:11 -0300901 dev_dbg(&i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300902
903 /* allocate memory for the internal state */
904 priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
905 if (priv == NULL)
906 goto err;
907
908 /* setup the priv */
909 priv->i2c = i2c;
910 priv->tuner = cfg->tuner;
911 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
912
913 /* check if the demod is there */
914 ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
915 if (ret)
916 goto err;
917
918 /* create dvb_frontend */
919 memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
920 priv->fe.demodulator_priv = priv;
921
922 /* TODO implement sleep mode */
923 priv->sleeping = true;
924
925 return &priv->fe;
926err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300927 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300928 kfree(priv);
929 return NULL;
930}
931EXPORT_SYMBOL(rtl2832_attach);
932
933static struct dvb_frontend_ops rtl2832_ops = {
934 .delsys = { SYS_DVBT },
935 .info = {
936 .name = "Realtek RTL2832 (DVB-T)",
937 .frequency_min = 174000000,
938 .frequency_max = 862000000,
939 .frequency_stepsize = 166667,
940 .caps = FE_CAN_FEC_1_2 |
941 FE_CAN_FEC_2_3 |
942 FE_CAN_FEC_3_4 |
943 FE_CAN_FEC_5_6 |
944 FE_CAN_FEC_7_8 |
945 FE_CAN_FEC_AUTO |
946 FE_CAN_QPSK |
947 FE_CAN_QAM_16 |
948 FE_CAN_QAM_64 |
949 FE_CAN_QAM_AUTO |
950 FE_CAN_TRANSMISSION_MODE_AUTO |
951 FE_CAN_GUARD_INTERVAL_AUTO |
952 FE_CAN_HIERARCHY_AUTO |
953 FE_CAN_RECOVER |
954 FE_CAN_MUTE_TS
955 },
956
957 .release = rtl2832_release,
958
959 .init = rtl2832_init,
960 .sleep = rtl2832_sleep,
961
962 .get_tune_settings = rtl2832_get_tune_settings,
963
964 .set_frontend = rtl2832_set_frontend,
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300965 .get_frontend = rtl2832_get_frontend,
Thomas Mair82041c02012-05-18 14:47:40 -0300966
967 .read_status = rtl2832_read_status,
Antti Palosaari73983492012-08-21 19:56:21 -0300968 .read_snr = rtl2832_read_snr,
Antti Palosaaridb32d742012-08-21 19:56:22 -0300969 .read_ber = rtl2832_read_ber,
Antti Palosaari73983492012-08-21 19:56:21 -0300970
Thomas Mair82041c02012-05-18 14:47:40 -0300971 .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
972};
973
974MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
975MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
976MODULE_LICENSE("GPL");
977MODULE_VERSION("0.5");