diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/dvb/frontends/tda10086.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/media/dvb/frontends/tda10086.c')
-rw-r--r-- | drivers/media/dvb/frontends/tda10086.c | 775 |
1 files changed, 775 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c new file mode 100644 index 00000000000..f2c8faac6f3 --- /dev/null +++ b/drivers/media/dvb/frontends/tda10086.c | |||
@@ -0,0 +1,775 @@ | |||
1 | /* | ||
2 | Driver for Philips tda10086 DVBS Demodulator | ||
3 | |||
4 | (c) 2006 Andrew de Quincey | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | |||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | |||
21 | */ | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/jiffies.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #include "dvb_frontend.h" | ||
31 | #include "tda10086.h" | ||
32 | |||
33 | #define SACLK 96000000 | ||
34 | |||
35 | struct tda10086_state { | ||
36 | struct i2c_adapter* i2c; | ||
37 | const struct tda10086_config* config; | ||
38 | struct dvb_frontend frontend; | ||
39 | |||
40 | /* private demod data */ | ||
41 | u32 frequency; | ||
42 | u32 symbol_rate; | ||
43 | bool has_lock; | ||
44 | }; | ||
45 | |||
46 | static int debug; | ||
47 | #define dprintk(args...) \ | ||
48 | do { \ | ||
49 | if (debug) printk(KERN_DEBUG "tda10086: " args); \ | ||
50 | } while (0) | ||
51 | |||
52 | static int tda10086_write_byte(struct tda10086_state *state, int reg, int data) | ||
53 | { | ||
54 | int ret; | ||
55 | u8 b0[] = { reg, data }; | ||
56 | struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 }; | ||
57 | |||
58 | msg.addr = state->config->demod_address; | ||
59 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
60 | |||
61 | if (ret != 1) | ||
62 | dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", | ||
63 | __func__, reg, data, ret); | ||
64 | |||
65 | return (ret != 1) ? ret : 0; | ||
66 | } | ||
67 | |||
68 | static int tda10086_read_byte(struct tda10086_state *state, int reg) | ||
69 | { | ||
70 | int ret; | ||
71 | u8 b0[] = { reg }; | ||
72 | u8 b1[] = { 0 }; | ||
73 | struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, | ||
74 | { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; | ||
75 | |||
76 | msg[0].addr = state->config->demod_address; | ||
77 | msg[1].addr = state->config->demod_address; | ||
78 | ret = i2c_transfer(state->i2c, msg, 2); | ||
79 | |||
80 | if (ret != 2) { | ||
81 | dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, | ||
82 | ret); | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | return b1[0]; | ||
87 | } | ||
88 | |||
89 | static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data) | ||
90 | { | ||
91 | int val; | ||
92 | |||
93 | /* read a byte and check */ | ||
94 | val = tda10086_read_byte(state, reg); | ||
95 | if (val < 0) | ||
96 | return val; | ||
97 | |||
98 | /* mask if off */ | ||
99 | val = val & ~mask; | ||
100 | val |= data & 0xff; | ||
101 | |||
102 | /* write it out again */ | ||
103 | return tda10086_write_byte(state, reg, val); | ||
104 | } | ||
105 | |||
106 | static int tda10086_init(struct dvb_frontend* fe) | ||
107 | { | ||
108 | struct tda10086_state* state = fe->demodulator_priv; | ||
109 | u8 t22k_off = 0x80; | ||
110 | |||
111 | dprintk ("%s\n", __func__); | ||
112 | |||
113 | if (state->config->diseqc_tone) | ||
114 | t22k_off = 0; | ||
115 | /* reset */ | ||
116 | tda10086_write_byte(state, 0x00, 0x00); | ||
117 | msleep(10); | ||
118 | |||
119 | /* misc setup */ | ||
120 | tda10086_write_byte(state, 0x01, 0x94); | ||
121 | tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */ | ||
122 | tda10086_write_byte(state, 0x03, 0xe4); | ||
123 | tda10086_write_byte(state, 0x04, 0x43); | ||
124 | tda10086_write_byte(state, 0x0c, 0x0c); | ||
125 | tda10086_write_byte(state, 0x1b, 0xb0); /* noise threshold */ | ||
126 | tda10086_write_byte(state, 0x20, 0x89); /* misc */ | ||
127 | tda10086_write_byte(state, 0x30, 0x04); /* acquisition period length */ | ||
128 | tda10086_write_byte(state, 0x32, 0x00); /* irq off */ | ||
129 | tda10086_write_byte(state, 0x31, 0x56); /* setup AFC */ | ||
130 | |||
131 | /* setup PLL (this assumes SACLK = 96MHz) */ | ||
132 | tda10086_write_byte(state, 0x55, 0x2c); /* misc PLL setup */ | ||
133 | if (state->config->xtal_freq == TDA10086_XTAL_16M) { | ||
134 | tda10086_write_byte(state, 0x3a, 0x0b); /* M=12 */ | ||
135 | tda10086_write_byte(state, 0x3b, 0x01); /* P=2 */ | ||
136 | } else { | ||
137 | tda10086_write_byte(state, 0x3a, 0x17); /* M=24 */ | ||
138 | tda10086_write_byte(state, 0x3b, 0x00); /* P=1 */ | ||
139 | } | ||
140 | tda10086_write_mask(state, 0x55, 0x20, 0x00); /* powerup PLL */ | ||
141 | |||
142 | /* setup TS interface */ | ||
143 | tda10086_write_byte(state, 0x11, 0x81); | ||
144 | tda10086_write_byte(state, 0x12, 0x81); | ||
145 | tda10086_write_byte(state, 0x19, 0x40); /* parallel mode A + MSBFIRST */ | ||
146 | tda10086_write_byte(state, 0x56, 0x80); /* powerdown WPLL - unused in the mode we use */ | ||
147 | tda10086_write_byte(state, 0x57, 0x08); /* bypass WPLL - unused in the mode we use */ | ||
148 | tda10086_write_byte(state, 0x10, 0x2a); | ||
149 | |||
150 | /* setup ADC */ | ||
151 | tda10086_write_byte(state, 0x58, 0x61); /* ADC setup */ | ||
152 | tda10086_write_mask(state, 0x58, 0x01, 0x00); /* powerup ADC */ | ||
153 | |||
154 | /* setup AGC */ | ||
155 | tda10086_write_byte(state, 0x05, 0x0B); | ||
156 | tda10086_write_byte(state, 0x37, 0x63); | ||
157 | tda10086_write_byte(state, 0x3f, 0x0a); /* NOTE: flydvb varies it */ | ||
158 | tda10086_write_byte(state, 0x40, 0x64); | ||
159 | tda10086_write_byte(state, 0x41, 0x4f); | ||
160 | tda10086_write_byte(state, 0x42, 0x43); | ||
161 | |||
162 | /* setup viterbi */ | ||
163 | tda10086_write_byte(state, 0x1a, 0x11); /* VBER 10^6, DVB, QPSK */ | ||
164 | |||
165 | /* setup carrier recovery */ | ||
166 | tda10086_write_byte(state, 0x3d, 0x80); | ||
167 | |||
168 | /* setup SEC */ | ||
169 | tda10086_write_byte(state, 0x36, t22k_off); /* all SEC off, 22k tone */ | ||
170 | tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); | ||
171 | tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static void tda10086_diseqc_wait(struct tda10086_state *state) | ||
177 | { | ||
178 | unsigned long timeout = jiffies + msecs_to_jiffies(200); | ||
179 | while (!(tda10086_read_byte(state, 0x50) & 0x01)) { | ||
180 | if(time_after(jiffies, timeout)) { | ||
181 | printk("%s: diseqc queue not ready, command may be lost.\n", __func__); | ||
182 | break; | ||
183 | } | ||
184 | msleep(10); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
189 | { | ||
190 | struct tda10086_state* state = fe->demodulator_priv; | ||
191 | u8 t22k_off = 0x80; | ||
192 | |||
193 | dprintk ("%s\n", __func__); | ||
194 | |||
195 | if (state->config->diseqc_tone) | ||
196 | t22k_off = 0; | ||
197 | |||
198 | switch (tone) { | ||
199 | case SEC_TONE_OFF: | ||
200 | tda10086_write_byte(state, 0x36, t22k_off); | ||
201 | break; | ||
202 | |||
203 | case SEC_TONE_ON: | ||
204 | tda10086_write_byte(state, 0x36, 0x01 + t22k_off); | ||
205 | break; | ||
206 | } | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static int tda10086_send_master_cmd (struct dvb_frontend* fe, | ||
212 | struct dvb_diseqc_master_cmd* cmd) | ||
213 | { | ||
214 | struct tda10086_state* state = fe->demodulator_priv; | ||
215 | int i; | ||
216 | u8 oldval; | ||
217 | u8 t22k_off = 0x80; | ||
218 | |||
219 | dprintk ("%s\n", __func__); | ||
220 | |||
221 | if (state->config->diseqc_tone) | ||
222 | t22k_off = 0; | ||
223 | |||
224 | if (cmd->msg_len > 6) | ||
225 | return -EINVAL; | ||
226 | oldval = tda10086_read_byte(state, 0x36); | ||
227 | |||
228 | for(i=0; i< cmd->msg_len; i++) { | ||
229 | tda10086_write_byte(state, 0x48+i, cmd->msg[i]); | ||
230 | } | ||
231 | tda10086_write_byte(state, 0x36, (0x08 + t22k_off) | ||
232 | | ((cmd->msg_len - 1) << 4)); | ||
233 | |||
234 | tda10086_diseqc_wait(state); | ||
235 | |||
236 | tda10086_write_byte(state, 0x36, oldval); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) | ||
242 | { | ||
243 | struct tda10086_state* state = fe->demodulator_priv; | ||
244 | u8 oldval = tda10086_read_byte(state, 0x36); | ||
245 | u8 t22k_off = 0x80; | ||
246 | |||
247 | dprintk ("%s\n", __func__); | ||
248 | |||
249 | if (state->config->diseqc_tone) | ||
250 | t22k_off = 0; | ||
251 | |||
252 | switch(minicmd) { | ||
253 | case SEC_MINI_A: | ||
254 | tda10086_write_byte(state, 0x36, 0x04 + t22k_off); | ||
255 | break; | ||
256 | |||
257 | case SEC_MINI_B: | ||
258 | tda10086_write_byte(state, 0x36, 0x06 + t22k_off); | ||
259 | break; | ||
260 | } | ||
261 | |||
262 | tda10086_diseqc_wait(state); | ||
263 | |||
264 | tda10086_write_byte(state, 0x36, oldval); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static int tda10086_set_inversion(struct tda10086_state *state, | ||
270 | struct dvb_frontend_parameters *fe_params) | ||
271 | { | ||
272 | u8 invval = 0x80; | ||
273 | |||
274 | dprintk ("%s %i %i\n", __func__, fe_params->inversion, state->config->invert); | ||
275 | |||
276 | switch(fe_params->inversion) { | ||
277 | case INVERSION_OFF: | ||
278 | if (state->config->invert) | ||
279 | invval = 0x40; | ||
280 | break; | ||
281 | case INVERSION_ON: | ||
282 | if (!state->config->invert) | ||
283 | invval = 0x40; | ||
284 | break; | ||
285 | case INVERSION_AUTO: | ||
286 | invval = 0x00; | ||
287 | break; | ||
288 | } | ||
289 | tda10086_write_mask(state, 0x0c, 0xc0, invval); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static int tda10086_set_symbol_rate(struct tda10086_state *state, | ||
295 | struct dvb_frontend_parameters *fe_params) | ||
296 | { | ||
297 | u8 dfn = 0; | ||
298 | u8 afs = 0; | ||
299 | u8 byp = 0; | ||
300 | u8 reg37 = 0x43; | ||
301 | u8 reg42 = 0x43; | ||
302 | u64 big; | ||
303 | u32 tmp; | ||
304 | u32 bdr; | ||
305 | u32 bdri; | ||
306 | u32 symbol_rate = fe_params->u.qpsk.symbol_rate; | ||
307 | |||
308 | dprintk ("%s %i\n", __func__, symbol_rate); | ||
309 | |||
310 | /* setup the decimation and anti-aliasing filters.. */ | ||
311 | if (symbol_rate < (u32) (SACLK * 0.0137)) { | ||
312 | dfn=4; | ||
313 | afs=1; | ||
314 | } else if (symbol_rate < (u32) (SACLK * 0.0208)) { | ||
315 | dfn=4; | ||
316 | afs=0; | ||
317 | } else if (symbol_rate < (u32) (SACLK * 0.0270)) { | ||
318 | dfn=3; | ||
319 | afs=1; | ||
320 | } else if (symbol_rate < (u32) (SACLK * 0.0416)) { | ||
321 | dfn=3; | ||
322 | afs=0; | ||
323 | } else if (symbol_rate < (u32) (SACLK * 0.0550)) { | ||
324 | dfn=2; | ||
325 | afs=1; | ||
326 | } else if (symbol_rate < (u32) (SACLK * 0.0833)) { | ||
327 | dfn=2; | ||
328 | afs=0; | ||
329 | } else if (symbol_rate < (u32) (SACLK * 0.1100)) { | ||
330 | dfn=1; | ||
331 | afs=1; | ||
332 | } else if (symbol_rate < (u32) (SACLK * 0.1666)) { | ||
333 | dfn=1; | ||
334 | afs=0; | ||
335 | } else if (symbol_rate < (u32) (SACLK * 0.2200)) { | ||
336 | dfn=0; | ||
337 | afs=1; | ||
338 | } else if (symbol_rate < (u32) (SACLK * 0.3333)) { | ||
339 | dfn=0; | ||
340 | afs=0; | ||
341 | } else { | ||
342 | reg37 = 0x63; | ||
343 | reg42 = 0x4f; | ||
344 | byp=1; | ||
345 | } | ||
346 | |||
347 | /* calculate BDR */ | ||
348 | big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn); | ||
349 | big += ((SACLK/1000ULL)-1ULL); | ||
350 | do_div(big, (SACLK/1000ULL)); | ||
351 | bdr = big & 0xfffff; | ||
352 | |||
353 | /* calculate BDRI */ | ||
354 | tmp = (1<<dfn)*(symbol_rate/1000); | ||
355 | bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp; | ||
356 | |||
357 | tda10086_write_byte(state, 0x21, (afs << 7) | dfn); | ||
358 | tda10086_write_mask(state, 0x20, 0x08, byp << 3); | ||
359 | tda10086_write_byte(state, 0x06, bdr); | ||
360 | tda10086_write_byte(state, 0x07, bdr >> 8); | ||
361 | tda10086_write_byte(state, 0x08, bdr >> 16); | ||
362 | tda10086_write_byte(state, 0x09, bdri); | ||
363 | tda10086_write_byte(state, 0x37, reg37); | ||
364 | tda10086_write_byte(state, 0x42, reg42); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | static int tda10086_set_fec(struct tda10086_state *state, | ||
370 | struct dvb_frontend_parameters *fe_params) | ||
371 | { | ||
372 | u8 fecval; | ||
373 | |||
374 | dprintk ("%s %i\n", __func__, fe_params->u.qpsk.fec_inner); | ||
375 | |||
376 | switch(fe_params->u.qpsk.fec_inner) { | ||
377 | case FEC_1_2: | ||
378 | fecval = 0x00; | ||
379 | break; | ||
380 | case FEC_2_3: | ||
381 | fecval = 0x01; | ||
382 | break; | ||
383 | case FEC_3_4: | ||
384 | fecval = 0x02; | ||
385 | break; | ||
386 | case FEC_4_5: | ||
387 | fecval = 0x03; | ||
388 | break; | ||
389 | case FEC_5_6: | ||
390 | fecval = 0x04; | ||
391 | break; | ||
392 | case FEC_6_7: | ||
393 | fecval = 0x05; | ||
394 | break; | ||
395 | case FEC_7_8: | ||
396 | fecval = 0x06; | ||
397 | break; | ||
398 | case FEC_8_9: | ||
399 | fecval = 0x07; | ||
400 | break; | ||
401 | case FEC_AUTO: | ||
402 | fecval = 0x08; | ||
403 | break; | ||
404 | default: | ||
405 | return -1; | ||
406 | } | ||
407 | tda10086_write_byte(state, 0x0d, fecval); | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | static int tda10086_set_frontend(struct dvb_frontend* fe, | ||
413 | struct dvb_frontend_parameters *fe_params) | ||
414 | { | ||
415 | struct tda10086_state *state = fe->demodulator_priv; | ||
416 | int ret; | ||
417 | u32 freq = 0; | ||
418 | int freqoff; | ||
419 | |||
420 | dprintk ("%s\n", __func__); | ||
421 | |||
422 | /* modify parameters for tuning */ | ||
423 | tda10086_write_byte(state, 0x02, 0x35); | ||
424 | state->has_lock = false; | ||
425 | |||
426 | /* set params */ | ||
427 | if (fe->ops.tuner_ops.set_params) { | ||
428 | fe->ops.tuner_ops.set_params(fe, fe_params); | ||
429 | if (fe->ops.i2c_gate_ctrl) | ||
430 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
431 | |||
432 | if (fe->ops.tuner_ops.get_frequency) | ||
433 | fe->ops.tuner_ops.get_frequency(fe, &freq); | ||
434 | if (fe->ops.i2c_gate_ctrl) | ||
435 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
436 | } | ||
437 | |||
438 | /* calcluate the frequency offset (in *Hz* not kHz) */ | ||
439 | freqoff = fe_params->frequency - freq; | ||
440 | freqoff = ((1<<16) * freqoff) / (SACLK/1000); | ||
441 | tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f)); | ||
442 | tda10086_write_byte(state, 0x3e, freqoff); | ||
443 | |||
444 | if ((ret = tda10086_set_inversion(state, fe_params)) < 0) | ||
445 | return ret; | ||
446 | if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0) | ||
447 | return ret; | ||
448 | if ((ret = tda10086_set_fec(state, fe_params)) < 0) | ||
449 | return ret; | ||
450 | |||
451 | /* soft reset + disable TS output until lock */ | ||
452 | tda10086_write_mask(state, 0x10, 0x40, 0x40); | ||
453 | tda10086_write_mask(state, 0x00, 0x01, 0x00); | ||
454 | |||
455 | state->symbol_rate = fe_params->u.qpsk.symbol_rate; | ||
456 | state->frequency = fe_params->frequency; | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) | ||
461 | { | ||
462 | struct tda10086_state* state = fe->demodulator_priv; | ||
463 | u8 val; | ||
464 | int tmp; | ||
465 | u64 tmp64; | ||
466 | |||
467 | dprintk ("%s\n", __func__); | ||
468 | |||
469 | /* check for invalid symbol rate */ | ||
470 | if (fe_params->u.qpsk.symbol_rate < 500000) | ||
471 | return -EINVAL; | ||
472 | |||
473 | /* calculate the updated frequency (note: we convert from Hz->kHz) */ | ||
474 | tmp64 = tda10086_read_byte(state, 0x52); | ||
475 | tmp64 |= (tda10086_read_byte(state, 0x51) << 8); | ||
476 | if (tmp64 & 0x8000) | ||
477 | tmp64 |= 0xffffffffffff0000ULL; | ||
478 | tmp64 = (tmp64 * (SACLK/1000ULL)); | ||
479 | do_div(tmp64, (1ULL<<15) * (1ULL<<1)); | ||
480 | fe_params->frequency = (int) state->frequency + (int) tmp64; | ||
481 | |||
482 | /* the inversion */ | ||
483 | val = tda10086_read_byte(state, 0x0c); | ||
484 | if (val & 0x80) { | ||
485 | switch(val & 0x40) { | ||
486 | case 0x00: | ||
487 | fe_params->inversion = INVERSION_OFF; | ||
488 | if (state->config->invert) | ||
489 | fe_params->inversion = INVERSION_ON; | ||
490 | break; | ||
491 | default: | ||
492 | fe_params->inversion = INVERSION_ON; | ||
493 | if (state->config->invert) | ||
494 | fe_params->inversion = INVERSION_OFF; | ||
495 | break; | ||
496 | } | ||
497 | } else { | ||
498 | tda10086_read_byte(state, 0x0f); | ||
499 | switch(val & 0x02) { | ||
500 | case 0x00: | ||
501 | fe_params->inversion = INVERSION_OFF; | ||
502 | if (state->config->invert) | ||
503 | fe_params->inversion = INVERSION_ON; | ||
504 | break; | ||
505 | default: | ||
506 | fe_params->inversion = INVERSION_ON; | ||
507 | if (state->config->invert) | ||
508 | fe_params->inversion = INVERSION_OFF; | ||
509 | break; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | /* calculate the updated symbol rate */ | ||
514 | tmp = tda10086_read_byte(state, 0x1d); | ||
515 | if (tmp & 0x80) | ||
516 | tmp |= 0xffffff00; | ||
517 | tmp = (tmp * 480 * (1<<1)) / 128; | ||
518 | tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000); | ||
519 | fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp; | ||
520 | |||
521 | /* the FEC */ | ||
522 | val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4; | ||
523 | switch(val) { | ||
524 | case 0x00: | ||
525 | fe_params->u.qpsk.fec_inner = FEC_1_2; | ||
526 | break; | ||
527 | case 0x01: | ||
528 | fe_params->u.qpsk.fec_inner = FEC_2_3; | ||
529 | break; | ||
530 | case 0x02: | ||
531 | fe_params->u.qpsk.fec_inner = FEC_3_4; | ||
532 | break; | ||
533 | case 0x03: | ||
534 | fe_params->u.qpsk.fec_inner = FEC_4_5; | ||
535 | break; | ||
536 | case 0x04: | ||
537 | fe_params->u.qpsk.fec_inner = FEC_5_6; | ||
538 | break; | ||
539 | case 0x05: | ||
540 | fe_params->u.qpsk.fec_inner = FEC_6_7; | ||
541 | break; | ||
542 | case 0x06: | ||
543 | fe_params->u.qpsk.fec_inner = FEC_7_8; | ||
544 | break; | ||
545 | case 0x07: | ||
546 | fe_params->u.qpsk.fec_inner = FEC_8_9; | ||
547 | break; | ||
548 | } | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status) | ||
554 | { | ||
555 | struct tda10086_state* state = fe->demodulator_priv; | ||
556 | u8 val; | ||
557 | |||
558 | dprintk ("%s\n", __func__); | ||
559 | |||
560 | val = tda10086_read_byte(state, 0x0e); | ||
561 | *fe_status = 0; | ||
562 | if (val & 0x01) | ||
563 | *fe_status |= FE_HAS_SIGNAL; | ||
564 | if (val & 0x02) | ||
565 | *fe_status |= FE_HAS_CARRIER; | ||
566 | if (val & 0x04) | ||
567 | *fe_status |= FE_HAS_VITERBI; | ||
568 | if (val & 0x08) | ||
569 | *fe_status |= FE_HAS_SYNC; | ||
570 | if (val & 0x10) { | ||
571 | *fe_status |= FE_HAS_LOCK; | ||
572 | if (!state->has_lock) { | ||
573 | state->has_lock = true; | ||
574 | /* modify parameters for stable reception */ | ||
575 | tda10086_write_byte(state, 0x02, 0x00); | ||
576 | } | ||
577 | } | ||
578 | |||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal) | ||
583 | { | ||
584 | struct tda10086_state* state = fe->demodulator_priv; | ||
585 | u8 _str; | ||
586 | |||
587 | dprintk ("%s\n", __func__); | ||
588 | |||
589 | _str = 0xff - tda10086_read_byte(state, 0x43); | ||
590 | *signal = (_str << 8) | _str; | ||
591 | |||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr) | ||
596 | { | ||
597 | struct tda10086_state* state = fe->demodulator_priv; | ||
598 | u8 _snr; | ||
599 | |||
600 | dprintk ("%s\n", __func__); | ||
601 | |||
602 | _snr = 0xff - tda10086_read_byte(state, 0x1c); | ||
603 | *snr = (_snr << 8) | _snr; | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
609 | { | ||
610 | struct tda10086_state* state = fe->demodulator_priv; | ||
611 | |||
612 | dprintk ("%s\n", __func__); | ||
613 | |||
614 | /* read it */ | ||
615 | *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f; | ||
616 | |||
617 | /* reset counter */ | ||
618 | tda10086_write_byte(state, 0x18, 0x00); | ||
619 | tda10086_write_byte(state, 0x18, 0x80); | ||
620 | |||
621 | return 0; | ||
622 | } | ||
623 | |||
624 | static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber) | ||
625 | { | ||
626 | struct tda10086_state* state = fe->demodulator_priv; | ||
627 | |||
628 | dprintk ("%s\n", __func__); | ||
629 | |||
630 | /* read it */ | ||
631 | *ber = 0; | ||
632 | *ber |= tda10086_read_byte(state, 0x15); | ||
633 | *ber |= tda10086_read_byte(state, 0x16) << 8; | ||
634 | *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16; | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | static int tda10086_sleep(struct dvb_frontend* fe) | ||
640 | { | ||
641 | struct tda10086_state* state = fe->demodulator_priv; | ||
642 | |||
643 | dprintk ("%s\n", __func__); | ||
644 | |||
645 | tda10086_write_mask(state, 0x00, 0x08, 0x08); | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
651 | { | ||
652 | struct tda10086_state* state = fe->demodulator_priv; | ||
653 | |||
654 | dprintk ("%s\n", __func__); | ||
655 | |||
656 | if (enable) { | ||
657 | tda10086_write_mask(state, 0x00, 0x10, 0x10); | ||
658 | } else { | ||
659 | tda10086_write_mask(state, 0x00, 0x10, 0x00); | ||
660 | } | ||
661 | |||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | ||
666 | { | ||
667 | if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { | ||
668 | fesettings->min_delay_ms = 50; | ||
669 | fesettings->step_size = 2000; | ||
670 | fesettings->max_drift = 8000; | ||
671 | } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) { | ||
672 | fesettings->min_delay_ms = 100; | ||
673 | fesettings->step_size = 1500; | ||
674 | fesettings->max_drift = 9000; | ||
675 | } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) { | ||
676 | fesettings->min_delay_ms = 100; | ||
677 | fesettings->step_size = 1000; | ||
678 | fesettings->max_drift = 8000; | ||
679 | } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) { | ||
680 | fesettings->min_delay_ms = 100; | ||
681 | fesettings->step_size = 500; | ||
682 | fesettings->max_drift = 7000; | ||
683 | } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) { | ||
684 | fesettings->min_delay_ms = 200; | ||
685 | fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); | ||
686 | fesettings->max_drift = 14 * fesettings->step_size; | ||
687 | } else { | ||
688 | fesettings->min_delay_ms = 200; | ||
689 | fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); | ||
690 | fesettings->max_drift = 18 * fesettings->step_size; | ||
691 | } | ||
692 | |||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | static void tda10086_release(struct dvb_frontend* fe) | ||
697 | { | ||
698 | struct tda10086_state *state = fe->demodulator_priv; | ||
699 | tda10086_sleep(fe); | ||
700 | kfree(state); | ||
701 | } | ||
702 | |||
703 | static struct dvb_frontend_ops tda10086_ops = { | ||
704 | |||
705 | .info = { | ||
706 | .name = "Philips TDA10086 DVB-S", | ||
707 | .type = FE_QPSK, | ||
708 | .frequency_min = 950000, | ||
709 | .frequency_max = 2150000, | ||
710 | .frequency_stepsize = 125, /* kHz for QPSK frontends */ | ||
711 | .symbol_rate_min = 1000000, | ||
712 | .symbol_rate_max = 45000000, | ||
713 | .caps = FE_CAN_INVERSION_AUTO | | ||
714 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
715 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
716 | FE_CAN_QPSK | ||
717 | }, | ||
718 | |||
719 | .release = tda10086_release, | ||
720 | |||
721 | .init = tda10086_init, | ||
722 | .sleep = tda10086_sleep, | ||
723 | .i2c_gate_ctrl = tda10086_i2c_gate_ctrl, | ||
724 | |||
725 | .set_frontend = tda10086_set_frontend, | ||
726 | .get_frontend = tda10086_get_frontend, | ||
727 | .get_tune_settings = tda10086_get_tune_settings, | ||
728 | |||
729 | .read_status = tda10086_read_status, | ||
730 | .read_ber = tda10086_read_ber, | ||
731 | .read_signal_strength = tda10086_read_signal_strength, | ||
732 | .read_snr = tda10086_read_snr, | ||
733 | .read_ucblocks = tda10086_read_ucblocks, | ||
734 | |||
735 | .diseqc_send_master_cmd = tda10086_send_master_cmd, | ||
736 | .diseqc_send_burst = tda10086_send_burst, | ||
737 | .set_tone = tda10086_set_tone, | ||
738 | }; | ||
739 | |||
740 | struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, | ||
741 | struct i2c_adapter* i2c) | ||
742 | { | ||
743 | struct tda10086_state *state; | ||
744 | |||
745 | dprintk ("%s\n", __func__); | ||
746 | |||
747 | /* allocate memory for the internal state */ | ||
748 | state = kzalloc(sizeof(struct tda10086_state), GFP_KERNEL); | ||
749 | if (!state) | ||
750 | return NULL; | ||
751 | |||
752 | /* setup the state */ | ||
753 | state->config = config; | ||
754 | state->i2c = i2c; | ||
755 | |||
756 | /* check if the demod is there */ | ||
757 | if (tda10086_read_byte(state, 0x1e) != 0xe1) { | ||
758 | kfree(state); | ||
759 | return NULL; | ||
760 | } | ||
761 | |||
762 | /* create dvb_frontend */ | ||
763 | memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops)); | ||
764 | state->frontend.demodulator_priv = state; | ||
765 | return &state->frontend; | ||
766 | } | ||
767 | |||
768 | module_param(debug, int, 0644); | ||
769 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
770 | |||
771 | MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator"); | ||
772 | MODULE_AUTHOR("Andrew de Quincey"); | ||
773 | MODULE_LICENSE("GPL"); | ||
774 | |||
775 | EXPORT_SYMBOL(tda10086_attach); | ||