Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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