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