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