]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/media/dvb/frontends/rtl2832.c
d0cbe27f979e74ac2e8133b422806a78ab47a01a
[karo-tx-linux.git] / drivers / media / dvb / frontends / rtl2832.c
1 /*
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"
22
23
24 int rtl2832_debug;
25 module_param_named(debug, rtl2832_debug, int, 0644);
26 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
27
28
29 static const int reg_mask[32] = {
30         0x00000001,
31         0x00000003,
32         0x00000007,
33         0x0000000f,
34         0x0000001f,
35         0x0000003f,
36         0x0000007f,
37         0x000000ff,
38         0x000001ff,
39         0x000003ff,
40         0x000007ff,
41         0x00000fff,
42         0x00001fff,
43         0x00003fff,
44         0x00007fff,
45         0x0000ffff,
46         0x0001ffff,
47         0x0003ffff,
48         0x0007ffff,
49         0x000fffff,
50         0x001fffff,
51         0x003fffff,
52         0x007fffff,
53         0x00ffffff,
54         0x01ffffff,
55         0x03ffffff,
56         0x07ffffff,
57         0x0fffffff,
58         0x1fffffff,
59         0x3fffffff,
60         0x7fffffff,
61         0xffffffff
62 };
63
64 static const struct rtl2832_reg_entry registers[] = {
65         [DVBT_SOFT_RST]         = {0x1, 0x1,   2, 2},
66         [DVBT_IIC_REPEAT]       = {0x1, 0x1,   3, 3},
67         [DVBT_TR_WAIT_MIN_8K]   = {0x1, 0x88, 11, 2},
68         [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
69         [DVBT_EN_BK_TRK]        = {0x1, 0xa6,  7, 7},
70         [DVBT_AD_EN_REG]        = {0x0, 0x8,   7, 7},
71         [DVBT_AD_EN_REG1]       = {0x0, 0x8,   6, 6},
72         [DVBT_EN_BBIN]          = {0x1, 0xb1,  0, 0},
73         [DVBT_MGD_THD0]         = {0x1, 0x95,  7, 0},
74         [DVBT_MGD_THD1]         = {0x1, 0x96,  7, 0},
75         [DVBT_MGD_THD2]         = {0x1, 0x97,  7, 0},
76         [DVBT_MGD_THD3]         = {0x1, 0x98,  7, 0},
77         [DVBT_MGD_THD4]         = {0x1, 0x99,  7, 0},
78         [DVBT_MGD_THD5]         = {0x1, 0x9a,  7, 0},
79         [DVBT_MGD_THD6]         = {0x1, 0x9b,  7, 0},
80         [DVBT_MGD_THD7]         = {0x1, 0x9c,  7, 0},
81         [DVBT_EN_CACQ_NOTCH]    = {0x1, 0x61,  4, 4},
82         [DVBT_AD_AV_REF]        = {0x0, 0x9,   6, 0},
83         [DVBT_REG_PI]           = {0x0, 0xa,   2, 0},
84         [DVBT_PIP_ON]           = {0x0, 0x21,  3, 3},
85         [DVBT_SCALE1_B92]       = {0x2, 0x92,  7, 0},
86         [DVBT_SCALE1_B93]       = {0x2, 0x93,  7, 0},
87         [DVBT_SCALE1_BA7]       = {0x2, 0xa7,  7, 0},
88         [DVBT_SCALE1_BA9]       = {0x2, 0xa9,  7, 0},
89         [DVBT_SCALE1_BAA]       = {0x2, 0xaa,  7, 0},
90         [DVBT_SCALE1_BAB]       = {0x2, 0xab,  7, 0},
91         [DVBT_SCALE1_BAC]       = {0x2, 0xac,  7, 0},
92         [DVBT_SCALE1_BB0]       = {0x2, 0xb0,  7, 0},
93         [DVBT_SCALE1_BB1]       = {0x2, 0xb1,  7, 0},
94         [DVBT_KB_P1]            = {0x1, 0x64,  3, 1},
95         [DVBT_KB_P2]            = {0x1, 0x64,  6, 4},
96         [DVBT_KB_P3]            = {0x1, 0x65,  2, 0},
97         [DVBT_OPT_ADC_IQ]       = {0x0, 0x6,   5, 4},
98         [DVBT_AD_AVI]           = {0x0, 0x9,   1, 0},
99         [DVBT_AD_AVQ]           = {0x0, 0x9,   3, 2},
100         [DVBT_K1_CR_STEP12]     = {0x2, 0xad,  9, 4},
101         [DVBT_TRK_KS_P2]        = {0x1, 0x6f,  2, 0},
102         [DVBT_TRK_KS_I2]        = {0x1, 0x70,  5, 3},
103         [DVBT_TR_THD_SET2]      = {0x1, 0x72,  3, 0},
104         [DVBT_TRK_KC_P2]        = {0x1, 0x73,  5, 3},
105         [DVBT_TRK_KC_I2]        = {0x1, 0x75,  2, 0},
106         [DVBT_CR_THD_SET2]      = {0x1, 0x76,  7, 6},
107         [DVBT_PSET_IFFREQ]      = {0x1, 0x19, 21, 0},
108         [DVBT_SPEC_INV]         = {0x1, 0x15,  0, 0},
109         [DVBT_RSAMP_RATIO]      = {0x1, 0x9f, 27, 2},
110         [DVBT_CFREQ_OFF_RATIO]  = {0x1, 0x9d, 23, 4},
111         [DVBT_FSM_STAGE]        = {0x3, 0x51,  6, 3},
112         [DVBT_RX_CONSTEL]       = {0x3, 0x3c,  3, 2},
113         [DVBT_RX_HIER]          = {0x3, 0x3c,  6, 4},
114         [DVBT_RX_C_RATE_LP]     = {0x3, 0x3d,  2, 0},
115         [DVBT_RX_C_RATE_HP]     = {0x3, 0x3d,  5, 3},
116         [DVBT_GI_IDX]           = {0x3, 0x51,  1, 0},
117         [DVBT_FFT_MODE_IDX]     = {0x3, 0x51,  2, 2},
118         [DVBT_RSD_BER_EST]      = {0x3, 0x4e, 15, 0},
119         [DVBT_CE_EST_EVM]       = {0x4, 0xc,  15, 0},
120         [DVBT_RF_AGC_VAL]       = {0x3, 0x5b, 13, 0},
121         [DVBT_IF_AGC_VAL]       = {0x3, 0x59, 13, 0},
122         [DVBT_DAGC_VAL]         = {0x3, 0x5,   7, 0},
123         [DVBT_SFREQ_OFF]        = {0x3, 0x18, 13, 0},
124         [DVBT_CFREQ_OFF]        = {0x3, 0x5f, 17, 0},
125         [DVBT_POLAR_RF_AGC]     = {0x0, 0xe,   1, 1},
126         [DVBT_POLAR_IF_AGC]     = {0x0, 0xe,   0, 0},
127         [DVBT_AAGC_HOLD]        = {0x1, 0x4,   5, 5},
128         [DVBT_EN_RF_AGC]        = {0x1, 0x4,   6, 6},
129         [DVBT_EN_IF_AGC]        = {0x1, 0x4,   7, 7},
130         [DVBT_IF_AGC_MIN]       = {0x1, 0x8,   7, 0},
131         [DVBT_IF_AGC_MAX]       = {0x1, 0x9,   7, 0},
132         [DVBT_RF_AGC_MIN]       = {0x1, 0xa,   7, 0},
133         [DVBT_RF_AGC_MAX]       = {0x1, 0xb,   7, 0},
134         [DVBT_IF_AGC_MAN]       = {0x1, 0xc,   6, 6},
135         [DVBT_IF_AGC_MAN_VAL]   = {0x1, 0xc,  13, 0},
136         [DVBT_RF_AGC_MAN]       = {0x1, 0xe,   6, 6},
137         [DVBT_RF_AGC_MAN_VAL]   = {0x1, 0xe,  13, 0},
138         [DVBT_DAGC_TRG_VAL]     = {0x1, 0x12,  7, 0},
139         [DVBT_AGC_TARG_VAL_0]   = {0x1, 0x2,   0, 0},
140         [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3,   7, 0},
141         [DVBT_AAGC_LOOP_GAIN]   = {0x1, 0xc7,  5, 1},
142         [DVBT_LOOP_GAIN2_3_0]   = {0x1, 0x4,   4, 1},
143         [DVBT_LOOP_GAIN2_4]     = {0x1, 0x5,   7, 7},
144         [DVBT_LOOP_GAIN3]       = {0x1, 0xc8,  4, 0},
145         [DVBT_VTOP1]            = {0x1, 0x6,   5, 0},
146         [DVBT_VTOP2]            = {0x1, 0xc9,  5, 0},
147         [DVBT_VTOP3]            = {0x1, 0xca,  5, 0},
148         [DVBT_KRF1]             = {0x1, 0xcb,  7, 0},
149         [DVBT_KRF2]             = {0x1, 0x7,   7, 0},
150         [DVBT_KRF3]             = {0x1, 0xcd,  7, 0},
151         [DVBT_KRF4]             = {0x1, 0xce,  7, 0},
152         [DVBT_EN_GI_PGA]        = {0x1, 0xe5,  0, 0},
153         [DVBT_THD_LOCK_UP]      = {0x1, 0xd9,  8, 0},
154         [DVBT_THD_LOCK_DW]      = {0x1, 0xdb,  8, 0},
155         [DVBT_THD_UP1]          = {0x1, 0xdd,  7, 0},
156         [DVBT_THD_DW1]          = {0x1, 0xde,  7, 0},
157         [DVBT_INTER_CNT_LEN]    = {0x1, 0xd8,  3, 0},
158         [DVBT_GI_PGA_STATE]     = {0x1, 0xe6,  3, 3},
159         [DVBT_EN_AGC_PGA]       = {0x1, 0xd7,  0, 0},
160         [DVBT_CKOUTPAR]         = {0x1, 0x7b,  5, 5},
161         [DVBT_CKOUT_PWR]        = {0x1, 0x7b,  6, 6},
162         [DVBT_SYNC_DUR]         = {0x1, 0x7b,  7, 7},
163         [DVBT_ERR_DUR]          = {0x1, 0x7c,  0, 0},
164         [DVBT_SYNC_LVL]         = {0x1, 0x7c,  1, 1},
165         [DVBT_ERR_LVL]          = {0x1, 0x7c,  2, 2},
166         [DVBT_VAL_LVL]          = {0x1, 0x7c,  3, 3},
167         [DVBT_SERIAL]           = {0x1, 0x7c,  4, 4},
168         [DVBT_SER_LSB]          = {0x1, 0x7c,  5, 5},
169         [DVBT_CDIV_PH0]         = {0x1, 0x7d,  3, 0},
170         [DVBT_CDIV_PH1]         = {0x1, 0x7d,  7, 4},
171         [DVBT_MPEG_IO_OPT_2_2]  = {0x0, 0x6,   7, 7},
172         [DVBT_MPEG_IO_OPT_1_0]  = {0x0, 0x7,   7, 6},
173         [DVBT_CKOUTPAR_PIP]     = {0x0, 0xb7,  4, 4},
174         [DVBT_CKOUT_PWR_PIP]    = {0x0, 0xb7,  3, 3},
175         [DVBT_SYNC_LVL_PIP]     = {0x0, 0xb7,  2, 2},
176         [DVBT_ERR_LVL_PIP]      = {0x0, 0xb7,  1, 1},
177         [DVBT_VAL_LVL_PIP]      = {0x0, 0xb7,  0, 0},
178         [DVBT_CKOUTPAR_PID]     = {0x0, 0xb9,  4, 4},
179         [DVBT_CKOUT_PWR_PID]    = {0x0, 0xb9,  3, 3},
180         [DVBT_SYNC_LVL_PID]     = {0x0, 0xb9,  2, 2},
181         [DVBT_ERR_LVL_PID]      = {0x0, 0xb9,  1, 1},
182         [DVBT_VAL_LVL_PID]      = {0x0, 0xb9,  0, 0},
183         [DVBT_SM_PASS]          = {0x1, 0x93, 11, 0},
184         [DVBT_AD7_SETTING]      = {0x0, 0x11, 15, 0},
185         [DVBT_RSSI_R]           = {0x3, 0x1,   6, 0},
186         [DVBT_ACI_DET_IND]      = {0x3, 0x12,  0, 0},
187         [DVBT_REG_MON]          = {0x0, 0xd,   1, 0},
188         [DVBT_REG_MONSEL]       = {0x0, 0xd,   2, 2},
189         [DVBT_REG_GPE]          = {0x0, 0xd,   7, 7},
190         [DVBT_REG_GPO]          = {0x0, 0x10,  0, 0},
191         [DVBT_REG_4MSEL]        = {0x0, 0x13,  0, 0},
192 };
193
194 /* write multiple hardware registers */
195 static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
196 {
197         int ret;
198         u8 buf[1+len];
199         struct i2c_msg msg[1] = {
200                 {
201                         .addr = priv->cfg.i2c_addr,
202                         .flags = 0,
203                         .len = 1+len,
204                         .buf = buf,
205                 }
206         };
207
208         buf[0] = reg;
209         memcpy(&buf[1], val, len);
210
211         ret = i2c_transfer(priv->i2c, msg, 1);
212         if (ret == 1) {
213                 ret = 0;
214         } else {
215                 warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
216                 ret = -EREMOTEIO;
217         }
218         return ret;
219 }
220
221 /* read multiple hardware registers */
222 static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
223 {
224         int ret;
225         struct i2c_msg msg[2] = {
226                 {
227                         .addr = priv->cfg.i2c_addr,
228                         .flags = 0,
229                         .len = 1,
230                         .buf = &reg,
231                 }, {
232                         .addr = priv->cfg.i2c_addr,
233                         .flags = I2C_M_RD,
234                         .len = len,
235                         .buf = val,
236                 }
237         };
238
239         ret = i2c_transfer(priv->i2c, msg, 2);
240         if (ret == 2) {
241                 ret = 0;
242         } else {
243                 warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
244                 ret = -EREMOTEIO;
245 }
246 return ret;
247 }
248
249 /* write multiple registers */
250 static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
251         int len)
252 {
253         int ret;
254
255
256         /* switch bank if needed */
257         if (page != priv->page) {
258                 ret = rtl2832_wr(priv, 0x00, &page, 1);
259                 if (ret)
260                         return ret;
261
262                 priv->page = page;
263 }
264
265 return rtl2832_wr(priv, reg, val, len);
266 }
267
268 /* read multiple registers */
269 static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
270         int len)
271 {
272         int ret;
273
274         /* switch bank if needed */
275         if (page != priv->page) {
276                 ret = rtl2832_wr(priv, 0x00, &page, 1);
277                 if (ret)
278                         return ret;
279
280                 priv->page = page;
281         }
282
283         return rtl2832_rd(priv, reg, val, len);
284 }
285
286 #if 0 /* currently not used */
287 /* write single register */
288 static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
289 {
290         return rtl2832_wr_regs(priv, reg, page, &val, 1);
291 }
292 #endif
293
294 /* read single register */
295 static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
296 {
297         return rtl2832_rd_regs(priv, reg, page, val, 1);
298 }
299
300 int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
301 {
302         int ret;
303
304         u8 reg_start_addr;
305         u8 msb, lsb;
306         u8 page;
307         u8 reading[4];
308         u32 reading_tmp;
309         int i;
310
311         u8 len;
312         u32 mask;
313
314         reg_start_addr = registers[reg].start_address;
315         msb = registers[reg].msb;
316         lsb = registers[reg].lsb;
317         page = registers[reg].page;
318
319         len = (msb >> 3) + 1;
320         mask = reg_mask[msb - lsb];
321
322         ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
323         if (ret)
324                 goto err;
325
326         reading_tmp = 0;
327         for (i = 0; i < len; i++)
328                 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
329
330         *val = (reading_tmp >> lsb) & mask;
331
332         return ret;
333
334 err:
335         dbg("%s: failed=%d", __func__, ret);
336         return ret;
337
338 }
339
340 int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
341 {
342         int ret, i;
343         u8 len;
344         u8 reg_start_addr;
345         u8 msb, lsb;
346         u8 page;
347         u32 mask;
348
349
350         u8 reading[4];
351         u8 writing[4];
352         u32 reading_tmp;
353         u32 writing_tmp;
354
355
356         reg_start_addr = registers[reg].start_address;
357         msb = registers[reg].msb;
358         lsb = registers[reg].lsb;
359         page = registers[reg].page;
360
361         len = (msb >> 3) + 1;
362         mask = reg_mask[msb - lsb];
363
364
365         ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
366         if (ret)
367                 goto err;
368
369         reading_tmp = 0;
370         for (i = 0; i < len; i++)
371                 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
372
373         writing_tmp = reading_tmp & ~(mask << lsb);
374         writing_tmp |= ((val & mask) << lsb);
375
376
377         for (i = 0; i < len; i++)
378                 writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
379
380         ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len);
381         if (ret)
382                 goto err;
383
384         return ret;
385
386 err:
387         dbg("%s: failed=%d", __func__, ret);
388         return ret;
389
390 }
391
392
393 static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
394 {
395         int ret;
396         struct rtl2832_priv *priv = fe->demodulator_priv;
397
398         dbg("%s: enable=%d", __func__, enable);
399
400         /* gate already open or close */
401         if (priv->i2c_gate_state == enable)
402                 return 0;
403
404         ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0));
405         if (ret)
406                 goto err;
407
408         priv->i2c_gate_state = enable;
409
410         return ret;
411 err:
412         dbg("%s: failed=%d", __func__, ret);
413         return ret;
414 }
415
416
417
418 static int rtl2832_init(struct dvb_frontend *fe)
419 {
420         struct rtl2832_priv *priv = fe->demodulator_priv;
421         int i, ret;
422
423         u8 en_bbin;
424         u64 pset_iffreq;
425
426         /* initialization values for the demodulator registers */
427         struct rtl2832_reg_value rtl2832_initial_regs[] = {
428                 {DVBT_AD_EN_REG,                0x1},
429                 {DVBT_AD_EN_REG1,               0x1},
430                 {DVBT_RSD_BER_FAIL_VAL,         0x2800},
431                 {DVBT_MGD_THD0,                 0x10},
432                 {DVBT_MGD_THD1,                 0x20},
433                 {DVBT_MGD_THD2,                 0x20},
434                 {DVBT_MGD_THD3,                 0x40},
435                 {DVBT_MGD_THD4,                 0x22},
436                 {DVBT_MGD_THD5,                 0x32},
437                 {DVBT_MGD_THD6,                 0x37},
438                 {DVBT_MGD_THD7,                 0x39},
439                 {DVBT_EN_BK_TRK,                0x0},
440                 {DVBT_EN_CACQ_NOTCH,            0x0},
441                 {DVBT_AD_AV_REF,                0x2a},
442                 {DVBT_REG_PI,                   0x6},
443                 {DVBT_PIP_ON,                   0x0},
444                 {DVBT_CDIV_PH0,                 0x8},
445                 {DVBT_CDIV_PH1,                 0x8},
446                 {DVBT_SCALE1_B92,               0x4},
447                 {DVBT_SCALE1_B93,               0xb0},
448                 {DVBT_SCALE1_BA7,               0x78},
449                 {DVBT_SCALE1_BA9,               0x28},
450                 {DVBT_SCALE1_BAA,               0x59},
451                 {DVBT_SCALE1_BAB,               0x83},
452                 {DVBT_SCALE1_BAC,               0xd4},
453                 {DVBT_SCALE1_BB0,               0x65},
454                 {DVBT_SCALE1_BB1,               0x43},
455                 {DVBT_KB_P1,                    0x1},
456                 {DVBT_KB_P2,                    0x4},
457                 {DVBT_KB_P3,                    0x7},
458                 {DVBT_K1_CR_STEP12,             0xa},
459                 {DVBT_REG_GPE,                  0x1},
460                 {DVBT_SERIAL,                   0x0},
461                 {DVBT_CDIV_PH0,                 0x9},
462                 {DVBT_CDIV_PH1,                 0x9},
463                 {DVBT_MPEG_IO_OPT_2_2,          0x0},
464                 {DVBT_MPEG_IO_OPT_1_0,          0x0},
465                 {DVBT_TRK_KS_P2,                0x4},
466                 {DVBT_TRK_KS_I2,                0x7},
467                 {DVBT_TR_THD_SET2,              0x6},
468                 {DVBT_TRK_KC_I2,                0x5},
469                 {DVBT_CR_THD_SET2,              0x1},
470                 {DVBT_SPEC_INV,                 0x0},
471                 {DVBT_DAGC_TRG_VAL,             0x5a},
472                 {DVBT_AGC_TARG_VAL_0,           0x0},
473                 {DVBT_AGC_TARG_VAL_8_1,         0x5a},
474                 {DVBT_AAGC_LOOP_GAIN,           0x16},
475                 {DVBT_LOOP_GAIN2_3_0,           0x6},
476                 {DVBT_LOOP_GAIN2_4,             0x1},
477                 {DVBT_LOOP_GAIN3,               0x16},
478                 {DVBT_VTOP1,                    0x35},
479                 {DVBT_VTOP2,                    0x21},
480                 {DVBT_VTOP3,                    0x21},
481                 {DVBT_KRF1,                     0x0},
482                 {DVBT_KRF2,                     0x40},
483                 {DVBT_KRF3,                     0x10},
484                 {DVBT_KRF4,                     0x10},
485                 {DVBT_IF_AGC_MIN,               0x80},
486                 {DVBT_IF_AGC_MAX,               0x7f},
487                 {DVBT_RF_AGC_MIN,               0x80},
488                 {DVBT_RF_AGC_MAX,               0x7f},
489                 {DVBT_POLAR_RF_AGC,             0x0},
490                 {DVBT_POLAR_IF_AGC,             0x0},
491                 {DVBT_AD7_SETTING,              0xe9bf},
492                 {DVBT_EN_GI_PGA,                0x0},
493                 {DVBT_THD_LOCK_UP,              0x0},
494                 {DVBT_THD_LOCK_DW,              0x0},
495                 {DVBT_THD_UP1,                  0x11},
496                 {DVBT_THD_DW1,                  0xef},
497                 {DVBT_INTER_CNT_LEN,            0xc},
498                 {DVBT_GI_PGA_STATE,             0x0},
499                 {DVBT_EN_AGC_PGA,               0x1},
500                 {DVBT_IF_AGC_MAN,               0x0},
501         };
502
503
504         dbg("%s", __func__);
505
506         en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
507
508         /*
509         * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
510         *               / CrystalFreqHz)
511         */
512         pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
513         pset_iffreq *= 0x400000;
514         pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
515         pset_iffreq = pset_iffreq & 0x3fffff;
516
517
518
519         for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
520                 ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
521                         rtl2832_initial_regs[i].value);
522                 if (ret)
523                         goto err;
524         }
525
526         /* if frequency settings */
527         ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
528                 if (ret)
529                         goto err;
530
531         ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
532                 if (ret)
533                         goto err;
534
535         priv->sleeping = false;
536
537         return ret;
538
539 err:
540         dbg("%s: failed=%d", __func__, ret);
541         return ret;
542 }
543
544 static int rtl2832_sleep(struct dvb_frontend *fe)
545 {
546         struct rtl2832_priv *priv = fe->demodulator_priv;
547
548         dbg("%s", __func__);
549         priv->sleeping = true;
550         return 0;
551 }
552
553 int rtl2832_get_tune_settings(struct dvb_frontend *fe,
554         struct dvb_frontend_tune_settings *s)
555 {
556         dbg("%s", __func__);
557         s->min_delay_ms = 1000;
558         s->step_size = fe->ops.info.frequency_stepsize * 2;
559         s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
560         return 0;
561 }
562
563 static int rtl2832_set_frontend(struct dvb_frontend *fe)
564 {
565         struct rtl2832_priv *priv = fe->demodulator_priv;
566         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
567         int ret, i, j;
568         u64 bw_mode, num, num2;
569         u32 resamp_ratio, cfreq_off_ratio;
570
571
572         static u8 bw_params[3][32] = {
573         /* 6 MHz bandwidth */
574                 {
575                 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
576                 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
577                 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
578                 0x19, 0xe0,
579                 },
580
581         /*  7 MHz bandwidth */
582                 {
583                 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
584                 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
585                 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
586                 0x19, 0x10,
587                 },
588
589         /*  8 MHz bandwidth */
590                 {
591                 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
592                 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
593                 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
594                 0x19, 0xe0,
595                 },
596         };
597
598
599         dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
600                 c->frequency, c->bandwidth_hz, c->inversion);
601
602
603         /* program tuner */
604         if (fe->ops.tuner_ops.set_params)
605                 fe->ops.tuner_ops.set_params(fe);
606
607
608         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:
622                 dbg("invalid bandwidth");
623                 return -EINVAL;
624         }
625
626         for (j = 0; j < sizeof(bw_params[j]); j++) {
627                 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;
668 err:
669         info("%s: failed=%d", __func__, ret);
670         return ret;
671 }
672
673 static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
674 {
675         struct rtl2832_priv *priv = fe->demodulator_priv;
676         int ret;
677         u32 tmp;
678         *status = 0;
679
680
681         dbg("%s", __func__);
682         if (priv->sleeping)
683                 return 0;
684
685         ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
686         if (ret)
687                 goto err;
688
689         if (tmp == 11) {
690                 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
691                                 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
692         }
693         /* TODO find out if this is also true for rtl2832? */
694         /*else if (tmp == 10) {
695                 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
696                                 FE_HAS_VITERBI;
697         }*/
698
699         return ret;
700 err:
701         info("%s: failed=%d", __func__, ret);
702         return ret;
703 }
704
705 static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
706 {
707         *snr = 0;
708         return 0;
709 }
710
711 static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
712 {
713         *ber = 0;
714         return 0;
715 }
716
717 static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
718 {
719         *ucblocks = 0;
720         return 0;
721 }
722
723
724 static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
725 {
726         *strength = 0;
727         return 0;
728 }
729
730 static struct dvb_frontend_ops rtl2832_ops;
731
732 static void rtl2832_release(struct dvb_frontend *fe)
733 {
734         struct rtl2832_priv *priv = fe->demodulator_priv;
735
736         dbg("%s", __func__);
737         kfree(priv);
738 }
739
740 struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
741         struct i2c_adapter *i2c)
742 {
743         struct rtl2832_priv *priv = NULL;
744         int ret = 0;
745         u8 tmp;
746
747         dbg("%s", __func__);
748
749         /* allocate memory for the internal state */
750         priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
751         if (priv == NULL)
752                 goto err;
753
754         /* setup the priv */
755         priv->i2c = i2c;
756         priv->tuner = cfg->tuner;
757         memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
758
759         /* check if the demod is there */
760         ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
761         if (ret)
762                 goto err;
763
764         /* create dvb_frontend */
765         memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
766         priv->fe.demodulator_priv = priv;
767
768         /* TODO implement sleep mode */
769         priv->sleeping = true;
770
771         return &priv->fe;
772 err:
773         dbg("%s: failed=%d", __func__, ret);
774         kfree(priv);
775         return NULL;
776 }
777 EXPORT_SYMBOL(rtl2832_attach);
778
779 static struct dvb_frontend_ops rtl2832_ops = {
780         .delsys = { SYS_DVBT },
781         .info = {
782                 .name = "Realtek RTL2832 (DVB-T)",
783                 .frequency_min    = 174000000,
784                 .frequency_max    = 862000000,
785                 .frequency_stepsize = 166667,
786                 .caps = FE_CAN_FEC_1_2 |
787                         FE_CAN_FEC_2_3 |
788                         FE_CAN_FEC_3_4 |
789                         FE_CAN_FEC_5_6 |
790                         FE_CAN_FEC_7_8 |
791                         FE_CAN_FEC_AUTO |
792                         FE_CAN_QPSK |
793                         FE_CAN_QAM_16 |
794                         FE_CAN_QAM_64 |
795                         FE_CAN_QAM_AUTO |
796                         FE_CAN_TRANSMISSION_MODE_AUTO |
797                         FE_CAN_GUARD_INTERVAL_AUTO |
798                         FE_CAN_HIERARCHY_AUTO |
799                         FE_CAN_RECOVER |
800                         FE_CAN_MUTE_TS
801          },
802
803         .release = rtl2832_release,
804
805         .init = rtl2832_init,
806         .sleep = rtl2832_sleep,
807
808         .get_tune_settings = rtl2832_get_tune_settings,
809
810         .set_frontend = rtl2832_set_frontend,
811
812         .read_status = rtl2832_read_status,
813         .read_snr = rtl2832_read_snr,
814         .read_ber = rtl2832_read_ber,
815         .read_ucblocks = rtl2832_read_ucblocks,
816         .read_signal_strength = rtl2832_read_signal_strength,
817         .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
818 };
819
820 MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
821 MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
822 MODULE_LICENSE("GPL");
823 MODULE_VERSION("0.5");