2 * Realtek RTL2830 DVB-T demodulator driver
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
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.
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.
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.
23 * Driver implements own I2C-adapter for tuner I2C access. That's since chip
24 * have unusual I2C-gate control which closes gate automatically after each
25 * I2C transfer. Using own I2C adapter we can workaround that.
28 #include "rtl2830_priv.h"
31 module_param_named(debug
, rtl2830_debug
, int, 0644);
32 MODULE_PARM_DESC(debug
, "Turn on/off frontend debugging (default:off).");
34 /* write multiple hardware registers */
35 static int rtl2830_wr(struct rtl2830_priv
*priv
, u8 reg
, u8
*val
, int len
)
39 struct i2c_msg msg
[1] = {
41 .addr
= priv
->cfg
.i2c_addr
,
49 memcpy(&buf
[1], val
, len
);
51 ret
= i2c_transfer(priv
->i2c
, msg
, 1);
55 warn("i2c wr failed=%d reg=%02x len=%d", ret
, reg
, len
);
61 /* read multiple hardware registers */
62 static int rtl2830_rd(struct rtl2830_priv
*priv
, u8 reg
, u8
*val
, int len
)
65 struct i2c_msg msg
[2] = {
67 .addr
= priv
->cfg
.i2c_addr
,
72 .addr
= priv
->cfg
.i2c_addr
,
79 ret
= i2c_transfer(priv
->i2c
, msg
, 2);
83 warn("i2c rd failed=%d reg=%02x len=%d", ret
, reg
, len
);
89 /* write multiple registers */
90 static int rtl2830_wr_regs(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
, int len
)
93 u8 reg2
= (reg
>> 0) & 0xff;
94 u8 page
= (reg
>> 8) & 0xff;
96 /* switch bank if needed */
97 if (page
!= priv
->page
) {
98 ret
= rtl2830_wr(priv
, 0x00, &page
, 1);
105 return rtl2830_wr(priv
, reg2
, val
, len
);
108 /* read multiple registers */
109 static int rtl2830_rd_regs(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
, int len
)
112 u8 reg2
= (reg
>> 0) & 0xff;
113 u8 page
= (reg
>> 8) & 0xff;
115 /* switch bank if needed */
116 if (page
!= priv
->page
) {
117 ret
= rtl2830_wr(priv
, 0x00, &page
, 1);
124 return rtl2830_rd(priv
, reg2
, val
, len
);
127 #if 0 /* currently not used */
128 /* write single register */
129 static int rtl2830_wr_reg(struct rtl2830_priv
*priv
, u16 reg
, u8 val
)
131 return rtl2830_wr_regs(priv
, reg
, &val
, 1);
135 /* read single register */
136 static int rtl2830_rd_reg(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
)
138 return rtl2830_rd_regs(priv
, reg
, val
, 1);
141 /* write single register with mask */
142 int rtl2830_wr_reg_mask(struct rtl2830_priv
*priv
, u16 reg
, u8 val
, u8 mask
)
147 /* no need for read if whole reg is written */
149 ret
= rtl2830_rd_regs(priv
, reg
, &tmp
, 1);
158 return rtl2830_wr_regs(priv
, reg
, &val
, 1);
161 /* read single register with mask */
162 int rtl2830_rd_reg_mask(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
, u8 mask
)
167 ret
= rtl2830_rd_regs(priv
, reg
, &tmp
, 1);
173 /* find position of the first bit */
174 for (i
= 0; i
< 8; i
++) {
175 if ((mask
>> i
) & 0x01)
183 static int rtl2830_init(struct dvb_frontend
*fe
)
185 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
190 struct rtl2830_reg_val_mask tab
[] = {
191 { 0x00d, 0x01, 0x03 },
192 { 0x00d, 0x10, 0x10 },
193 { 0x104, 0x00, 0x1e },
194 { 0x105, 0x80, 0x80 },
195 { 0x110, 0x02, 0x03 },
196 { 0x110, 0x08, 0x0c },
197 { 0x17b, 0x00, 0x40 },
198 { 0x17d, 0x05, 0x0f },
199 { 0x17d, 0x50, 0xf0 },
200 { 0x18c, 0x08, 0x0f },
201 { 0x18d, 0x00, 0xc0 },
202 { 0x188, 0x05, 0x0f },
203 { 0x189, 0x00, 0xfc },
204 { 0x2d5, 0x02, 0x02 },
205 { 0x2f1, 0x02, 0x06 },
206 { 0x2f1, 0x20, 0xf8 },
207 { 0x16d, 0x00, 0x01 },
208 { 0x1a6, 0x00, 0x80 },
209 { 0x106, priv
->cfg
.vtop
, 0x3f },
210 { 0x107, priv
->cfg
.krf
, 0x3f },
211 { 0x112, 0x28, 0xff },
212 { 0x103, priv
->cfg
.agc_targ_val
, 0xff },
213 { 0x00a, 0x02, 0x07 },
214 { 0x140, 0x0c, 0x3c },
215 { 0x140, 0x40, 0xc0 },
216 { 0x15b, 0x05, 0x07 },
217 { 0x15b, 0x28, 0x38 },
218 { 0x15c, 0x05, 0x07 },
219 { 0x15c, 0x28, 0x38 },
220 { 0x115, priv
->cfg
.spec_inv
, 0x01 },
221 { 0x16f, 0x01, 0x07 },
222 { 0x170, 0x18, 0x38 },
223 { 0x172, 0x0f, 0x0f },
224 { 0x173, 0x08, 0x38 },
225 { 0x175, 0x01, 0x07 },
226 { 0x176, 0x00, 0xc0 },
229 for (i
= 0; i
< ARRAY_SIZE(tab
); i
++) {
230 ret
= rtl2830_wr_reg_mask(priv
, tab
[i
].reg
, tab
[i
].val
,
236 ret
= rtl2830_wr_regs(priv
, 0x18f, "\x28\x00", 2);
240 ret
= rtl2830_wr_regs(priv
, 0x195,
241 "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
245 num
= priv
->cfg
.if_dvbt
% priv
->cfg
.xtal
;
247 num
= div_u64(num
, priv
->cfg
.xtal
);
249 if_ctl
= num
& 0x3fffff;
250 dbg("%s: if_ctl=%08x", __func__
, if_ctl
);
252 ret
= rtl2830_rd_reg_mask(priv
, 0x119, &tmp
, 0xc0); /* b[7:6] */
257 buf
[0] = (if_ctl
>> 16) & 0x3f;
258 buf
[1] = (if_ctl
>> 8) & 0xff;
259 buf
[2] = (if_ctl
>> 0) & 0xff;
261 ret
= rtl2830_wr_regs(priv
, 0x119, buf
, 3);
265 /* TODO: spec init */
268 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x04, 0x04);
272 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x00, 0x04);
276 priv
->sleeping
= false;
280 dbg("%s: failed=%d", __func__
, ret
);
284 static int rtl2830_sleep(struct dvb_frontend
*fe
)
286 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
287 priv
->sleeping
= true;
291 int rtl2830_get_tune_settings(struct dvb_frontend
*fe
,
292 struct dvb_frontend_tune_settings
*s
)
294 s
->min_delay_ms
= 500;
295 s
->step_size
= fe
->ops
.info
.frequency_stepsize
* 2;
296 s
->max_drift
= (fe
->ops
.info
.frequency_stepsize
* 2) + 1;
301 static int rtl2830_set_frontend(struct dvb_frontend
*fe
)
303 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
304 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
306 static u8 bw_params1
[3][34] = {
308 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
309 0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
310 0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
311 0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
313 0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
314 0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
315 0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
316 0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
318 0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
319 0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
320 0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
321 0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
324 static u8 bw_params2
[3][6] = {
325 {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30,}, /* 6 MHz */
326 {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98,}, /* 7 MHz */
327 {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64,}, /* 8 MHz */
331 dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__
,
332 c
->frequency
, c
->bandwidth_hz
, c
->inversion
);
335 if (fe
->ops
.tuner_ops
.set_params
)
336 fe
->ops
.tuner_ops
.set_params(fe
);
338 switch (c
->bandwidth_hz
) {
349 dbg("invalid bandwidth");
353 ret
= rtl2830_wr_reg_mask(priv
, 0x008, i
<< 1, 0x06);
357 /* 1/2 split I2C write */
358 ret
= rtl2830_wr_regs(priv
, 0x11c, &bw_params1
[i
][0], 17);
362 /* 2/2 split I2C write */
363 ret
= rtl2830_wr_regs(priv
, 0x12d, &bw_params1
[i
][17], 17);
367 ret
= rtl2830_wr_regs(priv
, 0x19d, bw_params2
[i
], 6);
373 dbg("%s: failed=%d", __func__
, ret
);
377 static int rtl2830_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
379 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
387 ret
= rtl2830_rd_reg_mask(priv
, 0x351, &tmp
, 0x78); /* [6:3] */
392 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
|
393 FE_HAS_VITERBI
| FE_HAS_SYNC
| FE_HAS_LOCK
;
394 } else if (tmp
== 10) {
395 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
|
401 dbg("%s: failed=%d", __func__
, ret
);
405 static int rtl2830_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
407 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
408 int ret
, hierarchy
, constellation
;
411 #define CONSTELLATION_NUM 3
412 #define HIERARCHY_NUM 4
413 static const u32 snr_constant
[CONSTELLATION_NUM
][HIERARCHY_NUM
] = {
414 { 70705899, 70705899, 70705899, 70705899 },
415 { 82433173, 82433173, 87483115, 94445660 },
416 { 92888734, 92888734, 95487525, 99770748 },
419 /* reports SNR in resolution of 0.1 dB */
421 ret
= rtl2830_rd_reg(priv
, 0x33c, &tmp
);
425 constellation
= (tmp
>> 2) & 0x03; /* [3:2] */
426 if (constellation
> CONSTELLATION_NUM
- 1)
429 hierarchy
= (tmp
>> 4) & 0x07; /* [6:4] */
430 if (hierarchy
> HIERARCHY_NUM
- 1)
433 ret
= rtl2830_rd_regs(priv
, 0x40c, buf
, 2);
437 tmp16
= buf
[0] << 8 | buf
[1];
440 *snr
= (snr_constant
[constellation
][hierarchy
] -
441 intlog10(tmp16
)) / ((1 << 24) / 100);
447 dbg("%s: failed=%d", __func__
, ret
);
451 static int rtl2830_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
453 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
457 ret
= rtl2830_rd_regs(priv
, 0x34e, buf
, 2);
461 *ber
= buf
[0] << 8 | buf
[1];
465 dbg("%s: failed=%d", __func__
, ret
);
469 static int rtl2830_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
475 static int rtl2830_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
477 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
480 u16 if_agc_raw
, if_agc
;
482 ret
= rtl2830_rd_regs(priv
, 0x359, buf
, 2);
486 if_agc_raw
= (buf
[0] << 8 | buf
[1]) & 0x3fff;
488 if (if_agc_raw
& (1 << 9))
489 if_agc
= -(~(if_agc_raw
- 1) & 0x1ff);
493 *strength
= (u8
) (55 - if_agc
/ 182);
494 *strength
|= *strength
<< 8;
498 dbg("%s: failed=%d", __func__
, ret
);
502 static struct dvb_frontend_ops rtl2830_ops
;
504 static u32
rtl2830_tuner_i2c_func(struct i2c_adapter
*adapter
)
509 static int rtl2830_tuner_i2c_xfer(struct i2c_adapter
*i2c_adap
,
510 struct i2c_msg msg
[], int num
)
512 struct rtl2830_priv
*priv
= i2c_get_adapdata(i2c_adap
);
516 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x08, 0x08);
520 ret
= i2c_transfer(priv
->i2c
, msg
, num
);
522 warn("tuner i2c failed=%d", ret
);
526 dbg("%s: failed=%d", __func__
, ret
);
530 static struct i2c_algorithm rtl2830_tuner_i2c_algo
= {
531 .master_xfer
= rtl2830_tuner_i2c_xfer
,
532 .functionality
= rtl2830_tuner_i2c_func
,
535 struct i2c_adapter
*rtl2830_get_tuner_i2c_adapter(struct dvb_frontend
*fe
)
537 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
538 return &priv
->tuner_i2c_adapter
;
540 EXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter
);
542 static void rtl2830_release(struct dvb_frontend
*fe
)
544 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
546 i2c_del_adapter(&priv
->tuner_i2c_adapter
);
550 struct dvb_frontend
*rtl2830_attach(const struct rtl2830_config
*cfg
,
551 struct i2c_adapter
*i2c
)
553 struct rtl2830_priv
*priv
= NULL
;
557 /* allocate memory for the internal state */
558 priv
= kzalloc(sizeof(struct rtl2830_priv
), GFP_KERNEL
);
564 memcpy(&priv
->cfg
, cfg
, sizeof(struct rtl2830_config
));
566 /* check if the demod is there */
567 ret
= rtl2830_rd_reg(priv
, 0x000, &tmp
);
571 /* create dvb_frontend */
572 memcpy(&priv
->fe
.ops
, &rtl2830_ops
, sizeof(struct dvb_frontend_ops
));
573 priv
->fe
.demodulator_priv
= priv
;
575 /* create tuner i2c adapter */
576 strlcpy(priv
->tuner_i2c_adapter
.name
, "RTL2830 tuner I2C adapter",
577 sizeof(priv
->tuner_i2c_adapter
.name
));
578 priv
->tuner_i2c_adapter
.algo
= &rtl2830_tuner_i2c_algo
;
579 priv
->tuner_i2c_adapter
.algo_data
= NULL
;
580 i2c_set_adapdata(&priv
->tuner_i2c_adapter
, priv
);
581 if (i2c_add_adapter(&priv
->tuner_i2c_adapter
) < 0) {
582 err("tuner I2C bus could not be initialized");
586 priv
->sleeping
= true;
590 dbg("%s: failed=%d", __func__
, ret
);
594 EXPORT_SYMBOL(rtl2830_attach
);
596 static struct dvb_frontend_ops rtl2830_ops
= {
597 .delsys
= { SYS_DVBT
},
599 .name
= "Realtek RTL2830 (DVB-T)",
600 .caps
= FE_CAN_FEC_1_2
|
610 FE_CAN_TRANSMISSION_MODE_AUTO
|
611 FE_CAN_GUARD_INTERVAL_AUTO
|
612 FE_CAN_HIERARCHY_AUTO
|
617 .release
= rtl2830_release
,
619 .init
= rtl2830_init
,
620 .sleep
= rtl2830_sleep
,
622 .get_tune_settings
= rtl2830_get_tune_settings
,
624 .set_frontend
= rtl2830_set_frontend
,
626 .read_status
= rtl2830_read_status
,
627 .read_snr
= rtl2830_read_snr
,
628 .read_ber
= rtl2830_read_ber
,
629 .read_ucblocks
= rtl2830_read_ucblocks
,
630 .read_signal_strength
= rtl2830_read_signal_strength
,
633 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
634 MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
635 MODULE_LICENSE("GPL");