1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include "hd29l2_priv.h"
24
25#define HD29L2_MAX_LEN (3)
26
27
28static int hd29l2_wr_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
29{
30 int ret;
31 u8 buf[2 + HD29L2_MAX_LEN];
32 struct i2c_msg msg[1] = {
33 {
34 .addr = priv->cfg.i2c_addr,
35 .flags = 0,
36 .len = 2 + len,
37 .buf = buf,
38 }
39 };
40
41 if (len > HD29L2_MAX_LEN)
42 return -EINVAL;
43 buf[0] = 0x00;
44 buf[1] = reg;
45 memcpy(&buf[2], val, len);
46
47 ret = i2c_transfer(priv->i2c, msg, 1);
48 if (ret == 1) {
49 ret = 0;
50 } else {
51 dev_warn(&priv->i2c->dev,
52 "%s: i2c wr failed=%d reg=%02x len=%d\n",
53 KBUILD_MODNAME, ret, reg, len);
54 ret = -EREMOTEIO;
55 }
56
57 return ret;
58}
59
60
61static int hd29l2_rd_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
62{
63 int ret;
64 u8 buf[2] = { 0x00, reg };
65 struct i2c_msg msg[2] = {
66 {
67 .addr = priv->cfg.i2c_addr,
68 .flags = 0,
69 .len = 2,
70 .buf = buf,
71 }, {
72 .addr = priv->cfg.i2c_addr,
73 .flags = I2C_M_RD,
74 .len = len,
75 .buf = val,
76 }
77 };
78
79 ret = i2c_transfer(priv->i2c, msg, 2);
80 if (ret == 2) {
81 ret = 0;
82 } else {
83 dev_warn(&priv->i2c->dev,
84 "%s: i2c rd failed=%d reg=%02x len=%d\n",
85 KBUILD_MODNAME, ret, reg, len);
86 ret = -EREMOTEIO;
87 }
88
89 return ret;
90}
91
92
93static int hd29l2_wr_reg(struct hd29l2_priv *priv, u8 reg, u8 val)
94{
95 return hd29l2_wr_regs(priv, reg, &val, 1);
96}
97
98
99static int hd29l2_rd_reg(struct hd29l2_priv *priv, u8 reg, u8 *val)
100{
101 return hd29l2_rd_regs(priv, reg, val, 1);
102}
103
104
105static int hd29l2_wr_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 val, u8 mask)
106{
107 int ret;
108 u8 tmp;
109
110
111 if (mask != 0xff) {
112 ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
113 if (ret)
114 return ret;
115
116 val &= mask;
117 tmp &= ~mask;
118 val |= tmp;
119 }
120
121 return hd29l2_wr_regs(priv, reg, &val, 1);
122}
123
124
125static int hd29l2_rd_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 *val, u8 mask)
126{
127 int ret, i;
128 u8 tmp;
129
130 ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
131 if (ret)
132 return ret;
133
134 tmp &= mask;
135
136
137 for (i = 0; i < 8; i++) {
138 if ((mask >> i) & 0x01)
139 break;
140 }
141 *val = tmp >> i;
142
143 return 0;
144}
145
146static int hd29l2_soft_reset(struct hd29l2_priv *priv)
147{
148 int ret;
149 u8 tmp;
150
151 ret = hd29l2_rd_reg(priv, 0x26, &tmp);
152 if (ret)
153 goto err;
154
155 ret = hd29l2_wr_reg(priv, 0x26, 0x0d);
156 if (ret)
157 goto err;
158
159 usleep_range(10000, 20000);
160
161 ret = hd29l2_wr_reg(priv, 0x26, tmp);
162 if (ret)
163 goto err;
164
165 return 0;
166err:
167 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
168 return ret;
169}
170
171static int hd29l2_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
172{
173 int ret, i;
174 struct hd29l2_priv *priv = fe->demodulator_priv;
175 u8 tmp;
176
177 dev_dbg(&priv->i2c->dev, "%s: enable=%d\n", __func__, enable);
178
179
180 if (!priv->tuner_i2c_addr_programmed && enable) {
181
182 ret = hd29l2_wr_reg(priv, 0x9d, priv->cfg.tuner_i2c_addr << 1);
183 if (ret)
184 goto err;
185
186 priv->tuner_i2c_addr_programmed = true;
187 }
188
189
190 ret = hd29l2_wr_reg(priv, 0x9f, enable);
191 if (ret)
192 goto err;
193
194
195 for (i = 10; i; i--) {
196 ret = hd29l2_rd_reg(priv, 0x9e, &tmp);
197 if (ret)
198 goto err;
199
200 if (tmp == enable)
201 break;
202
203 usleep_range(5000, 10000);
204 }
205
206 dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
207
208 return ret;
209err:
210 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
211 return ret;
212}
213
214static int hd29l2_read_status(struct dvb_frontend *fe, enum fe_status *status)
215{
216 int ret;
217 struct hd29l2_priv *priv = fe->demodulator_priv;
218 u8 buf[2];
219
220 *status = 0;
221
222 ret = hd29l2_rd_reg(priv, 0x05, &buf[0]);
223 if (ret)
224 goto err;
225
226 if (buf[0] & 0x01) {
227
228 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
229 FE_HAS_SYNC | FE_HAS_LOCK;
230 } else {
231 ret = hd29l2_rd_reg(priv, 0x0d, &buf[1]);
232 if (ret)
233 goto err;
234
235 if ((buf[1] & 0xfe) == 0x78)
236
237 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
238 FE_HAS_VITERBI | FE_HAS_SYNC;
239 }
240
241 priv->fe_status = *status;
242
243 return 0;
244err:
245 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
246 return ret;
247}
248
249static int hd29l2_read_snr(struct dvb_frontend *fe, u16 *snr)
250{
251 int ret;
252 struct hd29l2_priv *priv = fe->demodulator_priv;
253 u8 buf[2];
254 u16 tmp;
255
256 if (!(priv->fe_status & FE_HAS_LOCK)) {
257 *snr = 0;
258 ret = 0;
259 goto err;
260 }
261
262 ret = hd29l2_rd_regs(priv, 0x0b, buf, 2);
263 if (ret)
264 goto err;
265
266 tmp = (buf[0] << 8) | buf[1];
267
268
269 #define LOG10_20736_24 72422627
270 if (tmp)
271 *snr = (LOG10_20736_24 - intlog10(tmp)) / ((1 << 24) / 100);
272 else
273 *snr = 0;
274
275 return 0;
276err:
277 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
278 return ret;
279}
280
281static int hd29l2_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
282{
283 int ret;
284 struct hd29l2_priv *priv = fe->demodulator_priv;
285 u8 buf[2];
286 u16 tmp;
287
288 *strength = 0;
289
290 ret = hd29l2_rd_regs(priv, 0xd5, buf, 2);
291 if (ret)
292 goto err;
293
294 tmp = buf[0] << 8 | buf[1];
295 tmp = ~tmp & 0x0fff;
296
297
298 *strength = tmp * 0xffff / 0x0fff;
299
300 return 0;
301err:
302 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
303 return ret;
304}
305
306static int hd29l2_read_ber(struct dvb_frontend *fe, u32 *ber)
307{
308 int ret;
309 struct hd29l2_priv *priv = fe->demodulator_priv;
310 u8 buf[2];
311
312 if (!(priv->fe_status & FE_HAS_SYNC)) {
313 *ber = 0;
314 ret = 0;
315 goto err;
316 }
317
318 ret = hd29l2_rd_regs(priv, 0xd9, buf, 2);
319 if (ret) {
320 *ber = 0;
321 goto err;
322 }
323
324
325 *ber = ((buf[0] & 0x0f) << 8) | buf[1];
326
327 return 0;
328err:
329 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
330 return ret;
331}
332
333static int hd29l2_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
334{
335
336 *ucblocks = 0;
337 return 0;
338}
339
340static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
341{
342 int ret, i;
343 struct hd29l2_priv *priv = fe->demodulator_priv;
344 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
345 u8 tmp, buf[3];
346 u8 modulation, carrier, guard_interval, interleave, code_rate;
347 u64 num64;
348 u32 if_freq, if_ctl;
349 bool auto_mode;
350
351 dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
352 "bandwidth_hz=%d modulation=%d inversion=%d " \
353 "fec_inner=%d guard_interval=%d\n", __func__,
354 c->delivery_system, c->frequency, c->bandwidth_hz,
355 c->modulation, c->inversion, c->fec_inner,
356 c->guard_interval);
357
358
359 auto_mode = true;
360
361
362 if (fe->ops.tuner_ops.set_params)
363 fe->ops.tuner_ops.set_params(fe);
364
365
366 if (fe->ops.tuner_ops.get_if_frequency)
367 fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
368 else
369 if_freq = 0;
370
371 if (if_freq) {
372
373
374
375 num64 = if_freq;
376 num64 *= 0x800000;
377 num64 = div_u64(num64, HD29L2_XTAL);
378 num64 -= 0x800000;
379 if_ctl = num64;
380
381 tmp = 0xfc;
382 } else {
383
384 if_ctl = 0;
385 tmp = 0xfe;
386 }
387
388 buf[0] = ((if_ctl >> 0) & 0xff);
389 buf[1] = ((if_ctl >> 8) & 0xff);
390 buf[2] = ((if_ctl >> 16) & 0xff);
391
392
393 ret = hd29l2_wr_regs(priv, 0x14, buf, 3);
394 if (ret)
395 goto err;
396
397
398 ret = hd29l2_wr_reg(priv, 0xab, tmp);
399 if (ret)
400 goto err;
401
402 dev_dbg(&priv->i2c->dev, "%s: if_freq=%d if_ctl=%x\n",
403 __func__, if_freq, if_ctl);
404
405 if (auto_mode) {
406
407
408
409
410
411 ret = hd29l2_wr_reg_mask(priv, 0xac, 0 << 7, 0x80);
412 if (ret)
413 goto err;
414
415 ret = hd29l2_wr_reg_mask(priv, 0x82, 1 << 1, 0x02);
416 if (ret)
417 goto err;
418
419
420 ret = hd29l2_wr_reg_mask(priv, 0x7d, 1 << 6, 0x40);
421 if (ret)
422 goto err;
423
424 ret = hd29l2_wr_reg_mask(priv, 0x81, 1 << 3, 0x08);
425 if (ret)
426 goto err;
427
428
429 ret = hd29l2_soft_reset(priv);
430 if (ret)
431 goto err;
432
433
434 for (i = 30; i; i--) {
435 msleep(100);
436
437 ret = hd29l2_rd_reg(priv, 0x0d, &tmp);
438 if (ret)
439 goto err;
440
441 if ((((tmp & 0xf0) >= 0x10) &&
442 ((tmp & 0x0f) == 0x08)) || (tmp >= 0x2c))
443 break;
444 }
445
446 dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
447
448 if (i == 0)
449
450 return DVBFE_ALGO_SEARCH_FAILED;
451
452
453 ret = hd29l2_rd_reg_mask(priv, 0x7d, &modulation, 0x07);
454 if (ret)
455 goto err;
456 } else {
457
458
459
460
461 modulation = HD29L2_QAM64;
462 carrier = HD29L2_CARRIER_MULTI;
463 guard_interval = HD29L2_PN945;
464 interleave = HD29L2_INTERLEAVER_420;
465 code_rate = HD29L2_CODE_RATE_08;
466
467 tmp = (code_rate << 3) | modulation;
468 ret = hd29l2_wr_reg_mask(priv, 0x7d, tmp, 0x5f);
469 if (ret)
470 goto err;
471
472 tmp = (carrier << 2) | guard_interval;
473 ret = hd29l2_wr_reg_mask(priv, 0x81, tmp, 0x0f);
474 if (ret)
475 goto err;
476
477 tmp = interleave;
478 ret = hd29l2_wr_reg_mask(priv, 0x82, tmp, 0x03);
479 if (ret)
480 goto err;
481 }
482
483
484
485 if (modulation > (ARRAY_SIZE(reg_mod_vals_tab[0].val) - 1)) {
486 dev_dbg(&priv->i2c->dev, "%s: modulation=%d not valid\n",
487 __func__, modulation);
488 goto err;
489 }
490
491
492 for (i = 0; i < ARRAY_SIZE(reg_mod_vals_tab); i++) {
493 ret = hd29l2_wr_reg(priv, reg_mod_vals_tab[i].reg,
494 reg_mod_vals_tab[i].val[modulation]);
495 if (ret)
496 goto err;
497 }
498
499
500 ret = hd29l2_rd_reg_mask(priv, 0x81, &guard_interval, 0x03);
501 if (ret)
502 goto err;
503
504
505 ret = hd29l2_rd_reg_mask(priv, 0x81, &carrier, 0x04);
506 if (ret)
507 goto err;
508
509 dev_dbg(&priv->i2c->dev,
510 "%s: modulation=%d guard_interval=%d carrier=%d\n",
511 __func__, modulation, guard_interval, carrier);
512
513 if ((carrier == HD29L2_CARRIER_MULTI) && (modulation == HD29L2_QAM64) &&
514 (guard_interval == HD29L2_PN945)) {
515 dev_dbg(&priv->i2c->dev, "%s: C=3780 && QAM64 && PN945\n",
516 __func__);
517
518 ret = hd29l2_wr_reg(priv, 0x42, 0x33);
519 if (ret)
520 goto err;
521
522 ret = hd29l2_wr_reg(priv, 0xdd, 0x01);
523 if (ret)
524 goto err;
525 }
526
527 usleep_range(10000, 20000);
528
529
530 ret = hd29l2_soft_reset(priv);
531 if (ret)
532 goto err;
533
534
535 for (i = 30; i; i--) {
536 msleep(100);
537
538
539 ret = hd29l2_rd_reg_mask(priv, 0x05, &tmp, 0x01);
540 if (ret)
541 goto err;
542
543 if (tmp)
544 break;
545 }
546
547 dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
548
549 if (i == 0)
550 return DVBFE_ALGO_SEARCH_AGAIN;
551
552 return DVBFE_ALGO_SEARCH_SUCCESS;
553err:
554 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
555 return DVBFE_ALGO_SEARCH_ERROR;
556}
557
558static int hd29l2_get_frontend_algo(struct dvb_frontend *fe)
559{
560 return DVBFE_ALGO_CUSTOM;
561}
562
563static int hd29l2_get_frontend(struct dvb_frontend *fe,
564 struct dtv_frontend_properties *c)
565{
566 int ret;
567 struct hd29l2_priv *priv = fe->demodulator_priv;
568 u8 buf[3];
569 u32 if_ctl;
570 char *str_constellation, *str_code_rate, *str_constellation_code_rate,
571 *str_guard_interval, *str_carrier, *str_guard_interval_carrier,
572 *str_interleave, *str_interleave_;
573
574 ret = hd29l2_rd_reg(priv, 0x7d, &buf[0]);
575 if (ret)
576 goto err;
577
578 ret = hd29l2_rd_regs(priv, 0x81, &buf[1], 2);
579 if (ret)
580 goto err;
581
582
583 switch ((buf[0] >> 0) & 0x07) {
584 case 0:
585 str_constellation = "QAM4NR";
586 c->modulation = QAM_AUTO;
587 break;
588 case 1:
589 str_constellation = "QAM4";
590 c->modulation = QPSK;
591 break;
592 case 2:
593 str_constellation = "QAM16";
594 c->modulation = QAM_16;
595 break;
596 case 3:
597 str_constellation = "QAM32";
598 c->modulation = QAM_32;
599 break;
600 case 4:
601 str_constellation = "QAM64";
602 c->modulation = QAM_64;
603 break;
604 default:
605 str_constellation = "?";
606 }
607
608
609 switch ((buf[0] >> 3) & 0x03) {
610 case 0:
611 str_code_rate = "0.4";
612 c->fec_inner = FEC_AUTO;
613 break;
614 case 1:
615 str_code_rate = "0.6";
616 c->fec_inner = FEC_3_5;
617 break;
618 case 2:
619 str_code_rate = "0.8";
620 c->fec_inner = FEC_4_5;
621 break;
622 default:
623 str_code_rate = "?";
624 }
625
626
627 switch ((buf[0] >> 6) & 0x01) {
628 case 0:
629 str_constellation_code_rate = "manual";
630 break;
631 case 1:
632 str_constellation_code_rate = "auto";
633 break;
634 default:
635 str_constellation_code_rate = "?";
636 }
637
638
639 switch ((buf[1] >> 0) & 0x03) {
640 case 0:
641 str_guard_interval = "PN945";
642 c->guard_interval = GUARD_INTERVAL_AUTO;
643 break;
644 case 1:
645 str_guard_interval = "PN595";
646 c->guard_interval = GUARD_INTERVAL_AUTO;
647 break;
648 case 2:
649 str_guard_interval = "PN420";
650 c->guard_interval = GUARD_INTERVAL_AUTO;
651 break;
652 default:
653 str_guard_interval = "?";
654 }
655
656
657 switch ((buf[1] >> 2) & 0x01) {
658 case 0:
659 str_carrier = "C=1";
660 break;
661 case 1:
662 str_carrier = "C=3780";
663 break;
664 default:
665 str_carrier = "?";
666 }
667
668
669 switch ((buf[1] >> 3) & 0x01) {
670 case 0:
671 str_guard_interval_carrier = "manual";
672 break;
673 case 1:
674 str_guard_interval_carrier = "auto";
675 break;
676 default:
677 str_guard_interval_carrier = "?";
678 }
679
680
681 switch ((buf[2] >> 0) & 0x01) {
682 case 0:
683 str_interleave = "M=720";
684 break;
685 case 1:
686 str_interleave = "M=240";
687 break;
688 default:
689 str_interleave = "?";
690 }
691
692
693 switch ((buf[2] >> 1) & 0x01) {
694 case 0:
695 str_interleave_ = "manual";
696 break;
697 case 1:
698 str_interleave_ = "auto";
699 break;
700 default:
701 str_interleave_ = "?";
702 }
703
704
705
706
707
708
709
710 ret = hd29l2_rd_regs(priv, 0xb1, &buf[0], 3);
711 if (ret)
712 goto err;
713
714 if_ctl = (buf[0] << 16) | ((buf[1] - 7) << 8) | buf[2];
715
716 dev_dbg(&priv->i2c->dev, "%s: %s %s %s | %s %s %s | %s %s | NCO=%06x\n",
717 __func__, str_constellation, str_code_rate,
718 str_constellation_code_rate, str_guard_interval,
719 str_carrier, str_guard_interval_carrier, str_interleave,
720 str_interleave_, if_ctl);
721 return 0;
722err:
723 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
724 return ret;
725}
726
727static int hd29l2_init(struct dvb_frontend *fe)
728{
729 int ret, i;
730 struct hd29l2_priv *priv = fe->demodulator_priv;
731 u8 tmp;
732 static const struct reg_val tab[] = {
733 { 0x3a, 0x06 },
734 { 0x3b, 0x03 },
735 { 0x3c, 0x04 },
736 { 0xaf, 0x06 },
737 { 0xb0, 0x1b },
738 { 0x80, 0x64 },
739 { 0x10, 0x38 },
740 };
741
742 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
743
744
745
746 if (fe->callback) {
747 ret = fe->callback(fe, DVB_FRONTEND_COMPONENT_DEMOD, 0, 0);
748 if (ret)
749 goto err;
750
751
752 priv->tuner_i2c_addr_programmed = false;
753 }
754
755
756 for (i = 0; i < ARRAY_SIZE(tab); i++) {
757 ret = hd29l2_wr_reg(priv, tab[i].reg, tab[i].val);
758 if (ret)
759 goto err;
760 }
761
762
763 ret = hd29l2_rd_reg(priv, 0x36, &tmp);
764 if (ret)
765 goto err;
766
767 tmp &= 0x1b;
768 tmp |= priv->cfg.ts_mode;
769 ret = hd29l2_wr_reg(priv, 0x36, tmp);
770 if (ret)
771 goto err;
772
773 ret = hd29l2_rd_reg(priv, 0x31, &tmp);
774 tmp &= 0xef;
775
776 if (!(priv->cfg.ts_mode >> 7))
777
778 tmp |= 0x10;
779
780 ret = hd29l2_wr_reg(priv, 0x31, tmp);
781 if (ret)
782 goto err;
783
784 return ret;
785err:
786 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
787 return ret;
788}
789
790static void hd29l2_release(struct dvb_frontend *fe)
791{
792 struct hd29l2_priv *priv = fe->demodulator_priv;
793 kfree(priv);
794}
795
796static struct dvb_frontend_ops hd29l2_ops;
797
798struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
799 struct i2c_adapter *i2c)
800{
801 int ret;
802 struct hd29l2_priv *priv = NULL;
803 u8 tmp;
804
805
806 priv = kzalloc(sizeof(struct hd29l2_priv), GFP_KERNEL);
807 if (priv == NULL)
808 goto err;
809
810
811 priv->i2c = i2c;
812 memcpy(&priv->cfg, config, sizeof(struct hd29l2_config));
813
814
815
816 ret = hd29l2_rd_reg(priv, 0x00, &tmp);
817 if (ret)
818 goto err;
819
820
821 memcpy(&priv->fe.ops, &hd29l2_ops, sizeof(struct dvb_frontend_ops));
822 priv->fe.demodulator_priv = priv;
823
824 return &priv->fe;
825err:
826 kfree(priv);
827 return NULL;
828}
829EXPORT_SYMBOL(hd29l2_attach);
830
831static struct dvb_frontend_ops hd29l2_ops = {
832 .delsys = { SYS_DVBT },
833 .info = {
834 .name = "HDIC HD29L2 DMB-TH",
835 .frequency_min = 474000000,
836 .frequency_max = 858000000,
837 .frequency_stepsize = 10000,
838 .caps = FE_CAN_FEC_AUTO |
839 FE_CAN_QPSK |
840 FE_CAN_QAM_16 |
841 FE_CAN_QAM_32 |
842 FE_CAN_QAM_64 |
843 FE_CAN_QAM_AUTO |
844 FE_CAN_TRANSMISSION_MODE_AUTO |
845 FE_CAN_BANDWIDTH_AUTO |
846 FE_CAN_GUARD_INTERVAL_AUTO |
847 FE_CAN_HIERARCHY_AUTO |
848 FE_CAN_RECOVER
849 },
850
851 .release = hd29l2_release,
852
853 .init = hd29l2_init,
854
855 .get_frontend_algo = hd29l2_get_frontend_algo,
856 .search = hd29l2_search,
857 .get_frontend = hd29l2_get_frontend,
858
859 .read_status = hd29l2_read_status,
860 .read_snr = hd29l2_read_snr,
861 .read_signal_strength = hd29l2_read_signal_strength,
862 .read_ber = hd29l2_read_ber,
863 .read_ucblocks = hd29l2_read_ucblocks,
864
865 .i2c_gate_ctrl = hd29l2_i2c_gate_ctrl,
866};
867
868MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
869MODULE_DESCRIPTION("HDIC HD29L2 DMB-TH demodulator driver");
870MODULE_LICENSE("GPL");
871