Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtl2830.c
Go to the documentation of this file.
1 /*
2  * Realtek RTL2830 DVB-T demodulator driver
3  *
4  * Copyright (C) 2011 Antti Palosaari <[email protected]>
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 
22 /*
23  * Driver implements own I2C-adapter for tuner I2C access. That's since chip
24  * have unusual I2C-gate control which closes gate automatically after each
25  * I2C transfer. Using own I2C adapter we can workaround that.
26  */
27 
28 #include "rtl2830_priv.h"
29 
30 /* write multiple hardware registers */
31 static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, const u8 *val, int len)
32 {
33  int ret;
34  u8 buf[1+len];
35  struct i2c_msg msg[1] = {
36  {
37  .addr = priv->cfg.i2c_addr,
38  .flags = 0,
39  .len = 1+len,
40  .buf = buf,
41  }
42  };
43 
44  buf[0] = reg;
45  memcpy(&buf[1], 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, "%s: i2c wr failed=%d reg=%02x " \
52  "len=%d\n", KBUILD_MODNAME, ret, reg, len);
53  ret = -EREMOTEIO;
54  }
55  return ret;
56 }
57 
58 /* read multiple hardware registers */
59 static int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
60 {
61  int ret;
62  struct i2c_msg msg[2] = {
63  {
64  .addr = priv->cfg.i2c_addr,
65  .flags = 0,
66  .len = 1,
67  .buf = &reg,
68  }, {
69  .addr = priv->cfg.i2c_addr,
70  .flags = I2C_M_RD,
71  .len = len,
72  .buf = val,
73  }
74  };
75 
76  ret = i2c_transfer(priv->i2c, msg, 2);
77  if (ret == 2) {
78  ret = 0;
79  } else {
80  dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
81  "len=%d\n", KBUILD_MODNAME, ret, reg, len);
82  ret = -EREMOTEIO;
83  }
84  return ret;
85 }
86 
87 /* write multiple registers */
88 static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, const u8 *val,
89  int len)
90 {
91  int ret;
92  u8 reg2 = (reg >> 0) & 0xff;
93  u8 page = (reg >> 8) & 0xff;
94 
95  /* switch bank if needed */
96  if (page != priv->page) {
97  ret = rtl2830_wr(priv, 0x00, &page, 1);
98  if (ret)
99  return ret;
100 
101  priv->page = page;
102  }
103 
104  return rtl2830_wr(priv, reg2, val, len);
105 }
106 
107 /* read multiple registers */
108 static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
109 {
110  int ret;
111  u8 reg2 = (reg >> 0) & 0xff;
112  u8 page = (reg >> 8) & 0xff;
113 
114  /* switch bank if needed */
115  if (page != priv->page) {
116  ret = rtl2830_wr(priv, 0x00, &page, 1);
117  if (ret)
118  return ret;
119 
120  priv->page = page;
121  }
122 
123  return rtl2830_rd(priv, reg2, val, len);
124 }
125 
126 /* read single register */
127 static int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val)
128 {
129  return rtl2830_rd_regs(priv, reg, val, 1);
130 }
131 
132 /* write single register with mask */
133 int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask)
134 {
135  int ret;
136  u8 tmp;
137 
138  /* no need for read if whole reg is written */
139  if (mask != 0xff) {
140  ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
141  if (ret)
142  return ret;
143 
144  val &= mask;
145  tmp &= ~mask;
146  val |= tmp;
147  }
148 
149  return rtl2830_wr_regs(priv, reg, &val, 1);
150 }
151 
152 /* read single register with mask */
153 int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask)
154 {
155  int ret, i;
156  u8 tmp;
157 
158  ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
159  if (ret)
160  return ret;
161 
162  tmp &= mask;
163 
164  /* find position of the first bit */
165  for (i = 0; i < 8; i++) {
166  if ((mask >> i) & 0x01)
167  break;
168  }
169  *val = tmp >> i;
170 
171  return 0;
172 }
173 
174 static int rtl2830_init(struct dvb_frontend *fe)
175 {
176  struct rtl2830_priv *priv = fe->demodulator_priv;
177  int ret, i;
178  struct rtl2830_reg_val_mask tab[] = {
179  { 0x00d, 0x01, 0x03 },
180  { 0x00d, 0x10, 0x10 },
181  { 0x104, 0x00, 0x1e },
182  { 0x105, 0x80, 0x80 },
183  { 0x110, 0x02, 0x03 },
184  { 0x110, 0x08, 0x0c },
185  { 0x17b, 0x00, 0x40 },
186  { 0x17d, 0x05, 0x0f },
187  { 0x17d, 0x50, 0xf0 },
188  { 0x18c, 0x08, 0x0f },
189  { 0x18d, 0x00, 0xc0 },
190  { 0x188, 0x05, 0x0f },
191  { 0x189, 0x00, 0xfc },
192  { 0x2d5, 0x02, 0x02 },
193  { 0x2f1, 0x02, 0x06 },
194  { 0x2f1, 0x20, 0xf8 },
195  { 0x16d, 0x00, 0x01 },
196  { 0x1a6, 0x00, 0x80 },
197  { 0x106, priv->cfg.vtop, 0x3f },
198  { 0x107, priv->cfg.krf, 0x3f },
199  { 0x112, 0x28, 0xff },
200  { 0x103, priv->cfg.agc_targ_val, 0xff },
201  { 0x00a, 0x02, 0x07 },
202  { 0x140, 0x0c, 0x3c },
203  { 0x140, 0x40, 0xc0 },
204  { 0x15b, 0x05, 0x07 },
205  { 0x15b, 0x28, 0x38 },
206  { 0x15c, 0x05, 0x07 },
207  { 0x15c, 0x28, 0x38 },
208  { 0x115, priv->cfg.spec_inv, 0x01 },
209  { 0x16f, 0x01, 0x07 },
210  { 0x170, 0x18, 0x38 },
211  { 0x172, 0x0f, 0x0f },
212  { 0x173, 0x08, 0x38 },
213  { 0x175, 0x01, 0x07 },
214  { 0x176, 0x00, 0xc0 },
215  };
216 
217  for (i = 0; i < ARRAY_SIZE(tab); i++) {
218  ret = rtl2830_wr_reg_mask(priv, tab[i].reg, tab[i].val,
219  tab[i].mask);
220  if (ret)
221  goto err;
222  }
223 
224  ret = rtl2830_wr_regs(priv, 0x18f, "\x28\x00", 2);
225  if (ret)
226  goto err;
227 
228  ret = rtl2830_wr_regs(priv, 0x195,
229  "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
230  if (ret)
231  goto err;
232 
233  /* TODO: spec init */
234 
235  /* soft reset */
236  ret = rtl2830_wr_reg_mask(priv, 0x101, 0x04, 0x04);
237  if (ret)
238  goto err;
239 
240  ret = rtl2830_wr_reg_mask(priv, 0x101, 0x00, 0x04);
241  if (ret)
242  goto err;
243 
244  priv->sleeping = false;
245 
246  return ret;
247 err:
248  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
249  return ret;
250 }
251 
252 static int rtl2830_sleep(struct dvb_frontend *fe)
253 {
254  struct rtl2830_priv *priv = fe->demodulator_priv;
255  priv->sleeping = true;
256  return 0;
257 }
258 
261 {
262  s->min_delay_ms = 500;
263  s->step_size = fe->ops.info.frequency_stepsize * 2;
264  s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
265 
266  return 0;
267 }
268 
269 static int rtl2830_set_frontend(struct dvb_frontend *fe)
270 {
271  struct rtl2830_priv *priv = fe->demodulator_priv;
273  int ret, i;
274  u64 num;
275  u8 buf[3], tmp;
276  u32 if_ctl, if_frequency;
277  static const u8 bw_params1[3][34] = {
278  {
279  0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
280  0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
281  0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
282  0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
283  }, {
284  0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
285  0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
286  0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
287  0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
288  }, {
289  0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
290  0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
291  0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
292  0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
293  },
294  };
295  static const u8 bw_params2[3][6] = {
296  {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30}, /* 6 MHz */
297  {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98}, /* 7 MHz */
298  {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64}, /* 8 MHz */
299  };
300 
301  dev_dbg(&priv->i2c->dev,
302  "%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
303  __func__, c->frequency, c->bandwidth_hz, c->inversion);
304 
305  /* program tuner */
306  if (fe->ops.tuner_ops.set_params)
307  fe->ops.tuner_ops.set_params(fe);
308 
309  switch (c->bandwidth_hz) {
310  case 6000000:
311  i = 0;
312  break;
313  case 7000000:
314  i = 1;
315  break;
316  case 8000000:
317  i = 2;
318  break;
319  default:
320  dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__);
321  return -EINVAL;
322  }
323 
324  ret = rtl2830_wr_reg_mask(priv, 0x008, i << 1, 0x06);
325  if (ret)
326  goto err;
327 
328  /* program if frequency */
329  if (fe->ops.tuner_ops.get_if_frequency)
330  ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
331  else
332  ret = -EINVAL;
333 
334  if (ret < 0)
335  goto err;
336 
337  num = if_frequency % priv->cfg.xtal;
338  num *= 0x400000;
339  num = div_u64(num, priv->cfg.xtal);
340  num = -num;
341  if_ctl = num & 0x3fffff;
342  dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d if_ctl=%08x\n",
343  __func__, if_frequency, if_ctl);
344 
345  ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */
346  if (ret)
347  goto err;
348 
349  buf[0] = tmp << 6;
350  buf[0] |= (if_ctl >> 16) & 0x3f;
351  buf[1] = (if_ctl >> 8) & 0xff;
352  buf[2] = (if_ctl >> 0) & 0xff;
353 
354  ret = rtl2830_wr_regs(priv, 0x119, buf, 3);
355  if (ret)
356  goto err;
357 
358  /* 1/2 split I2C write */
359  ret = rtl2830_wr_regs(priv, 0x11c, &bw_params1[i][0], 17);
360  if (ret)
361  goto err;
362 
363  /* 2/2 split I2C write */
364  ret = rtl2830_wr_regs(priv, 0x12d, &bw_params1[i][17], 17);
365  if (ret)
366  goto err;
367 
368  ret = rtl2830_wr_regs(priv, 0x19d, bw_params2[i], 6);
369  if (ret)
370  goto err;
371 
372  return ret;
373 err:
374  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
375  return ret;
376 }
377 
378 static int rtl2830_get_frontend(struct dvb_frontend *fe)
379 {
380  struct rtl2830_priv *priv = fe->demodulator_priv;
382  int ret;
383  u8 buf[3];
384 
385  if (priv->sleeping)
386  return 0;
387 
388  ret = rtl2830_rd_regs(priv, 0x33c, buf, 2);
389  if (ret)
390  goto err;
391 
392  ret = rtl2830_rd_reg(priv, 0x351, &buf[2]);
393  if (ret)
394  goto err;
395 
396  dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf);
397 
398  switch ((buf[0] >> 2) & 3) {
399  case 0:
400  c->modulation = QPSK;
401  break;
402  case 1:
403  c->modulation = QAM_16;
404  break;
405  case 2:
406  c->modulation = QAM_64;
407  break;
408  }
409 
410  switch ((buf[2] >> 2) & 1) {
411  case 0:
413  break;
414  case 1:
416  }
417 
418  switch ((buf[2] >> 0) & 3) {
419  case 0:
421  break;
422  case 1:
424  break;
425  case 2:
427  break;
428  case 3:
430  break;
431  }
432 
433  switch ((buf[0] >> 4) & 7) {
434  case 0:
436  break;
437  case 1:
438  c->hierarchy = HIERARCHY_1;
439  break;
440  case 2:
441  c->hierarchy = HIERARCHY_2;
442  break;
443  case 3:
444  c->hierarchy = HIERARCHY_4;
445  break;
446  }
447 
448  switch ((buf[1] >> 3) & 7) {
449  case 0:
450  c->code_rate_HP = FEC_1_2;
451  break;
452  case 1:
453  c->code_rate_HP = FEC_2_3;
454  break;
455  case 2:
456  c->code_rate_HP = FEC_3_4;
457  break;
458  case 3:
459  c->code_rate_HP = FEC_5_6;
460  break;
461  case 4:
462  c->code_rate_HP = FEC_7_8;
463  break;
464  }
465 
466  switch ((buf[1] >> 0) & 7) {
467  case 0:
468  c->code_rate_LP = FEC_1_2;
469  break;
470  case 1:
471  c->code_rate_LP = FEC_2_3;
472  break;
473  case 2:
474  c->code_rate_LP = FEC_3_4;
475  break;
476  case 3:
477  c->code_rate_LP = FEC_5_6;
478  break;
479  case 4:
480  c->code_rate_LP = FEC_7_8;
481  break;
482  }
483 
484  return 0;
485 err:
486  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
487  return ret;
488 }
489 
490 static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status)
491 {
492  struct rtl2830_priv *priv = fe->demodulator_priv;
493  int ret;
494  u8 tmp;
495  *status = 0;
496 
497  if (priv->sleeping)
498  return 0;
499 
500  ret = rtl2830_rd_reg_mask(priv, 0x351, &tmp, 0x78); /* [6:3] */
501  if (ret)
502  goto err;
503 
504  if (tmp == 11) {
505  *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
507  } else if (tmp == 10) {
508  *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
510  }
511 
512  return ret;
513 err:
514  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
515  return ret;
516 }
517 
518 static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
519 {
520  struct rtl2830_priv *priv = fe->demodulator_priv;
521  int ret, hierarchy, constellation;
522  u8 buf[2], tmp;
523  u16 tmp16;
524 #define CONSTELLATION_NUM 3
525 #define HIERARCHY_NUM 4
526  static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
527  { 70705899, 70705899, 70705899, 70705899 },
528  { 82433173, 82433173, 87483115, 94445660 },
529  { 92888734, 92888734, 95487525, 99770748 },
530  };
531 
532  if (priv->sleeping)
533  return 0;
534 
535  /* reports SNR in resolution of 0.1 dB */
536 
537  ret = rtl2830_rd_reg(priv, 0x33c, &tmp);
538  if (ret)
539  goto err;
540 
541  constellation = (tmp >> 2) & 0x03; /* [3:2] */
542  if (constellation > CONSTELLATION_NUM - 1)
543  goto err;
544 
545  hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
546  if (hierarchy > HIERARCHY_NUM - 1)
547  goto err;
548 
549  ret = rtl2830_rd_regs(priv, 0x40c, buf, 2);
550  if (ret)
551  goto err;
552 
553  tmp16 = buf[0] << 8 | buf[1];
554 
555  if (tmp16)
556  *snr = (snr_constant[constellation][hierarchy] -
557  intlog10(tmp16)) / ((1 << 24) / 100);
558  else
559  *snr = 0;
560 
561  return 0;
562 err:
563  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
564  return ret;
565 }
566 
567 static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
568 {
569  struct rtl2830_priv *priv = fe->demodulator_priv;
570  int ret;
571  u8 buf[2];
572 
573  if (priv->sleeping)
574  return 0;
575 
576  ret = rtl2830_rd_regs(priv, 0x34e, buf, 2);
577  if (ret)
578  goto err;
579 
580  *ber = buf[0] << 8 | buf[1];
581 
582  return 0;
583 err:
584  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
585  return ret;
586 }
587 
588 static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
589 {
590  *ucblocks = 0;
591  return 0;
592 }
593 
594 static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
595 {
596  struct rtl2830_priv *priv = fe->demodulator_priv;
597  int ret;
598  u8 buf[2];
599  u16 if_agc_raw, if_agc;
600 
601  if (priv->sleeping)
602  return 0;
603 
604  ret = rtl2830_rd_regs(priv, 0x359, buf, 2);
605  if (ret)
606  goto err;
607 
608  if_agc_raw = (buf[0] << 8 | buf[1]) & 0x3fff;
609 
610  if (if_agc_raw & (1 << 9))
611  if_agc = -(~(if_agc_raw - 1) & 0x1ff);
612  else
613  if_agc = if_agc_raw;
614 
615  *strength = (u8) (55 - if_agc / 182);
616  *strength |= *strength << 8;
617 
618  return 0;
619 err:
620  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
621  return ret;
622 }
623 
624 static struct dvb_frontend_ops rtl2830_ops;
625 
626 static u32 rtl2830_tuner_i2c_func(struct i2c_adapter *adapter)
627 {
628  return I2C_FUNC_I2C;
629 }
630 
631 static int rtl2830_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
632  struct i2c_msg msg[], int num)
633 {
634  struct rtl2830_priv *priv = i2c_get_adapdata(i2c_adap);
635  int ret;
636 
637  /* open i2c-gate */
638  ret = rtl2830_wr_reg_mask(priv, 0x101, 0x08, 0x08);
639  if (ret)
640  goto err;
641 
642  ret = i2c_transfer(priv->i2c, msg, num);
643  if (ret < 0)
644  dev_warn(&priv->i2c->dev, "%s: tuner i2c failed=%d\n",
645  KBUILD_MODNAME, ret);
646 
647  return ret;
648 err:
649  dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
650  return ret;
651 }
652 
653 static struct i2c_algorithm rtl2830_tuner_i2c_algo = {
654  .master_xfer = rtl2830_tuner_i2c_xfer,
655  .functionality = rtl2830_tuner_i2c_func,
656 };
657 
659 {
660  struct rtl2830_priv *priv = fe->demodulator_priv;
661  return &priv->tuner_i2c_adapter;
662 }
664 
665 static void rtl2830_release(struct dvb_frontend *fe)
666 {
667  struct rtl2830_priv *priv = fe->demodulator_priv;
668 
670  kfree(priv);
671 }
672 
674  struct i2c_adapter *i2c)
675 {
676  struct rtl2830_priv *priv = NULL;
677  int ret = 0;
678  u8 tmp;
679 
680  /* allocate memory for the internal state */
681  priv = kzalloc(sizeof(struct rtl2830_priv), GFP_KERNEL);
682  if (priv == NULL)
683  goto err;
684 
685  /* setup the priv */
686  priv->i2c = i2c;
687  memcpy(&priv->cfg, cfg, sizeof(struct rtl2830_config));
688 
689  /* check if the demod is there */
690  ret = rtl2830_rd_reg(priv, 0x000, &tmp);
691  if (ret)
692  goto err;
693 
694  /* create dvb_frontend */
695  memcpy(&priv->fe.ops, &rtl2830_ops, sizeof(struct dvb_frontend_ops));
696  priv->fe.demodulator_priv = priv;
697 
698  /* create tuner i2c adapter */
699  strlcpy(priv->tuner_i2c_adapter.name, "RTL2830 tuner I2C adapter",
700  sizeof(priv->tuner_i2c_adapter.name));
701  priv->tuner_i2c_adapter.algo = &rtl2830_tuner_i2c_algo;
702  priv->tuner_i2c_adapter.algo_data = NULL;
703  i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
704  if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
705  dev_err(&i2c->dev,
706  "%s: tuner i2c bus could not be initialized\n",
707  KBUILD_MODNAME);
708  goto err;
709  }
710 
711  priv->sleeping = true;
712 
713  return &priv->fe;
714 err:
715  dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
716  kfree(priv);
717  return NULL;
718 }
720 
721 static struct dvb_frontend_ops rtl2830_ops = {
722  .delsys = { SYS_DVBT },
723  .info = {
724  .name = "Realtek RTL2830 (DVB-T)",
725  .caps = FE_CAN_FEC_1_2 |
731  FE_CAN_QPSK |
732  FE_CAN_QAM_16 |
733  FE_CAN_QAM_64 |
740  },
741 
742  .release = rtl2830_release,
743 
744  .init = rtl2830_init,
745  .sleep = rtl2830_sleep,
746 
747  .get_tune_settings = rtl2830_get_tune_settings,
748 
749  .set_frontend = rtl2830_set_frontend,
750  .get_frontend = rtl2830_get_frontend,
751 
752  .read_status = rtl2830_read_status,
753  .read_snr = rtl2830_read_snr,
754  .read_ber = rtl2830_read_ber,
755  .read_ucblocks = rtl2830_read_ucblocks,
756  .read_signal_strength = rtl2830_read_signal_strength,
757 };
758 
759 MODULE_AUTHOR("Antti Palosaari <[email protected]>");
760 MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
761 MODULE_LICENSE("GPL");