blob: aaf0c29f0229e78c4ac9def2da0faf4aa94c8f31 [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 Palosaari832cc7c2012-09-11 22:27:04 -0300471 default:
472 ret = -EINVAL;
473 goto err;
474 }
475
476 for (i = 0; i < len; i++) {
Antti Palosaari5db41872012-09-11 22:27:08 -0300477 ret = rtl2832_wr_demod_reg(priv, init[i].reg, init[i].value);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300478 if (ret)
479 goto err;
480 }
481
Thomas Mair82041c02012-05-18 14:47:40 -0300482 /* if frequency settings */
483 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
484 if (ret)
485 goto err;
486
487 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
488 if (ret)
489 goto err;
490
491 priv->sleeping = false;
492
493 return ret;
494
495err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300496 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300497 return ret;
498}
499
500static int rtl2832_sleep(struct dvb_frontend *fe)
501{
502 struct rtl2832_priv *priv = fe->demodulator_priv;
503
Antti Palosaari298efdd2012-09-11 22:27:11 -0300504 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300505 priv->sleeping = true;
506 return 0;
507}
508
509int rtl2832_get_tune_settings(struct dvb_frontend *fe,
510 struct dvb_frontend_tune_settings *s)
511{
Antti Palosaari298efdd2012-09-11 22:27:11 -0300512 struct rtl2832_priv *priv = fe->demodulator_priv;
513
514 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300515 s->min_delay_ms = 1000;
516 s->step_size = fe->ops.info.frequency_stepsize * 2;
517 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
518 return 0;
519}
520
521static int rtl2832_set_frontend(struct dvb_frontend *fe)
522{
523 struct rtl2832_priv *priv = fe->demodulator_priv;
524 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
525 int ret, i, j;
526 u64 bw_mode, num, num2;
527 u32 resamp_ratio, cfreq_off_ratio;
Thomas Mair82041c02012-05-18 14:47:40 -0300528 static u8 bw_params[3][32] = {
529 /* 6 MHz bandwidth */
530 {
531 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
532 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
533 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
534 0x19, 0xe0,
535 },
536
537 /* 7 MHz bandwidth */
538 {
539 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
540 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
541 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
542 0x19, 0x10,
543 },
544
545 /* 8 MHz bandwidth */
546 {
547 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
548 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
549 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
550 0x19, 0xe0,
551 },
552 };
553
554
Antti Palosaari298efdd2012-09-11 22:27:11 -0300555 dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
556 "inversion=%d\n", __func__, c->frequency,
557 c->bandwidth_hz, c->inversion);
Thomas Mair82041c02012-05-18 14:47:40 -0300558
559 /* program tuner */
560 if (fe->ops.tuner_ops.set_params)
561 fe->ops.tuner_ops.set_params(fe);
562
Thomas Mair82041c02012-05-18 14:47:40 -0300563 switch (c->bandwidth_hz) {
564 case 6000000:
565 i = 0;
566 bw_mode = 48000000;
567 break;
568 case 7000000:
569 i = 1;
570 bw_mode = 56000000;
571 break;
572 case 8000000:
573 i = 2;
574 bw_mode = 64000000;
575 break;
576 default:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300577 dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300578 return -EINVAL;
579 }
580
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300581 for (j = 0; j < sizeof(bw_params[0]); j++) {
Thomas Mair82041c02012-05-18 14:47:40 -0300582 ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
583 if (ret)
584 goto err;
585 }
586
587 /* calculate and set resample ratio
588 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
589 * / ConstWithBandwidthMode)
590 */
591 num = priv->cfg.xtal * 7;
592 num *= 0x400000;
593 num = div_u64(num, bw_mode);
594 resamp_ratio = num & 0x3ffffff;
595 ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
596 if (ret)
597 goto err;
598
599 /* calculate and set cfreq off ratio
600 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
601 * / (CrystalFreqHz * 7))
602 */
603 num = bw_mode << 20;
604 num2 = priv->cfg.xtal * 7;
605 num = div_u64(num, num2);
606 num = -num;
607 cfreq_off_ratio = num & 0xfffff;
608 ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
609 if (ret)
610 goto err;
611
612
613 /* soft reset */
614 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
615 if (ret)
616 goto err;
617
618 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
619 if (ret)
620 goto err;
621
622 return ret;
623err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300624 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300625 return ret;
626}
627
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300628static int rtl2832_get_frontend(struct dvb_frontend *fe)
629{
630 struct rtl2832_priv *priv = fe->demodulator_priv;
631 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
632 int ret;
633 u8 buf[3];
634
635 if (priv->sleeping)
636 return 0;
637
638 ret = rtl2832_rd_regs(priv, 0x3c, 3, buf, 2);
639 if (ret)
640 goto err;
641
642 ret = rtl2832_rd_reg(priv, 0x51, 3, &buf[2]);
643 if (ret)
644 goto err;
645
Antti Palosaari298efdd2012-09-11 22:27:11 -0300646 dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300647
648 switch ((buf[0] >> 2) & 3) {
649 case 0:
650 c->modulation = QPSK;
651 break;
652 case 1:
653 c->modulation = QAM_16;
654 break;
655 case 2:
656 c->modulation = QAM_64;
657 break;
658 }
659
660 switch ((buf[2] >> 2) & 1) {
661 case 0:
662 c->transmission_mode = TRANSMISSION_MODE_2K;
663 break;
664 case 1:
665 c->transmission_mode = TRANSMISSION_MODE_8K;
666 }
667
668 switch ((buf[2] >> 0) & 3) {
669 case 0:
670 c->guard_interval = GUARD_INTERVAL_1_32;
671 break;
672 case 1:
673 c->guard_interval = GUARD_INTERVAL_1_16;
674 break;
675 case 2:
676 c->guard_interval = GUARD_INTERVAL_1_8;
677 break;
678 case 3:
679 c->guard_interval = GUARD_INTERVAL_1_4;
680 break;
681 }
682
683 switch ((buf[0] >> 4) & 7) {
684 case 0:
685 c->hierarchy = HIERARCHY_NONE;
686 break;
687 case 1:
688 c->hierarchy = HIERARCHY_1;
689 break;
690 case 2:
691 c->hierarchy = HIERARCHY_2;
692 break;
693 case 3:
694 c->hierarchy = HIERARCHY_4;
695 break;
696 }
697
698 switch ((buf[1] >> 3) & 7) {
699 case 0:
700 c->code_rate_HP = FEC_1_2;
701 break;
702 case 1:
703 c->code_rate_HP = FEC_2_3;
704 break;
705 case 2:
706 c->code_rate_HP = FEC_3_4;
707 break;
708 case 3:
709 c->code_rate_HP = FEC_5_6;
710 break;
711 case 4:
712 c->code_rate_HP = FEC_7_8;
713 break;
714 }
715
716 switch ((buf[1] >> 0) & 7) {
717 case 0:
718 c->code_rate_LP = FEC_1_2;
719 break;
720 case 1:
721 c->code_rate_LP = FEC_2_3;
722 break;
723 case 2:
724 c->code_rate_LP = FEC_3_4;
725 break;
726 case 3:
727 c->code_rate_LP = FEC_5_6;
728 break;
729 case 4:
730 c->code_rate_LP = FEC_7_8;
731 break;
732 }
733
734 return 0;
735err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300736 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300737 return ret;
738}
739
Thomas Mair82041c02012-05-18 14:47:40 -0300740static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
741{
742 struct rtl2832_priv *priv = fe->demodulator_priv;
743 int ret;
744 u32 tmp;
745 *status = 0;
746
Antti Palosaari298efdd2012-09-11 22:27:11 -0300747 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300748 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:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300767 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300768 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:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300813 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari73983492012-08-21 19:56:21 -0300814 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:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300831 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaaridb32d742012-08-21 19:56:22 -0300832 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
Antti Palosaari298efdd2012-09-11 22:27:11 -0300841 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300842 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
Antti Palosaari298efdd2012-09-11 22:27:11 -0300852 dev_dbg(&i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300853
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:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300878 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300879 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");