blob: 2f5a2b504932d583828a5c0b6bffc97e3ee869e6 [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);
399 pset_iffreq = pset_iffreq & 0x3fffff;
400 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
401 if (ret)
402 return ret;
403
404 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
405
406 return (ret);
407}
408
Thomas Mair82041c02012-05-18 14:47:40 -0300409static int rtl2832_init(struct dvb_frontend *fe)
410{
411 struct rtl2832_priv *priv = fe->demodulator_priv;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300412 const struct rtl2832_reg_value *init;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300413 int i, ret, len;
Thomas Mair82041c02012-05-18 14:47:40 -0300414
415 /* initialization values for the demodulator registers */
416 struct rtl2832_reg_value rtl2832_initial_regs[] = {
417 {DVBT_AD_EN_REG, 0x1},
418 {DVBT_AD_EN_REG1, 0x1},
419 {DVBT_RSD_BER_FAIL_VAL, 0x2800},
420 {DVBT_MGD_THD0, 0x10},
421 {DVBT_MGD_THD1, 0x20},
422 {DVBT_MGD_THD2, 0x20},
423 {DVBT_MGD_THD3, 0x40},
424 {DVBT_MGD_THD4, 0x22},
425 {DVBT_MGD_THD5, 0x32},
426 {DVBT_MGD_THD6, 0x37},
427 {DVBT_MGD_THD7, 0x39},
428 {DVBT_EN_BK_TRK, 0x0},
429 {DVBT_EN_CACQ_NOTCH, 0x0},
430 {DVBT_AD_AV_REF, 0x2a},
431 {DVBT_REG_PI, 0x6},
432 {DVBT_PIP_ON, 0x0},
433 {DVBT_CDIV_PH0, 0x8},
434 {DVBT_CDIV_PH1, 0x8},
435 {DVBT_SCALE1_B92, 0x4},
436 {DVBT_SCALE1_B93, 0xb0},
437 {DVBT_SCALE1_BA7, 0x78},
438 {DVBT_SCALE1_BA9, 0x28},
439 {DVBT_SCALE1_BAA, 0x59},
440 {DVBT_SCALE1_BAB, 0x83},
441 {DVBT_SCALE1_BAC, 0xd4},
442 {DVBT_SCALE1_BB0, 0x65},
443 {DVBT_SCALE1_BB1, 0x43},
444 {DVBT_KB_P1, 0x1},
445 {DVBT_KB_P2, 0x4},
446 {DVBT_KB_P3, 0x7},
447 {DVBT_K1_CR_STEP12, 0xa},
448 {DVBT_REG_GPE, 0x1},
449 {DVBT_SERIAL, 0x0},
450 {DVBT_CDIV_PH0, 0x9},
451 {DVBT_CDIV_PH1, 0x9},
452 {DVBT_MPEG_IO_OPT_2_2, 0x0},
453 {DVBT_MPEG_IO_OPT_1_0, 0x0},
454 {DVBT_TRK_KS_P2, 0x4},
455 {DVBT_TRK_KS_I2, 0x7},
456 {DVBT_TR_THD_SET2, 0x6},
457 {DVBT_TRK_KC_I2, 0x5},
458 {DVBT_CR_THD_SET2, 0x1},
Thomas Mair82041c02012-05-18 14:47:40 -0300459 };
460
Antti Palosaari298efdd2012-09-11 22:27:11 -0300461 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300462
Thomas Mair82041c02012-05-18 14:47:40 -0300463 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
464 ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
465 rtl2832_initial_regs[i].value);
466 if (ret)
467 goto err;
468 }
469
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300470 /* load tuner specific settings */
Antti Palosaari298efdd2012-09-11 22:27:11 -0300471 dev_dbg(&priv->i2c->dev, "%s: load settings for tuner=%02x\n",
472 __func__, priv->cfg.tuner);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300473 switch (priv->cfg.tuner) {
474 case RTL2832_TUNER_FC0012:
475 case RTL2832_TUNER_FC0013:
476 len = ARRAY_SIZE(rtl2832_tuner_init_fc0012);
477 init = rtl2832_tuner_init_fc0012;
478 break;
Antti Palosaari5db41872012-09-11 22:27:08 -0300479 case RTL2832_TUNER_TUA9001:
480 len = ARRAY_SIZE(rtl2832_tuner_init_tua9001);
481 init = rtl2832_tuner_init_tua9001;
482 break;
Antti Palosaari7e688de2012-09-17 17:53:04 -0300483 case RTL2832_TUNER_E4000:
484 len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
485 init = rtl2832_tuner_init_e4000;
486 break;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300487 case RTL2832_TUNER_R820T:
488 len = ARRAY_SIZE(rtl2832_tuner_init_r820t);
489 init = rtl2832_tuner_init_r820t;
490 break;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300491 default:
492 ret = -EINVAL;
493 goto err;
494 }
495
496 for (i = 0; i < len; i++) {
Antti Palosaari5db41872012-09-11 22:27:08 -0300497 ret = rtl2832_wr_demod_reg(priv, init[i].reg, init[i].value);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300498 if (ret)
499 goto err;
500 }
501
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300502 if (!fe->ops.tuner_ops.get_if_frequency) {
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300503 ret = rtl2832_set_if(fe, priv->cfg.if_dvbt);
504 if (ret)
505 goto err;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300506 }
507
508 /*
509 * r820t NIM code does a software reset here at the demod -
510 * may not be needed, as there's already a software reset at set_params()
511 */
512#if 1
513 /* soft reset */
514 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
515 if (ret)
516 goto err;
517
518 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
519 if (ret)
520 goto err;
521#endif
Thomas Mair82041c02012-05-18 14:47:40 -0300522
523 priv->sleeping = false;
524
525 return ret;
526
527err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300528 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300529 return ret;
530}
531
532static int rtl2832_sleep(struct dvb_frontend *fe)
533{
534 struct rtl2832_priv *priv = fe->demodulator_priv;
535
Antti Palosaari298efdd2012-09-11 22:27:11 -0300536 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300537 priv->sleeping = true;
538 return 0;
539}
540
Mauro Carvalho Chehabb0944ea2012-10-27 11:24:37 -0300541static int rtl2832_get_tune_settings(struct dvb_frontend *fe,
Thomas Mair82041c02012-05-18 14:47:40 -0300542 struct dvb_frontend_tune_settings *s)
543{
Antti Palosaari298efdd2012-09-11 22:27:11 -0300544 struct rtl2832_priv *priv = fe->demodulator_priv;
545
546 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300547 s->min_delay_ms = 1000;
548 s->step_size = fe->ops.info.frequency_stepsize * 2;
549 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
550 return 0;
551}
552
553static int rtl2832_set_frontend(struct dvb_frontend *fe)
554{
555 struct rtl2832_priv *priv = fe->demodulator_priv;
556 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
557 int ret, i, j;
558 u64 bw_mode, num, num2;
559 u32 resamp_ratio, cfreq_off_ratio;
Thomas Mair82041c02012-05-18 14:47:40 -0300560 static u8 bw_params[3][32] = {
561 /* 6 MHz bandwidth */
562 {
563 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
564 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
565 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
566 0x19, 0xe0,
567 },
568
569 /* 7 MHz bandwidth */
570 {
571 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
572 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
573 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
574 0x19, 0x10,
575 },
576
577 /* 8 MHz bandwidth */
578 {
579 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
580 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
581 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
582 0x19, 0xe0,
583 },
584 };
585
586
Antti Palosaari298efdd2012-09-11 22:27:11 -0300587 dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
588 "inversion=%d\n", __func__, c->frequency,
589 c->bandwidth_hz, c->inversion);
Thomas Mair82041c02012-05-18 14:47:40 -0300590
591 /* program tuner */
592 if (fe->ops.tuner_ops.set_params)
593 fe->ops.tuner_ops.set_params(fe);
594
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300595 /* If the frontend has get_if_frequency(), use it */
596 if (fe->ops.tuner_ops.get_if_frequency) {
597 u32 if_freq;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300598
599 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
600 if (ret)
601 goto err;
602
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300603 ret = rtl2832_set_if(fe, if_freq);
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300604 if (ret)
605 goto err;
606 }
607
Thomas Mair82041c02012-05-18 14:47:40 -0300608 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:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300622 dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300623 return -EINVAL;
624 }
625
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300626 for (j = 0; j < sizeof(bw_params[0]); j++) {
Thomas Mair82041c02012-05-18 14:47:40 -0300627 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:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300669 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300670 return ret;
671}
672
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300673static int rtl2832_get_frontend(struct dvb_frontend *fe)
674{
675 struct rtl2832_priv *priv = fe->demodulator_priv;
676 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
677 int ret;
678 u8 buf[3];
679
680 if (priv->sleeping)
681 return 0;
682
683 ret = rtl2832_rd_regs(priv, 0x3c, 3, buf, 2);
684 if (ret)
685 goto err;
686
687 ret = rtl2832_rd_reg(priv, 0x51, 3, &buf[2]);
688 if (ret)
689 goto err;
690
Antti Palosaari298efdd2012-09-11 22:27:11 -0300691 dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300692
693 switch ((buf[0] >> 2) & 3) {
694 case 0:
695 c->modulation = QPSK;
696 break;
697 case 1:
698 c->modulation = QAM_16;
699 break;
700 case 2:
701 c->modulation = QAM_64;
702 break;
703 }
704
705 switch ((buf[2] >> 2) & 1) {
706 case 0:
707 c->transmission_mode = TRANSMISSION_MODE_2K;
708 break;
709 case 1:
710 c->transmission_mode = TRANSMISSION_MODE_8K;
711 }
712
713 switch ((buf[2] >> 0) & 3) {
714 case 0:
715 c->guard_interval = GUARD_INTERVAL_1_32;
716 break;
717 case 1:
718 c->guard_interval = GUARD_INTERVAL_1_16;
719 break;
720 case 2:
721 c->guard_interval = GUARD_INTERVAL_1_8;
722 break;
723 case 3:
724 c->guard_interval = GUARD_INTERVAL_1_4;
725 break;
726 }
727
728 switch ((buf[0] >> 4) & 7) {
729 case 0:
730 c->hierarchy = HIERARCHY_NONE;
731 break;
732 case 1:
733 c->hierarchy = HIERARCHY_1;
734 break;
735 case 2:
736 c->hierarchy = HIERARCHY_2;
737 break;
738 case 3:
739 c->hierarchy = HIERARCHY_4;
740 break;
741 }
742
743 switch ((buf[1] >> 3) & 7) {
744 case 0:
745 c->code_rate_HP = FEC_1_2;
746 break;
747 case 1:
748 c->code_rate_HP = FEC_2_3;
749 break;
750 case 2:
751 c->code_rate_HP = FEC_3_4;
752 break;
753 case 3:
754 c->code_rate_HP = FEC_5_6;
755 break;
756 case 4:
757 c->code_rate_HP = FEC_7_8;
758 break;
759 }
760
761 switch ((buf[1] >> 0) & 7) {
762 case 0:
763 c->code_rate_LP = FEC_1_2;
764 break;
765 case 1:
766 c->code_rate_LP = FEC_2_3;
767 break;
768 case 2:
769 c->code_rate_LP = FEC_3_4;
770 break;
771 case 3:
772 c->code_rate_LP = FEC_5_6;
773 break;
774 case 4:
775 c->code_rate_LP = FEC_7_8;
776 break;
777 }
778
779 return 0;
780err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300781 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300782 return ret;
783}
784
Thomas Mair82041c02012-05-18 14:47:40 -0300785static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
786{
787 struct rtl2832_priv *priv = fe->demodulator_priv;
788 int ret;
789 u32 tmp;
790 *status = 0;
791
Antti Palosaari298efdd2012-09-11 22:27:11 -0300792 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300793 if (priv->sleeping)
794 return 0;
795
796 ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
797 if (ret)
798 goto err;
799
800 if (tmp == 11) {
801 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
802 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
803 }
804 /* TODO find out if this is also true for rtl2832? */
805 /*else if (tmp == 10) {
806 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
807 FE_HAS_VITERBI;
808 }*/
809
810 return ret;
811err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300812 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300813 return ret;
814}
815
Antti Palosaari73983492012-08-21 19:56:21 -0300816static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
817{
818 struct rtl2832_priv *priv = fe->demodulator_priv;
819 int ret, hierarchy, constellation;
820 u8 buf[2], tmp;
821 u16 tmp16;
822#define CONSTELLATION_NUM 3
823#define HIERARCHY_NUM 4
824 static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
825 { 85387325, 85387325, 85387325, 85387325 },
826 { 86676178, 86676178, 87167949, 87795660 },
827 { 87659938, 87659938, 87885178, 88241743 },
828 };
829
830 /* reports SNR in resolution of 0.1 dB */
831
832 ret = rtl2832_rd_reg(priv, 0x3c, 3, &tmp);
833 if (ret)
834 goto err;
835
836 constellation = (tmp >> 2) & 0x03; /* [3:2] */
837 if (constellation > CONSTELLATION_NUM - 1)
838 goto err;
839
840 hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
841 if (hierarchy > HIERARCHY_NUM - 1)
842 goto err;
843
844 ret = rtl2832_rd_regs(priv, 0x0c, 4, buf, 2);
845 if (ret)
846 goto err;
847
848 tmp16 = buf[0] << 8 | buf[1];
849
850 if (tmp16)
851 *snr = (snr_constant[constellation][hierarchy] -
852 intlog10(tmp16)) / ((1 << 24) / 100);
853 else
854 *snr = 0;
855
856 return 0;
857err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300858 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari73983492012-08-21 19:56:21 -0300859 return ret;
860}
861
Antti Palosaaridb32d742012-08-21 19:56:22 -0300862static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
863{
864 struct rtl2832_priv *priv = fe->demodulator_priv;
865 int ret;
866 u8 buf[2];
867
868 ret = rtl2832_rd_regs(priv, 0x4e, 3, buf, 2);
869 if (ret)
870 goto err;
871
872 *ber = buf[0] << 8 | buf[1];
873
874 return 0;
875err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300876 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaaridb32d742012-08-21 19:56:22 -0300877 return ret;
878}
879
Thomas Mair82041c02012-05-18 14:47:40 -0300880static struct dvb_frontend_ops rtl2832_ops;
881
882static void rtl2832_release(struct dvb_frontend *fe)
883{
884 struct rtl2832_priv *priv = fe->demodulator_priv;
885
Antti Palosaari298efdd2012-09-11 22:27:11 -0300886 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300887 kfree(priv);
888}
889
890struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
891 struct i2c_adapter *i2c)
892{
893 struct rtl2832_priv *priv = NULL;
894 int ret = 0;
895 u8 tmp;
896
Antti Palosaari298efdd2012-09-11 22:27:11 -0300897 dev_dbg(&i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300898
899 /* allocate memory for the internal state */
900 priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
901 if (priv == NULL)
902 goto err;
903
904 /* setup the priv */
905 priv->i2c = i2c;
906 priv->tuner = cfg->tuner;
907 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
908
909 /* check if the demod is there */
910 ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
911 if (ret)
912 goto err;
913
914 /* create dvb_frontend */
915 memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
916 priv->fe.demodulator_priv = priv;
917
918 /* TODO implement sleep mode */
919 priv->sleeping = true;
920
921 return &priv->fe;
922err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300923 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300924 kfree(priv);
925 return NULL;
926}
927EXPORT_SYMBOL(rtl2832_attach);
928
929static struct dvb_frontend_ops rtl2832_ops = {
930 .delsys = { SYS_DVBT },
931 .info = {
932 .name = "Realtek RTL2832 (DVB-T)",
933 .frequency_min = 174000000,
934 .frequency_max = 862000000,
935 .frequency_stepsize = 166667,
936 .caps = FE_CAN_FEC_1_2 |
937 FE_CAN_FEC_2_3 |
938 FE_CAN_FEC_3_4 |
939 FE_CAN_FEC_5_6 |
940 FE_CAN_FEC_7_8 |
941 FE_CAN_FEC_AUTO |
942 FE_CAN_QPSK |
943 FE_CAN_QAM_16 |
944 FE_CAN_QAM_64 |
945 FE_CAN_QAM_AUTO |
946 FE_CAN_TRANSMISSION_MODE_AUTO |
947 FE_CAN_GUARD_INTERVAL_AUTO |
948 FE_CAN_HIERARCHY_AUTO |
949 FE_CAN_RECOVER |
950 FE_CAN_MUTE_TS
951 },
952
953 .release = rtl2832_release,
954
955 .init = rtl2832_init,
956 .sleep = rtl2832_sleep,
957
958 .get_tune_settings = rtl2832_get_tune_settings,
959
960 .set_frontend = rtl2832_set_frontend,
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300961 .get_frontend = rtl2832_get_frontend,
Thomas Mair82041c02012-05-18 14:47:40 -0300962
963 .read_status = rtl2832_read_status,
Antti Palosaari73983492012-08-21 19:56:21 -0300964 .read_snr = rtl2832_read_snr,
Antti Palosaaridb32d742012-08-21 19:56:22 -0300965 .read_ber = rtl2832_read_ber,
Antti Palosaari73983492012-08-21 19:56:21 -0300966
Thomas Mair82041c02012-05-18 14:47:40 -0300967 .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
968};
969
970MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
971MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
972MODULE_LICENSE("GPL");
973MODULE_VERSION("0.5");