1 /* 2 * Silicon Labs Si2168 DVB-T/T2/C demodulator driver 3 * 4 * Copyright (C) 2014 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 17 #include "si2168_priv.h" 18 19 static const struct dvb_frontend_ops si2168_ops; 20 21 /* execute firmware command */ 22 static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd) 23 { 24 int ret; 25 unsigned long timeout; 26 27 mutex_lock(&s->i2c_mutex); 28 29 if (cmd->wlen) { 30 /* write cmd and args for firmware */ 31 ret = i2c_master_send(s->client, cmd->args, cmd->wlen); 32 if (ret < 0) { 33 goto err_mutex_unlock; 34 } else if (ret != cmd->wlen) { 35 ret = -EREMOTEIO; 36 goto err_mutex_unlock; 37 } 38 } 39 40 if (cmd->rlen) { 41 /* wait cmd execution terminate */ 42 #define TIMEOUT 50 43 timeout = jiffies + msecs_to_jiffies(TIMEOUT); 44 while (!time_after(jiffies, timeout)) { 45 ret = i2c_master_recv(s->client, cmd->args, cmd->rlen); 46 if (ret < 0) { 47 goto err_mutex_unlock; 48 } else if (ret != cmd->rlen) { 49 ret = -EREMOTEIO; 50 goto err_mutex_unlock; 51 } 52 53 /* firmware ready? */ 54 if ((cmd->args[0] >> 7) & 0x01) 55 break; 56 } 57 58 dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n", 59 __func__, 60 jiffies_to_msecs(jiffies) - 61 (jiffies_to_msecs(timeout) - TIMEOUT)); 62 63 if (!(cmd->args[0] >> 7) & 0x01) { 64 ret = -ETIMEDOUT; 65 goto err_mutex_unlock; 66 } 67 } 68 69 ret = 0; 70 71 err_mutex_unlock: 72 mutex_unlock(&s->i2c_mutex); 73 if (ret) 74 goto err; 75 76 return 0; 77 err: 78 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 79 return ret; 80 } 81 82 static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status) 83 { 84 struct si2168 *s = fe->demodulator_priv; 85 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 86 int ret; 87 struct si2168_cmd cmd; 88 89 *status = 0; 90 91 if (!s->active) { 92 ret = -EAGAIN; 93 goto err; 94 } 95 96 switch (c->delivery_system) { 97 case SYS_DVBT: 98 cmd.args[0] = 0xa0; 99 cmd.args[1] = 0x01; 100 cmd.wlen = 2; 101 cmd.rlen = 13; 102 break; 103 case SYS_DVBC_ANNEX_A: 104 cmd.args[0] = 0x90; 105 cmd.args[1] = 0x01; 106 cmd.wlen = 2; 107 cmd.rlen = 9; 108 break; 109 case SYS_DVBT2: 110 cmd.args[0] = 0x50; 111 cmd.args[1] = 0x01; 112 cmd.wlen = 2; 113 cmd.rlen = 14; 114 break; 115 default: 116 ret = -EINVAL; 117 goto err; 118 } 119 120 ret = si2168_cmd_execute(s, &cmd); 121 if (ret) 122 goto err; 123 124 /* 125 * Possible values seen, in order from strong signal to weak: 126 * 16 0001 0110 full lock 127 * 1e 0001 1110 partial lock 128 * 1a 0001 1010 partial lock 129 * 18 0001 1000 no lock 130 * 131 * [b3:b1] lock bits 132 * [b4] statistics ready? Set in a few secs after lock is gained. 133 */ 134 135 switch ((cmd.args[2] >> 1) & 0x03) { 136 case 0x01: 137 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; 138 break; 139 case 0x03: 140 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | 141 FE_HAS_SYNC | FE_HAS_LOCK; 142 break; 143 } 144 145 s->fe_status = *status; 146 147 dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n", 148 __func__, *status, cmd.rlen, cmd.args); 149 150 return 0; 151 err: 152 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 153 return ret; 154 } 155 156 static int si2168_set_frontend(struct dvb_frontend *fe) 157 { 158 struct si2168 *s = fe->demodulator_priv; 159 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 160 int ret; 161 struct si2168_cmd cmd; 162 u8 bandwidth, delivery_system; 163 164 dev_dbg(&s->client->dev, 165 "%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u\n", 166 __func__, c->delivery_system, c->modulation, 167 c->frequency, c->bandwidth_hz, c->symbol_rate, 168 c->inversion); 169 170 if (!s->active) { 171 ret = -EAGAIN; 172 goto err; 173 } 174 175 switch (c->delivery_system) { 176 case SYS_DVBT: 177 delivery_system = 0x20; 178 break; 179 case SYS_DVBC_ANNEX_A: 180 delivery_system = 0x30; 181 break; 182 case SYS_DVBT2: 183 delivery_system = 0x70; 184 break; 185 default: 186 ret = -EINVAL; 187 goto err; 188 } 189 190 if (c->bandwidth_hz <= 5000000) 191 bandwidth = 0x05; 192 else if (c->bandwidth_hz <= 6000000) 193 bandwidth = 0x06; 194 else if (c->bandwidth_hz <= 7000000) 195 bandwidth = 0x07; 196 else if (c->bandwidth_hz <= 8000000) 197 bandwidth = 0x08; 198 else if (c->bandwidth_hz <= 9000000) 199 bandwidth = 0x09; 200 else if (c->bandwidth_hz <= 10000000) 201 bandwidth = 0x0a; 202 else 203 bandwidth = 0x0f; 204 205 /* program tuner */ 206 if (fe->ops.tuner_ops.set_params) { 207 ret = fe->ops.tuner_ops.set_params(fe); 208 if (ret) 209 goto err; 210 } 211 212 memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5); 213 cmd.wlen = 5; 214 cmd.rlen = 5; 215 ret = si2168_cmd_execute(s, &cmd); 216 if (ret) 217 goto err; 218 219 /* that has no big effect */ 220 if (c->delivery_system == SYS_DVBT) 221 memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6); 222 else if (c->delivery_system == SYS_DVBC_ANNEX_A) 223 memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6); 224 else if (c->delivery_system == SYS_DVBT2) 225 memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6); 226 cmd.wlen = 6; 227 cmd.rlen = 3; 228 ret = si2168_cmd_execute(s, &cmd); 229 if (ret) 230 goto err; 231 232 memcpy(cmd.args, "\x51\x03", 2); 233 cmd.wlen = 2; 234 cmd.rlen = 12; 235 ret = si2168_cmd_execute(s, &cmd); 236 if (ret) 237 goto err; 238 239 memcpy(cmd.args, "\x12\x08\x04", 3); 240 cmd.wlen = 3; 241 cmd.rlen = 3; 242 ret = si2168_cmd_execute(s, &cmd); 243 if (ret) 244 goto err; 245 246 memcpy(cmd.args, "\x14\x00\x01\x04\x00\x00", 6); 247 cmd.wlen = 6; 248 cmd.rlen = 1; 249 ret = si2168_cmd_execute(s, &cmd); 250 if (ret) 251 goto err; 252 253 memcpy(cmd.args, "\x14\x00\x03\x10\x17\x00", 6); 254 cmd.wlen = 6; 255 cmd.rlen = 1; 256 ret = si2168_cmd_execute(s, &cmd); 257 if (ret) 258 goto err; 259 260 memcpy(cmd.args, "\x14\x00\x02\x10\x15\x00", 6); 261 cmd.wlen = 6; 262 cmd.rlen = 1; 263 ret = si2168_cmd_execute(s, &cmd); 264 if (ret) 265 goto err; 266 267 memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6); 268 cmd.wlen = 6; 269 cmd.rlen = 1; 270 ret = si2168_cmd_execute(s, &cmd); 271 if (ret) 272 goto err; 273 274 memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6); 275 cmd.wlen = 6; 276 cmd.rlen = 1; 277 ret = si2168_cmd_execute(s, &cmd); 278 if (ret) 279 goto err; 280 281 memcpy(cmd.args, "\x14\x00\x0b\x10\x88\x13", 6); 282 cmd.wlen = 6; 283 cmd.rlen = 1; 284 ret = si2168_cmd_execute(s, &cmd); 285 if (ret) 286 goto err; 287 288 memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6); 289 cmd.wlen = 6; 290 cmd.rlen = 1; 291 ret = si2168_cmd_execute(s, &cmd); 292 if (ret) 293 goto err; 294 295 memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6); 296 cmd.args[4] = delivery_system | bandwidth; 297 cmd.wlen = 6; 298 cmd.rlen = 1; 299 ret = si2168_cmd_execute(s, &cmd); 300 if (ret) 301 goto err; 302 303 memcpy(cmd.args, "\x14\x00\x04\x10\x15\x00", 6); 304 cmd.wlen = 6; 305 cmd.rlen = 1; 306 ret = si2168_cmd_execute(s, &cmd); 307 if (ret) 308 goto err; 309 310 memcpy(cmd.args, "\x14\x00\x05\x10\xa1\x00", 6); 311 cmd.wlen = 6; 312 cmd.rlen = 1; 313 ret = si2168_cmd_execute(s, &cmd); 314 if (ret) 315 goto err; 316 317 memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6); 318 cmd.wlen = 6; 319 cmd.rlen = 1; 320 ret = si2168_cmd_execute(s, &cmd); 321 if (ret) 322 goto err; 323 324 memcpy(cmd.args, "\x14\x00\x0d\x10\xd0\x02", 6); 325 cmd.wlen = 6; 326 cmd.rlen = 1; 327 ret = si2168_cmd_execute(s, &cmd); 328 if (ret) 329 goto err; 330 331 memcpy(cmd.args, "\x14\x00\x01\x10\x00\x00", 6); 332 cmd.wlen = 6; 333 cmd.rlen = 1; 334 ret = si2168_cmd_execute(s, &cmd); 335 if (ret) 336 goto err; 337 338 memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6); 339 cmd.wlen = 6; 340 cmd.rlen = 1; 341 ret = si2168_cmd_execute(s, &cmd); 342 if (ret) 343 goto err; 344 345 memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6); 346 cmd.wlen = 6; 347 cmd.rlen = 1; 348 ret = si2168_cmd_execute(s, &cmd); 349 if (ret) 350 goto err; 351 352 memcpy(cmd.args, "\x14\x00\x04\x03\x00\x00", 6); 353 cmd.wlen = 6; 354 cmd.rlen = 1; 355 ret = si2168_cmd_execute(s, &cmd); 356 if (ret) 357 goto err; 358 359 memcpy(cmd.args, "\x14\x00\x03\x03\x00\x00", 6); 360 cmd.wlen = 6; 361 cmd.rlen = 1; 362 ret = si2168_cmd_execute(s, &cmd); 363 if (ret) 364 goto err; 365 366 memcpy(cmd.args, "\x14\x00\x08\x03\x00\x00", 6); 367 cmd.wlen = 6; 368 cmd.rlen = 1; 369 ret = si2168_cmd_execute(s, &cmd); 370 if (ret) 371 goto err; 372 373 memcpy(cmd.args, "\x14\x00\x07\x03\x01\x02", 6); 374 cmd.wlen = 6; 375 cmd.rlen = 1; 376 ret = si2168_cmd_execute(s, &cmd); 377 if (ret) 378 goto err; 379 380 memcpy(cmd.args, "\x14\x00\x06\x03\x00\x00", 6); 381 cmd.wlen = 6; 382 cmd.rlen = 1; 383 ret = si2168_cmd_execute(s, &cmd); 384 if (ret) 385 goto err; 386 387 memcpy(cmd.args, "\x14\x00\x05\x03\x00\x00", 6); 388 cmd.wlen = 6; 389 cmd.rlen = 1; 390 ret = si2168_cmd_execute(s, &cmd); 391 if (ret) 392 goto err; 393 394 memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x40", 6); 395 cmd.wlen = 6; 396 cmd.rlen = 1; 397 ret = si2168_cmd_execute(s, &cmd); 398 if (ret) 399 goto err; 400 401 memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6); 402 cmd.wlen = 6; 403 cmd.rlen = 1; 404 ret = si2168_cmd_execute(s, &cmd); 405 if (ret) 406 goto err; 407 408 memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6); 409 cmd.wlen = 6; 410 cmd.rlen = 1; 411 ret = si2168_cmd_execute(s, &cmd); 412 if (ret) 413 goto err; 414 415 cmd.args[0] = 0x85; 416 cmd.wlen = 1; 417 cmd.rlen = 1; 418 ret = si2168_cmd_execute(s, &cmd); 419 if (ret) 420 goto err; 421 422 s->delivery_system = c->delivery_system; 423 424 return 0; 425 err: 426 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 427 return ret; 428 } 429 430 static int si2168_init(struct dvb_frontend *fe) 431 { 432 struct si2168 *s = fe->demodulator_priv; 433 int ret, len, remaining; 434 const struct firmware *fw = NULL; 435 u8 *fw_file = SI2168_FIRMWARE; 436 const unsigned int i2c_wr_max = 8; 437 struct si2168_cmd cmd; 438 439 dev_dbg(&s->client->dev, "%s:\n", __func__); 440 441 cmd.args[0] = 0x13; 442 cmd.wlen = 1; 443 cmd.rlen = 0; 444 ret = si2168_cmd_execute(s, &cmd); 445 if (ret) 446 goto err; 447 448 cmd.args[0] = 0xc0; 449 cmd.args[1] = 0x12; 450 cmd.args[2] = 0x00; 451 cmd.args[3] = 0x0c; 452 cmd.args[4] = 0x00; 453 cmd.args[5] = 0x0d; 454 cmd.args[6] = 0x16; 455 cmd.args[7] = 0x00; 456 cmd.args[8] = 0x00; 457 cmd.args[9] = 0x00; 458 cmd.args[10] = 0x00; 459 cmd.args[11] = 0x00; 460 cmd.args[12] = 0x00; 461 cmd.wlen = 13; 462 cmd.rlen = 0; 463 ret = si2168_cmd_execute(s, &cmd); 464 if (ret) 465 goto err; 466 467 cmd.args[0] = 0xc0; 468 cmd.args[1] = 0x06; 469 cmd.args[2] = 0x01; 470 cmd.args[3] = 0x0f; 471 cmd.args[4] = 0x00; 472 cmd.args[5] = 0x20; 473 cmd.args[6] = 0x20; 474 cmd.args[7] = 0x01; 475 cmd.wlen = 8; 476 cmd.rlen = 1; 477 ret = si2168_cmd_execute(s, &cmd); 478 if (ret) 479 goto err; 480 481 cmd.args[0] = 0x02; 482 cmd.wlen = 1; 483 cmd.rlen = 13; 484 ret = si2168_cmd_execute(s, &cmd); 485 if (ret) 486 goto err; 487 488 cmd.args[0] = 0x05; 489 cmd.args[1] = 0x00; 490 cmd.args[2] = 0xaa; 491 cmd.args[3] = 0x4d; 492 cmd.args[4] = 0x56; 493 cmd.args[5] = 0x40; 494 cmd.args[6] = 0x00; 495 cmd.args[7] = 0x00; 496 cmd.wlen = 8; 497 cmd.rlen = 1; 498 ret = si2168_cmd_execute(s, &cmd); 499 if (ret) 500 goto err; 501 502 /* cold state - try to download firmware */ 503 dev_info(&s->client->dev, "%s: found a '%s' in cold state\n", 504 KBUILD_MODNAME, si2168_ops.info.name); 505 506 /* request the firmware, this will block and timeout */ 507 ret = request_firmware(&fw, fw_file, &s->client->dev); 508 if (ret) { 509 dev_err(&s->client->dev, "%s: firmare file '%s' not found\n", 510 KBUILD_MODNAME, fw_file); 511 goto err; 512 } 513 514 dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n", 515 KBUILD_MODNAME, fw_file); 516 517 for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) { 518 len = remaining; 519 if (len > i2c_wr_max) 520 len = i2c_wr_max; 521 522 memcpy(cmd.args, &fw->data[fw->size - remaining], len); 523 cmd.wlen = len; 524 cmd.rlen = 1; 525 ret = si2168_cmd_execute(s, &cmd); 526 if (ret) { 527 dev_err(&s->client->dev, 528 "%s: firmware download failed=%d\n", 529 KBUILD_MODNAME, ret); 530 goto err; 531 } 532 } 533 534 release_firmware(fw); 535 fw = NULL; 536 537 cmd.args[0] = 0x01; 538 cmd.args[1] = 0x01; 539 cmd.wlen = 2; 540 cmd.rlen = 1; 541 ret = si2168_cmd_execute(s, &cmd); 542 if (ret) 543 goto err; 544 545 dev_info(&s->client->dev, "%s: found a '%s' in warm state\n", 546 KBUILD_MODNAME, si2168_ops.info.name); 547 548 s->active = true; 549 550 return 0; 551 err: 552 if (fw) 553 release_firmware(fw); 554 555 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 556 return ret; 557 } 558 559 static int si2168_sleep(struct dvb_frontend *fe) 560 { 561 struct si2168 *s = fe->demodulator_priv; 562 563 dev_dbg(&s->client->dev, "%s:\n", __func__); 564 565 s->active = false; 566 567 return 0; 568 } 569 570 static int si2168_get_tune_settings(struct dvb_frontend *fe, 571 struct dvb_frontend_tune_settings *s) 572 { 573 s->min_delay_ms = 900; 574 575 return 0; 576 } 577 578 /* 579 * I2C gate logic 580 * We must use unlocked i2c_transfer() here because I2C lock is already taken 581 * by tuner driver. 582 */ 583 static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) 584 { 585 struct si2168 *s = mux_priv; 586 int ret; 587 struct i2c_msg gate_open_msg = { 588 .addr = s->client->addr, 589 .flags = 0, 590 .len = 3, 591 .buf = "\xc0\x0d\x01", 592 }; 593 594 mutex_lock(&s->i2c_mutex); 595 596 /* open tuner I2C gate */ 597 ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1); 598 if (ret != 1) { 599 dev_warn(&s->client->dev, "%s: i2c write failed=%d\n", 600 KBUILD_MODNAME, ret); 601 if (ret >= 0) 602 ret = -EREMOTEIO; 603 } else { 604 ret = 0; 605 } 606 607 return ret; 608 } 609 610 static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan) 611 { 612 struct si2168 *s = mux_priv; 613 int ret; 614 struct i2c_msg gate_close_msg = { 615 .addr = s->client->addr, 616 .flags = 0, 617 .len = 3, 618 .buf = "\xc0\x0d\x00", 619 }; 620 621 /* close tuner I2C gate */ 622 ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1); 623 if (ret != 1) { 624 dev_warn(&s->client->dev, "%s: i2c write failed=%d\n", 625 KBUILD_MODNAME, ret); 626 if (ret >= 0) 627 ret = -EREMOTEIO; 628 } else { 629 ret = 0; 630 } 631 632 mutex_unlock(&s->i2c_mutex); 633 634 return ret; 635 } 636 637 static const struct dvb_frontend_ops si2168_ops = { 638 .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A}, 639 .info = { 640 .name = "Silicon Labs Si2168", 641 .caps = FE_CAN_FEC_1_2 | 642 FE_CAN_FEC_2_3 | 643 FE_CAN_FEC_3_4 | 644 FE_CAN_FEC_5_6 | 645 FE_CAN_FEC_7_8 | 646 FE_CAN_FEC_AUTO | 647 FE_CAN_QPSK | 648 FE_CAN_QAM_16 | 649 FE_CAN_QAM_32 | 650 FE_CAN_QAM_64 | 651 FE_CAN_QAM_128 | 652 FE_CAN_QAM_256 | 653 FE_CAN_QAM_AUTO | 654 FE_CAN_TRANSMISSION_MODE_AUTO | 655 FE_CAN_GUARD_INTERVAL_AUTO | 656 FE_CAN_HIERARCHY_AUTO | 657 FE_CAN_MUTE_TS | 658 FE_CAN_2G_MODULATION 659 }, 660 661 .get_tune_settings = si2168_get_tune_settings, 662 663 .init = si2168_init, 664 .sleep = si2168_sleep, 665 666 .set_frontend = si2168_set_frontend, 667 668 .read_status = si2168_read_status, 669 }; 670 671 static int si2168_probe(struct i2c_client *client, 672 const struct i2c_device_id *id) 673 { 674 struct si2168_config *config = client->dev.platform_data; 675 struct si2168 *s; 676 int ret; 677 struct si2168_cmd cmd; 678 679 dev_dbg(&client->dev, "%s:\n", __func__); 680 681 s = kzalloc(sizeof(struct si2168), GFP_KERNEL); 682 if (!s) { 683 ret = -ENOMEM; 684 dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); 685 goto err; 686 } 687 688 s->client = client; 689 mutex_init(&s->i2c_mutex); 690 691 /* check if the demod is there */ 692 cmd.wlen = 0; 693 cmd.rlen = 1; 694 ret = si2168_cmd_execute(s, &cmd); 695 if (ret) 696 goto err; 697 698 /* create mux i2c adapter for tuner */ 699 s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s, 700 0, 0, 0, si2168_select, si2168_deselect); 701 if (s->adapter == NULL) 702 goto err; 703 704 /* create dvb_frontend */ 705 memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops)); 706 s->fe.demodulator_priv = s; 707 708 *config->i2c_adapter = s->adapter; 709 *config->fe = &s->fe; 710 711 i2c_set_clientdata(client, s); 712 713 dev_info(&s->client->dev, 714 "%s: Silicon Labs Si2168 successfully attached\n", 715 KBUILD_MODNAME); 716 return 0; 717 err: 718 kfree(s); 719 dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret); 720 return ret; 721 } 722 723 static int si2168_remove(struct i2c_client *client) 724 { 725 struct si2168 *s = i2c_get_clientdata(client); 726 727 dev_dbg(&client->dev, "%s:\n", __func__); 728 729 i2c_del_mux_adapter(s->adapter); 730 731 s->fe.ops.release = NULL; 732 s->fe.demodulator_priv = NULL; 733 734 kfree(s); 735 736 return 0; 737 } 738 739 static const struct i2c_device_id si2168_id[] = { 740 {"si2168", 0}, 741 {} 742 }; 743 MODULE_DEVICE_TABLE(i2c, si2168_id); 744 745 static struct i2c_driver si2168_driver = { 746 .driver = { 747 .owner = THIS_MODULE, 748 .name = "si2168", 749 }, 750 .probe = si2168_probe, 751 .remove = si2168_remove, 752 .id_table = si2168_id, 753 }; 754 755 module_i2c_driver(si2168_driver); 756 757 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 758 MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver"); 759 MODULE_LICENSE("GPL"); 760 MODULE_FIRMWARE(SI2168_FIRMWARE); 761