diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 22:13:41 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 22:13:41 -0400 |
commit | 9a0bf528b4d66b605f02634236da085595c22101 (patch) | |
tree | e9ff008ff15c3ee5add6d41173ee5e61939480dd /drivers/media/dvb/frontends/tda10071.c | |
parent | 3d6c2bc08ac4f75bf3597740357c98f2207ca412 (diff) |
[media] move the dvb/frontends to drivers/media/dvb-frontends
Raise the DVB frontends one level up, as the intention is to remove
the drivers/media/dvb directory.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends/tda10071.c')
-rw-r--r-- | drivers/media/dvb/frontends/tda10071.c | 1284 |
1 files changed, 0 insertions, 1284 deletions
diff --git a/drivers/media/dvb/frontends/tda10071.c b/drivers/media/dvb/frontends/tda10071.c deleted file mode 100644 index 703c3d05f9f4..000000000000 --- a/drivers/media/dvb/frontends/tda10071.c +++ /dev/null | |||
@@ -1,1284 +0,0 @@ | |||
1 | /* | ||
2 | * NXP TDA10071 + Conexant CX24118A DVB-S/S2 demodulator + tuner driver | ||
3 | * | ||
4 | * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> | ||
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 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include "tda10071_priv.h" | ||
22 | |||
23 | static struct dvb_frontend_ops tda10071_ops; | ||
24 | |||
25 | /* write multiple registers */ | ||
26 | static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val, | ||
27 | int len) | ||
28 | { | ||
29 | int ret; | ||
30 | u8 buf[len+1]; | ||
31 | struct i2c_msg msg[1] = { | ||
32 | { | ||
33 | .addr = priv->cfg.i2c_address, | ||
34 | .flags = 0, | ||
35 | .len = sizeof(buf), | ||
36 | .buf = buf, | ||
37 | } | ||
38 | }; | ||
39 | |||
40 | buf[0] = reg; | ||
41 | memcpy(&buf[1], val, len); | ||
42 | |||
43 | ret = i2c_transfer(priv->i2c, msg, 1); | ||
44 | if (ret == 1) { | ||
45 | ret = 0; | ||
46 | } else { | ||
47 | dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ | ||
48 | "len=%d\n", KBUILD_MODNAME, ret, reg, len); | ||
49 | ret = -EREMOTEIO; | ||
50 | } | ||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | /* read multiple registers */ | ||
55 | static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val, | ||
56 | int len) | ||
57 | { | ||
58 | int ret; | ||
59 | u8 buf[len]; | ||
60 | struct i2c_msg msg[2] = { | ||
61 | { | ||
62 | .addr = priv->cfg.i2c_address, | ||
63 | .flags = 0, | ||
64 | .len = 1, | ||
65 | .buf = ®, | ||
66 | }, { | ||
67 | .addr = priv->cfg.i2c_address, | ||
68 | .flags = I2C_M_RD, | ||
69 | .len = sizeof(buf), | ||
70 | .buf = buf, | ||
71 | } | ||
72 | }; | ||
73 | |||
74 | ret = i2c_transfer(priv->i2c, msg, 2); | ||
75 | if (ret == 2) { | ||
76 | memcpy(val, buf, len); | ||
77 | ret = 0; | ||
78 | } else { | ||
79 | dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ | ||
80 | "len=%d\n", KBUILD_MODNAME, ret, reg, len); | ||
81 | ret = -EREMOTEIO; | ||
82 | } | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | /* write single register */ | ||
87 | static int tda10071_wr_reg(struct tda10071_priv *priv, u8 reg, u8 val) | ||
88 | { | ||
89 | return tda10071_wr_regs(priv, reg, &val, 1); | ||
90 | } | ||
91 | |||
92 | /* read single register */ | ||
93 | static int tda10071_rd_reg(struct tda10071_priv *priv, u8 reg, u8 *val) | ||
94 | { | ||
95 | return tda10071_rd_regs(priv, reg, val, 1); | ||
96 | } | ||
97 | |||
98 | /* write single register with mask */ | ||
99 | int tda10071_wr_reg_mask(struct tda10071_priv *priv, u8 reg, u8 val, u8 mask) | ||
100 | { | ||
101 | int ret; | ||
102 | u8 tmp; | ||
103 | |||
104 | /* no need for read if whole reg is written */ | ||
105 | if (mask != 0xff) { | ||
106 | ret = tda10071_rd_regs(priv, reg, &tmp, 1); | ||
107 | if (ret) | ||
108 | return ret; | ||
109 | |||
110 | val &= mask; | ||
111 | tmp &= ~mask; | ||
112 | val |= tmp; | ||
113 | } | ||
114 | |||
115 | return tda10071_wr_regs(priv, reg, &val, 1); | ||
116 | } | ||
117 | |||
118 | /* read single register with mask */ | ||
119 | int tda10071_rd_reg_mask(struct tda10071_priv *priv, u8 reg, u8 *val, u8 mask) | ||
120 | { | ||
121 | int ret, i; | ||
122 | u8 tmp; | ||
123 | |||
124 | ret = tda10071_rd_regs(priv, reg, &tmp, 1); | ||
125 | if (ret) | ||
126 | return ret; | ||
127 | |||
128 | tmp &= mask; | ||
129 | |||
130 | /* find position of the first bit */ | ||
131 | for (i = 0; i < 8; i++) { | ||
132 | if ((mask >> i) & 0x01) | ||
133 | break; | ||
134 | } | ||
135 | *val = tmp >> i; | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | /* execute firmware command */ | ||
141 | static int tda10071_cmd_execute(struct tda10071_priv *priv, | ||
142 | struct tda10071_cmd *cmd) | ||
143 | { | ||
144 | int ret, i; | ||
145 | u8 tmp; | ||
146 | |||
147 | if (!priv->warm) { | ||
148 | ret = -EFAULT; | ||
149 | goto error; | ||
150 | } | ||
151 | |||
152 | /* write cmd and args for firmware */ | ||
153 | ret = tda10071_wr_regs(priv, 0x00, cmd->args, cmd->len); | ||
154 | if (ret) | ||
155 | goto error; | ||
156 | |||
157 | /* start cmd execution */ | ||
158 | ret = tda10071_wr_reg(priv, 0x1f, 1); | ||
159 | if (ret) | ||
160 | goto error; | ||
161 | |||
162 | /* wait cmd execution terminate */ | ||
163 | for (i = 1000, tmp = 1; i && tmp; i--) { | ||
164 | ret = tda10071_rd_reg(priv, 0x1f, &tmp); | ||
165 | if (ret) | ||
166 | goto error; | ||
167 | |||
168 | usleep_range(200, 5000); | ||
169 | } | ||
170 | |||
171 | dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); | ||
172 | |||
173 | if (i == 0) { | ||
174 | ret = -ETIMEDOUT; | ||
175 | goto error; | ||
176 | } | ||
177 | |||
178 | return ret; | ||
179 | error: | ||
180 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | static int tda10071_set_tone(struct dvb_frontend *fe, | ||
185 | fe_sec_tone_mode_t fe_sec_tone_mode) | ||
186 | { | ||
187 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
188 | struct tda10071_cmd cmd; | ||
189 | int ret; | ||
190 | u8 tone; | ||
191 | |||
192 | if (!priv->warm) { | ||
193 | ret = -EFAULT; | ||
194 | goto error; | ||
195 | } | ||
196 | |||
197 | dev_dbg(&priv->i2c->dev, "%s: tone_mode=%d\n", __func__, | ||
198 | fe_sec_tone_mode); | ||
199 | |||
200 | switch (fe_sec_tone_mode) { | ||
201 | case SEC_TONE_ON: | ||
202 | tone = 1; | ||
203 | break; | ||
204 | case SEC_TONE_OFF: | ||
205 | tone = 0; | ||
206 | break; | ||
207 | default: | ||
208 | dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_tone_mode\n", | ||
209 | __func__); | ||
210 | ret = -EINVAL; | ||
211 | goto error; | ||
212 | } | ||
213 | |||
214 | cmd.args[0] = CMD_LNB_PCB_CONFIG; | ||
215 | cmd.args[1] = 0; | ||
216 | cmd.args[2] = 0x00; | ||
217 | cmd.args[3] = 0x00; | ||
218 | cmd.args[4] = tone; | ||
219 | cmd.len = 5; | ||
220 | ret = tda10071_cmd_execute(priv, &cmd); | ||
221 | if (ret) | ||
222 | goto error; | ||
223 | |||
224 | return ret; | ||
225 | error: | ||
226 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static int tda10071_set_voltage(struct dvb_frontend *fe, | ||
231 | fe_sec_voltage_t fe_sec_voltage) | ||
232 | { | ||
233 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
234 | struct tda10071_cmd cmd; | ||
235 | int ret; | ||
236 | u8 voltage; | ||
237 | |||
238 | if (!priv->warm) { | ||
239 | ret = -EFAULT; | ||
240 | goto error; | ||
241 | } | ||
242 | |||
243 | dev_dbg(&priv->i2c->dev, "%s: voltage=%d\n", __func__, fe_sec_voltage); | ||
244 | |||
245 | switch (fe_sec_voltage) { | ||
246 | case SEC_VOLTAGE_13: | ||
247 | voltage = 0; | ||
248 | break; | ||
249 | case SEC_VOLTAGE_18: | ||
250 | voltage = 1; | ||
251 | break; | ||
252 | case SEC_VOLTAGE_OFF: | ||
253 | voltage = 0; | ||
254 | break; | ||
255 | default: | ||
256 | dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n", | ||
257 | __func__); | ||
258 | ret = -EINVAL; | ||
259 | goto error; | ||
260 | }; | ||
261 | |||
262 | cmd.args[0] = CMD_LNB_SET_DC_LEVEL; | ||
263 | cmd.args[1] = 0; | ||
264 | cmd.args[2] = voltage; | ||
265 | cmd.len = 3; | ||
266 | ret = tda10071_cmd_execute(priv, &cmd); | ||
267 | if (ret) | ||
268 | goto error; | ||
269 | |||
270 | return ret; | ||
271 | error: | ||
272 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
273 | return ret; | ||
274 | } | ||
275 | |||
276 | static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe, | ||
277 | struct dvb_diseqc_master_cmd *diseqc_cmd) | ||
278 | { | ||
279 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
280 | struct tda10071_cmd cmd; | ||
281 | int ret, i; | ||
282 | u8 tmp; | ||
283 | |||
284 | if (!priv->warm) { | ||
285 | ret = -EFAULT; | ||
286 | goto error; | ||
287 | } | ||
288 | |||
289 | dev_dbg(&priv->i2c->dev, "%s: msg_len=%d\n", __func__, | ||
290 | diseqc_cmd->msg_len); | ||
291 | |||
292 | if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) { | ||
293 | ret = -EINVAL; | ||
294 | goto error; | ||
295 | } | ||
296 | |||
297 | /* wait LNB TX */ | ||
298 | for (i = 500, tmp = 0; i && !tmp; i--) { | ||
299 | ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x01); | ||
300 | if (ret) | ||
301 | goto error; | ||
302 | |||
303 | usleep_range(10000, 20000); | ||
304 | } | ||
305 | |||
306 | dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); | ||
307 | |||
308 | if (i == 0) { | ||
309 | ret = -ETIMEDOUT; | ||
310 | goto error; | ||
311 | } | ||
312 | |||
313 | ret = tda10071_wr_reg_mask(priv, 0x47, 0x00, 0x01); | ||
314 | if (ret) | ||
315 | goto error; | ||
316 | |||
317 | cmd.args[0] = CMD_LNB_SEND_DISEQC; | ||
318 | cmd.args[1] = 0; | ||
319 | cmd.args[2] = 0; | ||
320 | cmd.args[3] = 0; | ||
321 | cmd.args[4] = 2; | ||
322 | cmd.args[5] = 0; | ||
323 | cmd.args[6] = diseqc_cmd->msg_len; | ||
324 | memcpy(&cmd.args[7], diseqc_cmd->msg, diseqc_cmd->msg_len); | ||
325 | cmd.len = 7 + diseqc_cmd->msg_len; | ||
326 | ret = tda10071_cmd_execute(priv, &cmd); | ||
327 | if (ret) | ||
328 | goto error; | ||
329 | |||
330 | return ret; | ||
331 | error: | ||
332 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
333 | return ret; | ||
334 | } | ||
335 | |||
336 | static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe, | ||
337 | struct dvb_diseqc_slave_reply *reply) | ||
338 | { | ||
339 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
340 | struct tda10071_cmd cmd; | ||
341 | int ret, i; | ||
342 | u8 tmp; | ||
343 | |||
344 | if (!priv->warm) { | ||
345 | ret = -EFAULT; | ||
346 | goto error; | ||
347 | } | ||
348 | |||
349 | dev_dbg(&priv->i2c->dev, "%s:\n", __func__); | ||
350 | |||
351 | /* wait LNB RX */ | ||
352 | for (i = 500, tmp = 0; i && !tmp; i--) { | ||
353 | ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x02); | ||
354 | if (ret) | ||
355 | goto error; | ||
356 | |||
357 | usleep_range(10000, 20000); | ||
358 | } | ||
359 | |||
360 | dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); | ||
361 | |||
362 | if (i == 0) { | ||
363 | ret = -ETIMEDOUT; | ||
364 | goto error; | ||
365 | } | ||
366 | |||
367 | /* reply len */ | ||
368 | ret = tda10071_rd_reg(priv, 0x46, &tmp); | ||
369 | if (ret) | ||
370 | goto error; | ||
371 | |||
372 | reply->msg_len = tmp & 0x1f; /* [4:0] */; | ||
373 | if (reply->msg_len > sizeof(reply->msg)) | ||
374 | reply->msg_len = sizeof(reply->msg); /* truncate API max */ | ||
375 | |||
376 | /* read reply */ | ||
377 | cmd.args[0] = CMD_LNB_UPDATE_REPLY; | ||
378 | cmd.args[1] = 0; | ||
379 | cmd.len = 2; | ||
380 | ret = tda10071_cmd_execute(priv, &cmd); | ||
381 | if (ret) | ||
382 | goto error; | ||
383 | |||
384 | ret = tda10071_rd_regs(priv, cmd.len, reply->msg, reply->msg_len); | ||
385 | if (ret) | ||
386 | goto error; | ||
387 | |||
388 | return ret; | ||
389 | error: | ||
390 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
391 | return ret; | ||
392 | } | ||
393 | |||
394 | static int tda10071_diseqc_send_burst(struct dvb_frontend *fe, | ||
395 | fe_sec_mini_cmd_t fe_sec_mini_cmd) | ||
396 | { | ||
397 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
398 | struct tda10071_cmd cmd; | ||
399 | int ret, i; | ||
400 | u8 tmp, burst; | ||
401 | |||
402 | if (!priv->warm) { | ||
403 | ret = -EFAULT; | ||
404 | goto error; | ||
405 | } | ||
406 | |||
407 | dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__, | ||
408 | fe_sec_mini_cmd); | ||
409 | |||
410 | switch (fe_sec_mini_cmd) { | ||
411 | case SEC_MINI_A: | ||
412 | burst = 0; | ||
413 | break; | ||
414 | case SEC_MINI_B: | ||
415 | burst = 1; | ||
416 | break; | ||
417 | default: | ||
418 | dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_mini_cmd\n", | ||
419 | __func__); | ||
420 | ret = -EINVAL; | ||
421 | goto error; | ||
422 | } | ||
423 | |||
424 | /* wait LNB TX */ | ||
425 | for (i = 500, tmp = 0; i && !tmp; i--) { | ||
426 | ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x01); | ||
427 | if (ret) | ||
428 | goto error; | ||
429 | |||
430 | usleep_range(10000, 20000); | ||
431 | } | ||
432 | |||
433 | dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); | ||
434 | |||
435 | if (i == 0) { | ||
436 | ret = -ETIMEDOUT; | ||
437 | goto error; | ||
438 | } | ||
439 | |||
440 | ret = tda10071_wr_reg_mask(priv, 0x47, 0x00, 0x01); | ||
441 | if (ret) | ||
442 | goto error; | ||
443 | |||
444 | cmd.args[0] = CMD_LNB_SEND_TONEBURST; | ||
445 | cmd.args[1] = 0; | ||
446 | cmd.args[2] = burst; | ||
447 | cmd.len = 3; | ||
448 | ret = tda10071_cmd_execute(priv, &cmd); | ||
449 | if (ret) | ||
450 | goto error; | ||
451 | |||
452 | return ret; | ||
453 | error: | ||
454 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
455 | return ret; | ||
456 | } | ||
457 | |||
458 | static int tda10071_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
459 | { | ||
460 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
461 | int ret; | ||
462 | u8 tmp; | ||
463 | |||
464 | *status = 0; | ||
465 | |||
466 | if (!priv->warm) { | ||
467 | ret = 0; | ||
468 | goto error; | ||
469 | } | ||
470 | |||
471 | ret = tda10071_rd_reg(priv, 0x39, &tmp); | ||
472 | if (ret) | ||
473 | goto error; | ||
474 | |||
475 | if (tmp & 0x01) /* tuner PLL */ | ||
476 | *status |= FE_HAS_SIGNAL; | ||
477 | if (tmp & 0x02) /* demod PLL */ | ||
478 | *status |= FE_HAS_CARRIER; | ||
479 | if (tmp & 0x04) /* viterbi or LDPC*/ | ||
480 | *status |= FE_HAS_VITERBI; | ||
481 | if (tmp & 0x08) /* RS or BCH */ | ||
482 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; | ||
483 | |||
484 | priv->fe_status = *status; | ||
485 | |||
486 | return ret; | ||
487 | error: | ||
488 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
489 | return ret; | ||
490 | } | ||
491 | |||
492 | static int tda10071_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
493 | { | ||
494 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
495 | int ret; | ||
496 | u8 buf[2]; | ||
497 | |||
498 | if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) { | ||
499 | *snr = 0; | ||
500 | ret = 0; | ||
501 | goto error; | ||
502 | } | ||
503 | |||
504 | ret = tda10071_rd_regs(priv, 0x3a, buf, 2); | ||
505 | if (ret) | ||
506 | goto error; | ||
507 | |||
508 | /* Es/No dBx10 */ | ||
509 | *snr = buf[0] << 8 | buf[1]; | ||
510 | |||
511 | return ret; | ||
512 | error: | ||
513 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | static int tda10071_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||
518 | { | ||
519 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
520 | struct tda10071_cmd cmd; | ||
521 | int ret; | ||
522 | u8 tmp; | ||
523 | |||
524 | if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) { | ||
525 | *strength = 0; | ||
526 | ret = 0; | ||
527 | goto error; | ||
528 | } | ||
529 | |||
530 | cmd.args[0] = CMD_GET_AGCACC; | ||
531 | cmd.args[1] = 0; | ||
532 | cmd.len = 2; | ||
533 | ret = tda10071_cmd_execute(priv, &cmd); | ||
534 | if (ret) | ||
535 | goto error; | ||
536 | |||
537 | /* input power estimate dBm */ | ||
538 | ret = tda10071_rd_reg(priv, 0x50, &tmp); | ||
539 | if (ret) | ||
540 | goto error; | ||
541 | |||
542 | if (tmp < 181) | ||
543 | tmp = 181; /* -75 dBm */ | ||
544 | else if (tmp > 236) | ||
545 | tmp = 236; /* -20 dBm */ | ||
546 | |||
547 | /* scale value to 0x0000-0xffff */ | ||
548 | *strength = (tmp-181) * 0xffff / (236-181); | ||
549 | |||
550 | return ret; | ||
551 | error: | ||
552 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | static int tda10071_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
557 | { | ||
558 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
559 | struct tda10071_cmd cmd; | ||
560 | int ret, i, len; | ||
561 | u8 tmp, reg, buf[8]; | ||
562 | |||
563 | if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) { | ||
564 | *ber = priv->ber = 0; | ||
565 | ret = 0; | ||
566 | goto error; | ||
567 | } | ||
568 | |||
569 | switch (priv->delivery_system) { | ||
570 | case SYS_DVBS: | ||
571 | reg = 0x4c; | ||
572 | len = 8; | ||
573 | i = 1; | ||
574 | break; | ||
575 | case SYS_DVBS2: | ||
576 | reg = 0x4d; | ||
577 | len = 4; | ||
578 | i = 0; | ||
579 | break; | ||
580 | default: | ||
581 | *ber = priv->ber = 0; | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | ret = tda10071_rd_reg(priv, reg, &tmp); | ||
586 | if (ret) | ||
587 | goto error; | ||
588 | |||
589 | if (priv->meas_count[i] == tmp) { | ||
590 | dev_dbg(&priv->i2c->dev, "%s: meas not ready=%02x\n", __func__, | ||
591 | tmp); | ||
592 | *ber = priv->ber; | ||
593 | return 0; | ||
594 | } else { | ||
595 | priv->meas_count[i] = tmp; | ||
596 | } | ||
597 | |||
598 | cmd.args[0] = CMD_BER_UPDATE_COUNTERS; | ||
599 | cmd.args[1] = 0; | ||
600 | cmd.args[2] = i; | ||
601 | cmd.len = 3; | ||
602 | ret = tda10071_cmd_execute(priv, &cmd); | ||
603 | if (ret) | ||
604 | goto error; | ||
605 | |||
606 | ret = tda10071_rd_regs(priv, cmd.len, buf, len); | ||
607 | if (ret) | ||
608 | goto error; | ||
609 | |||
610 | if (priv->delivery_system == SYS_DVBS) { | ||
611 | *ber = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | ||
612 | priv->ucb += (buf[4] << 8) | buf[5]; | ||
613 | } else { | ||
614 | *ber = (buf[0] << 8) | buf[1]; | ||
615 | } | ||
616 | priv->ber = *ber; | ||
617 | |||
618 | return ret; | ||
619 | error: | ||
620 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
621 | return ret; | ||
622 | } | ||
623 | |||
624 | static int tda10071_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
625 | { | ||
626 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
627 | int ret = 0; | ||
628 | |||
629 | if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) { | ||
630 | *ucblocks = 0; | ||
631 | goto error; | ||
632 | } | ||
633 | |||
634 | /* UCB is updated when BER is read. Assume BER is read anyway. */ | ||
635 | |||
636 | *ucblocks = priv->ucb; | ||
637 | |||
638 | return ret; | ||
639 | error: | ||
640 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
641 | return ret; | ||
642 | } | ||
643 | |||
644 | static int tda10071_set_frontend(struct dvb_frontend *fe) | ||
645 | { | ||
646 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
647 | struct tda10071_cmd cmd; | ||
648 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
649 | int ret, i; | ||
650 | u8 mode, rolloff, pilot, inversion, div; | ||
651 | |||
652 | dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \ | ||
653 | "frequency=%d symbol_rate=%d inversion=%d pilot=%d " \ | ||
654 | "rolloff=%d\n", __func__, c->delivery_system, c->modulation, | ||
655 | c->frequency, c->symbol_rate, c->inversion, c->pilot, | ||
656 | c->rolloff); | ||
657 | |||
658 | priv->delivery_system = SYS_UNDEFINED; | ||
659 | |||
660 | if (!priv->warm) { | ||
661 | ret = -EFAULT; | ||
662 | goto error; | ||
663 | } | ||
664 | |||
665 | switch (c->inversion) { | ||
666 | case INVERSION_OFF: | ||
667 | inversion = 1; | ||
668 | break; | ||
669 | case INVERSION_ON: | ||
670 | inversion = 0; | ||
671 | break; | ||
672 | case INVERSION_AUTO: | ||
673 | /* 2 = auto; try first on then off | ||
674 | * 3 = auto; try first off then on */ | ||
675 | inversion = 3; | ||
676 | break; | ||
677 | default: | ||
678 | dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n", __func__); | ||
679 | ret = -EINVAL; | ||
680 | goto error; | ||
681 | } | ||
682 | |||
683 | switch (c->delivery_system) { | ||
684 | case SYS_DVBS: | ||
685 | rolloff = 0; | ||
686 | pilot = 2; | ||
687 | break; | ||
688 | case SYS_DVBS2: | ||
689 | switch (c->rolloff) { | ||
690 | case ROLLOFF_20: | ||
691 | rolloff = 2; | ||
692 | break; | ||
693 | case ROLLOFF_25: | ||
694 | rolloff = 1; | ||
695 | break; | ||
696 | case ROLLOFF_35: | ||
697 | rolloff = 0; | ||
698 | break; | ||
699 | case ROLLOFF_AUTO: | ||
700 | default: | ||
701 | dev_dbg(&priv->i2c->dev, "%s: invalid rolloff\n", | ||
702 | __func__); | ||
703 | ret = -EINVAL; | ||
704 | goto error; | ||
705 | } | ||
706 | |||
707 | switch (c->pilot) { | ||
708 | case PILOT_OFF: | ||
709 | pilot = 0; | ||
710 | break; | ||
711 | case PILOT_ON: | ||
712 | pilot = 1; | ||
713 | break; | ||
714 | case PILOT_AUTO: | ||
715 | pilot = 2; | ||
716 | break; | ||
717 | default: | ||
718 | dev_dbg(&priv->i2c->dev, "%s: invalid pilot\n", | ||
719 | __func__); | ||
720 | ret = -EINVAL; | ||
721 | goto error; | ||
722 | } | ||
723 | break; | ||
724 | default: | ||
725 | dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n", | ||
726 | __func__); | ||
727 | ret = -EINVAL; | ||
728 | goto error; | ||
729 | } | ||
730 | |||
731 | for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) { | ||
732 | if (c->delivery_system == TDA10071_MODCOD[i].delivery_system && | ||
733 | c->modulation == TDA10071_MODCOD[i].modulation && | ||
734 | c->fec_inner == TDA10071_MODCOD[i].fec) { | ||
735 | mode = TDA10071_MODCOD[i].val; | ||
736 | dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n", | ||
737 | __func__, mode); | ||
738 | break; | ||
739 | } | ||
740 | } | ||
741 | |||
742 | if (mode == 0xff) { | ||
743 | dev_dbg(&priv->i2c->dev, "%s: invalid parameter combination\n", | ||
744 | __func__); | ||
745 | ret = -EINVAL; | ||
746 | goto error; | ||
747 | } | ||
748 | |||
749 | if (c->symbol_rate <= 5000000) | ||
750 | div = 14; | ||
751 | else | ||
752 | div = 4; | ||
753 | |||
754 | ret = tda10071_wr_reg(priv, 0x81, div); | ||
755 | if (ret) | ||
756 | goto error; | ||
757 | |||
758 | ret = tda10071_wr_reg(priv, 0xe3, div); | ||
759 | if (ret) | ||
760 | goto error; | ||
761 | |||
762 | cmd.args[0] = CMD_CHANGE_CHANNEL; | ||
763 | cmd.args[1] = 0; | ||
764 | cmd.args[2] = mode; | ||
765 | cmd.args[3] = (c->frequency >> 16) & 0xff; | ||
766 | cmd.args[4] = (c->frequency >> 8) & 0xff; | ||
767 | cmd.args[5] = (c->frequency >> 0) & 0xff; | ||
768 | cmd.args[6] = ((c->symbol_rate / 1000) >> 8) & 0xff; | ||
769 | cmd.args[7] = ((c->symbol_rate / 1000) >> 0) & 0xff; | ||
770 | cmd.args[8] = (tda10071_ops.info.frequency_tolerance >> 8) & 0xff; | ||
771 | cmd.args[9] = (tda10071_ops.info.frequency_tolerance >> 0) & 0xff; | ||
772 | cmd.args[10] = rolloff; | ||
773 | cmd.args[11] = inversion; | ||
774 | cmd.args[12] = pilot; | ||
775 | cmd.args[13] = 0x00; | ||
776 | cmd.args[14] = 0x00; | ||
777 | cmd.len = 15; | ||
778 | ret = tda10071_cmd_execute(priv, &cmd); | ||
779 | if (ret) | ||
780 | goto error; | ||
781 | |||
782 | priv->delivery_system = c->delivery_system; | ||
783 | |||
784 | return ret; | ||
785 | error: | ||
786 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
787 | return ret; | ||
788 | } | ||
789 | |||
790 | static int tda10071_get_frontend(struct dvb_frontend *fe) | ||
791 | { | ||
792 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
793 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
794 | int ret, i; | ||
795 | u8 buf[5], tmp; | ||
796 | |||
797 | if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) { | ||
798 | ret = -EFAULT; | ||
799 | goto error; | ||
800 | } | ||
801 | |||
802 | ret = tda10071_rd_regs(priv, 0x30, buf, 5); | ||
803 | if (ret) | ||
804 | goto error; | ||
805 | |||
806 | tmp = buf[0] & 0x3f; | ||
807 | for (i = 0; i < ARRAY_SIZE(TDA10071_MODCOD); i++) { | ||
808 | if (tmp == TDA10071_MODCOD[i].val) { | ||
809 | c->modulation = TDA10071_MODCOD[i].modulation; | ||
810 | c->fec_inner = TDA10071_MODCOD[i].fec; | ||
811 | c->delivery_system = TDA10071_MODCOD[i].delivery_system; | ||
812 | } | ||
813 | } | ||
814 | |||
815 | switch ((buf[1] >> 0) & 0x01) { | ||
816 | case 0: | ||
817 | c->inversion = INVERSION_OFF; | ||
818 | break; | ||
819 | case 1: | ||
820 | c->inversion = INVERSION_ON; | ||
821 | break; | ||
822 | } | ||
823 | |||
824 | switch ((buf[1] >> 7) & 0x01) { | ||
825 | case 0: | ||
826 | c->pilot = PILOT_OFF; | ||
827 | break; | ||
828 | case 1: | ||
829 | c->pilot = PILOT_ON; | ||
830 | break; | ||
831 | } | ||
832 | |||
833 | c->frequency = (buf[2] << 16) | (buf[3] << 8) | (buf[4] << 0); | ||
834 | |||
835 | ret = tda10071_rd_regs(priv, 0x52, buf, 3); | ||
836 | if (ret) | ||
837 | goto error; | ||
838 | |||
839 | c->symbol_rate = (buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0); | ||
840 | |||
841 | return ret; | ||
842 | error: | ||
843 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
844 | return ret; | ||
845 | } | ||
846 | |||
847 | static int tda10071_init(struct dvb_frontend *fe) | ||
848 | { | ||
849 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
850 | struct tda10071_cmd cmd; | ||
851 | int ret, i, len, remaining, fw_size; | ||
852 | const struct firmware *fw; | ||
853 | u8 *fw_file = TDA10071_DEFAULT_FIRMWARE; | ||
854 | u8 tmp, buf[4]; | ||
855 | struct tda10071_reg_val_mask tab[] = { | ||
856 | { 0xcd, 0x00, 0x07 }, | ||
857 | { 0x80, 0x00, 0x02 }, | ||
858 | { 0xcd, 0x00, 0xc0 }, | ||
859 | { 0xce, 0x00, 0x1b }, | ||
860 | { 0x9d, 0x00, 0x01 }, | ||
861 | { 0x9d, 0x00, 0x02 }, | ||
862 | { 0x9e, 0x00, 0x01 }, | ||
863 | { 0x87, 0x00, 0x80 }, | ||
864 | { 0xce, 0x00, 0x08 }, | ||
865 | { 0xce, 0x00, 0x10 }, | ||
866 | }; | ||
867 | struct tda10071_reg_val_mask tab2[] = { | ||
868 | { 0xf1, 0x70, 0xff }, | ||
869 | { 0x88, priv->cfg.pll_multiplier, 0x3f }, | ||
870 | { 0x89, 0x00, 0x10 }, | ||
871 | { 0x89, 0x10, 0x10 }, | ||
872 | { 0xc0, 0x01, 0x01 }, | ||
873 | { 0xc0, 0x00, 0x01 }, | ||
874 | { 0xe0, 0xff, 0xff }, | ||
875 | { 0xe0, 0x00, 0xff }, | ||
876 | { 0x96, 0x1e, 0x7e }, | ||
877 | { 0x8b, 0x08, 0x08 }, | ||
878 | { 0x8b, 0x00, 0x08 }, | ||
879 | { 0x8f, 0x1a, 0x7e }, | ||
880 | { 0x8c, 0x68, 0xff }, | ||
881 | { 0x8d, 0x08, 0xff }, | ||
882 | { 0x8e, 0x4c, 0xff }, | ||
883 | { 0x8f, 0x01, 0x01 }, | ||
884 | { 0x8b, 0x04, 0x04 }, | ||
885 | { 0x8b, 0x00, 0x04 }, | ||
886 | { 0x87, 0x05, 0x07 }, | ||
887 | { 0x80, 0x00, 0x20 }, | ||
888 | { 0xc8, 0x01, 0xff }, | ||
889 | { 0xb4, 0x47, 0xff }, | ||
890 | { 0xb5, 0x9c, 0xff }, | ||
891 | { 0xb6, 0x7d, 0xff }, | ||
892 | { 0xba, 0x00, 0x03 }, | ||
893 | { 0xb7, 0x47, 0xff }, | ||
894 | { 0xb8, 0x9c, 0xff }, | ||
895 | { 0xb9, 0x7d, 0xff }, | ||
896 | { 0xba, 0x00, 0x0c }, | ||
897 | { 0xc8, 0x00, 0xff }, | ||
898 | { 0xcd, 0x00, 0x04 }, | ||
899 | { 0xcd, 0x00, 0x20 }, | ||
900 | { 0xe8, 0x02, 0xff }, | ||
901 | { 0xcf, 0x20, 0xff }, | ||
902 | { 0x9b, 0xd7, 0xff }, | ||
903 | { 0x9a, 0x01, 0x03 }, | ||
904 | { 0xa8, 0x05, 0x0f }, | ||
905 | { 0xa8, 0x65, 0xf0 }, | ||
906 | { 0xa6, 0xa0, 0xf0 }, | ||
907 | { 0x9d, 0x50, 0xfc }, | ||
908 | { 0x9e, 0x20, 0xe0 }, | ||
909 | { 0xa3, 0x1c, 0x7c }, | ||
910 | { 0xd5, 0x03, 0x03 }, | ||
911 | }; | ||
912 | |||
913 | /* firmware status */ | ||
914 | ret = tda10071_rd_reg(priv, 0x51, &tmp); | ||
915 | if (ret) | ||
916 | goto error; | ||
917 | |||
918 | if (!tmp) { | ||
919 | /* warm state - wake up device from sleep */ | ||
920 | priv->warm = 1; | ||
921 | |||
922 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | ||
923 | ret = tda10071_wr_reg_mask(priv, tab[i].reg, | ||
924 | tab[i].val, tab[i].mask); | ||
925 | if (ret) | ||
926 | goto error; | ||
927 | } | ||
928 | |||
929 | cmd.args[0] = CMD_SET_SLEEP_MODE; | ||
930 | cmd.args[1] = 0; | ||
931 | cmd.args[2] = 0; | ||
932 | cmd.len = 3; | ||
933 | ret = tda10071_cmd_execute(priv, &cmd); | ||
934 | if (ret) | ||
935 | goto error; | ||
936 | } else { | ||
937 | /* cold state - try to download firmware */ | ||
938 | priv->warm = 0; | ||
939 | |||
940 | /* request the firmware, this will block and timeout */ | ||
941 | ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent); | ||
942 | if (ret) { | ||
943 | dev_err(&priv->i2c->dev, "%s: did not find the " \ | ||
944 | "firmware file. (%s) Please see " \ | ||
945 | "linux/Documentation/dvb/ for more " \ | ||
946 | "details on firmware-problems. (%d)\n", | ||
947 | KBUILD_MODNAME, fw_file, ret); | ||
948 | goto error; | ||
949 | } | ||
950 | |||
951 | /* init */ | ||
952 | for (i = 0; i < ARRAY_SIZE(tab2); i++) { | ||
953 | ret = tda10071_wr_reg_mask(priv, tab2[i].reg, | ||
954 | tab2[i].val, tab2[i].mask); | ||
955 | if (ret) | ||
956 | goto error_release_firmware; | ||
957 | } | ||
958 | |||
959 | /* download firmware */ | ||
960 | ret = tda10071_wr_reg(priv, 0xe0, 0x7f); | ||
961 | if (ret) | ||
962 | goto error_release_firmware; | ||
963 | |||
964 | ret = tda10071_wr_reg(priv, 0xf7, 0x81); | ||
965 | if (ret) | ||
966 | goto error_release_firmware; | ||
967 | |||
968 | ret = tda10071_wr_reg(priv, 0xf8, 0x00); | ||
969 | if (ret) | ||
970 | goto error_release_firmware; | ||
971 | |||
972 | ret = tda10071_wr_reg(priv, 0xf9, 0x00); | ||
973 | if (ret) | ||
974 | goto error_release_firmware; | ||
975 | |||
976 | dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state, " \ | ||
977 | "will try to load a firmware\n", KBUILD_MODNAME, | ||
978 | tda10071_ops.info.name); | ||
979 | dev_info(&priv->i2c->dev, "%s: downloading firmware from " \ | ||
980 | "file '%s'\n", KBUILD_MODNAME, fw_file); | ||
981 | |||
982 | /* do not download last byte */ | ||
983 | fw_size = fw->size - 1; | ||
984 | |||
985 | for (remaining = fw_size; remaining > 0; | ||
986 | remaining -= (priv->cfg.i2c_wr_max - 1)) { | ||
987 | len = remaining; | ||
988 | if (len > (priv->cfg.i2c_wr_max - 1)) | ||
989 | len = (priv->cfg.i2c_wr_max - 1); | ||
990 | |||
991 | ret = tda10071_wr_regs(priv, 0xfa, | ||
992 | (u8 *) &fw->data[fw_size - remaining], len); | ||
993 | if (ret) { | ||
994 | dev_err(&priv->i2c->dev, "%s: firmware " \ | ||
995 | "download failed=%d\n", | ||
996 | KBUILD_MODNAME, ret); | ||
997 | if (ret) | ||
998 | goto error_release_firmware; | ||
999 | } | ||
1000 | } | ||
1001 | release_firmware(fw); | ||
1002 | |||
1003 | ret = tda10071_wr_reg(priv, 0xf7, 0x0c); | ||
1004 | if (ret) | ||
1005 | goto error; | ||
1006 | |||
1007 | ret = tda10071_wr_reg(priv, 0xe0, 0x00); | ||
1008 | if (ret) | ||
1009 | goto error; | ||
1010 | |||
1011 | /* wait firmware start */ | ||
1012 | msleep(250); | ||
1013 | |||
1014 | /* firmware status */ | ||
1015 | ret = tda10071_rd_reg(priv, 0x51, &tmp); | ||
1016 | if (ret) | ||
1017 | goto error; | ||
1018 | |||
1019 | if (tmp) { | ||
1020 | dev_info(&priv->i2c->dev, "%s: firmware did not run\n", | ||
1021 | KBUILD_MODNAME); | ||
1022 | ret = -EFAULT; | ||
1023 | goto error; | ||
1024 | } else { | ||
1025 | priv->warm = 1; | ||
1026 | } | ||
1027 | |||
1028 | cmd.args[0] = CMD_GET_FW_VERSION; | ||
1029 | cmd.len = 1; | ||
1030 | ret = tda10071_cmd_execute(priv, &cmd); | ||
1031 | if (ret) | ||
1032 | goto error; | ||
1033 | |||
1034 | ret = tda10071_rd_regs(priv, cmd.len, buf, 4); | ||
1035 | if (ret) | ||
1036 | goto error; | ||
1037 | |||
1038 | dev_info(&priv->i2c->dev, "%s: firmware version %d.%d.%d.%d\n", | ||
1039 | KBUILD_MODNAME, buf[0], buf[1], buf[2], buf[3]); | ||
1040 | dev_info(&priv->i2c->dev, "%s: found a '%s' in warm state\n", | ||
1041 | KBUILD_MODNAME, tda10071_ops.info.name); | ||
1042 | |||
1043 | ret = tda10071_rd_regs(priv, 0x81, buf, 2); | ||
1044 | if (ret) | ||
1045 | goto error; | ||
1046 | |||
1047 | cmd.args[0] = CMD_DEMOD_INIT; | ||
1048 | cmd.args[1] = ((priv->cfg.xtal / 1000) >> 8) & 0xff; | ||
1049 | cmd.args[2] = ((priv->cfg.xtal / 1000) >> 0) & 0xff; | ||
1050 | cmd.args[3] = buf[0]; | ||
1051 | cmd.args[4] = buf[1]; | ||
1052 | cmd.args[5] = priv->cfg.pll_multiplier; | ||
1053 | cmd.args[6] = priv->cfg.spec_inv; | ||
1054 | cmd.args[7] = 0x00; | ||
1055 | cmd.len = 8; | ||
1056 | ret = tda10071_cmd_execute(priv, &cmd); | ||
1057 | if (ret) | ||
1058 | goto error; | ||
1059 | |||
1060 | cmd.args[0] = CMD_TUNER_INIT; | ||
1061 | cmd.args[1] = 0x00; | ||
1062 | cmd.args[2] = 0x00; | ||
1063 | cmd.args[3] = 0x00; | ||
1064 | cmd.args[4] = 0x00; | ||
1065 | cmd.args[5] = 0x14; | ||
1066 | cmd.args[6] = 0x00; | ||
1067 | cmd.args[7] = 0x03; | ||
1068 | cmd.args[8] = 0x02; | ||
1069 | cmd.args[9] = 0x02; | ||
1070 | cmd.args[10] = 0x00; | ||
1071 | cmd.args[11] = 0x00; | ||
1072 | cmd.args[12] = 0x00; | ||
1073 | cmd.args[13] = 0x00; | ||
1074 | cmd.args[14] = 0x00; | ||
1075 | cmd.len = 15; | ||
1076 | ret = tda10071_cmd_execute(priv, &cmd); | ||
1077 | if (ret) | ||
1078 | goto error; | ||
1079 | |||
1080 | cmd.args[0] = CMD_MPEG_CONFIG; | ||
1081 | cmd.args[1] = 0; | ||
1082 | cmd.args[2] = priv->cfg.ts_mode; | ||
1083 | cmd.args[3] = 0x00; | ||
1084 | cmd.args[4] = 0x04; | ||
1085 | cmd.args[5] = 0x00; | ||
1086 | cmd.len = 6; | ||
1087 | ret = tda10071_cmd_execute(priv, &cmd); | ||
1088 | if (ret) | ||
1089 | goto error; | ||
1090 | |||
1091 | ret = tda10071_wr_reg_mask(priv, 0xf0, 0x01, 0x01); | ||
1092 | if (ret) | ||
1093 | goto error; | ||
1094 | |||
1095 | cmd.args[0] = CMD_LNB_CONFIG; | ||
1096 | cmd.args[1] = 0; | ||
1097 | cmd.args[2] = 150; | ||
1098 | cmd.args[3] = 3; | ||
1099 | cmd.args[4] = 22; | ||
1100 | cmd.args[5] = 1; | ||
1101 | cmd.args[6] = 1; | ||
1102 | cmd.args[7] = 30; | ||
1103 | cmd.args[8] = 30; | ||
1104 | cmd.args[9] = 30; | ||
1105 | cmd.args[10] = 30; | ||
1106 | cmd.len = 11; | ||
1107 | ret = tda10071_cmd_execute(priv, &cmd); | ||
1108 | if (ret) | ||
1109 | goto error; | ||
1110 | |||
1111 | cmd.args[0] = CMD_BER_CONTROL; | ||
1112 | cmd.args[1] = 0; | ||
1113 | cmd.args[2] = 14; | ||
1114 | cmd.args[3] = 14; | ||
1115 | cmd.len = 4; | ||
1116 | ret = tda10071_cmd_execute(priv, &cmd); | ||
1117 | if (ret) | ||
1118 | goto error; | ||
1119 | } | ||
1120 | |||
1121 | return ret; | ||
1122 | error_release_firmware: | ||
1123 | release_firmware(fw); | ||
1124 | error: | ||
1125 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
1126 | return ret; | ||
1127 | } | ||
1128 | |||
1129 | static int tda10071_sleep(struct dvb_frontend *fe) | ||
1130 | { | ||
1131 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
1132 | struct tda10071_cmd cmd; | ||
1133 | int ret, i; | ||
1134 | struct tda10071_reg_val_mask tab[] = { | ||
1135 | { 0xcd, 0x07, 0x07 }, | ||
1136 | { 0x80, 0x02, 0x02 }, | ||
1137 | { 0xcd, 0xc0, 0xc0 }, | ||
1138 | { 0xce, 0x1b, 0x1b }, | ||
1139 | { 0x9d, 0x01, 0x01 }, | ||
1140 | { 0x9d, 0x02, 0x02 }, | ||
1141 | { 0x9e, 0x01, 0x01 }, | ||
1142 | { 0x87, 0x80, 0x80 }, | ||
1143 | { 0xce, 0x08, 0x08 }, | ||
1144 | { 0xce, 0x10, 0x10 }, | ||
1145 | }; | ||
1146 | |||
1147 | if (!priv->warm) { | ||
1148 | ret = -EFAULT; | ||
1149 | goto error; | ||
1150 | } | ||
1151 | |||
1152 | cmd.args[0] = CMD_SET_SLEEP_MODE; | ||
1153 | cmd.args[1] = 0; | ||
1154 | cmd.args[2] = 1; | ||
1155 | cmd.len = 3; | ||
1156 | ret = tda10071_cmd_execute(priv, &cmd); | ||
1157 | if (ret) | ||
1158 | goto error; | ||
1159 | |||
1160 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | ||
1161 | ret = tda10071_wr_reg_mask(priv, tab[i].reg, tab[i].val, | ||
1162 | tab[i].mask); | ||
1163 | if (ret) | ||
1164 | goto error; | ||
1165 | } | ||
1166 | |||
1167 | return ret; | ||
1168 | error: | ||
1169 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
1170 | return ret; | ||
1171 | } | ||
1172 | |||
1173 | static int tda10071_get_tune_settings(struct dvb_frontend *fe, | ||
1174 | struct dvb_frontend_tune_settings *s) | ||
1175 | { | ||
1176 | s->min_delay_ms = 8000; | ||
1177 | s->step_size = 0; | ||
1178 | s->max_drift = 0; | ||
1179 | |||
1180 | return 0; | ||
1181 | } | ||
1182 | |||
1183 | static void tda10071_release(struct dvb_frontend *fe) | ||
1184 | { | ||
1185 | struct tda10071_priv *priv = fe->demodulator_priv; | ||
1186 | kfree(priv); | ||
1187 | } | ||
1188 | |||
1189 | struct dvb_frontend *tda10071_attach(const struct tda10071_config *config, | ||
1190 | struct i2c_adapter *i2c) | ||
1191 | { | ||
1192 | int ret; | ||
1193 | struct tda10071_priv *priv = NULL; | ||
1194 | u8 tmp; | ||
1195 | |||
1196 | /* allocate memory for the internal priv */ | ||
1197 | priv = kzalloc(sizeof(struct tda10071_priv), GFP_KERNEL); | ||
1198 | if (priv == NULL) { | ||
1199 | ret = -ENOMEM; | ||
1200 | goto error; | ||
1201 | } | ||
1202 | |||
1203 | /* setup the priv */ | ||
1204 | priv->i2c = i2c; | ||
1205 | memcpy(&priv->cfg, config, sizeof(struct tda10071_config)); | ||
1206 | |||
1207 | /* chip ID */ | ||
1208 | ret = tda10071_rd_reg(priv, 0xff, &tmp); | ||
1209 | if (ret || tmp != 0x0f) | ||
1210 | goto error; | ||
1211 | |||
1212 | /* chip type */ | ||
1213 | ret = tda10071_rd_reg(priv, 0xdd, &tmp); | ||
1214 | if (ret || tmp != 0x00) | ||
1215 | goto error; | ||
1216 | |||
1217 | /* chip version */ | ||
1218 | ret = tda10071_rd_reg(priv, 0xfe, &tmp); | ||
1219 | if (ret || tmp != 0x01) | ||
1220 | goto error; | ||
1221 | |||
1222 | /* create dvb_frontend */ | ||
1223 | memcpy(&priv->fe.ops, &tda10071_ops, sizeof(struct dvb_frontend_ops)); | ||
1224 | priv->fe.demodulator_priv = priv; | ||
1225 | |||
1226 | return &priv->fe; | ||
1227 | error: | ||
1228 | dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
1229 | kfree(priv); | ||
1230 | return NULL; | ||
1231 | } | ||
1232 | EXPORT_SYMBOL(tda10071_attach); | ||
1233 | |||
1234 | static struct dvb_frontend_ops tda10071_ops = { | ||
1235 | .delsys = { SYS_DVBS, SYS_DVBS2 }, | ||
1236 | .info = { | ||
1237 | .name = "NXP TDA10071", | ||
1238 | .frequency_min = 950000, | ||
1239 | .frequency_max = 2150000, | ||
1240 | .frequency_tolerance = 5000, | ||
1241 | .symbol_rate_min = 1000000, | ||
1242 | .symbol_rate_max = 45000000, | ||
1243 | .caps = FE_CAN_INVERSION_AUTO | | ||
1244 | FE_CAN_FEC_1_2 | | ||
1245 | FE_CAN_FEC_2_3 | | ||
1246 | FE_CAN_FEC_3_4 | | ||
1247 | FE_CAN_FEC_4_5 | | ||
1248 | FE_CAN_FEC_5_6 | | ||
1249 | FE_CAN_FEC_6_7 | | ||
1250 | FE_CAN_FEC_7_8 | | ||
1251 | FE_CAN_FEC_8_9 | | ||
1252 | FE_CAN_FEC_AUTO | | ||
1253 | FE_CAN_QPSK | | ||
1254 | FE_CAN_RECOVER | | ||
1255 | FE_CAN_2G_MODULATION | ||
1256 | }, | ||
1257 | |||
1258 | .release = tda10071_release, | ||
1259 | |||
1260 | .get_tune_settings = tda10071_get_tune_settings, | ||
1261 | |||
1262 | .init = tda10071_init, | ||
1263 | .sleep = tda10071_sleep, | ||
1264 | |||
1265 | .set_frontend = tda10071_set_frontend, | ||
1266 | .get_frontend = tda10071_get_frontend, | ||
1267 | |||
1268 | .read_status = tda10071_read_status, | ||
1269 | .read_snr = tda10071_read_snr, | ||
1270 | .read_signal_strength = tda10071_read_signal_strength, | ||
1271 | .read_ber = tda10071_read_ber, | ||
1272 | .read_ucblocks = tda10071_read_ucblocks, | ||
1273 | |||
1274 | .diseqc_send_master_cmd = tda10071_diseqc_send_master_cmd, | ||
1275 | .diseqc_recv_slave_reply = tda10071_diseqc_recv_slave_reply, | ||
1276 | .diseqc_send_burst = tda10071_diseqc_send_burst, | ||
1277 | |||
1278 | .set_tone = tda10071_set_tone, | ||
1279 | .set_voltage = tda10071_set_voltage, | ||
1280 | }; | ||
1281 | |||
1282 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
1283 | MODULE_DESCRIPTION("NXP TDA10071 DVB-S/S2 demodulator driver"); | ||
1284 | MODULE_LICENSE("GPL"); | ||