• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/media/dvb/frontends/
1/*
2 * Driver for DiBcom DiB3000MC/P-demodulator.
3 *
4 * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * This code is partially based on the previous dib3000mc.c .
8 *
9 * This program is free software; you can redistribute it and/or
10 *	modify it under the terms of the GNU General Public License as
11 *	published by the Free Software Foundation, version 2.
12 */
13
14#include <linux/kernel.h>
15#include <linux/slab.h>
16#include <linux/i2c.h>
17
18#include "dvb_frontend.h"
19
20#include "dib3000mc.h"
21
22static int debug;
23module_param(debug, int, 0644);
24MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
25
26static int buggy_sfn_workaround;
27module_param(buggy_sfn_workaround, int, 0644);
28MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
29
30#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
31
32struct dib3000mc_state {
33	struct dvb_frontend demod;
34	struct dib3000mc_config *cfg;
35
36	u8 i2c_addr;
37	struct i2c_adapter *i2c_adap;
38
39	struct dibx000_i2c_master i2c_master;
40
41	u32 timf;
42
43	fe_bandwidth_t current_bandwidth;
44
45	u16 dev_id;
46
47	u8 sfn_workaround_active :1;
48};
49
50static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
51{
52	u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
53	u8 rb[2];
54	struct i2c_msg msg[2] = {
55		{ .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
56		{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
57	};
58
59	if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
60		dprintk("i2c read error on %d\n",reg);
61
62	return (rb[0] << 8) | rb[1];
63}
64
65static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
66{
67	u8 b[4] = {
68		(reg >> 8) & 0xff, reg & 0xff,
69		(val >> 8) & 0xff, val & 0xff,
70	};
71	struct i2c_msg msg = {
72		.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
73	};
74	return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
75}
76
77static int dib3000mc_identify(struct dib3000mc_state *state)
78{
79	u16 value;
80	if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
81		dprintk("-E-  DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
82		return -EREMOTEIO;
83	}
84
85	value = dib3000mc_read_word(state, 1026);
86	if (value != 0x3001 && value != 0x3002) {
87		dprintk("-E-  DiB3000MC/P: wrong Device ID (%x)\n",value);
88		return -EREMOTEIO;
89	}
90	state->dev_id = value;
91
92	dprintk("-I-  found DiB3000MC/P: %x\n",state->dev_id);
93
94	return 0;
95}
96
97static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
98{
99	u32 timf;
100
101	if (state->timf == 0) {
102		timf = 1384402; // default value for 8MHz
103		if (update_offset)
104			msleep(200); // first time we do an update
105	} else
106		timf = state->timf;
107
108	timf *= (bw / 1000);
109
110	if (update_offset) {
111		s16 tim_offs = dib3000mc_read_word(state, 416);
112
113		if (tim_offs &  0x2000)
114			tim_offs -= 0x4000;
115
116		if (nfft == TRANSMISSION_MODE_2K)
117			tim_offs *= 4;
118
119		timf += tim_offs;
120		state->timf = timf / (bw / 1000);
121	}
122
123	dprintk("timf: %d\n", timf);
124
125	dib3000mc_write_word(state, 23, (u16) (timf >> 16));
126	dib3000mc_write_word(state, 24, (u16) (timf      ) & 0xffff);
127
128	return 0;
129}
130
131static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
132{
133	u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
134    if (state->cfg->pwm3_inversion) {
135		reg_51 =  (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
136		reg_52 |= (1 << 2);
137	} else {
138		reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
139		reg_52 |= (1 << 8);
140	}
141	dib3000mc_write_word(state, 51, reg_51);
142	dib3000mc_write_word(state, 52, reg_52);
143
144    if (state->cfg->use_pwm3)
145		dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
146	else
147		dib3000mc_write_word(state, 245, 0);
148
149    dib3000mc_write_word(state, 1040, 0x3);
150	return 0;
151}
152
153static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
154{
155	int    ret = 0;
156	u16 fifo_threshold = 1792;
157	u16 outreg = 0;
158	u16 outmode = 0;
159	u16 elecout = 1;
160	u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
161
162	dprintk("-I-  Setting output mode for demod %p to %d\n",
163			&state->demod, mode);
164
165	switch (mode) {
166		case OUTMODE_HIGH_Z:  // disable
167			elecout = 0;
168			break;
169		case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
170			outmode = 0;
171			break;
172		case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
173			outmode = 1;
174			break;
175		case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
176			outmode = 2;
177			break;
178		case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
179			elecout = 3;
180			/*ADDR @ 206 :
181			P_smo_error_discard  [1;6:6] = 0
182			P_smo_rs_discard     [1;5:5] = 0
183			P_smo_pid_parse      [1;4:4] = 0
184			P_smo_fifo_flush     [1;3:3] = 0
185			P_smo_mode           [2;2:1] = 11
186			P_smo_ovf_prot       [1;0:0] = 0
187			*/
188			smo_reg |= 3 << 1;
189			fifo_threshold = 512;
190			outmode = 5;
191			break;
192		case OUTMODE_DIVERSITY:
193			outmode = 4;
194			elecout = 1;
195			break;
196		default:
197			dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
198			outmode = 0;
199			break;
200	}
201
202	if ((state->cfg->output_mpeg2_in_188_bytes))
203		smo_reg |= (1 << 5); // P_smo_rs_discard     [1;5:5] = 1
204
205	outreg = dib3000mc_read_word(state, 244) & 0x07FF;
206	outreg |= (outmode << 11);
207	ret |= dib3000mc_write_word(state,  244, outreg);
208	ret |= dib3000mc_write_word(state,  206, smo_reg);   /*smo_ mode*/
209	ret |= dib3000mc_write_word(state,  207, fifo_threshold); /* synchronous fread */
210	ret |= dib3000mc_write_word(state, 1040, elecout);         /* P_out_cfg */
211	return ret;
212}
213
214static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
215{
216	u16 bw_cfg[6] = { 0 };
217	u16 imp_bw_cfg[3] = { 0 };
218	u16 reg;
219
220/* settings here are for 27.7MHz */
221	switch (bw) {
222		case 8000:
223			bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
224			imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
225			break;
226
227		case 7000:
228			bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
229			imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
230			break;
231
232		case 6000:
233			bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
234			imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
235			break;
236
237		case 5000:
238			bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
239			imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
240			break;
241
242		default: return -EINVAL;
243	}
244
245	for (reg = 6; reg < 12; reg++)
246		dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
247	dib3000mc_write_word(state, 12, 0x0000);
248	dib3000mc_write_word(state, 13, 0x03e8);
249	dib3000mc_write_word(state, 14, 0x0000);
250	dib3000mc_write_word(state, 15, 0x03f2);
251	dib3000mc_write_word(state, 16, 0x0001);
252	dib3000mc_write_word(state, 17, 0xb0d0);
253	// P_sec_len
254	dib3000mc_write_word(state, 18, 0x0393);
255	dib3000mc_write_word(state, 19, 0x8700);
256
257	for (reg = 55; reg < 58; reg++)
258		dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
259
260	// Timing configuration
261	dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
262
263	return 0;
264}
265
266static u16 impulse_noise_val[29] =
267
268{
269	0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
270	0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
271	0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
272};
273
274static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
275{
276	u16 i;
277	for (i = 58; i < 87; i++)
278		dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
279
280	if (nfft == TRANSMISSION_MODE_8K) {
281		dib3000mc_write_word(state, 58, 0x3b);
282		dib3000mc_write_word(state, 84, 0x00);
283		dib3000mc_write_word(state, 85, 0x8200);
284	}
285
286	dib3000mc_write_word(state, 34, 0x1294);
287	dib3000mc_write_word(state, 35, 0x1ff8);
288	if (mode == 1)
289		dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
290}
291
292static int dib3000mc_init(struct dvb_frontend *demod)
293{
294	struct dib3000mc_state *state = demod->demodulator_priv;
295	struct dibx000_agc_config *agc = state->cfg->agc;
296
297	// Restart Configuration
298	dib3000mc_write_word(state, 1027, 0x8000);
299	dib3000mc_write_word(state, 1027, 0x0000);
300
301	// power up the demod + mobility configuration
302	dib3000mc_write_word(state, 140, 0x0000);
303	dib3000mc_write_word(state, 1031, 0);
304
305	if (state->cfg->mobile_mode) {
306		dib3000mc_write_word(state, 139,  0x0000);
307		dib3000mc_write_word(state, 141,  0x0000);
308		dib3000mc_write_word(state, 175,  0x0002);
309		dib3000mc_write_word(state, 1032, 0x0000);
310	} else {
311		dib3000mc_write_word(state, 139,  0x0001);
312		dib3000mc_write_word(state, 141,  0x0000);
313		dib3000mc_write_word(state, 175,  0x0000);
314		dib3000mc_write_word(state, 1032, 0x012C);
315	}
316	dib3000mc_write_word(state, 1033, 0x0000);
317
318	// P_clk_cfg
319	dib3000mc_write_word(state, 1037, 0x3130);
320
321	// other configurations
322
323	// P_ctrl_sfreq
324	dib3000mc_write_word(state, 33, (5 << 0));
325	dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
326
327	// Phase noise control
328	// P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
329	dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
330
331	if (state->cfg->phase_noise_mode == 0)
332		dib3000mc_write_word(state, 111, 0x00);
333	else
334		dib3000mc_write_word(state, 111, 0x02);
335
336	// P_agc_global
337	dib3000mc_write_word(state, 50, 0x8000);
338
339	// agc setup misc
340	dib3000mc_setup_pwm_state(state);
341
342	// P_agc_counter_lock
343	dib3000mc_write_word(state, 53, 0x87);
344	// P_agc_counter_unlock
345	dib3000mc_write_word(state, 54, 0x87);
346
347	/* agc */
348	dib3000mc_write_word(state, 36, state->cfg->max_time);
349	dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
350	dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
351	dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
352
353	// set_agc_loop_Bw
354	dib3000mc_write_word(state, 40, 0x0179);
355	dib3000mc_write_word(state, 41, 0x03f0);
356
357	dib3000mc_write_word(state, 42, agc->agc1_max);
358	dib3000mc_write_word(state, 43, agc->agc1_min);
359	dib3000mc_write_word(state, 44, agc->agc2_max);
360	dib3000mc_write_word(state, 45, agc->agc2_min);
361	dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
362	dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
363	dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
364	dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
365
366// Begin: TimeOut registers
367	// P_pha3_thres
368	dib3000mc_write_word(state, 110, 3277);
369	// P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
370	dib3000mc_write_word(state,  26, 0x6680);
371	// lock_mask0
372	dib3000mc_write_word(state, 1, 4);
373	// lock_mask1
374	dib3000mc_write_word(state, 2, 4);
375	// lock_mask2
376	dib3000mc_write_word(state, 3, 0x1000);
377	// P_search_maxtrial=1
378	dib3000mc_write_word(state, 5, 1);
379
380	dib3000mc_set_bandwidth(state, 8000);
381
382	// div_lock_mask
383	dib3000mc_write_word(state,  4, 0x814);
384
385	dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
386	dib3000mc_write_word(state, 22, 0x463d);
387
388	// Spurious rm cfg
389	// P_cspu_regul, P_cspu_win_cut
390	dib3000mc_write_word(state, 120, 0x200f);
391	// P_adp_selec_monit
392	dib3000mc_write_word(state, 134, 0);
393
394	// Fec cfg
395	dib3000mc_write_word(state, 195, 0x10);
396
397	// diversity register: P_dvsy_sync_wait..
398	dib3000mc_write_word(state, 180, 0x2FF0);
399
400	// Impulse noise configuration
401	dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
402
403	// output mode set-up
404	dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
405
406	/* close the i2c-gate */
407	dib3000mc_write_word(state, 769, (1 << 7) );
408
409	return 0;
410}
411
412static int dib3000mc_sleep(struct dvb_frontend *demod)
413{
414	struct dib3000mc_state *state = demod->demodulator_priv;
415
416	dib3000mc_write_word(state, 1031, 0xFFFF);
417	dib3000mc_write_word(state, 1032, 0xFFFF);
418	dib3000mc_write_word(state, 1033, 0xFFF0);
419
420    return 0;
421}
422
423static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
424{
425	u16 cfg[4] = { 0 },reg;
426	switch (qam) {
427		case QPSK:
428			cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
429			break;
430		case QAM_16:
431			cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
432			break;
433		case QAM_64:
434			cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
435			break;
436	}
437	for (reg = 129; reg < 133; reg++)
438		dib3000mc_write_word(state, reg, cfg[reg - 129]);
439}
440
441static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq)
442{
443	u16 value;
444    dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
445	dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0);
446
447//	if (boost)
448//		dib3000mc_write_word(state, 100, (11 << 6) + 6);
449//	else
450		dib3000mc_write_word(state, 100, (16 << 6) + 9);
451
452	dib3000mc_write_word(state, 1027, 0x0800);
453	dib3000mc_write_word(state, 1027, 0x0000);
454
455	//Default cfg isi offset adp
456	dib3000mc_write_word(state, 26,  0x6680);
457	dib3000mc_write_word(state, 29,  0x1273);
458	dib3000mc_write_word(state, 33,       5);
459	dib3000mc_set_adp_cfg(state, QAM_16);
460	dib3000mc_write_word(state, 133,  15564);
461
462	dib3000mc_write_word(state, 12 , 0x0);
463	dib3000mc_write_word(state, 13 , 0x3e8);
464	dib3000mc_write_word(state, 14 , 0x0);
465	dib3000mc_write_word(state, 15 , 0x3f2);
466
467	dib3000mc_write_word(state, 93,0);
468	dib3000mc_write_word(state, 94,0);
469	dib3000mc_write_word(state, 95,0);
470	dib3000mc_write_word(state, 96,0);
471	dib3000mc_write_word(state, 97,0);
472	dib3000mc_write_word(state, 98,0);
473
474	dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode);
475
476	value = 0;
477	switch (ch->u.ofdm.transmission_mode) {
478		case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
479		default:
480		case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
481	}
482	switch (ch->u.ofdm.guard_interval) {
483		case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
484		case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
485		case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
486		default:
487		case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
488	}
489	switch (ch->u.ofdm.constellation) {
490		case QPSK:  value |= (0 << 3); break;
491		case QAM_16: value |= (1 << 3); break;
492		default:
493		case QAM_64: value |= (2 << 3); break;
494	}
495	switch (HIERARCHY_1) {
496		case HIERARCHY_2: value |= 2; break;
497		case HIERARCHY_4: value |= 4; break;
498		default:
499		case HIERARCHY_1: value |= 1; break;
500	}
501	dib3000mc_write_word(state, 0, value);
502	dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
503
504	value = 0;
505	if (ch->u.ofdm.hierarchy_information == 1)
506		value |= (1 << 4);
507	if (1 == 1)
508		value |= 1;
509	switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
510		case FEC_2_3: value |= (2 << 1); break;
511		case FEC_3_4: value |= (3 << 1); break;
512		case FEC_5_6: value |= (5 << 1); break;
513		case FEC_7_8: value |= (7 << 1); break;
514		default:
515		case FEC_1_2: value |= (1 << 1); break;
516	}
517	dib3000mc_write_word(state, 181, value);
518
519	// diversity synchro delay add 50% SFN margin
520	switch (ch->u.ofdm.transmission_mode) {
521		case TRANSMISSION_MODE_8K: value = 256; break;
522		case TRANSMISSION_MODE_2K:
523		default: value = 64; break;
524	}
525	switch (ch->u.ofdm.guard_interval) {
526		case GUARD_INTERVAL_1_16: value *= 2; break;
527		case GUARD_INTERVAL_1_8:  value *= 4; break;
528		case GUARD_INTERVAL_1_4:  value *= 8; break;
529		default:
530		case GUARD_INTERVAL_1_32: value *= 1; break;
531	}
532	value <<= 4;
533	value |= dib3000mc_read_word(state, 180) & 0x000f;
534	dib3000mc_write_word(state, 180, value);
535
536	// restart demod
537	value = dib3000mc_read_word(state, 0);
538	dib3000mc_write_word(state, 0, value | (1 << 9));
539	dib3000mc_write_word(state, 0, value);
540
541	msleep(30);
542
543	dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode);
544}
545
546static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan)
547{
548	struct dib3000mc_state *state = demod->demodulator_priv;
549	u16 reg;
550//	u32 val;
551	struct dvb_frontend_parameters schan;
552
553	schan = *chan;
554
555	/* TODO what is that ? */
556
557	/* a channel for autosearch */
558	schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
559	schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
560	schan.u.ofdm.constellation = QAM_64;
561	schan.u.ofdm.code_rate_HP = FEC_2_3;
562	schan.u.ofdm.code_rate_LP = FEC_2_3;
563	schan.u.ofdm.hierarchy_information = 0;
564
565	dib3000mc_set_channel_cfg(state, &schan, 11);
566
567	reg = dib3000mc_read_word(state, 0);
568	dib3000mc_write_word(state, 0, reg | (1 << 8));
569	dib3000mc_read_word(state, 511);
570	dib3000mc_write_word(state, 0, reg);
571
572	return 0;
573}
574
575static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
576{
577	struct dib3000mc_state *state = demod->demodulator_priv;
578	u16 irq_pending = dib3000mc_read_word(state, 511);
579
580	if (irq_pending & 0x1) // failed
581		return 1;
582
583	if (irq_pending & 0x2) // succeeded
584		return 2;
585
586	return 0; // still pending
587}
588
589static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
590{
591	struct dib3000mc_state *state = demod->demodulator_priv;
592
593	// ** configure demod **
594	dib3000mc_set_channel_cfg(state, ch, 0);
595
596	// activates isi
597	if (state->sfn_workaround_active) {
598		dprintk("SFN workaround is active\n");
599		dib3000mc_write_word(state, 29, 0x1273);
600		dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
601	} else {
602		dib3000mc_write_word(state, 29, 0x1073);
603		dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
604	}
605
606	dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
607	if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
608		dib3000mc_write_word(state, 26, 38528);
609		dib3000mc_write_word(state, 33, 8);
610	} else {
611		dib3000mc_write_word(state, 26, 30336);
612		dib3000mc_write_word(state, 33, 6);
613	}
614
615	if (dib3000mc_read_word(state, 509) & 0x80)
616		dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1);
617
618	return 0;
619}
620
621struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
622{
623	struct dib3000mc_state *st = demod->demodulator_priv;
624	return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
625}
626
627EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
628
629static int dib3000mc_get_frontend(struct dvb_frontend* fe,
630				struct dvb_frontend_parameters *fep)
631{
632	struct dib3000mc_state *state = fe->demodulator_priv;
633	u16 tps = dib3000mc_read_word(state,458);
634
635	fep->inversion = INVERSION_AUTO;
636
637	fep->u.ofdm.bandwidth = state->current_bandwidth;
638
639	switch ((tps >> 8) & 0x1) {
640		case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
641		case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
642	}
643
644	switch (tps & 0x3) {
645		case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
646		case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
647		case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
648		case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
649	}
650
651	switch ((tps >> 13) & 0x3) {
652		case 0: fep->u.ofdm.constellation = QPSK; break;
653		case 1: fep->u.ofdm.constellation = QAM_16; break;
654		case 2:
655		default: fep->u.ofdm.constellation = QAM_64; break;
656	}
657
658	/* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
659	/* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
660
661	fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
662	switch ((tps >> 5) & 0x7) {
663		case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
664		case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
665		case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
666		case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
667		case 7:
668		default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
669
670	}
671
672	switch ((tps >> 2) & 0x7) {
673		case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
674		case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
675		case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
676		case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
677		case 7:
678		default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
679	}
680
681	return 0;
682}
683
684static int dib3000mc_set_frontend(struct dvb_frontend* fe,
685				struct dvb_frontend_parameters *fep)
686{
687	struct dib3000mc_state *state = fe->demodulator_priv;
688    int ret;
689
690	dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
691
692	state->current_bandwidth = fep->u.ofdm.bandwidth;
693	dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
694
695	/* maybe the parameter has been changed */
696	state->sfn_workaround_active = buggy_sfn_workaround;
697
698	if (fe->ops.tuner_ops.set_params) {
699		fe->ops.tuner_ops.set_params(fe, fep);
700		msleep(100);
701	}
702
703	if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
704		fep->u.ofdm.guard_interval    == GUARD_INTERVAL_AUTO ||
705		fep->u.ofdm.constellation     == QAM_AUTO ||
706		fep->u.ofdm.code_rate_HP      == FEC_AUTO) {
707		int i = 1000, found;
708
709		dib3000mc_autosearch_start(fe, fep);
710		do {
711			msleep(1);
712			found = dib3000mc_autosearch_is_irq(fe);
713		} while (found == 0 && i--);
714
715		dprintk("autosearch returns: %d\n",found);
716		if (found == 0 || found == 1)
717			return 0; // no channel found
718
719		dib3000mc_get_frontend(fe, fep);
720	}
721
722    ret = dib3000mc_tune(fe, fep);
723
724	/* make this a config parameter */
725	dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
726    return ret;
727}
728
729static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
730{
731	struct dib3000mc_state *state = fe->demodulator_priv;
732	u16 lock = dib3000mc_read_word(state, 509);
733
734	*stat = 0;
735
736	if (lock & 0x8000)
737		*stat |= FE_HAS_SIGNAL;
738	if (lock & 0x3000)
739		*stat |= FE_HAS_CARRIER;
740	if (lock & 0x0100)
741		*stat |= FE_HAS_VITERBI;
742	if (lock & 0x0010)
743		*stat |= FE_HAS_SYNC;
744	if (lock & 0x0008)
745		*stat |= FE_HAS_LOCK;
746
747	return 0;
748}
749
750static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
751{
752	struct dib3000mc_state *state = fe->demodulator_priv;
753	*ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
754	return 0;
755}
756
757static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
758{
759	struct dib3000mc_state *state = fe->demodulator_priv;
760	*unc = dib3000mc_read_word(state, 508);
761	return 0;
762}
763
764static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
765{
766	struct dib3000mc_state *state = fe->demodulator_priv;
767	u16 val = dib3000mc_read_word(state, 392);
768	*strength = 65535 - val;
769	return 0;
770}
771
772static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
773{
774	*snr = 0x0000;
775	return 0;
776}
777
778static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
779{
780	tune->min_delay_ms = 1000;
781	return 0;
782}
783
784static void dib3000mc_release(struct dvb_frontend *fe)
785{
786	struct dib3000mc_state *state = fe->demodulator_priv;
787	dibx000_exit_i2c_master(&state->i2c_master);
788	kfree(state);
789}
790
791int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
792{
793	struct dib3000mc_state *state = fe->demodulator_priv;
794	dib3000mc_write_word(state, 212 + index,  onoff ? (1 << 13) | pid : 0);
795	return 0;
796}
797EXPORT_SYMBOL(dib3000mc_pid_control);
798
799int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
800{
801	struct dib3000mc_state *state = fe->demodulator_priv;
802	u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
803	tmp |= (onoff << 4);
804	return dib3000mc_write_word(state, 206, tmp);
805}
806EXPORT_SYMBOL(dib3000mc_pid_parse);
807
808void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
809{
810	struct dib3000mc_state *state = fe->demodulator_priv;
811	state->cfg = cfg;
812}
813EXPORT_SYMBOL(dib3000mc_set_config);
814
815int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
816{
817	struct dib3000mc_state *dmcst;
818	int k;
819	u8 new_addr;
820
821	static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
822
823	dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
824	if (dmcst == NULL)
825		return -ENOMEM;
826
827	dmcst->i2c_adap = i2c;
828
829	for (k = no_of_demods-1; k >= 0; k--) {
830		dmcst->cfg = &cfg[k];
831
832		/* designated i2c address */
833		new_addr          = DIB3000MC_I2C_ADDRESS[k];
834		dmcst->i2c_addr = new_addr;
835		if (dib3000mc_identify(dmcst) != 0) {
836			dmcst->i2c_addr = default_addr;
837			if (dib3000mc_identify(dmcst) != 0) {
838				dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
839				kfree(dmcst);
840				return -ENODEV;
841			}
842		}
843
844		dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
845
846		// set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
847		dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
848		dmcst->i2c_addr = new_addr;
849	}
850
851	for (k = 0; k < no_of_demods; k++) {
852		dmcst->cfg = &cfg[k];
853		dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
854
855		dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
856
857		/* turn off data output */
858		dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
859	}
860
861	kfree(dmcst);
862	return 0;
863}
864EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
865
866static struct dvb_frontend_ops dib3000mc_ops;
867
868struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
869{
870	struct dvb_frontend *demod;
871	struct dib3000mc_state *st;
872	st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
873	if (st == NULL)
874		return NULL;
875
876	st->cfg = cfg;
877	st->i2c_adap = i2c_adap;
878	st->i2c_addr = i2c_addr;
879
880	demod                   = &st->demod;
881	demod->demodulator_priv = st;
882	memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
883
884	if (dib3000mc_identify(st) != 0)
885		goto error;
886
887	dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
888
889	dib3000mc_write_word(st, 1037, 0x3130);
890
891	return demod;
892
893error:
894	kfree(st);
895	return NULL;
896}
897EXPORT_SYMBOL(dib3000mc_attach);
898
899static struct dvb_frontend_ops dib3000mc_ops = {
900	.info = {
901		.name = "DiBcom 3000MC/P",
902		.type = FE_OFDM,
903		.frequency_min      = 44250000,
904		.frequency_max      = 867250000,
905		.frequency_stepsize = 62500,
906		.caps = FE_CAN_INVERSION_AUTO |
907			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
908			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
909			FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
910			FE_CAN_TRANSMISSION_MODE_AUTO |
911			FE_CAN_GUARD_INTERVAL_AUTO |
912			FE_CAN_RECOVER |
913			FE_CAN_HIERARCHY_AUTO,
914	},
915
916	.release              = dib3000mc_release,
917
918	.init                 = dib3000mc_init,
919	.sleep                = dib3000mc_sleep,
920
921	.set_frontend         = dib3000mc_set_frontend,
922	.get_tune_settings    = dib3000mc_fe_get_tune_settings,
923	.get_frontend         = dib3000mc_get_frontend,
924
925	.read_status          = dib3000mc_read_status,
926	.read_ber             = dib3000mc_read_ber,
927	.read_signal_strength = dib3000mc_read_signal_strength,
928	.read_snr             = dib3000mc_read_snr,
929	.read_ucblocks        = dib3000mc_read_unc_blocks,
930};
931
932MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
933MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
934MODULE_LICENSE("GPL");
935