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