blob: 7403198eeb145066284c5d1053abc4dfb0c0624e [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
3 * DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
Paul Bolle395cf962011-08-15 02:02:26 +020020 * see Documentation/dvb/README.dvb-usb for more information
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 *
22 */
23
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <linux/init.h>
27#include <linux/delay.h>
Tim Schmielau4e57b682005-10-30 15:03:48 -080028#include <linux/string.h>
29#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Patrick Boettcher74340b02006-07-04 13:47:16 -030031#include "dvb_frontend.h"
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include "dib3000.h"
Patrick Boettcher74340b02006-07-04 13:47:16 -030034#include "dib3000mb_priv.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36/* Version information */
37#define DRIVER_VERSION "0.1"
38#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
39#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
40
Linus Torvalds1da177e2005-04-16 15:20:36 -070041static int debug;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
Christoph Egger9059cd42010-01-15 08:49:41 -030044
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#define deb_info(args...) dprintk(0x01,args)
Patrick Boettcher74340b02006-07-04 13:47:16 -030046#define deb_i2c(args...) dprintk(0x02,args)
47#define deb_srch(args...) dprintk(0x04,args)
48#define deb_info(args...) dprintk(0x01,args)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#define deb_xfer(args...) dprintk(0x02,args)
50#define deb_setf(args...) dprintk(0x04,args)
51#define deb_getf(args...) dprintk(0x08,args)
52
Patrick Boettcher74340b02006-07-04 13:47:16 -030053static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
54{
55 u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
56 u8 rb[2];
57 struct i2c_msg msg[] = {
58 { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
59 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
60 };
61
62 if (i2c_transfer(state->i2c, msg, 2) != 2)
63 deb_i2c("i2c read error\n");
64
65 deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
66 (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
67
68 return (rb[0] << 8) | rb[1];
69}
70
71static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
72{
73 u8 b[] = {
74 (reg >> 8) & 0xff, reg & 0xff,
75 (val >> 8) & 0xff, val & 0xff,
76 };
77 struct i2c_msg msg[] = {
78 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
79 };
80 deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
81
82 return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
83}
84
85static int dib3000_search_status(u16 irq,u16 lock)
86{
87 if (irq & 0x02) {
88 if (lock & 0x01) {
89 deb_srch("auto search succeeded\n");
90 return 1; // auto search succeeded
91 } else {
92 deb_srch("auto search not successful\n");
93 return 0; // auto search failed
94 }
95 } else if (irq & 0x01) {
96 deb_srch("auto search failed\n");
97 return 0; // auto search failed
98 }
99 return -1; // try again
100}
101
102/* for auto search */
103static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
104 { /* fft */
105 { /* gua */
106 { 0, 1 }, /* 0 0 { 0,1 } */
107 { 3, 9 }, /* 0 1 { 0,1 } */
108 },
109 {
110 { 2, 5 }, /* 1 0 { 0,1 } */
111 { 6, 11 }, /* 1 1 { 0,1 } */
112 }
113 };
114
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115static int dib3000mb_get_frontend(struct dvb_frontend* fe,
116 struct dvb_frontend_parameters *fep);
117
118static int dib3000mb_set_frontend(struct dvb_frontend* fe,
119 struct dvb_frontend_parameters *fep, int tuner)
120{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700121 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
123 fe_code_rate_t fe_cr = FEC_NONE;
124 int search_state, seq;
125
Patrick Boettcherdea74862006-05-14 05:01:31 -0300126 if (tuner && fe->ops.tuner_ops.set_params) {
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -0300127 fe->ops.tuner_ops.set_params(fe);
Patrick Boettcherdea74862006-05-14 05:01:31 -0300128 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
130 deb_setf("bandwidth: ");
131 switch (ofdm->bandwidth) {
132 case BANDWIDTH_8_MHZ:
133 deb_setf("8 MHz\n");
134 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
135 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
136 break;
137 case BANDWIDTH_7_MHZ:
138 deb_setf("7 MHz\n");
139 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]);
140 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz);
141 break;
142 case BANDWIDTH_6_MHZ:
143 deb_setf("6 MHz\n");
144 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]);
145 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz);
146 break;
147 case BANDWIDTH_AUTO:
148 return -EOPNOTSUPP;
149 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -0200150 err("unknown bandwidth value.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 return -EINVAL;
152 }
153 }
154 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
155
156 deb_setf("transmission mode: ");
157 switch (ofdm->transmission_mode) {
158 case TRANSMISSION_MODE_2K:
159 deb_setf("2k\n");
160 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K);
161 break;
162 case TRANSMISSION_MODE_8K:
163 deb_setf("8k\n");
164 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K);
165 break;
166 case TRANSMISSION_MODE_AUTO:
167 deb_setf("auto\n");
168 break;
169 default:
170 return -EINVAL;
171 }
172
173 deb_setf("guard: ");
174 switch (ofdm->guard_interval) {
175 case GUARD_INTERVAL_1_32:
176 deb_setf("1_32\n");
177 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32);
178 break;
179 case GUARD_INTERVAL_1_16:
180 deb_setf("1_16\n");
181 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16);
182 break;
183 case GUARD_INTERVAL_1_8:
184 deb_setf("1_8\n");
185 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8);
186 break;
187 case GUARD_INTERVAL_1_4:
188 deb_setf("1_4\n");
189 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4);
190 break;
191 case GUARD_INTERVAL_AUTO:
192 deb_setf("auto\n");
193 break;
194 default:
195 return -EINVAL;
196 }
197
198 deb_setf("inversion: ");
199 switch (fep->inversion) {
200 case INVERSION_OFF:
201 deb_setf("off\n");
202 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF);
203 break;
204 case INVERSION_AUTO:
205 deb_setf("auto ");
206 break;
207 case INVERSION_ON:
208 deb_setf("on\n");
209 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON);
210 break;
211 default:
212 return -EINVAL;
213 }
214
215 deb_setf("constellation: ");
216 switch (ofdm->constellation) {
217 case QPSK:
218 deb_setf("qpsk\n");
219 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK);
220 break;
221 case QAM_16:
222 deb_setf("qam16\n");
223 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM);
224 break;
225 case QAM_64:
226 deb_setf("qam64\n");
227 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM);
228 break;
229 case QAM_AUTO:
230 break;
231 default:
232 return -EINVAL;
233 }
Uwe Kleine-König1b3c3712007-02-17 19:23:03 +0100234 deb_setf("hierarchy: ");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 switch (ofdm->hierarchy_information) {
236 case HIERARCHY_NONE:
237 deb_setf("none ");
238 /* fall through */
239 case HIERARCHY_1:
240 deb_setf("alpha=1\n");
241 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1);
242 break;
243 case HIERARCHY_2:
244 deb_setf("alpha=2\n");
245 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2);
246 break;
247 case HIERARCHY_4:
248 deb_setf("alpha=4\n");
249 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4);
250 break;
251 case HIERARCHY_AUTO:
252 deb_setf("alpha=auto\n");
253 break;
254 default:
255 return -EINVAL;
256 }
257
258 deb_setf("hierarchy: ");
259 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
260 deb_setf("none\n");
261 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF);
262 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP);
263 fe_cr = ofdm->code_rate_HP;
264 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
265 deb_setf("on\n");
266 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON);
267 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP);
268 fe_cr = ofdm->code_rate_LP;
269 }
270 deb_setf("fec: ");
271 switch (fe_cr) {
272 case FEC_1_2:
273 deb_setf("1_2\n");
274 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2);
275 break;
276 case FEC_2_3:
277 deb_setf("2_3\n");
278 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3);
279 break;
280 case FEC_3_4:
281 deb_setf("3_4\n");
282 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4);
283 break;
284 case FEC_5_6:
285 deb_setf("5_6\n");
286 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6);
287 break;
288 case FEC_7_8:
289 deb_setf("7_8\n");
290 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8);
291 break;
292 case FEC_NONE:
293 deb_setf("none ");
294 break;
295 case FEC_AUTO:
296 deb_setf("auto\n");
297 break;
298 default:
299 return -EINVAL;
300 }
301
302 seq = dib3000_seq
303 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
304 [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
305 [fep->inversion == INVERSION_AUTO];
306
307 deb_setf("seq? %d\n", seq);
308
309 wr(DIB3000MB_REG_SEQ, seq);
310
311 wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
312
313 if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) {
314 if (ofdm->guard_interval == GUARD_INTERVAL_1_8) {
315 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8);
316 } else {
317 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT);
318 }
319
320 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K);
321 } else {
322 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT);
323 }
324
325 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF);
326 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
327 wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF);
328
329 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high);
330
331 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE);
332
333 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL);
334 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
335
336 /* wait for AGC lock */
337 msleep(70);
338
339 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
340
341 /* something has to be auto searched */
342 if (ofdm->constellation == QAM_AUTO ||
343 ofdm->hierarchy_information == HIERARCHY_AUTO ||
344 fe_cr == FEC_AUTO ||
345 fep->inversion == INVERSION_AUTO) {
346 int as_count=0;
347
348 deb_setf("autosearch enabled.\n");
349
350 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
351
352 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH);
353 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
354
355 while ((search_state =
356 dib3000_search_status(
357 rd(DIB3000MB_REG_AS_IRQ_PENDING),
358 rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100)
359 msleep(1);
360
361 deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count);
362
363 if (search_state == 1) {
364 struct dvb_frontend_parameters feps;
365 if (dib3000mb_get_frontend(fe, &feps) == 0) {
366 deb_setf("reading tuning data from frontend succeeded.\n");
367 return dib3000mb_set_frontend(fe, &feps, 0);
368 }
369 }
370
371 } else {
372 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL);
373 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
374 }
375
376 return 0;
377}
378
379static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
380{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700381 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383 deb_info("dib3000mb is getting up.\n");
384 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
385
386 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
387
388 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE);
389 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST);
390
391 wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT);
392
393 wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON);
394
395 wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB);
396 wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB);
397
398 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
399
400 wr_foreach(dib3000mb_reg_impulse_noise,
401 dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]);
402
403 wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain);
404
405 wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT);
406
407 wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase);
408
409 wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration);
410
411 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
412
413 wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT);
414 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
415 wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT);
416 wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]);
417
418 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
419
420 wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68);
421 wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69);
422 wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71);
423 wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77);
424 wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78);
425 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
426 wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92);
427 wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96);
428 wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97);
429 wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106);
430 wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107);
431 wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108);
432 wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122);
433 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
434 wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT);
435
436 wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs);
437
438 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON);
439 wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB);
440 wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB);
441
442 wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE);
443
444 wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142);
445 wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188);
446 wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE);
447 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
448 wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146);
449 wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147);
450
451 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
452
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 return 0;
454}
455
456static int dib3000mb_get_frontend(struct dvb_frontend* fe,
457 struct dvb_frontend_parameters *fep)
458{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700459 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
461 fe_code_rate_t *cr;
462 u16 tps_val;
463 int inv_test1,inv_test2;
464 u32 dds_val, threshold = 0x800000;
465
466 if (!rd(DIB3000MB_REG_TPS_LOCK))
467 return 0;
468
469 dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
470 deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
471 if (dds_val < threshold)
472 inv_test1 = 0;
473 else if (dds_val == threshold)
474 inv_test1 = 1;
475 else
476 inv_test1 = 2;
477
478 dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
479 deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
480 if (dds_val < threshold)
481 inv_test2 = 0;
482 else if (dds_val == threshold)
483 inv_test2 = 1;
484 else
485 inv_test2 = 2;
486
487 fep->inversion =
488 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
489 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
490 INVERSION_ON : INVERSION_OFF;
491
492 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
493
494 switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
495 case DIB3000_CONSTELLATION_QPSK:
496 deb_getf("QPSK ");
497 ofdm->constellation = QPSK;
498 break;
499 case DIB3000_CONSTELLATION_16QAM:
500 deb_getf("QAM16 ");
501 ofdm->constellation = QAM_16;
502 break;
503 case DIB3000_CONSTELLATION_64QAM:
504 deb_getf("QAM64 ");
505 ofdm->constellation = QAM_64;
506 break;
507 default:
508 err("Unexpected constellation returned by TPS (%d)", tps_val);
509 break;
510 }
511 deb_getf("TPS: %d\n", tps_val);
512
513 if (rd(DIB3000MB_REG_TPS_HRCH)) {
514 deb_getf("HRCH ON\n");
515 cr = &ofdm->code_rate_LP;
516 ofdm->code_rate_HP = FEC_NONE;
517 switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
518 case DIB3000_ALPHA_0:
519 deb_getf("HIERARCHY_NONE ");
520 ofdm->hierarchy_information = HIERARCHY_NONE;
521 break;
522 case DIB3000_ALPHA_1:
523 deb_getf("HIERARCHY_1 ");
524 ofdm->hierarchy_information = HIERARCHY_1;
525 break;
526 case DIB3000_ALPHA_2:
527 deb_getf("HIERARCHY_2 ");
528 ofdm->hierarchy_information = HIERARCHY_2;
529 break;
530 case DIB3000_ALPHA_4:
531 deb_getf("HIERARCHY_4 ");
532 ofdm->hierarchy_information = HIERARCHY_4;
533 break;
534 default:
535 err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
536 break;
537 }
538 deb_getf("TPS: %d\n", tps_val);
539
540 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
541 } else {
542 deb_getf("HRCH OFF\n");
543 cr = &ofdm->code_rate_HP;
544 ofdm->code_rate_LP = FEC_NONE;
545 ofdm->hierarchy_information = HIERARCHY_NONE;
546
547 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
548 }
549
550 switch (tps_val) {
551 case DIB3000_FEC_1_2:
552 deb_getf("FEC_1_2 ");
553 *cr = FEC_1_2;
554 break;
555 case DIB3000_FEC_2_3:
556 deb_getf("FEC_2_3 ");
557 *cr = FEC_2_3;
558 break;
559 case DIB3000_FEC_3_4:
560 deb_getf("FEC_3_4 ");
561 *cr = FEC_3_4;
562 break;
563 case DIB3000_FEC_5_6:
564 deb_getf("FEC_5_6 ");
565 *cr = FEC_4_5;
566 break;
567 case DIB3000_FEC_7_8:
568 deb_getf("FEC_7_8 ");
569 *cr = FEC_7_8;
570 break;
571 default:
572 err("Unexpected FEC returned by TPS (%d)", tps_val);
573 break;
574 }
575 deb_getf("TPS: %d\n",tps_val);
576
577 switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
578 case DIB3000_GUARD_TIME_1_32:
579 deb_getf("GUARD_INTERVAL_1_32 ");
580 ofdm->guard_interval = GUARD_INTERVAL_1_32;
581 break;
582 case DIB3000_GUARD_TIME_1_16:
583 deb_getf("GUARD_INTERVAL_1_16 ");
584 ofdm->guard_interval = GUARD_INTERVAL_1_16;
585 break;
586 case DIB3000_GUARD_TIME_1_8:
587 deb_getf("GUARD_INTERVAL_1_8 ");
588 ofdm->guard_interval = GUARD_INTERVAL_1_8;
589 break;
590 case DIB3000_GUARD_TIME_1_4:
591 deb_getf("GUARD_INTERVAL_1_4 ");
592 ofdm->guard_interval = GUARD_INTERVAL_1_4;
593 break;
594 default:
595 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
596 break;
597 }
598 deb_getf("TPS: %d\n", tps_val);
599
600 switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
601 case DIB3000_TRANSMISSION_MODE_2K:
602 deb_getf("TRANSMISSION_MODE_2K ");
603 ofdm->transmission_mode = TRANSMISSION_MODE_2K;
604 break;
605 case DIB3000_TRANSMISSION_MODE_8K:
606 deb_getf("TRANSMISSION_MODE_8K ");
607 ofdm->transmission_mode = TRANSMISSION_MODE_8K;
608 break;
609 default:
610 err("unexpected transmission mode return by TPS (%d)", tps_val);
611 break;
612 }
613 deb_getf("TPS: %d\n", tps_val);
614
615 return 0;
616}
617
618static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
619{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700620 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
622 *stat = 0;
623
624 if (rd(DIB3000MB_REG_AGC_LOCK))
625 *stat |= FE_HAS_SIGNAL;
626 if (rd(DIB3000MB_REG_CARRIER_LOCK))
627 *stat |= FE_HAS_CARRIER;
628 if (rd(DIB3000MB_REG_VIT_LCK))
629 *stat |= FE_HAS_VITERBI;
630 if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
631 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
632
633 deb_getf("actual status is %2x\n",*stat);
634
635 deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
636 rd(DIB3000MB_REG_TPS_LOCK),
637 rd(DIB3000MB_REG_TPS_QAM),
638 rd(DIB3000MB_REG_TPS_HRCH),
639 rd(DIB3000MB_REG_TPS_VIT_ALPHA),
640 rd(DIB3000MB_REG_TPS_CODE_RATE_HP),
641 rd(DIB3000MB_REG_TPS_CODE_RATE_LP),
642 rd(DIB3000MB_REG_TPS_GUARD_TIME),
643 rd(DIB3000MB_REG_TPS_FFT),
644 rd(DIB3000MB_REG_TPS_CELL_ID));
645
646 //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
647 return 0;
648}
649
650static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
651{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700652 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653
654 *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
655 return 0;
656}
657
658/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
659static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
660{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700661 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662
663 *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
664 return 0;
665}
666
667static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
668{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700669 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
671 int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
672 rd(DIB3000MB_REG_NOISE_POWER_LSB);
673 *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);
674 return 0;
675}
676
677static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
678{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700679 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680
Johannes Stezenbach776338e2005-06-23 22:02:35 -0700681 *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 return 0;
683}
684
685static int dib3000mb_sleep(struct dvb_frontend* fe)
686{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700687 struct dib3000_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 deb_info("dib3000mb is going to bed.\n");
689 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
690 return 0;
691}
692
693static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
694{
695 tune->min_delay_ms = 800;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 return 0;
697}
698
699static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe)
700{
701 return dib3000mb_fe_init(fe, 0);
702}
703
704static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
705{
706 return dib3000mb_set_frontend(fe, fep, 1);
707}
708
709static void dib3000mb_release(struct dvb_frontend* fe)
710{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700711 struct dib3000_state *state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 kfree(state);
713}
714
715/* pid filter and transfer stuff */
716static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
717{
718 struct dib3000_state *state = fe->demodulator_priv;
719 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
720 wr(index+DIB3000MB_REG_FIRST_PID,pid);
721 return 0;
722}
723
724static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
725{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700726 struct dib3000_state *state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727
728 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
729 if (onoff) {
730 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE);
731 } else {
732 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
733 }
734 return 0;
735}
736
737static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
738{
739 struct dib3000_state *state = fe->demodulator_priv;
740 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
741 wr(DIB3000MB_REG_PID_PARSE,onoff);
742 return 0;
743}
744
745static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
746{
Johannes Stezenbachb8742702005-05-16 21:54:31 -0700747 struct dib3000_state *state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 if (onoff) {
749 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
750 } else {
751 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
752 }
753 return 0;
754}
755
756static struct dvb_frontend_ops dib3000mb_ops;
757
758struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
759 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
760{
761 struct dib3000_state* state = NULL;
762
763 /* allocate memory for the internal state */
Panagiotis Issaris74081872006-01-11 19:40:56 -0200764 state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 if (state == NULL)
766 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767
768 /* setup the state */
769 state->i2c = i2c;
770 memcpy(&state->config,config,sizeof(struct dib3000_config));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771
772 /* check for the correct demod */
773 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
774 goto error;
775
776 if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
777 goto error;
778
779 /* create dvb_frontend */
Patrick Boettcherdea74862006-05-14 05:01:31 -0300780 memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 state->frontend.demodulator_priv = state;
782
783 /* set the xfer operations */
784 xfer_ops->pid_parse = dib3000mb_pid_parse;
785 xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
786 xfer_ops->pid_ctrl = dib3000mb_pid_control;
787 xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
788
789 return &state->frontend;
790
791error:
792 kfree(state);
793 return NULL;
794}
795
796static struct dvb_frontend_ops dib3000mb_ops = {
797
798 .info = {
799 .name = "DiBcom 3000M-B DVB-T",
800 .type = FE_OFDM,
801 .frequency_min = 44250000,
802 .frequency_max = 867250000,
803 .frequency_stepsize = 62500,
804 .caps = FE_CAN_INVERSION_AUTO |
805 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
806 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
807 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
808 FE_CAN_TRANSMISSION_MODE_AUTO |
809 FE_CAN_GUARD_INTERVAL_AUTO |
810 FE_CAN_RECOVER |
811 FE_CAN_HIERARCHY_AUTO,
812 },
813
814 .release = dib3000mb_release,
815
816 .init = dib3000mb_fe_init_nonmobile,
817 .sleep = dib3000mb_sleep,
818
819 .set_frontend = dib3000mb_set_frontend_and_tuner,
820 .get_frontend = dib3000mb_get_frontend,
821 .get_tune_settings = dib3000mb_fe_get_tune_settings,
822
823 .read_status = dib3000mb_read_status,
824 .read_ber = dib3000mb_read_ber,
825 .read_signal_strength = dib3000mb_read_signal_strength,
826 .read_snr = dib3000mb_read_snr,
827 .read_ucblocks = dib3000mb_read_unc_blocks,
828};
829
830MODULE_AUTHOR(DRIVER_AUTHOR);
831MODULE_DESCRIPTION(DRIVER_DESC);
832MODULE_LICENSE("GPL");
833
834EXPORT_SYMBOL(dib3000mb_attach);