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"
30 /* write multiple hardware registers */
31 static int rtl2830_wr(struct rtl2830_priv
*priv
, u8 reg
, u8
*val
, int len
)
35 struct i2c_msg msg
[1] = {
37 .addr
= priv
->cfg
.i2c_addr
,
45 memcpy(&buf
[1], val
, len
);
47 ret
= i2c_transfer(priv
->i2c
, msg
, 1);
51 dev_warn(&priv
->i2c
->dev
, "%s: i2c wr failed=%d reg=%02x " \
52 "len=%d\n", KBUILD_MODNAME
, ret
, reg
, len
);
58 /* read multiple hardware registers */
59 static int rtl2830_rd(struct rtl2830_priv
*priv
, u8 reg
, u8
*val
, int len
)
62 struct i2c_msg msg
[2] = {
64 .addr
= priv
->cfg
.i2c_addr
,
69 .addr
= priv
->cfg
.i2c_addr
,
76 ret
= i2c_transfer(priv
->i2c
, msg
, 2);
80 dev_warn(&priv
->i2c
->dev
, "%s: i2c rd failed=%d reg=%02x " \
81 "len=%d\n", KBUILD_MODNAME
, ret
, reg
, len
);
87 /* write multiple registers */
88 static int rtl2830_wr_regs(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
, int len
)
91 u8 reg2
= (reg
>> 0) & 0xff;
92 u8 page
= (reg
>> 8) & 0xff;
94 /* switch bank if needed */
95 if (page
!= priv
->page
) {
96 ret
= rtl2830_wr(priv
, 0x00, &page
, 1);
103 return rtl2830_wr(priv
, reg2
, val
, len
);
106 /* read multiple registers */
107 static int rtl2830_rd_regs(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
, int len
)
110 u8 reg2
= (reg
>> 0) & 0xff;
111 u8 page
= (reg
>> 8) & 0xff;
113 /* switch bank if needed */
114 if (page
!= priv
->page
) {
115 ret
= rtl2830_wr(priv
, 0x00, &page
, 1);
122 return rtl2830_rd(priv
, reg2
, val
, len
);
125 #if 0 /* currently not used */
126 /* write single register */
127 static int rtl2830_wr_reg(struct rtl2830_priv
*priv
, u16 reg
, u8 val
)
129 return rtl2830_wr_regs(priv
, reg
, &val
, 1);
133 /* read single register */
134 static int rtl2830_rd_reg(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
)
136 return rtl2830_rd_regs(priv
, reg
, val
, 1);
139 /* write single register with mask */
140 int rtl2830_wr_reg_mask(struct rtl2830_priv
*priv
, u16 reg
, u8 val
, u8 mask
)
145 /* no need for read if whole reg is written */
147 ret
= rtl2830_rd_regs(priv
, reg
, &tmp
, 1);
156 return rtl2830_wr_regs(priv
, reg
, &val
, 1);
159 /* read single register with mask */
160 int rtl2830_rd_reg_mask(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
, u8 mask
)
165 ret
= rtl2830_rd_regs(priv
, reg
, &tmp
, 1);
171 /* find position of the first bit */
172 for (i
= 0; i
< 8; i
++) {
173 if ((mask
>> i
) & 0x01)
181 static int rtl2830_init(struct dvb_frontend
*fe
)
183 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
188 struct rtl2830_reg_val_mask tab
[] = {
189 { 0x00d, 0x01, 0x03 },
190 { 0x00d, 0x10, 0x10 },
191 { 0x104, 0x00, 0x1e },
192 { 0x105, 0x80, 0x80 },
193 { 0x110, 0x02, 0x03 },
194 { 0x110, 0x08, 0x0c },
195 { 0x17b, 0x00, 0x40 },
196 { 0x17d, 0x05, 0x0f },
197 { 0x17d, 0x50, 0xf0 },
198 { 0x18c, 0x08, 0x0f },
199 { 0x18d, 0x00, 0xc0 },
200 { 0x188, 0x05, 0x0f },
201 { 0x189, 0x00, 0xfc },
202 { 0x2d5, 0x02, 0x02 },
203 { 0x2f1, 0x02, 0x06 },
204 { 0x2f1, 0x20, 0xf8 },
205 { 0x16d, 0x00, 0x01 },
206 { 0x1a6, 0x00, 0x80 },
207 { 0x106, priv
->cfg
.vtop
, 0x3f },
208 { 0x107, priv
->cfg
.krf
, 0x3f },
209 { 0x112, 0x28, 0xff },
210 { 0x103, priv
->cfg
.agc_targ_val
, 0xff },
211 { 0x00a, 0x02, 0x07 },
212 { 0x140, 0x0c, 0x3c },
213 { 0x140, 0x40, 0xc0 },
214 { 0x15b, 0x05, 0x07 },
215 { 0x15b, 0x28, 0x38 },
216 { 0x15c, 0x05, 0x07 },
217 { 0x15c, 0x28, 0x38 },
218 { 0x115, priv
->cfg
.spec_inv
, 0x01 },
219 { 0x16f, 0x01, 0x07 },
220 { 0x170, 0x18, 0x38 },
221 { 0x172, 0x0f, 0x0f },
222 { 0x173, 0x08, 0x38 },
223 { 0x175, 0x01, 0x07 },
224 { 0x176, 0x00, 0xc0 },
227 for (i
= 0; i
< ARRAY_SIZE(tab
); i
++) {
228 ret
= rtl2830_wr_reg_mask(priv
, tab
[i
].reg
, tab
[i
].val
,
234 ret
= rtl2830_wr_regs(priv
, 0x18f, "\x28\x00", 2);
238 ret
= rtl2830_wr_regs(priv
, 0x195,
239 "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
243 num
= priv
->cfg
.if_dvbt
% priv
->cfg
.xtal
;
245 num
= div_u64(num
, priv
->cfg
.xtal
);
247 if_ctl
= num
& 0x3fffff;
248 dev_dbg(&priv
->i2c
->dev
, "%s: if_ctl=%08x\n", __func__
, if_ctl
);
250 ret
= rtl2830_rd_reg_mask(priv
, 0x119, &tmp
, 0xc0); /* b[7:6] */
255 buf
[0] = (if_ctl
>> 16) & 0x3f;
256 buf
[1] = (if_ctl
>> 8) & 0xff;
257 buf
[2] = (if_ctl
>> 0) & 0xff;
259 ret
= rtl2830_wr_regs(priv
, 0x119, buf
, 3);
263 /* TODO: spec init */
266 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x04, 0x04);
270 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x00, 0x04);
274 priv
->sleeping
= false;
278 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
282 static int rtl2830_sleep(struct dvb_frontend
*fe
)
284 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
285 priv
->sleeping
= true;
289 int rtl2830_get_tune_settings(struct dvb_frontend
*fe
,
290 struct dvb_frontend_tune_settings
*s
)
292 s
->min_delay_ms
= 500;
293 s
->step_size
= fe
->ops
.info
.frequency_stepsize
* 2;
294 s
->max_drift
= (fe
->ops
.info
.frequency_stepsize
* 2) + 1;
299 static int rtl2830_set_frontend(struct dvb_frontend
*fe
)
301 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
302 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
304 static u8 bw_params1
[3][34] = {
306 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
307 0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
308 0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
309 0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
311 0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
312 0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
313 0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
314 0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
316 0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
317 0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
318 0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
319 0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
322 static u8 bw_params2
[3][6] = {
323 {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30,}, /* 6 MHz */
324 {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98,}, /* 7 MHz */
325 {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64,}, /* 8 MHz */
329 dev_dbg(&priv
->i2c
->dev
,
330 "%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
331 __func__
, c
->frequency
, c
->bandwidth_hz
, c
->inversion
);
334 if (fe
->ops
.tuner_ops
.set_params
)
335 fe
->ops
.tuner_ops
.set_params(fe
);
337 switch (c
->bandwidth_hz
) {
348 dev_dbg(&priv
->i2c
->dev
, "%s: invalid bandwidth\n", __func__
);
352 ret
= rtl2830_wr_reg_mask(priv
, 0x008, i
<< 1, 0x06);
356 /* 1/2 split I2C write */
357 ret
= rtl2830_wr_regs(priv
, 0x11c, &bw_params1
[i
][0], 17);
361 /* 2/2 split I2C write */
362 ret
= rtl2830_wr_regs(priv
, 0x12d, &bw_params1
[i
][17], 17);
366 ret
= rtl2830_wr_regs(priv
, 0x19d, bw_params2
[i
], 6);
372 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
376 static int rtl2830_get_frontend(struct dvb_frontend
*fe
)
378 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
379 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
386 ret
= rtl2830_rd_regs(priv
, 0x33c, buf
, 2);
390 ret
= rtl2830_rd_reg(priv
, 0x351, &buf
[2]);
394 dev_dbg(&priv
->i2c
->dev
, "%s: TPS=%*ph\n", __func__
, 3, buf
);
396 switch ((buf
[0] >> 2) & 3) {
398 c
->modulation
= QPSK
;
401 c
->modulation
= QAM_16
;
404 c
->modulation
= QAM_64
;
408 switch ((buf
[2] >> 2) & 1) {
410 c
->transmission_mode
= TRANSMISSION_MODE_2K
;
413 c
->transmission_mode
= TRANSMISSION_MODE_8K
;
416 switch ((buf
[2] >> 0) & 3) {
418 c
->guard_interval
= GUARD_INTERVAL_1_32
;
421 c
->guard_interval
= GUARD_INTERVAL_1_16
;
424 c
->guard_interval
= GUARD_INTERVAL_1_8
;
427 c
->guard_interval
= GUARD_INTERVAL_1_4
;
431 switch ((buf
[0] >> 4) & 7) {
433 c
->hierarchy
= HIERARCHY_NONE
;
436 c
->hierarchy
= HIERARCHY_1
;
439 c
->hierarchy
= HIERARCHY_2
;
442 c
->hierarchy
= HIERARCHY_4
;
446 switch ((buf
[1] >> 3) & 7) {
448 c
->code_rate_HP
= FEC_1_2
;
451 c
->code_rate_HP
= FEC_2_3
;
454 c
->code_rate_HP
= FEC_3_4
;
457 c
->code_rate_HP
= FEC_5_6
;
460 c
->code_rate_HP
= FEC_7_8
;
464 switch ((buf
[1] >> 0) & 7) {
466 c
->code_rate_LP
= FEC_1_2
;
469 c
->code_rate_LP
= FEC_2_3
;
472 c
->code_rate_LP
= FEC_3_4
;
475 c
->code_rate_LP
= FEC_5_6
;
478 c
->code_rate_LP
= FEC_7_8
;
484 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
488 static int rtl2830_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
490 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
498 ret
= rtl2830_rd_reg_mask(priv
, 0x351, &tmp
, 0x78); /* [6:3] */
503 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
|
504 FE_HAS_VITERBI
| FE_HAS_SYNC
| FE_HAS_LOCK
;
505 } else if (tmp
== 10) {
506 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
|
512 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
516 static int rtl2830_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
518 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
519 int ret
, hierarchy
, constellation
;
522 #define CONSTELLATION_NUM 3
523 #define HIERARCHY_NUM 4
524 static const u32 snr_constant
[CONSTELLATION_NUM
][HIERARCHY_NUM
] = {
525 { 70705899, 70705899, 70705899, 70705899 },
526 { 82433173, 82433173, 87483115, 94445660 },
527 { 92888734, 92888734, 95487525, 99770748 },
533 /* reports SNR in resolution of 0.1 dB */
535 ret
= rtl2830_rd_reg(priv
, 0x33c, &tmp
);
539 constellation
= (tmp
>> 2) & 0x03; /* [3:2] */
540 if (constellation
> CONSTELLATION_NUM
- 1)
543 hierarchy
= (tmp
>> 4) & 0x07; /* [6:4] */
544 if (hierarchy
> HIERARCHY_NUM
- 1)
547 ret
= rtl2830_rd_regs(priv
, 0x40c, buf
, 2);
551 tmp16
= buf
[0] << 8 | buf
[1];
554 *snr
= (snr_constant
[constellation
][hierarchy
] -
555 intlog10(tmp16
)) / ((1 << 24) / 100);
561 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
565 static int rtl2830_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
567 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
574 ret
= rtl2830_rd_regs(priv
, 0x34e, buf
, 2);
578 *ber
= buf
[0] << 8 | buf
[1];
582 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
586 static int rtl2830_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
592 static int rtl2830_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
594 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
597 u16 if_agc_raw
, if_agc
;
602 ret
= rtl2830_rd_regs(priv
, 0x359, buf
, 2);
606 if_agc_raw
= (buf
[0] << 8 | buf
[1]) & 0x3fff;
608 if (if_agc_raw
& (1 << 9))
609 if_agc
= -(~(if_agc_raw
- 1) & 0x1ff);
613 *strength
= (u8
) (55 - if_agc
/ 182);
614 *strength
|= *strength
<< 8;
618 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
622 static struct dvb_frontend_ops rtl2830_ops
;
624 static u32
rtl2830_tuner_i2c_func(struct i2c_adapter
*adapter
)
629 static int rtl2830_tuner_i2c_xfer(struct i2c_adapter
*i2c_adap
,
630 struct i2c_msg msg
[], int num
)
632 struct rtl2830_priv
*priv
= i2c_get_adapdata(i2c_adap
);
636 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x08, 0x08);
640 ret
= i2c_transfer(priv
->i2c
, msg
, num
);
642 dev_warn(&priv
->i2c
->dev
, "%s: tuner i2c failed=%d\n",
643 KBUILD_MODNAME
, ret
);
647 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
651 static struct i2c_algorithm rtl2830_tuner_i2c_algo
= {
652 .master_xfer
= rtl2830_tuner_i2c_xfer
,
653 .functionality
= rtl2830_tuner_i2c_func
,
656 struct i2c_adapter
*rtl2830_get_tuner_i2c_adapter(struct dvb_frontend
*fe
)
658 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
659 return &priv
->tuner_i2c_adapter
;
661 EXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter
);
663 static void rtl2830_release(struct dvb_frontend
*fe
)
665 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
667 i2c_del_adapter(&priv
->tuner_i2c_adapter
);
671 struct dvb_frontend
*rtl2830_attach(const struct rtl2830_config
*cfg
,
672 struct i2c_adapter
*i2c
)
674 struct rtl2830_priv
*priv
= NULL
;
678 /* allocate memory for the internal state */
679 priv
= kzalloc(sizeof(struct rtl2830_priv
), GFP_KERNEL
);
685 memcpy(&priv
->cfg
, cfg
, sizeof(struct rtl2830_config
));
687 /* check if the demod is there */
688 ret
= rtl2830_rd_reg(priv
, 0x000, &tmp
);
692 /* create dvb_frontend */
693 memcpy(&priv
->fe
.ops
, &rtl2830_ops
, sizeof(struct dvb_frontend_ops
));
694 priv
->fe
.demodulator_priv
= priv
;
696 /* create tuner i2c adapter */
697 strlcpy(priv
->tuner_i2c_adapter
.name
, "RTL2830 tuner I2C adapter",
698 sizeof(priv
->tuner_i2c_adapter
.name
));
699 priv
->tuner_i2c_adapter
.algo
= &rtl2830_tuner_i2c_algo
;
700 priv
->tuner_i2c_adapter
.algo_data
= NULL
;
701 i2c_set_adapdata(&priv
->tuner_i2c_adapter
, priv
);
702 if (i2c_add_adapter(&priv
->tuner_i2c_adapter
) < 0) {
704 "%s: tuner i2c bus could not be initialized\n",
709 priv
->sleeping
= true;
713 dev_dbg(&i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
717 EXPORT_SYMBOL(rtl2830_attach
);
719 static struct dvb_frontend_ops rtl2830_ops
= {
720 .delsys
= { SYS_DVBT
},
722 .name
= "Realtek RTL2830 (DVB-T)",
723 .caps
= FE_CAN_FEC_1_2
|
733 FE_CAN_TRANSMISSION_MODE_AUTO
|
734 FE_CAN_GUARD_INTERVAL_AUTO
|
735 FE_CAN_HIERARCHY_AUTO
|
740 .release
= rtl2830_release
,
742 .init
= rtl2830_init
,
743 .sleep
= rtl2830_sleep
,
745 .get_tune_settings
= rtl2830_get_tune_settings
,
747 .set_frontend
= rtl2830_set_frontend
,
748 .get_frontend
= rtl2830_get_frontend
,
750 .read_status
= rtl2830_read_status
,
751 .read_snr
= rtl2830_read_snr
,
752 .read_ber
= rtl2830_read_ber
,
753 .read_ucblocks
= rtl2830_read_ucblocks
,
754 .read_signal_strength
= rtl2830_read_signal_strength
,
757 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
758 MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
759 MODULE_LICENSE("GPL");