1 /*
2  *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
3  *    ATBM8830, ATBM8831
4  *
5  *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
6  *
7  *    This program is free software; you can redistribute it and/or modify
8  *    it under the terms of the GNU General Public License as published by
9  *    the Free Software Foundation; either version 2 of the License, or
10  *    (at your option) any later version.
11  *
12  *    This program is distributed in the hope that it will be useful,
13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *    GNU General Public License for more details.
16  */
17 
18 #include <asm/div64.h>
19 #include <media/dvb_frontend.h>
20 
21 #include "atbm8830.h"
22 #include "atbm8830_priv.h"
23 
24 #define dprintk(args...) \
25 	do { \
26 		if (debug) \
27 			printk(KERN_DEBUG "atbm8830: " args); \
28 	} while (0)
29 
30 static int debug;
31 
32 module_param(debug, int, 0644);
33 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
34 
35 static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
36 {
37 	int ret = 0;
38 	u8 dev_addr;
39 	u8 buf1[] = { reg >> 8, reg & 0xFF };
40 	u8 buf2[] = { data };
41 	struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
42 	struct i2c_msg msg2 = { .flags = 0, .buf = buf2, .len = 1 };
43 
44 	dev_addr = priv->config->demod_address;
45 	msg1.addr = dev_addr;
46 	msg2.addr = dev_addr;
47 
48 	if (debug >= 2)
49 		dprintk("%s: reg=0x%04X, data=0x%02X\n", __func__, reg, data);
50 
51 	ret = i2c_transfer(priv->i2c, &msg1, 1);
52 	if (ret != 1)
53 		return -EIO;
54 
55 	ret = i2c_transfer(priv->i2c, &msg2, 1);
56 	return (ret != 1) ? -EIO : 0;
57 }
58 
59 static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
60 {
61 	int ret;
62 	u8 dev_addr;
63 
64 	u8 buf1[] = { reg >> 8, reg & 0xFF };
65 	u8 buf2[] = { 0 };
66 	struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
67 	struct i2c_msg msg2 = { .flags = I2C_M_RD, .buf = buf2, .len = 1 };
68 
69 	dev_addr = priv->config->demod_address;
70 	msg1.addr = dev_addr;
71 	msg2.addr = dev_addr;
72 
73 	ret = i2c_transfer(priv->i2c, &msg1, 1);
74 	if (ret != 1) {
75 		dprintk("%s: error reg=0x%04x, ret=%i\n", __func__, reg, ret);
76 		return -EIO;
77 	}
78 
79 	ret = i2c_transfer(priv->i2c, &msg2, 1);
80 	if (ret != 1)
81 		return -EIO;
82 
83 	*p_data = buf2[0];
84 	if (debug >= 2)
85 		dprintk("%s: reg=0x%04X, data=0x%02X\n",
86 			__func__, reg, buf2[0]);
87 
88 	return 0;
89 }
90 
91 /* Lock register latch so that multi-register read is atomic */
92 static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock)
93 {
94 	return atbm8830_write_reg(priv, REG_READ_LATCH, lock ? 1 : 0);
95 }
96 
97 static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
98 {
99 	u32 val;
100 	u64 t;
101 
102 	/* 0x100000 * freq / 30.4MHz */
103 	t = (u64)0x100000 * freq;
104 	do_div(t, 30400);
105 	val = t;
106 
107 	atbm8830_write_reg(priv, REG_OSC_CLK, val);
108 	atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8);
109 	atbm8830_write_reg(priv, REG_OSC_CLK + 2, val >> 16);
110 
111 	return 0;
112 }
113 
114 static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
115 {
116 
117 	u32 fs = priv->config->osc_clk_freq;
118 	u64 t;
119 	u32 val;
120 	u8 dat;
121 
122 	if (freq != 0) {
123 		/* 2 * PI * (freq - fs) / fs * (2 ^ 22) */
124 		t = (u64) 2 * 31416 * (freq - fs);
125 		t <<= 22;
126 		do_div(t, fs);
127 		do_div(t, 1000);
128 		val = t;
129 
130 		atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1);
131 		atbm8830_write_reg(priv, REG_IF_FREQ, val);
132 		atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8);
133 		atbm8830_write_reg(priv, REG_IF_FREQ+2, val >> 16);
134 
135 		atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
136 		dat &= 0xFC;
137 		atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
138 	} else {
139 		/* Zero IF */
140 		atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 0);
141 
142 		atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
143 		dat &= 0xFC;
144 		dat |= 0x02;
145 		atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
146 
147 		if (priv->config->zif_swap_iq)
148 			atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x03);
149 		else
150 			atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x01);
151 	}
152 
153 	return 0;
154 }
155 
156 static int is_locked(struct atbm_state *priv, u8 *locked)
157 {
158 	u8 status;
159 
160 	atbm8830_read_reg(priv, REG_LOCK_STATUS, &status);
161 
162 	if (locked != NULL)
163 		*locked = (status == 1);
164 	return 0;
165 }
166 
167 static int set_agc_config(struct atbm_state *priv,
168 	u8 min, u8 max, u8 hold_loop)
169 {
170 	/* no effect if both min and max are zero */
171 	if (!min && !max)
172 	    return 0;
173 
174 	atbm8830_write_reg(priv, REG_AGC_MIN, min);
175 	atbm8830_write_reg(priv, REG_AGC_MAX, max);
176 	atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop);
177 
178 	return 0;
179 }
180 
181 static int set_static_channel_mode(struct atbm_state *priv)
182 {
183 	int i;
184 
185 	for (i = 0; i < 5; i++)
186 		atbm8830_write_reg(priv, 0x099B + i, 0x08);
187 
188 	atbm8830_write_reg(priv, 0x095B, 0x7F);
189 	atbm8830_write_reg(priv, 0x09CB, 0x01);
190 	atbm8830_write_reg(priv, 0x09CC, 0x7F);
191 	atbm8830_write_reg(priv, 0x09CD, 0x7F);
192 	atbm8830_write_reg(priv, 0x0E01, 0x20);
193 
194 	/* For single carrier */
195 	atbm8830_write_reg(priv, 0x0B03, 0x0A);
196 	atbm8830_write_reg(priv, 0x0935, 0x10);
197 	atbm8830_write_reg(priv, 0x0936, 0x08);
198 	atbm8830_write_reg(priv, 0x093E, 0x08);
199 	atbm8830_write_reg(priv, 0x096E, 0x06);
200 
201 	/* frame_count_max0 */
202 	atbm8830_write_reg(priv, 0x0B09, 0x00);
203 	/* frame_count_max1 */
204 	atbm8830_write_reg(priv, 0x0B0A, 0x08);
205 
206 	return 0;
207 }
208 
209 static int set_ts_config(struct atbm_state *priv)
210 {
211 	const struct atbm8830_config *cfg = priv->config;
212 
213 	/*Set parallel/serial ts mode*/
214 	atbm8830_write_reg(priv, REG_TS_SERIAL, cfg->serial_ts ? 1 : 0);
215 	atbm8830_write_reg(priv, REG_TS_CLK_MODE, cfg->serial_ts ? 1 : 0);
216 	/*Set ts sampling edge*/
217 	atbm8830_write_reg(priv, REG_TS_SAMPLE_EDGE,
218 		cfg->ts_sampling_edge ? 1 : 0);
219 	/*Set ts clock freerun*/
220 	atbm8830_write_reg(priv, REG_TS_CLK_FREERUN,
221 		cfg->ts_clk_gated ? 0 : 1);
222 
223 	return 0;
224 }
225 
226 static int atbm8830_init(struct dvb_frontend *fe)
227 {
228 	struct atbm_state *priv = fe->demodulator_priv;
229 	const struct atbm8830_config *cfg = priv->config;
230 
231 	/*Set oscillator frequency*/
232 	set_osc_freq(priv, cfg->osc_clk_freq);
233 
234 	/*Set IF frequency*/
235 	set_if_freq(priv, cfg->if_freq);
236 
237 	/*Set AGC Config*/
238 	set_agc_config(priv, cfg->agc_min, cfg->agc_max,
239 		cfg->agc_hold_loop);
240 
241 	/*Set static channel mode*/
242 	set_static_channel_mode(priv);
243 
244 	set_ts_config(priv);
245 	/*Turn off DSP reset*/
246 	atbm8830_write_reg(priv, 0x000A, 0);
247 
248 	/*SW version test*/
249 	atbm8830_write_reg(priv, 0x020C, 11);
250 
251 	/* Run */
252 	atbm8830_write_reg(priv, REG_DEMOD_RUN, 1);
253 
254 	return 0;
255 }
256 
257 
258 static void atbm8830_release(struct dvb_frontend *fe)
259 {
260 	struct atbm_state *state = fe->demodulator_priv;
261 	dprintk("%s\n", __func__);
262 
263 	kfree(state);
264 }
265 
266 static int atbm8830_set_fe(struct dvb_frontend *fe)
267 {
268 	struct atbm_state *priv = fe->demodulator_priv;
269 	int i;
270 	u8 locked = 0;
271 	dprintk("%s\n", __func__);
272 
273 	/* set frequency */
274 	if (fe->ops.tuner_ops.set_params) {
275 		if (fe->ops.i2c_gate_ctrl)
276 			fe->ops.i2c_gate_ctrl(fe, 1);
277 		fe->ops.tuner_ops.set_params(fe);
278 		if (fe->ops.i2c_gate_ctrl)
279 			fe->ops.i2c_gate_ctrl(fe, 0);
280 	}
281 
282 	/* start auto lock */
283 	for (i = 0; i < 10; i++) {
284 		mdelay(100);
285 		dprintk("Try %d\n", i);
286 		is_locked(priv, &locked);
287 		if (locked != 0) {
288 			dprintk("ATBM8830 locked!\n");
289 			break;
290 		}
291 	}
292 
293 	return 0;
294 }
295 
296 static int atbm8830_get_fe(struct dvb_frontend *fe,
297 			   struct dtv_frontend_properties *c)
298 {
299 	dprintk("%s\n", __func__);
300 
301 	/* TODO: get real readings from device */
302 	/* inversion status */
303 	c->inversion = INVERSION_OFF;
304 
305 	/* bandwidth */
306 	c->bandwidth_hz = 8000000;
307 
308 	c->code_rate_HP = FEC_AUTO;
309 	c->code_rate_LP = FEC_AUTO;
310 
311 	c->modulation = QAM_AUTO;
312 
313 	/* transmission mode */
314 	c->transmission_mode = TRANSMISSION_MODE_AUTO;
315 
316 	/* guard interval */
317 	c->guard_interval = GUARD_INTERVAL_AUTO;
318 
319 	/* hierarchy */
320 	c->hierarchy = HIERARCHY_NONE;
321 
322 	return 0;
323 }
324 
325 static int atbm8830_get_tune_settings(struct dvb_frontend *fe,
326 	struct dvb_frontend_tune_settings *fesettings)
327 {
328 	fesettings->min_delay_ms = 0;
329 	fesettings->step_size = 0;
330 	fesettings->max_drift = 0;
331 	return 0;
332 }
333 
334 static int atbm8830_read_status(struct dvb_frontend *fe,
335 				enum fe_status *fe_status)
336 {
337 	struct atbm_state *priv = fe->demodulator_priv;
338 	u8 locked = 0;
339 	u8 agc_locked = 0;
340 
341 	dprintk("%s\n", __func__);
342 	*fe_status = 0;
343 
344 	is_locked(priv, &locked);
345 	if (locked) {
346 		*fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
347 			FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
348 	}
349 	dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
350 
351 	atbm8830_read_reg(priv, REG_AGC_LOCK, &agc_locked);
352 	dprintk("AGC Lock: %d\n", agc_locked);
353 
354 	return 0;
355 }
356 
357 static int atbm8830_read_ber(struct dvb_frontend *fe, u32 *ber)
358 {
359 	struct atbm_state *priv = fe->demodulator_priv;
360 	u32 frame_err;
361 	u8 t;
362 
363 	dprintk("%s\n", __func__);
364 
365 	atbm8830_reglatch_lock(priv, 1);
366 
367 	atbm8830_read_reg(priv, REG_FRAME_ERR_CNT + 1, &t);
368 	frame_err = t & 0x7F;
369 	frame_err <<= 8;
370 	atbm8830_read_reg(priv, REG_FRAME_ERR_CNT, &t);
371 	frame_err |= t;
372 
373 	atbm8830_reglatch_lock(priv, 0);
374 
375 	*ber = frame_err * 100 / 32767;
376 
377 	dprintk("%s: ber=0x%x\n", __func__, *ber);
378 	return 0;
379 }
380 
381 static int atbm8830_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
382 {
383 	struct atbm_state *priv = fe->demodulator_priv;
384 	u32 pwm;
385 	u8 t;
386 
387 	dprintk("%s\n", __func__);
388 	atbm8830_reglatch_lock(priv, 1);
389 
390 	atbm8830_read_reg(priv, REG_AGC_PWM_VAL + 1, &t);
391 	pwm = t & 0x03;
392 	pwm <<= 8;
393 	atbm8830_read_reg(priv, REG_AGC_PWM_VAL, &t);
394 	pwm |= t;
395 
396 	atbm8830_reglatch_lock(priv, 0);
397 
398 	dprintk("AGC PWM = 0x%02X\n", pwm);
399 	pwm = 0x400 - pwm;
400 
401 	*signal = pwm * 0x10000 / 0x400;
402 
403 	return 0;
404 }
405 
406 static int atbm8830_read_snr(struct dvb_frontend *fe, u16 *snr)
407 {
408 	dprintk("%s\n", __func__);
409 	*snr = 0;
410 	return 0;
411 }
412 
413 static int atbm8830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
414 {
415 	dprintk("%s\n", __func__);
416 	*ucblocks = 0;
417 	return 0;
418 }
419 
420 static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
421 {
422 	struct atbm_state *priv = fe->demodulator_priv;
423 
424 	return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0);
425 }
426 
427 static const struct dvb_frontend_ops atbm8830_ops = {
428 	.delsys = { SYS_DTMB },
429 	.info = {
430 		.name = "AltoBeam ATBM8830/8831 DMB-TH",
431 		.frequency_min_hz = 474 * MHz,
432 		.frequency_max_hz = 858 * MHz,
433 		.frequency_stepsize_hz = 10 * kHz,
434 		.caps =
435 			FE_CAN_FEC_AUTO |
436 			FE_CAN_QAM_AUTO |
437 			FE_CAN_TRANSMISSION_MODE_AUTO |
438 			FE_CAN_GUARD_INTERVAL_AUTO
439 	},
440 
441 	.release = atbm8830_release,
442 
443 	.init = atbm8830_init,
444 	.sleep = NULL,
445 	.write = NULL,
446 	.i2c_gate_ctrl = atbm8830_i2c_gate_ctrl,
447 
448 	.set_frontend = atbm8830_set_fe,
449 	.get_frontend = atbm8830_get_fe,
450 	.get_tune_settings = atbm8830_get_tune_settings,
451 
452 	.read_status = atbm8830_read_status,
453 	.read_ber = atbm8830_read_ber,
454 	.read_signal_strength = atbm8830_read_signal_strength,
455 	.read_snr = atbm8830_read_snr,
456 	.read_ucblocks = atbm8830_read_ucblocks,
457 };
458 
459 struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
460 	struct i2c_adapter *i2c)
461 {
462 	struct atbm_state *priv = NULL;
463 	u8 data = 0;
464 
465 	dprintk("%s()\n", __func__);
466 
467 	if (config == NULL || i2c == NULL)
468 		return NULL;
469 
470 	priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL);
471 	if (priv == NULL)
472 		goto error_out;
473 
474 	priv->config = config;
475 	priv->i2c = i2c;
476 
477 	/* check if the demod is there */
478 	if (atbm8830_read_reg(priv, REG_CHIP_ID, &data) != 0) {
479 		dprintk("%s atbm8830/8831 not found at i2c addr 0x%02X\n",
480 			__func__, priv->config->demod_address);
481 		goto error_out;
482 	}
483 	dprintk("atbm8830 chip id: 0x%02X\n", data);
484 
485 	memcpy(&priv->frontend.ops, &atbm8830_ops,
486 	       sizeof(struct dvb_frontend_ops));
487 	priv->frontend.demodulator_priv = priv;
488 
489 	atbm8830_init(&priv->frontend);
490 
491 	atbm8830_i2c_gate_ctrl(&priv->frontend, 1);
492 
493 	return &priv->frontend;
494 
495 error_out:
496 	dprintk("%s() error_out\n", __func__);
497 	kfree(priv);
498 	return NULL;
499 
500 }
501 EXPORT_SYMBOL(atbm8830_attach);
502 
503 MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver");
504 MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
505 MODULE_LICENSE("GPL");
506