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