• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Realtek RTL2830 DVB-T demodulator driver
3  *
4  * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
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 
22 /*
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.
26  */
27 
28 #include "rtl2830_priv.h"
29 
30 int rtl2830_debug;
31 module_param_named(debug, rtl2830_debug, int, 0644);
32 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
33 
34 /* write multiple hardware registers */
rtl2830_wr(struct rtl2830_priv * priv,u8 reg,u8 * val,int len)35 static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
36 {
37 	int ret;
38 	u8 buf[1+len];
39 	struct i2c_msg msg[1] = {
40 		{
41 			.addr = priv->cfg.i2c_addr,
42 			.flags = 0,
43 			.len = 1+len,
44 			.buf = buf,
45 		}
46 	};
47 
48 	buf[0] = reg;
49 	memcpy(&buf[1], val, len);
50 
51 	ret = i2c_transfer(priv->i2c, msg, 1);
52 	if (ret == 1) {
53 		ret = 0;
54 	} else {
55 		warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
56 		ret = -EREMOTEIO;
57 	}
58 	return ret;
59 }
60 
61 /* read multiple hardware registers */
rtl2830_rd(struct rtl2830_priv * priv,u8 reg,u8 * val,int len)62 static int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
63 {
64 	int ret;
65 	struct i2c_msg msg[2] = {
66 		{
67 			.addr = priv->cfg.i2c_addr,
68 			.flags = 0,
69 			.len = 1,
70 			.buf = &reg,
71 		}, {
72 			.addr = priv->cfg.i2c_addr,
73 			.flags = I2C_M_RD,
74 			.len = len,
75 			.buf = val,
76 		}
77 	};
78 
79 	ret = i2c_transfer(priv->i2c, msg, 2);
80 	if (ret == 2) {
81 		ret = 0;
82 	} else {
83 		warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
84 		ret = -EREMOTEIO;
85 	}
86 	return ret;
87 }
88 
89 /* write multiple registers */
rtl2830_wr_regs(struct rtl2830_priv * priv,u16 reg,u8 * val,int len)90 static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
91 {
92 	int ret;
93 	u8 reg2 = (reg >> 0) & 0xff;
94 	u8 page = (reg >> 8) & 0xff;
95 
96 	/* switch bank if needed */
97 	if (page != priv->page) {
98 		ret = rtl2830_wr(priv, 0x00, &page, 1);
99 		if (ret)
100 			return ret;
101 
102 		priv->page = page;
103 	}
104 
105 	return rtl2830_wr(priv, reg2, val, len);
106 }
107 
108 /* read multiple registers */
rtl2830_rd_regs(struct rtl2830_priv * priv,u16 reg,u8 * val,int len)109 static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
110 {
111 	int ret;
112 	u8 reg2 = (reg >> 0) & 0xff;
113 	u8 page = (reg >> 8) & 0xff;
114 
115 	/* switch bank if needed */
116 	if (page != priv->page) {
117 		ret = rtl2830_wr(priv, 0x00, &page, 1);
118 		if (ret)
119 			return ret;
120 
121 		priv->page = page;
122 	}
123 
124 	return rtl2830_rd(priv, reg2, val, len);
125 }
126 
127 #if 0 /* currently not used */
128 /* write single register */
129 static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val)
130 {
131 	return rtl2830_wr_regs(priv, reg, &val, 1);
132 }
133 #endif
134 
135 /* read single register */
rtl2830_rd_reg(struct rtl2830_priv * priv,u16 reg,u8 * val)136 static int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val)
137 {
138 	return rtl2830_rd_regs(priv, reg, val, 1);
139 }
140 
141 /* write single register with mask */
rtl2830_wr_reg_mask(struct rtl2830_priv * priv,u16 reg,u8 val,u8 mask)142 int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask)
143 {
144 	int ret;
145 	u8 tmp;
146 
147 	/* no need for read if whole reg is written */
148 	if (mask != 0xff) {
149 		ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
150 		if (ret)
151 			return ret;
152 
153 		val &= mask;
154 		tmp &= ~mask;
155 		val |= tmp;
156 	}
157 
158 	return rtl2830_wr_regs(priv, reg, &val, 1);
159 }
160 
161 /* read single register with mask */
rtl2830_rd_reg_mask(struct rtl2830_priv * priv,u16 reg,u8 * val,u8 mask)162 int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask)
163 {
164 	int ret, i;
165 	u8 tmp;
166 
167 	ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
168 	if (ret)
169 		return ret;
170 
171 	tmp &= mask;
172 
173 	/* find position of the first bit */
174 	for (i = 0; i < 8; i++) {
175 		if ((mask >> i) & 0x01)
176 			break;
177 	}
178 	*val = tmp >> i;
179 
180 	return 0;
181 }
182 
rtl2830_init(struct dvb_frontend * fe)183 static int rtl2830_init(struct dvb_frontend *fe)
184 {
185 	struct rtl2830_priv *priv = fe->demodulator_priv;
186 	int ret, i;
187 	u64 num;
188 	u8 buf[3], tmp;
189 	u32 if_ctl;
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 },
227 	};
228 
229 	for (i = 0; i < ARRAY_SIZE(tab); i++) {
230 		ret = rtl2830_wr_reg_mask(priv, tab[i].reg, tab[i].val,
231 			tab[i].mask);
232 		if (ret)
233 			goto err;
234 	}
235 
236 	ret = rtl2830_wr_regs(priv, 0x18f, "\x28\x00", 2);
237 	if (ret)
238 		goto err;
239 
240 	ret = rtl2830_wr_regs(priv, 0x195,
241 		"\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
242 	if (ret)
243 		goto err;
244 
245 	num = priv->cfg.if_dvbt % priv->cfg.xtal;
246 	num *= 0x400000;
247 	num = div_u64(num, priv->cfg.xtal);
248 	num = -num;
249 	if_ctl = num & 0x3fffff;
250 	dbg("%s: if_ctl=%08x", __func__, if_ctl);
251 
252 	ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */
253 	if (ret)
254 		goto err;
255 
256 	buf[0] = tmp << 6;
257 	buf[0] = (if_ctl >> 16) & 0x3f;
258 	buf[1] = (if_ctl >>  8) & 0xff;
259 	buf[2] = (if_ctl >>  0) & 0xff;
260 
261 	ret = rtl2830_wr_regs(priv, 0x119, buf, 3);
262 	if (ret)
263 		goto err;
264 
265 	/* TODO: spec init */
266 
267 	/* soft reset */
268 	ret = rtl2830_wr_reg_mask(priv, 0x101, 0x04, 0x04);
269 	if (ret)
270 		goto err;
271 
272 	ret = rtl2830_wr_reg_mask(priv, 0x101, 0x00, 0x04);
273 	if (ret)
274 		goto err;
275 
276 	priv->sleeping = false;
277 
278 	return ret;
279 err:
280 	dbg("%s: failed=%d", __func__, ret);
281 	return ret;
282 }
283 
rtl2830_sleep(struct dvb_frontend * fe)284 static int rtl2830_sleep(struct dvb_frontend *fe)
285 {
286 	struct rtl2830_priv *priv = fe->demodulator_priv;
287 	priv->sleeping = true;
288 	return 0;
289 }
290 
rtl2830_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * s)291 int rtl2830_get_tune_settings(struct dvb_frontend *fe,
292 	struct dvb_frontend_tune_settings *s)
293 {
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;
297 
298 	return 0;
299 }
300 
rtl2830_set_frontend(struct dvb_frontend * fe)301 static int rtl2830_set_frontend(struct dvb_frontend *fe)
302 {
303 	struct rtl2830_priv *priv = fe->demodulator_priv;
304 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
305 	int ret, i;
306 	static u8 bw_params1[3][34] = {
307 		{
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 */
312 		}, {
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 */
317 		}, {
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 */
322 		},
323 	};
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 */
328 	};
329 
330 
331 	dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
332 		c->frequency, c->bandwidth_hz, c->inversion);
333 
334 	/* program tuner */
335 	if (fe->ops.tuner_ops.set_params)
336 		fe->ops.tuner_ops.set_params(fe);
337 
338 	switch (c->bandwidth_hz) {
339 	case 6000000:
340 		i = 0;
341 		break;
342 	case 7000000:
343 		i = 1;
344 		break;
345 	case 8000000:
346 		i = 2;
347 		break;
348 	default:
349 		dbg("invalid bandwidth");
350 		return -EINVAL;
351 	}
352 
353 	ret = rtl2830_wr_reg_mask(priv, 0x008, i << 1, 0x06);
354 	if (ret)
355 		goto err;
356 
357 	/* 1/2 split I2C write */
358 	ret = rtl2830_wr_regs(priv, 0x11c, &bw_params1[i][0], 17);
359 	if (ret)
360 		goto err;
361 
362 	/* 2/2 split I2C write */
363 	ret = rtl2830_wr_regs(priv, 0x12d, &bw_params1[i][17], 17);
364 	if (ret)
365 		goto err;
366 
367 	ret = rtl2830_wr_regs(priv, 0x19d, bw_params2[i], 6);
368 	if (ret)
369 		goto err;
370 
371 	return ret;
372 err:
373 	dbg("%s: failed=%d", __func__, ret);
374 	return ret;
375 }
376 
rtl2830_read_status(struct dvb_frontend * fe,fe_status_t * status)377 static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status)
378 {
379 	struct rtl2830_priv *priv = fe->demodulator_priv;
380 	int ret;
381 	u8 tmp;
382 	*status = 0;
383 
384 	if (priv->sleeping)
385 		return 0;
386 
387 	ret = rtl2830_rd_reg_mask(priv, 0x351, &tmp, 0x78); /* [6:3] */
388 	if (ret)
389 		goto err;
390 
391 	if (tmp == 11) {
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 |
396 			FE_HAS_VITERBI;
397 	}
398 
399 	return ret;
400 err:
401 	dbg("%s: failed=%d", __func__, ret);
402 	return ret;
403 }
404 
rtl2830_read_snr(struct dvb_frontend * fe,u16 * snr)405 static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
406 {
407 	*snr = 0;
408 	return 0;
409 }
410 
rtl2830_read_ber(struct dvb_frontend * fe,u32 * ber)411 static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
412 {
413 	*ber = 0;
414 	return 0;
415 }
416 
rtl2830_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)417 static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
418 {
419 	*ucblocks = 0;
420 	return 0;
421 }
422 
rtl2830_read_signal_strength(struct dvb_frontend * fe,u16 * strength)423 static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
424 {
425 	*strength = 0;
426 	return 0;
427 }
428 
429 static struct dvb_frontend_ops rtl2830_ops;
430 
rtl2830_tuner_i2c_func(struct i2c_adapter * adapter)431 static u32 rtl2830_tuner_i2c_func(struct i2c_adapter *adapter)
432 {
433 	return I2C_FUNC_I2C;
434 }
435 
rtl2830_tuner_i2c_xfer(struct i2c_adapter * i2c_adap,struct i2c_msg msg[],int num)436 static int rtl2830_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
437 	struct i2c_msg msg[], int num)
438 {
439 	struct rtl2830_priv *priv = i2c_get_adapdata(i2c_adap);
440 	int ret;
441 
442 	/* open i2c-gate */
443 	ret = rtl2830_wr_reg_mask(priv, 0x101, 0x08, 0x08);
444 	if (ret)
445 		goto err;
446 
447 	ret = i2c_transfer(priv->i2c, msg, num);
448 	if (ret < 0)
449 		warn("tuner i2c failed=%d", ret);
450 
451 	return ret;
452 err:
453 	dbg("%s: failed=%d", __func__, ret);
454 	return ret;
455 }
456 
457 static struct i2c_algorithm rtl2830_tuner_i2c_algo = {
458 	.master_xfer   = rtl2830_tuner_i2c_xfer,
459 	.functionality = rtl2830_tuner_i2c_func,
460 };
461 
rtl2830_get_tuner_i2c_adapter(struct dvb_frontend * fe)462 struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(struct dvb_frontend *fe)
463 {
464 	struct rtl2830_priv *priv = fe->demodulator_priv;
465 	return &priv->tuner_i2c_adapter;
466 }
467 EXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter);
468 
rtl2830_release(struct dvb_frontend * fe)469 static void rtl2830_release(struct dvb_frontend *fe)
470 {
471 	struct rtl2830_priv *priv = fe->demodulator_priv;
472 
473 	i2c_del_adapter(&priv->tuner_i2c_adapter);
474 	kfree(priv);
475 }
476 
rtl2830_attach(const struct rtl2830_config * cfg,struct i2c_adapter * i2c)477 struct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg,
478 	struct i2c_adapter *i2c)
479 {
480 	struct rtl2830_priv *priv = NULL;
481 	int ret = 0;
482 	u8 tmp;
483 
484 	/* allocate memory for the internal state */
485 	priv = kzalloc(sizeof(struct rtl2830_priv), GFP_KERNEL);
486 	if (priv == NULL)
487 		goto err;
488 
489 	/* setup the priv */
490 	priv->i2c = i2c;
491 	memcpy(&priv->cfg, cfg, sizeof(struct rtl2830_config));
492 
493 	/* check if the demod is there */
494 	ret = rtl2830_rd_reg(priv, 0x000, &tmp);
495 	if (ret)
496 		goto err;
497 
498 	/* create dvb_frontend */
499 	memcpy(&priv->fe.ops, &rtl2830_ops, sizeof(struct dvb_frontend_ops));
500 	priv->fe.demodulator_priv = priv;
501 
502 	/* create tuner i2c adapter */
503 	strlcpy(priv->tuner_i2c_adapter.name, "RTL2830 tuner I2C adapter",
504 		sizeof(priv->tuner_i2c_adapter.name));
505 	priv->tuner_i2c_adapter.algo = &rtl2830_tuner_i2c_algo;
506 	priv->tuner_i2c_adapter.algo_data = NULL;
507 	i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
508 	if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
509 		err("tuner I2C bus could not be initialized");
510 		goto err;
511 	}
512 
513 	priv->sleeping = true;
514 
515 	return &priv->fe;
516 err:
517 	dbg("%s: failed=%d", __func__, ret);
518 	kfree(priv);
519 	return NULL;
520 }
521 EXPORT_SYMBOL(rtl2830_attach);
522 
523 static struct dvb_frontend_ops rtl2830_ops = {
524 	.delsys = { SYS_DVBT },
525 	.info = {
526 		.name = "Realtek RTL2830 (DVB-T)",
527 		.caps = FE_CAN_FEC_1_2 |
528 			FE_CAN_FEC_2_3 |
529 			FE_CAN_FEC_3_4 |
530 			FE_CAN_FEC_5_6 |
531 			FE_CAN_FEC_7_8 |
532 			FE_CAN_FEC_AUTO |
533 			FE_CAN_QPSK |
534 			FE_CAN_QAM_16 |
535 			FE_CAN_QAM_64 |
536 			FE_CAN_QAM_AUTO |
537 			FE_CAN_TRANSMISSION_MODE_AUTO |
538 			FE_CAN_GUARD_INTERVAL_AUTO |
539 			FE_CAN_HIERARCHY_AUTO |
540 			FE_CAN_RECOVER |
541 			FE_CAN_MUTE_TS
542 	},
543 
544 	.release = rtl2830_release,
545 
546 	.init = rtl2830_init,
547 	.sleep = rtl2830_sleep,
548 
549 	.get_tune_settings = rtl2830_get_tune_settings,
550 
551 	.set_frontend = rtl2830_set_frontend,
552 
553 	.read_status = rtl2830_read_status,
554 	.read_snr = rtl2830_read_snr,
555 	.read_ber = rtl2830_read_ber,
556 	.read_ucblocks = rtl2830_read_ucblocks,
557 	.read_signal_strength = rtl2830_read_signal_strength,
558 };
559 
560 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
561 MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
562 MODULE_LICENSE("GPL");
563