blob: 80c8e5f1182fdc377a7e6ac83ff3e2efc8e523c8 [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
268int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
269{
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
308int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
309{
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
Thomas Mair82041c02012-05-18 14:47:40 -0300383static int rtl2832_init(struct dvb_frontend *fe)
384{
385 struct rtl2832_priv *priv = fe->demodulator_priv;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300386 int i, ret, len;
Thomas Mair82041c02012-05-18 14:47:40 -0300387 u8 en_bbin;
388 u64 pset_iffreq;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300389 const struct rtl2832_reg_value *init;
Thomas Mair82041c02012-05-18 14:47:40 -0300390
391 /* initialization values for the demodulator registers */
392 struct rtl2832_reg_value rtl2832_initial_regs[] = {
393 {DVBT_AD_EN_REG, 0x1},
394 {DVBT_AD_EN_REG1, 0x1},
395 {DVBT_RSD_BER_FAIL_VAL, 0x2800},
396 {DVBT_MGD_THD0, 0x10},
397 {DVBT_MGD_THD1, 0x20},
398 {DVBT_MGD_THD2, 0x20},
399 {DVBT_MGD_THD3, 0x40},
400 {DVBT_MGD_THD4, 0x22},
401 {DVBT_MGD_THD5, 0x32},
402 {DVBT_MGD_THD6, 0x37},
403 {DVBT_MGD_THD7, 0x39},
404 {DVBT_EN_BK_TRK, 0x0},
405 {DVBT_EN_CACQ_NOTCH, 0x0},
406 {DVBT_AD_AV_REF, 0x2a},
407 {DVBT_REG_PI, 0x6},
408 {DVBT_PIP_ON, 0x0},
409 {DVBT_CDIV_PH0, 0x8},
410 {DVBT_CDIV_PH1, 0x8},
411 {DVBT_SCALE1_B92, 0x4},
412 {DVBT_SCALE1_B93, 0xb0},
413 {DVBT_SCALE1_BA7, 0x78},
414 {DVBT_SCALE1_BA9, 0x28},
415 {DVBT_SCALE1_BAA, 0x59},
416 {DVBT_SCALE1_BAB, 0x83},
417 {DVBT_SCALE1_BAC, 0xd4},
418 {DVBT_SCALE1_BB0, 0x65},
419 {DVBT_SCALE1_BB1, 0x43},
420 {DVBT_KB_P1, 0x1},
421 {DVBT_KB_P2, 0x4},
422 {DVBT_KB_P3, 0x7},
423 {DVBT_K1_CR_STEP12, 0xa},
424 {DVBT_REG_GPE, 0x1},
425 {DVBT_SERIAL, 0x0},
426 {DVBT_CDIV_PH0, 0x9},
427 {DVBT_CDIV_PH1, 0x9},
428 {DVBT_MPEG_IO_OPT_2_2, 0x0},
429 {DVBT_MPEG_IO_OPT_1_0, 0x0},
430 {DVBT_TRK_KS_P2, 0x4},
431 {DVBT_TRK_KS_I2, 0x7},
432 {DVBT_TR_THD_SET2, 0x6},
433 {DVBT_TRK_KC_I2, 0x5},
434 {DVBT_CR_THD_SET2, 0x1},
435 {DVBT_SPEC_INV, 0x0},
Thomas Mair82041c02012-05-18 14:47:40 -0300436 };
437
Antti Palosaari298efdd2012-09-11 22:27:11 -0300438 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300439
440 en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
441
442 /*
443 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
444 * / CrystalFreqHz)
445 */
446 pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
447 pset_iffreq *= 0x400000;
448 pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
449 pset_iffreq = pset_iffreq & 0x3fffff;
450
Thomas Mair82041c02012-05-18 14:47:40 -0300451 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
452 ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
453 rtl2832_initial_regs[i].value);
454 if (ret)
455 goto err;
456 }
457
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300458 /* load tuner specific settings */
Antti Palosaari298efdd2012-09-11 22:27:11 -0300459 dev_dbg(&priv->i2c->dev, "%s: load settings for tuner=%02x\n",
460 __func__, priv->cfg.tuner);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300461 switch (priv->cfg.tuner) {
462 case RTL2832_TUNER_FC0012:
463 case RTL2832_TUNER_FC0013:
464 len = ARRAY_SIZE(rtl2832_tuner_init_fc0012);
465 init = rtl2832_tuner_init_fc0012;
466 break;
Antti Palosaari5db41872012-09-11 22:27:08 -0300467 case RTL2832_TUNER_TUA9001:
468 len = ARRAY_SIZE(rtl2832_tuner_init_tua9001);
469 init = rtl2832_tuner_init_tua9001;
470 break;
Antti Palosaari7e688de2012-09-17 17:53:04 -0300471 case RTL2832_TUNER_E4000:
472 len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
473 init = rtl2832_tuner_init_e4000;
474 break;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300475 default:
476 ret = -EINVAL;
477 goto err;
478 }
479
480 for (i = 0; i < len; i++) {
Antti Palosaari5db41872012-09-11 22:27:08 -0300481 ret = rtl2832_wr_demod_reg(priv, init[i].reg, init[i].value);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300482 if (ret)
483 goto err;
484 }
485
Thomas Mair82041c02012-05-18 14:47:40 -0300486 /* if frequency settings */
487 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
488 if (ret)
489 goto err;
490
491 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
492 if (ret)
493 goto err;
494
495 priv->sleeping = false;
496
497 return ret;
498
499err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300500 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300501 return ret;
502}
503
504static int rtl2832_sleep(struct dvb_frontend *fe)
505{
506 struct rtl2832_priv *priv = fe->demodulator_priv;
507
Antti Palosaari298efdd2012-09-11 22:27:11 -0300508 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300509 priv->sleeping = true;
510 return 0;
511}
512
513int rtl2832_get_tune_settings(struct dvb_frontend *fe,
514 struct dvb_frontend_tune_settings *s)
515{
Antti Palosaari298efdd2012-09-11 22:27:11 -0300516 struct rtl2832_priv *priv = fe->demodulator_priv;
517
518 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300519 s->min_delay_ms = 1000;
520 s->step_size = fe->ops.info.frequency_stepsize * 2;
521 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
522 return 0;
523}
524
525static int rtl2832_set_frontend(struct dvb_frontend *fe)
526{
527 struct rtl2832_priv *priv = fe->demodulator_priv;
528 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
529 int ret, i, j;
530 u64 bw_mode, num, num2;
531 u32 resamp_ratio, cfreq_off_ratio;
Thomas Mair82041c02012-05-18 14:47:40 -0300532 static u8 bw_params[3][32] = {
533 /* 6 MHz bandwidth */
534 {
535 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
536 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
537 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
538 0x19, 0xe0,
539 },
540
541 /* 7 MHz bandwidth */
542 {
543 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
544 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
545 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
546 0x19, 0x10,
547 },
548
549 /* 8 MHz bandwidth */
550 {
551 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
552 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
553 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
554 0x19, 0xe0,
555 },
556 };
557
558
Antti Palosaari298efdd2012-09-11 22:27:11 -0300559 dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
560 "inversion=%d\n", __func__, c->frequency,
561 c->bandwidth_hz, c->inversion);
Thomas Mair82041c02012-05-18 14:47:40 -0300562
563 /* program tuner */
564 if (fe->ops.tuner_ops.set_params)
565 fe->ops.tuner_ops.set_params(fe);
566
Thomas Mair82041c02012-05-18 14:47:40 -0300567 switch (c->bandwidth_hz) {
568 case 6000000:
569 i = 0;
570 bw_mode = 48000000;
571 break;
572 case 7000000:
573 i = 1;
574 bw_mode = 56000000;
575 break;
576 case 8000000:
577 i = 2;
578 bw_mode = 64000000;
579 break;
580 default:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300581 dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300582 return -EINVAL;
583 }
584
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300585 for (j = 0; j < sizeof(bw_params[0]); j++) {
Thomas Mair82041c02012-05-18 14:47:40 -0300586 ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
587 if (ret)
588 goto err;
589 }
590
591 /* calculate and set resample ratio
592 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
593 * / ConstWithBandwidthMode)
594 */
595 num = priv->cfg.xtal * 7;
596 num *= 0x400000;
597 num = div_u64(num, bw_mode);
598 resamp_ratio = num & 0x3ffffff;
599 ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
600 if (ret)
601 goto err;
602
603 /* calculate and set cfreq off ratio
604 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
605 * / (CrystalFreqHz * 7))
606 */
607 num = bw_mode << 20;
608 num2 = priv->cfg.xtal * 7;
609 num = div_u64(num, num2);
610 num = -num;
611 cfreq_off_ratio = num & 0xfffff;
612 ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
613 if (ret)
614 goto err;
615
616
617 /* soft reset */
618 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
619 if (ret)
620 goto err;
621
622 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
623 if (ret)
624 goto err;
625
626 return ret;
627err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300628 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300629 return ret;
630}
631
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300632static int rtl2832_get_frontend(struct dvb_frontend *fe)
633{
634 struct rtl2832_priv *priv = fe->demodulator_priv;
635 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
636 int ret;
637 u8 buf[3];
638
639 if (priv->sleeping)
640 return 0;
641
642 ret = rtl2832_rd_regs(priv, 0x3c, 3, buf, 2);
643 if (ret)
644 goto err;
645
646 ret = rtl2832_rd_reg(priv, 0x51, 3, &buf[2]);
647 if (ret)
648 goto err;
649
Antti Palosaari298efdd2012-09-11 22:27:11 -0300650 dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300651
652 switch ((buf[0] >> 2) & 3) {
653 case 0:
654 c->modulation = QPSK;
655 break;
656 case 1:
657 c->modulation = QAM_16;
658 break;
659 case 2:
660 c->modulation = QAM_64;
661 break;
662 }
663
664 switch ((buf[2] >> 2) & 1) {
665 case 0:
666 c->transmission_mode = TRANSMISSION_MODE_2K;
667 break;
668 case 1:
669 c->transmission_mode = TRANSMISSION_MODE_8K;
670 }
671
672 switch ((buf[2] >> 0) & 3) {
673 case 0:
674 c->guard_interval = GUARD_INTERVAL_1_32;
675 break;
676 case 1:
677 c->guard_interval = GUARD_INTERVAL_1_16;
678 break;
679 case 2:
680 c->guard_interval = GUARD_INTERVAL_1_8;
681 break;
682 case 3:
683 c->guard_interval = GUARD_INTERVAL_1_4;
684 break;
685 }
686
687 switch ((buf[0] >> 4) & 7) {
688 case 0:
689 c->hierarchy = HIERARCHY_NONE;
690 break;
691 case 1:
692 c->hierarchy = HIERARCHY_1;
693 break;
694 case 2:
695 c->hierarchy = HIERARCHY_2;
696 break;
697 case 3:
698 c->hierarchy = HIERARCHY_4;
699 break;
700 }
701
702 switch ((buf[1] >> 3) & 7) {
703 case 0:
704 c->code_rate_HP = FEC_1_2;
705 break;
706 case 1:
707 c->code_rate_HP = FEC_2_3;
708 break;
709 case 2:
710 c->code_rate_HP = FEC_3_4;
711 break;
712 case 3:
713 c->code_rate_HP = FEC_5_6;
714 break;
715 case 4:
716 c->code_rate_HP = FEC_7_8;
717 break;
718 }
719
720 switch ((buf[1] >> 0) & 7) {
721 case 0:
722 c->code_rate_LP = FEC_1_2;
723 break;
724 case 1:
725 c->code_rate_LP = FEC_2_3;
726 break;
727 case 2:
728 c->code_rate_LP = FEC_3_4;
729 break;
730 case 3:
731 c->code_rate_LP = FEC_5_6;
732 break;
733 case 4:
734 c->code_rate_LP = FEC_7_8;
735 break;
736 }
737
738 return 0;
739err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300740 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300741 return ret;
742}
743
Thomas Mair82041c02012-05-18 14:47:40 -0300744static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
745{
746 struct rtl2832_priv *priv = fe->demodulator_priv;
747 int ret;
748 u32 tmp;
749 *status = 0;
750
Antti Palosaari298efdd2012-09-11 22:27:11 -0300751 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300752 if (priv->sleeping)
753 return 0;
754
755 ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
756 if (ret)
757 goto err;
758
759 if (tmp == 11) {
760 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
761 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
762 }
763 /* TODO find out if this is also true for rtl2832? */
764 /*else if (tmp == 10) {
765 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
766 FE_HAS_VITERBI;
767 }*/
768
769 return ret;
770err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300771 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300772 return ret;
773}
774
Antti Palosaari73983492012-08-21 19:56:21 -0300775static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
776{
777 struct rtl2832_priv *priv = fe->demodulator_priv;
778 int ret, hierarchy, constellation;
779 u8 buf[2], tmp;
780 u16 tmp16;
781#define CONSTELLATION_NUM 3
782#define HIERARCHY_NUM 4
783 static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
784 { 85387325, 85387325, 85387325, 85387325 },
785 { 86676178, 86676178, 87167949, 87795660 },
786 { 87659938, 87659938, 87885178, 88241743 },
787 };
788
789 /* reports SNR in resolution of 0.1 dB */
790
791 ret = rtl2832_rd_reg(priv, 0x3c, 3, &tmp);
792 if (ret)
793 goto err;
794
795 constellation = (tmp >> 2) & 0x03; /* [3:2] */
796 if (constellation > CONSTELLATION_NUM - 1)
797 goto err;
798
799 hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
800 if (hierarchy > HIERARCHY_NUM - 1)
801 goto err;
802
803 ret = rtl2832_rd_regs(priv, 0x0c, 4, buf, 2);
804 if (ret)
805 goto err;
806
807 tmp16 = buf[0] << 8 | buf[1];
808
809 if (tmp16)
810 *snr = (snr_constant[constellation][hierarchy] -
811 intlog10(tmp16)) / ((1 << 24) / 100);
812 else
813 *snr = 0;
814
815 return 0;
816err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300817 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari73983492012-08-21 19:56:21 -0300818 return ret;
819}
820
Antti Palosaaridb32d742012-08-21 19:56:22 -0300821static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
822{
823 struct rtl2832_priv *priv = fe->demodulator_priv;
824 int ret;
825 u8 buf[2];
826
827 ret = rtl2832_rd_regs(priv, 0x4e, 3, buf, 2);
828 if (ret)
829 goto err;
830
831 *ber = buf[0] << 8 | buf[1];
832
833 return 0;
834err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300835 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaaridb32d742012-08-21 19:56:22 -0300836 return ret;
837}
838
Thomas Mair82041c02012-05-18 14:47:40 -0300839static struct dvb_frontend_ops rtl2832_ops;
840
841static void rtl2832_release(struct dvb_frontend *fe)
842{
843 struct rtl2832_priv *priv = fe->demodulator_priv;
844
Antti Palosaari298efdd2012-09-11 22:27:11 -0300845 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300846 kfree(priv);
847}
848
849struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
850 struct i2c_adapter *i2c)
851{
852 struct rtl2832_priv *priv = NULL;
853 int ret = 0;
854 u8 tmp;
855
Antti Palosaari298efdd2012-09-11 22:27:11 -0300856 dev_dbg(&i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300857
858 /* allocate memory for the internal state */
859 priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
860 if (priv == NULL)
861 goto err;
862
863 /* setup the priv */
864 priv->i2c = i2c;
865 priv->tuner = cfg->tuner;
866 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
867
868 /* check if the demod is there */
869 ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
870 if (ret)
871 goto err;
872
873 /* create dvb_frontend */
874 memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
875 priv->fe.demodulator_priv = priv;
876
877 /* TODO implement sleep mode */
878 priv->sleeping = true;
879
880 return &priv->fe;
881err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300882 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300883 kfree(priv);
884 return NULL;
885}
886EXPORT_SYMBOL(rtl2832_attach);
887
888static struct dvb_frontend_ops rtl2832_ops = {
889 .delsys = { SYS_DVBT },
890 .info = {
891 .name = "Realtek RTL2832 (DVB-T)",
892 .frequency_min = 174000000,
893 .frequency_max = 862000000,
894 .frequency_stepsize = 166667,
895 .caps = FE_CAN_FEC_1_2 |
896 FE_CAN_FEC_2_3 |
897 FE_CAN_FEC_3_4 |
898 FE_CAN_FEC_5_6 |
899 FE_CAN_FEC_7_8 |
900 FE_CAN_FEC_AUTO |
901 FE_CAN_QPSK |
902 FE_CAN_QAM_16 |
903 FE_CAN_QAM_64 |
904 FE_CAN_QAM_AUTO |
905 FE_CAN_TRANSMISSION_MODE_AUTO |
906 FE_CAN_GUARD_INTERVAL_AUTO |
907 FE_CAN_HIERARCHY_AUTO |
908 FE_CAN_RECOVER |
909 FE_CAN_MUTE_TS
910 },
911
912 .release = rtl2832_release,
913
914 .init = rtl2832_init,
915 .sleep = rtl2832_sleep,
916
917 .get_tune_settings = rtl2832_get_tune_settings,
918
919 .set_frontend = rtl2832_set_frontend,
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300920 .get_frontend = rtl2832_get_frontend,
Thomas Mair82041c02012-05-18 14:47:40 -0300921
922 .read_status = rtl2832_read_status,
Antti Palosaari73983492012-08-21 19:56:21 -0300923 .read_snr = rtl2832_read_snr,
Antti Palosaaridb32d742012-08-21 19:56:22 -0300924 .read_ber = rtl2832_read_ber,
Antti Palosaari73983492012-08-21 19:56:21 -0300925
Thomas Mair82041c02012-05-18 14:47:40 -0300926 .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
927};
928
929MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
930MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
931MODULE_LICENSE("GPL");
932MODULE_VERSION("0.5");