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
, const 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
, const u8
*val
,
92 u8 reg2
= (reg
>> 0) & 0xff;
93 u8 page
= (reg
>> 8) & 0xff;
95 /* switch bank if needed */
96 if (page
!= priv
->page
) {
97 ret
= rtl2830_wr(priv
, 0x00, &page
, 1);
104 return rtl2830_wr(priv
, reg2
, val
, len
);
107 /* read multiple registers */
108 static int rtl2830_rd_regs(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
, int len
)
111 u8 reg2
= (reg
>> 0) & 0xff;
112 u8 page
= (reg
>> 8) & 0xff;
114 /* switch bank if needed */
115 if (page
!= priv
->page
) {
116 ret
= rtl2830_wr(priv
, 0x00, &page
, 1);
123 return rtl2830_rd(priv
, reg2
, val
, len
);
126 /* read single register */
127 static int rtl2830_rd_reg(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
)
129 return rtl2830_rd_regs(priv
, reg
, val
, 1);
132 /* write single register with mask */
133 static int rtl2830_wr_reg_mask(struct rtl2830_priv
*priv
, u16 reg
, u8 val
, u8 mask
)
138 /* no need for read if whole reg is written */
140 ret
= rtl2830_rd_regs(priv
, reg
, &tmp
, 1);
149 return rtl2830_wr_regs(priv
, reg
, &val
, 1);
152 /* read single register with mask */
153 static int rtl2830_rd_reg_mask(struct rtl2830_priv
*priv
, u16 reg
, u8
*val
, u8 mask
)
158 ret
= rtl2830_rd_regs(priv
, reg
, &tmp
, 1);
164 /* find position of the first bit */
165 for (i
= 0; i
< 8; i
++) {
166 if ((mask
>> i
) & 0x01)
174 static int rtl2830_init(struct dvb_frontend
*fe
)
176 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
178 struct rtl2830_reg_val_mask tab
[] = {
179 { 0x00d, 0x01, 0x03 },
180 { 0x00d, 0x10, 0x10 },
181 { 0x104, 0x00, 0x1e },
182 { 0x105, 0x80, 0x80 },
183 { 0x110, 0x02, 0x03 },
184 { 0x110, 0x08, 0x0c },
185 { 0x17b, 0x00, 0x40 },
186 { 0x17d, 0x05, 0x0f },
187 { 0x17d, 0x50, 0xf0 },
188 { 0x18c, 0x08, 0x0f },
189 { 0x18d, 0x00, 0xc0 },
190 { 0x188, 0x05, 0x0f },
191 { 0x189, 0x00, 0xfc },
192 { 0x2d5, 0x02, 0x02 },
193 { 0x2f1, 0x02, 0x06 },
194 { 0x2f1, 0x20, 0xf8 },
195 { 0x16d, 0x00, 0x01 },
196 { 0x1a6, 0x00, 0x80 },
197 { 0x106, priv
->cfg
.vtop
, 0x3f },
198 { 0x107, priv
->cfg
.krf
, 0x3f },
199 { 0x112, 0x28, 0xff },
200 { 0x103, priv
->cfg
.agc_targ_val
, 0xff },
201 { 0x00a, 0x02, 0x07 },
202 { 0x140, 0x0c, 0x3c },
203 { 0x140, 0x40, 0xc0 },
204 { 0x15b, 0x05, 0x07 },
205 { 0x15b, 0x28, 0x38 },
206 { 0x15c, 0x05, 0x07 },
207 { 0x15c, 0x28, 0x38 },
208 { 0x115, priv
->cfg
.spec_inv
, 0x01 },
209 { 0x16f, 0x01, 0x07 },
210 { 0x170, 0x18, 0x38 },
211 { 0x172, 0x0f, 0x0f },
212 { 0x173, 0x08, 0x38 },
213 { 0x175, 0x01, 0x07 },
214 { 0x176, 0x00, 0xc0 },
217 for (i
= 0; i
< ARRAY_SIZE(tab
); i
++) {
218 ret
= rtl2830_wr_reg_mask(priv
, tab
[i
].reg
, tab
[i
].val
,
224 ret
= rtl2830_wr_regs(priv
, 0x18f, "\x28\x00", 2);
228 ret
= rtl2830_wr_regs(priv
, 0x195,
229 "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
233 /* TODO: spec init */
236 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x04, 0x04);
240 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x00, 0x04);
244 priv
->sleeping
= false;
248 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
252 static int rtl2830_sleep(struct dvb_frontend
*fe
)
254 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
255 priv
->sleeping
= true;
259 static int rtl2830_get_tune_settings(struct dvb_frontend
*fe
,
260 struct dvb_frontend_tune_settings
*s
)
262 s
->min_delay_ms
= 500;
263 s
->step_size
= fe
->ops
.info
.frequency_stepsize
* 2;
264 s
->max_drift
= (fe
->ops
.info
.frequency_stepsize
* 2) + 1;
269 static int rtl2830_set_frontend(struct dvb_frontend
*fe
)
271 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
272 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
276 u32 if_ctl
, if_frequency
;
277 static const u8 bw_params1
[3][34] = {
279 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
280 0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
281 0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
282 0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
284 0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
285 0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
286 0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
287 0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
289 0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
290 0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
291 0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
292 0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
295 static const u8 bw_params2
[3][6] = {
296 {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30}, /* 6 MHz */
297 {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98}, /* 7 MHz */
298 {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64}, /* 8 MHz */
301 dev_dbg(&priv
->i2c
->dev
,
302 "%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
303 __func__
, c
->frequency
, c
->bandwidth_hz
, c
->inversion
);
306 if (fe
->ops
.tuner_ops
.set_params
)
307 fe
->ops
.tuner_ops
.set_params(fe
);
309 switch (c
->bandwidth_hz
) {
320 dev_dbg(&priv
->i2c
->dev
, "%s: invalid bandwidth\n", __func__
);
324 ret
= rtl2830_wr_reg_mask(priv
, 0x008, i
<< 1, 0x06);
328 /* program if frequency */
329 if (fe
->ops
.tuner_ops
.get_if_frequency
)
330 ret
= fe
->ops
.tuner_ops
.get_if_frequency(fe
, &if_frequency
);
337 num
= if_frequency
% priv
->cfg
.xtal
;
339 num
= div_u64(num
, priv
->cfg
.xtal
);
341 if_ctl
= num
& 0x3fffff;
342 dev_dbg(&priv
->i2c
->dev
, "%s: if_frequency=%d if_ctl=%08x\n",
343 __func__
, if_frequency
, if_ctl
);
345 ret
= rtl2830_rd_reg_mask(priv
, 0x119, &tmp
, 0xc0); /* b[7:6] */
350 buf
[0] |= (if_ctl
>> 16) & 0x3f;
351 buf
[1] = (if_ctl
>> 8) & 0xff;
352 buf
[2] = (if_ctl
>> 0) & 0xff;
354 ret
= rtl2830_wr_regs(priv
, 0x119, buf
, 3);
358 /* 1/2 split I2C write */
359 ret
= rtl2830_wr_regs(priv
, 0x11c, &bw_params1
[i
][0], 17);
363 /* 2/2 split I2C write */
364 ret
= rtl2830_wr_regs(priv
, 0x12d, &bw_params1
[i
][17], 17);
368 ret
= rtl2830_wr_regs(priv
, 0x19d, bw_params2
[i
], 6);
374 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
378 static int rtl2830_get_frontend(struct dvb_frontend
*fe
)
380 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
381 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
388 ret
= rtl2830_rd_regs(priv
, 0x33c, buf
, 2);
392 ret
= rtl2830_rd_reg(priv
, 0x351, &buf
[2]);
396 dev_dbg(&priv
->i2c
->dev
, "%s: TPS=%*ph\n", __func__
, 3, buf
);
398 switch ((buf
[0] >> 2) & 3) {
400 c
->modulation
= QPSK
;
403 c
->modulation
= QAM_16
;
406 c
->modulation
= QAM_64
;
410 switch ((buf
[2] >> 2) & 1) {
412 c
->transmission_mode
= TRANSMISSION_MODE_2K
;
415 c
->transmission_mode
= TRANSMISSION_MODE_8K
;
418 switch ((buf
[2] >> 0) & 3) {
420 c
->guard_interval
= GUARD_INTERVAL_1_32
;
423 c
->guard_interval
= GUARD_INTERVAL_1_16
;
426 c
->guard_interval
= GUARD_INTERVAL_1_8
;
429 c
->guard_interval
= GUARD_INTERVAL_1_4
;
433 switch ((buf
[0] >> 4) & 7) {
435 c
->hierarchy
= HIERARCHY_NONE
;
438 c
->hierarchy
= HIERARCHY_1
;
441 c
->hierarchy
= HIERARCHY_2
;
444 c
->hierarchy
= HIERARCHY_4
;
448 switch ((buf
[1] >> 3) & 7) {
450 c
->code_rate_HP
= FEC_1_2
;
453 c
->code_rate_HP
= FEC_2_3
;
456 c
->code_rate_HP
= FEC_3_4
;
459 c
->code_rate_HP
= FEC_5_6
;
462 c
->code_rate_HP
= FEC_7_8
;
466 switch ((buf
[1] >> 0) & 7) {
468 c
->code_rate_LP
= FEC_1_2
;
471 c
->code_rate_LP
= FEC_2_3
;
474 c
->code_rate_LP
= FEC_3_4
;
477 c
->code_rate_LP
= FEC_5_6
;
480 c
->code_rate_LP
= FEC_7_8
;
486 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
490 static int rtl2830_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
492 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
500 ret
= rtl2830_rd_reg_mask(priv
, 0x351, &tmp
, 0x78); /* [6:3] */
505 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
|
506 FE_HAS_VITERBI
| FE_HAS_SYNC
| FE_HAS_LOCK
;
507 } else if (tmp
== 10) {
508 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
|
514 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
518 static int rtl2830_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
520 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
521 int ret
, hierarchy
, constellation
;
524 #define CONSTELLATION_NUM 3
525 #define HIERARCHY_NUM 4
526 static const u32 snr_constant
[CONSTELLATION_NUM
][HIERARCHY_NUM
] = {
527 { 70705899, 70705899, 70705899, 70705899 },
528 { 82433173, 82433173, 87483115, 94445660 },
529 { 92888734, 92888734, 95487525, 99770748 },
535 /* reports SNR in resolution of 0.1 dB */
537 ret
= rtl2830_rd_reg(priv
, 0x33c, &tmp
);
541 constellation
= (tmp
>> 2) & 0x03; /* [3:2] */
542 if (constellation
> CONSTELLATION_NUM
- 1)
545 hierarchy
= (tmp
>> 4) & 0x07; /* [6:4] */
546 if (hierarchy
> HIERARCHY_NUM
- 1)
549 ret
= rtl2830_rd_regs(priv
, 0x40c, buf
, 2);
553 tmp16
= buf
[0] << 8 | buf
[1];
556 *snr
= (snr_constant
[constellation
][hierarchy
] -
557 intlog10(tmp16
)) / ((1 << 24) / 100);
563 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
567 static int rtl2830_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
569 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
576 ret
= rtl2830_rd_regs(priv
, 0x34e, buf
, 2);
580 *ber
= buf
[0] << 8 | buf
[1];
584 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
588 static int rtl2830_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
594 static int rtl2830_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
596 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
599 u16 if_agc_raw
, if_agc
;
604 ret
= rtl2830_rd_regs(priv
, 0x359, buf
, 2);
608 if_agc_raw
= (buf
[0] << 8 | buf
[1]) & 0x3fff;
610 if (if_agc_raw
& (1 << 9))
611 if_agc
= -(~(if_agc_raw
- 1) & 0x1ff);
615 *strength
= (u8
) (55 - if_agc
/ 182);
616 *strength
|= *strength
<< 8;
620 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
624 static struct dvb_frontend_ops rtl2830_ops
;
626 static u32
rtl2830_tuner_i2c_func(struct i2c_adapter
*adapter
)
631 static int rtl2830_tuner_i2c_xfer(struct i2c_adapter
*i2c_adap
,
632 struct i2c_msg msg
[], int num
)
634 struct rtl2830_priv
*priv
= i2c_get_adapdata(i2c_adap
);
638 ret
= rtl2830_wr_reg_mask(priv
, 0x101, 0x08, 0x08);
642 ret
= i2c_transfer(priv
->i2c
, msg
, num
);
644 dev_warn(&priv
->i2c
->dev
, "%s: tuner i2c failed=%d\n",
645 KBUILD_MODNAME
, ret
);
649 dev_dbg(&priv
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
653 static struct i2c_algorithm rtl2830_tuner_i2c_algo
= {
654 .master_xfer
= rtl2830_tuner_i2c_xfer
,
655 .functionality
= rtl2830_tuner_i2c_func
,
658 struct i2c_adapter
*rtl2830_get_tuner_i2c_adapter(struct dvb_frontend
*fe
)
660 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
661 return &priv
->tuner_i2c_adapter
;
663 EXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter
);
665 static void rtl2830_release(struct dvb_frontend
*fe
)
667 struct rtl2830_priv
*priv
= fe
->demodulator_priv
;
669 i2c_del_adapter(&priv
->tuner_i2c_adapter
);
673 struct dvb_frontend
*rtl2830_attach(const struct rtl2830_config
*cfg
,
674 struct i2c_adapter
*i2c
)
676 struct rtl2830_priv
*priv
= NULL
;
680 /* allocate memory for the internal state */
681 priv
= kzalloc(sizeof(struct rtl2830_priv
), GFP_KERNEL
);
687 memcpy(&priv
->cfg
, cfg
, sizeof(struct rtl2830_config
));
689 /* check if the demod is there */
690 ret
= rtl2830_rd_reg(priv
, 0x000, &tmp
);
694 /* create dvb_frontend */
695 memcpy(&priv
->fe
.ops
, &rtl2830_ops
, sizeof(struct dvb_frontend_ops
));
696 priv
->fe
.demodulator_priv
= priv
;
698 /* create tuner i2c adapter */
699 strlcpy(priv
->tuner_i2c_adapter
.name
, "RTL2830 tuner I2C adapter",
700 sizeof(priv
->tuner_i2c_adapter
.name
));
701 priv
->tuner_i2c_adapter
.algo
= &rtl2830_tuner_i2c_algo
;
702 priv
->tuner_i2c_adapter
.algo_data
= NULL
;
703 i2c_set_adapdata(&priv
->tuner_i2c_adapter
, priv
);
704 if (i2c_add_adapter(&priv
->tuner_i2c_adapter
) < 0) {
706 "%s: tuner i2c bus could not be initialized\n",
711 priv
->sleeping
= true;
715 dev_dbg(&i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
719 EXPORT_SYMBOL(rtl2830_attach
);
721 static struct dvb_frontend_ops rtl2830_ops
= {
722 .delsys
= { SYS_DVBT
},
724 .name
= "Realtek RTL2830 (DVB-T)",
725 .caps
= FE_CAN_FEC_1_2
|
735 FE_CAN_TRANSMISSION_MODE_AUTO
|
736 FE_CAN_GUARD_INTERVAL_AUTO
|
737 FE_CAN_HIERARCHY_AUTO
|
742 .release
= rtl2830_release
,
744 .init
= rtl2830_init
,
745 .sleep
= rtl2830_sleep
,
747 .get_tune_settings
= rtl2830_get_tune_settings
,
749 .set_frontend
= rtl2830_set_frontend
,
750 .get_frontend
= rtl2830_get_frontend
,
752 .read_status
= rtl2830_read_status
,
753 .read_snr
= rtl2830_read_snr
,
754 .read_ber
= rtl2830_read_ber
,
755 .read_ucblocks
= rtl2830_read_ucblocks
,
756 .read_signal_strength
= rtl2830_read_signal_strength
,
759 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
760 MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
761 MODULE_LICENSE("GPL");