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