blob: b6f50c7a15e69503903acd71129a88ad1a1d383a [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
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},
Thomas Mair82041c02012-05-18 14:47:40 -0300435 };
436
Antti Palosaari298efdd2012-09-11 22:27:11 -0300437 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300438
439 en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
440
Thomas Mair82041c02012-05-18 14:47:40 -0300441 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
442 ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
443 rtl2832_initial_regs[i].value);
444 if (ret)
445 goto err;
446 }
447
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300448 /* load tuner specific settings */
Antti Palosaari298efdd2012-09-11 22:27:11 -0300449 dev_dbg(&priv->i2c->dev, "%s: load settings for tuner=%02x\n",
450 __func__, priv->cfg.tuner);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300451 switch (priv->cfg.tuner) {
452 case RTL2832_TUNER_FC0012:
453 case RTL2832_TUNER_FC0013:
454 len = ARRAY_SIZE(rtl2832_tuner_init_fc0012);
455 init = rtl2832_tuner_init_fc0012;
456 break;
Antti Palosaari5db41872012-09-11 22:27:08 -0300457 case RTL2832_TUNER_TUA9001:
458 len = ARRAY_SIZE(rtl2832_tuner_init_tua9001);
459 init = rtl2832_tuner_init_tua9001;
460 break;
Antti Palosaari7e688de2012-09-17 17:53:04 -0300461 case RTL2832_TUNER_E4000:
462 len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
463 init = rtl2832_tuner_init_e4000;
464 break;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300465 case RTL2832_TUNER_R820T:
466 len = ARRAY_SIZE(rtl2832_tuner_init_r820t);
467 init = rtl2832_tuner_init_r820t;
468 break;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300469 default:
470 ret = -EINVAL;
471 goto err;
472 }
473
474 for (i = 0; i < len; i++) {
Antti Palosaari5db41872012-09-11 22:27:08 -0300475 ret = rtl2832_wr_demod_reg(priv, init[i].reg, init[i].value);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300476 if (ret)
477 goto err;
478 }
479
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300480 /*
481 * if frequency settings
482 * Some tuners (r820t) don't initialize IF here; instead; they do it
483 * at set_params()
484 */
485 if (!fe->ops.tuner_ops.get_if_frequency) {
486 /*
487 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
488 * / CrystalFreqHz)
489 */
490 pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
491 pset_iffreq *= 0x400000;
492 pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
493 pset_iffreq = pset_iffreq & 0x3fffff;
494 ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
495 if (ret)
496 goto err;
Thomas Mair82041c02012-05-18 14:47:40 -0300497
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300498 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
499 if (ret)
500 goto err;
501 }
502
503 /*
504 * r820t NIM code does a software reset here at the demod -
505 * may not be needed, as there's already a software reset at set_params()
506 */
507#if 1
508 /* soft reset */
509 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
510 if (ret)
511 goto err;
512
513 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
514 if (ret)
515 goto err;
516#endif
Thomas Mair82041c02012-05-18 14:47:40 -0300517
518 priv->sleeping = false;
519
520 return ret;
521
522err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300523 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300524 return ret;
525}
526
527static int rtl2832_sleep(struct dvb_frontend *fe)
528{
529 struct rtl2832_priv *priv = fe->demodulator_priv;
530
Antti Palosaari298efdd2012-09-11 22:27:11 -0300531 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300532 priv->sleeping = true;
533 return 0;
534}
535
Mauro Carvalho Chehabb0944ea2012-10-27 11:24:37 -0300536static int rtl2832_get_tune_settings(struct dvb_frontend *fe,
Thomas Mair82041c02012-05-18 14:47:40 -0300537 struct dvb_frontend_tune_settings *s)
538{
Antti Palosaari298efdd2012-09-11 22:27:11 -0300539 struct rtl2832_priv *priv = fe->demodulator_priv;
540
541 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300542 s->min_delay_ms = 1000;
543 s->step_size = fe->ops.info.frequency_stepsize * 2;
544 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
545 return 0;
546}
547
548static int rtl2832_set_frontend(struct dvb_frontend *fe)
549{
550 struct rtl2832_priv *priv = fe->demodulator_priv;
551 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
552 int ret, i, j;
553 u64 bw_mode, num, num2;
554 u32 resamp_ratio, cfreq_off_ratio;
Thomas Mair82041c02012-05-18 14:47:40 -0300555 static u8 bw_params[3][32] = {
556 /* 6 MHz bandwidth */
557 {
558 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
559 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
560 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
561 0x19, 0xe0,
562 },
563
564 /* 7 MHz bandwidth */
565 {
566 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
567 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
568 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
569 0x19, 0x10,
570 },
571
572 /* 8 MHz bandwidth */
573 {
574 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
575 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
576 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
577 0x19, 0xe0,
578 },
579 };
580
581
Antti Palosaari298efdd2012-09-11 22:27:11 -0300582 dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
583 "inversion=%d\n", __func__, c->frequency,
584 c->bandwidth_hz, c->inversion);
Thomas Mair82041c02012-05-18 14:47:40 -0300585
586 /* program tuner */
587 if (fe->ops.tuner_ops.set_params)
588 fe->ops.tuner_ops.set_params(fe);
589
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300590 /* If the frontend has get_if_frequency(), use it */
591 if (fe->ops.tuner_ops.get_if_frequency) {
592 u32 if_freq;
593 u64 pset_iffreq;
594
595 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
596 if (ret)
597 goto err;
598
599 pset_iffreq = if_freq % priv->cfg.xtal;
600 pset_iffreq *= 0x400000;
601 pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
602 pset_iffreq = pset_iffreq & 0x3fffff;
603
604 ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
605 if (ret)
606 goto err;
607 }
608
Thomas Mair82041c02012-05-18 14:47:40 -0300609 switch (c->bandwidth_hz) {
610 case 6000000:
611 i = 0;
612 bw_mode = 48000000;
613 break;
614 case 7000000:
615 i = 1;
616 bw_mode = 56000000;
617 break;
618 case 8000000:
619 i = 2;
620 bw_mode = 64000000;
621 break;
622 default:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300623 dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300624 return -EINVAL;
625 }
626
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300627 for (j = 0; j < sizeof(bw_params[0]); j++) {
Thomas Mair82041c02012-05-18 14:47:40 -0300628 ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
629 if (ret)
630 goto err;
631 }
632
633 /* calculate and set resample ratio
634 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
635 * / ConstWithBandwidthMode)
636 */
637 num = priv->cfg.xtal * 7;
638 num *= 0x400000;
639 num = div_u64(num, bw_mode);
640 resamp_ratio = num & 0x3ffffff;
641 ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
642 if (ret)
643 goto err;
644
645 /* calculate and set cfreq off ratio
646 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
647 * / (CrystalFreqHz * 7))
648 */
649 num = bw_mode << 20;
650 num2 = priv->cfg.xtal * 7;
651 num = div_u64(num, num2);
652 num = -num;
653 cfreq_off_ratio = num & 0xfffff;
654 ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
655 if (ret)
656 goto err;
657
658
659 /* soft reset */
660 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
661 if (ret)
662 goto err;
663
664 ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
665 if (ret)
666 goto err;
667
668 return ret;
669err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300670 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300671 return ret;
672}
673
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300674static int rtl2832_get_frontend(struct dvb_frontend *fe)
675{
676 struct rtl2832_priv *priv = fe->demodulator_priv;
677 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
678 int ret;
679 u8 buf[3];
680
681 if (priv->sleeping)
682 return 0;
683
684 ret = rtl2832_rd_regs(priv, 0x3c, 3, buf, 2);
685 if (ret)
686 goto err;
687
688 ret = rtl2832_rd_reg(priv, 0x51, 3, &buf[2]);
689 if (ret)
690 goto err;
691
Antti Palosaari298efdd2012-09-11 22:27:11 -0300692 dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300693
694 switch ((buf[0] >> 2) & 3) {
695 case 0:
696 c->modulation = QPSK;
697 break;
698 case 1:
699 c->modulation = QAM_16;
700 break;
701 case 2:
702 c->modulation = QAM_64;
703 break;
704 }
705
706 switch ((buf[2] >> 2) & 1) {
707 case 0:
708 c->transmission_mode = TRANSMISSION_MODE_2K;
709 break;
710 case 1:
711 c->transmission_mode = TRANSMISSION_MODE_8K;
712 }
713
714 switch ((buf[2] >> 0) & 3) {
715 case 0:
716 c->guard_interval = GUARD_INTERVAL_1_32;
717 break;
718 case 1:
719 c->guard_interval = GUARD_INTERVAL_1_16;
720 break;
721 case 2:
722 c->guard_interval = GUARD_INTERVAL_1_8;
723 break;
724 case 3:
725 c->guard_interval = GUARD_INTERVAL_1_4;
726 break;
727 }
728
729 switch ((buf[0] >> 4) & 7) {
730 case 0:
731 c->hierarchy = HIERARCHY_NONE;
732 break;
733 case 1:
734 c->hierarchy = HIERARCHY_1;
735 break;
736 case 2:
737 c->hierarchy = HIERARCHY_2;
738 break;
739 case 3:
740 c->hierarchy = HIERARCHY_4;
741 break;
742 }
743
744 switch ((buf[1] >> 3) & 7) {
745 case 0:
746 c->code_rate_HP = FEC_1_2;
747 break;
748 case 1:
749 c->code_rate_HP = FEC_2_3;
750 break;
751 case 2:
752 c->code_rate_HP = FEC_3_4;
753 break;
754 case 3:
755 c->code_rate_HP = FEC_5_6;
756 break;
757 case 4:
758 c->code_rate_HP = FEC_7_8;
759 break;
760 }
761
762 switch ((buf[1] >> 0) & 7) {
763 case 0:
764 c->code_rate_LP = FEC_1_2;
765 break;
766 case 1:
767 c->code_rate_LP = FEC_2_3;
768 break;
769 case 2:
770 c->code_rate_LP = FEC_3_4;
771 break;
772 case 3:
773 c->code_rate_LP = FEC_5_6;
774 break;
775 case 4:
776 c->code_rate_LP = FEC_7_8;
777 break;
778 }
779
780 return 0;
781err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300782 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300783 return ret;
784}
785
Thomas Mair82041c02012-05-18 14:47:40 -0300786static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
787{
788 struct rtl2832_priv *priv = fe->demodulator_priv;
789 int ret;
790 u32 tmp;
791 *status = 0;
792
Antti Palosaari298efdd2012-09-11 22:27:11 -0300793 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300794 if (priv->sleeping)
795 return 0;
796
797 ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
798 if (ret)
799 goto err;
800
801 if (tmp == 11) {
802 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
803 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
804 }
805 /* TODO find out if this is also true for rtl2832? */
806 /*else if (tmp == 10) {
807 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
808 FE_HAS_VITERBI;
809 }*/
810
811 return ret;
812err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300813 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300814 return ret;
815}
816
Antti Palosaari73983492012-08-21 19:56:21 -0300817static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
818{
819 struct rtl2832_priv *priv = fe->demodulator_priv;
820 int ret, hierarchy, constellation;
821 u8 buf[2], tmp;
822 u16 tmp16;
823#define CONSTELLATION_NUM 3
824#define HIERARCHY_NUM 4
825 static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
826 { 85387325, 85387325, 85387325, 85387325 },
827 { 86676178, 86676178, 87167949, 87795660 },
828 { 87659938, 87659938, 87885178, 88241743 },
829 };
830
831 /* reports SNR in resolution of 0.1 dB */
832
833 ret = rtl2832_rd_reg(priv, 0x3c, 3, &tmp);
834 if (ret)
835 goto err;
836
837 constellation = (tmp >> 2) & 0x03; /* [3:2] */
838 if (constellation > CONSTELLATION_NUM - 1)
839 goto err;
840
841 hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
842 if (hierarchy > HIERARCHY_NUM - 1)
843 goto err;
844
845 ret = rtl2832_rd_regs(priv, 0x0c, 4, buf, 2);
846 if (ret)
847 goto err;
848
849 tmp16 = buf[0] << 8 | buf[1];
850
851 if (tmp16)
852 *snr = (snr_constant[constellation][hierarchy] -
853 intlog10(tmp16)) / ((1 << 24) / 100);
854 else
855 *snr = 0;
856
857 return 0;
858err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300859 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaari73983492012-08-21 19:56:21 -0300860 return ret;
861}
862
Antti Palosaaridb32d742012-08-21 19:56:22 -0300863static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
864{
865 struct rtl2832_priv *priv = fe->demodulator_priv;
866 int ret;
867 u8 buf[2];
868
869 ret = rtl2832_rd_regs(priv, 0x4e, 3, buf, 2);
870 if (ret)
871 goto err;
872
873 *ber = buf[0] << 8 | buf[1];
874
875 return 0;
876err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300877 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
Antti Palosaaridb32d742012-08-21 19:56:22 -0300878 return ret;
879}
880
Thomas Mair82041c02012-05-18 14:47:40 -0300881static struct dvb_frontend_ops rtl2832_ops;
882
883static void rtl2832_release(struct dvb_frontend *fe)
884{
885 struct rtl2832_priv *priv = fe->demodulator_priv;
886
Antti Palosaari298efdd2012-09-11 22:27:11 -0300887 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300888 kfree(priv);
889}
890
891struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
892 struct i2c_adapter *i2c)
893{
894 struct rtl2832_priv *priv = NULL;
895 int ret = 0;
896 u8 tmp;
897
Antti Palosaari298efdd2012-09-11 22:27:11 -0300898 dev_dbg(&i2c->dev, "%s:\n", __func__);
Thomas Mair82041c02012-05-18 14:47:40 -0300899
900 /* allocate memory for the internal state */
901 priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
902 if (priv == NULL)
903 goto err;
904
905 /* setup the priv */
906 priv->i2c = i2c;
907 priv->tuner = cfg->tuner;
908 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
909
910 /* check if the demod is there */
911 ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
912 if (ret)
913 goto err;
914
915 /* create dvb_frontend */
916 memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
917 priv->fe.demodulator_priv = priv;
918
919 /* TODO implement sleep mode */
920 priv->sleeping = true;
921
922 return &priv->fe;
923err:
Antti Palosaari298efdd2012-09-11 22:27:11 -0300924 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300925 kfree(priv);
926 return NULL;
927}
928EXPORT_SYMBOL(rtl2832_attach);
929
930static struct dvb_frontend_ops rtl2832_ops = {
931 .delsys = { SYS_DVBT },
932 .info = {
933 .name = "Realtek RTL2832 (DVB-T)",
934 .frequency_min = 174000000,
935 .frequency_max = 862000000,
936 .frequency_stepsize = 166667,
937 .caps = FE_CAN_FEC_1_2 |
938 FE_CAN_FEC_2_3 |
939 FE_CAN_FEC_3_4 |
940 FE_CAN_FEC_5_6 |
941 FE_CAN_FEC_7_8 |
942 FE_CAN_FEC_AUTO |
943 FE_CAN_QPSK |
944 FE_CAN_QAM_16 |
945 FE_CAN_QAM_64 |
946 FE_CAN_QAM_AUTO |
947 FE_CAN_TRANSMISSION_MODE_AUTO |
948 FE_CAN_GUARD_INTERVAL_AUTO |
949 FE_CAN_HIERARCHY_AUTO |
950 FE_CAN_RECOVER |
951 FE_CAN_MUTE_TS
952 },
953
954 .release = rtl2832_release,
955
956 .init = rtl2832_init,
957 .sleep = rtl2832_sleep,
958
959 .get_tune_settings = rtl2832_get_tune_settings,
960
961 .set_frontend = rtl2832_set_frontend,
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300962 .get_frontend = rtl2832_get_frontend,
Thomas Mair82041c02012-05-18 14:47:40 -0300963
964 .read_status = rtl2832_read_status,
Antti Palosaari73983492012-08-21 19:56:21 -0300965 .read_snr = rtl2832_read_snr,
Antti Palosaaridb32d742012-08-21 19:56:22 -0300966 .read_ber = rtl2832_read_ber,
Antti Palosaari73983492012-08-21 19:56:21 -0300967
Thomas Mair82041c02012-05-18 14:47:40 -0300968 .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
969};
970
971MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
972MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
973MODULE_LICENSE("GPL");
974MODULE_VERSION("0.5");