si2168.c revision b6b6fd6feb5f71267ef535f15061a397f86ebb26
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 19static const struct dvb_frontend_ops si2168_ops; 20 21/* execute firmware command */ 22static 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 71err_mutex_unlock: 72 mutex_unlock(&s->i2c_mutex); 73 if (ret) 74 goto err; 75 76 return 0; 77err: 78 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 79 return ret; 80} 81 82static 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; 157err: 158 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 159 return ret; 160} 161 162static 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 memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6); 282 cmd.wlen = 6; 283 cmd.rlen = 4; 284 ret = si2168_cmd_execute(s, &cmd); 285 if (ret) 286 goto err; 287 288 memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6); 289 cmd.wlen = 6; 290 cmd.rlen = 4; 291 ret = si2168_cmd_execute(s, &cmd); 292 if (ret) 293 goto err; 294 295 memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6); 296 cmd.wlen = 6; 297 cmd.rlen = 4; 298 ret = si2168_cmd_execute(s, &cmd); 299 if (ret) 300 goto err; 301 302 memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6); 303 cmd.wlen = 6; 304 cmd.rlen = 4; 305 ret = si2168_cmd_execute(s, &cmd); 306 if (ret) 307 goto err; 308 309 memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6); 310 cmd.wlen = 6; 311 cmd.rlen = 4; 312 ret = si2168_cmd_execute(s, &cmd); 313 if (ret) 314 goto err; 315 316 memcpy(cmd.args, "\x85", 1); 317 cmd.wlen = 1; 318 cmd.rlen = 1; 319 ret = si2168_cmd_execute(s, &cmd); 320 if (ret) 321 goto err; 322 323 s->delivery_system = c->delivery_system; 324 325 return 0; 326err: 327 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 328 return ret; 329} 330 331static int si2168_init(struct dvb_frontend *fe) 332{ 333 struct si2168 *s = fe->demodulator_priv; 334 int ret, len, remaining; 335 const struct firmware *fw = NULL; 336 u8 *fw_file; 337 const unsigned int i2c_wr_max = 8; 338 struct si2168_cmd cmd; 339 unsigned int chip_id; 340 341 dev_dbg(&s->client->dev, "%s:\n", __func__); 342 343 memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13); 344 cmd.wlen = 13; 345 cmd.rlen = 0; 346 ret = si2168_cmd_execute(s, &cmd); 347 if (ret) 348 goto err; 349 350 memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8); 351 cmd.wlen = 8; 352 cmd.rlen = 1; 353 ret = si2168_cmd_execute(s, &cmd); 354 if (ret) 355 goto err; 356 357 /* query chip revision */ 358 memcpy(cmd.args, "\x02", 1); 359 cmd.wlen = 1; 360 cmd.rlen = 13; 361 ret = si2168_cmd_execute(s, &cmd); 362 if (ret) 363 goto err; 364 365 cmd.args[0] = 0x05; 366 cmd.args[1] = 0x00; 367 cmd.args[2] = 0xaa; 368 cmd.args[3] = 0x4d; 369 cmd.args[4] = 0x56; 370 cmd.args[5] = 0x40; 371 cmd.args[6] = 0x00; 372 cmd.args[7] = 0x00; 373 cmd.wlen = 8; 374 cmd.rlen = 1; 375 ret = si2168_cmd_execute(s, &cmd); 376 if (ret) 377 goto err; 378 379 chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 | 380 cmd.args[4] << 0; 381 382 #define SI2168_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0) 383 #define SI2168_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0) 384 385 switch (chip_id) { 386 case SI2168_A30: 387 fw_file = SI2168_A30_FIRMWARE; 388 break; 389 case SI2168_B40: 390 fw_file = SI2168_B40_FIRMWARE; 391 break; 392 default: 393 dev_err(&s->client->dev, 394 "%s: unkown chip version Si21%d-%c%c%c\n", 395 KBUILD_MODNAME, cmd.args[2], cmd.args[1], 396 cmd.args[3], cmd.args[4]); 397 ret = -EINVAL; 398 goto err; 399 } 400 401 /* cold state - try to download firmware */ 402 dev_info(&s->client->dev, "%s: found a '%s' in cold state\n", 403 KBUILD_MODNAME, si2168_ops.info.name); 404 405 /* request the firmware, this will block and timeout */ 406 ret = request_firmware(&fw, fw_file, &s->client->dev); 407 if (ret) { 408 /* fallback mechanism to handle old name for Si2168 B40 fw */ 409 if (chip_id == SI2168_B40) { 410 fw_file = SI2168_B40_FIRMWARE_FALLBACK; 411 ret = request_firmware(&fw, fw_file, &s->client->dev); 412 } 413 414 if (ret == 0) { 415 dev_notice(&s->client->dev, 416 "%s: please install firmware file '%s'\n", 417 KBUILD_MODNAME, SI2168_B40_FIRMWARE); 418 } else { 419 dev_err(&s->client->dev, 420 "%s: firmware file '%s' not found\n", 421 KBUILD_MODNAME, fw_file); 422 goto err; 423 } 424 } 425 426 dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n", 427 KBUILD_MODNAME, fw_file); 428 429 for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) { 430 len = remaining; 431 if (len > i2c_wr_max) 432 len = i2c_wr_max; 433 434 memcpy(cmd.args, &fw->data[fw->size - remaining], len); 435 cmd.wlen = len; 436 cmd.rlen = 1; 437 ret = si2168_cmd_execute(s, &cmd); 438 if (ret) { 439 dev_err(&s->client->dev, 440 "%s: firmware download failed=%d\n", 441 KBUILD_MODNAME, ret); 442 goto err; 443 } 444 } 445 446 release_firmware(fw); 447 fw = NULL; 448 449 memcpy(cmd.args, "\x01\x01", 2); 450 cmd.wlen = 2; 451 cmd.rlen = 1; 452 ret = si2168_cmd_execute(s, &cmd); 453 if (ret) 454 goto err; 455 456 dev_info(&s->client->dev, "%s: found a '%s' in warm state\n", 457 KBUILD_MODNAME, si2168_ops.info.name); 458 459 s->active = true; 460 461 return 0; 462err: 463 if (fw) 464 release_firmware(fw); 465 466 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 467 return ret; 468} 469 470static int si2168_sleep(struct dvb_frontend *fe) 471{ 472 struct si2168 *s = fe->demodulator_priv; 473 int ret; 474 struct si2168_cmd cmd; 475 476 dev_dbg(&s->client->dev, "%s:\n", __func__); 477 478 s->active = false; 479 480 memcpy(cmd.args, "\x13", 1); 481 cmd.wlen = 1; 482 cmd.rlen = 0; 483 ret = si2168_cmd_execute(s, &cmd); 484 if (ret) 485 goto err; 486 487 return 0; 488err: 489 dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 490 return ret; 491} 492 493static int si2168_get_tune_settings(struct dvb_frontend *fe, 494 struct dvb_frontend_tune_settings *s) 495{ 496 s->min_delay_ms = 900; 497 498 return 0; 499} 500 501/* 502 * I2C gate logic 503 * We must use unlocked i2c_transfer() here because I2C lock is already taken 504 * by tuner driver. 505 */ 506static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) 507{ 508 struct si2168 *s = mux_priv; 509 int ret; 510 struct i2c_msg gate_open_msg = { 511 .addr = s->client->addr, 512 .flags = 0, 513 .len = 3, 514 .buf = "\xc0\x0d\x01", 515 }; 516 517 mutex_lock(&s->i2c_mutex); 518 519 /* open tuner I2C gate */ 520 ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1); 521 if (ret != 1) { 522 dev_warn(&s->client->dev, "%s: i2c write failed=%d\n", 523 KBUILD_MODNAME, ret); 524 if (ret >= 0) 525 ret = -EREMOTEIO; 526 } else { 527 ret = 0; 528 } 529 530 return ret; 531} 532 533static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan) 534{ 535 struct si2168 *s = mux_priv; 536 int ret; 537 struct i2c_msg gate_close_msg = { 538 .addr = s->client->addr, 539 .flags = 0, 540 .len = 3, 541 .buf = "\xc0\x0d\x00", 542 }; 543 544 /* close tuner I2C gate */ 545 ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1); 546 if (ret != 1) { 547 dev_warn(&s->client->dev, "%s: i2c write failed=%d\n", 548 KBUILD_MODNAME, ret); 549 if (ret >= 0) 550 ret = -EREMOTEIO; 551 } else { 552 ret = 0; 553 } 554 555 mutex_unlock(&s->i2c_mutex); 556 557 return ret; 558} 559 560static const struct dvb_frontend_ops si2168_ops = { 561 .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A}, 562 .info = { 563 .name = "Silicon Labs Si2168", 564 .caps = FE_CAN_FEC_1_2 | 565 FE_CAN_FEC_2_3 | 566 FE_CAN_FEC_3_4 | 567 FE_CAN_FEC_5_6 | 568 FE_CAN_FEC_7_8 | 569 FE_CAN_FEC_AUTO | 570 FE_CAN_QPSK | 571 FE_CAN_QAM_16 | 572 FE_CAN_QAM_32 | 573 FE_CAN_QAM_64 | 574 FE_CAN_QAM_128 | 575 FE_CAN_QAM_256 | 576 FE_CAN_QAM_AUTO | 577 FE_CAN_TRANSMISSION_MODE_AUTO | 578 FE_CAN_GUARD_INTERVAL_AUTO | 579 FE_CAN_HIERARCHY_AUTO | 580 FE_CAN_MUTE_TS | 581 FE_CAN_2G_MODULATION 582 }, 583 584 .get_tune_settings = si2168_get_tune_settings, 585 586 .init = si2168_init, 587 .sleep = si2168_sleep, 588 589 .set_frontend = si2168_set_frontend, 590 591 .read_status = si2168_read_status, 592}; 593 594static int si2168_probe(struct i2c_client *client, 595 const struct i2c_device_id *id) 596{ 597 struct si2168_config *config = client->dev.platform_data; 598 struct si2168 *s; 599 int ret; 600 struct si2168_cmd cmd; 601 602 dev_dbg(&client->dev, "%s:\n", __func__); 603 604 s = kzalloc(sizeof(struct si2168), GFP_KERNEL); 605 if (!s) { 606 ret = -ENOMEM; 607 dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); 608 goto err; 609 } 610 611 s->client = client; 612 mutex_init(&s->i2c_mutex); 613 614 /* check if the demod is there */ 615 cmd.wlen = 0; 616 cmd.rlen = 1; 617 ret = si2168_cmd_execute(s, &cmd); 618 if (ret) 619 goto err; 620 621 /* create mux i2c adapter for tuner */ 622 s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s, 623 0, 0, 0, si2168_select, si2168_deselect); 624 if (s->adapter == NULL) 625 goto err; 626 627 /* create dvb_frontend */ 628 memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops)); 629 s->fe.demodulator_priv = s; 630 631 *config->i2c_adapter = s->adapter; 632 *config->fe = &s->fe; 633 634 i2c_set_clientdata(client, s); 635 636 dev_info(&s->client->dev, 637 "%s: Silicon Labs Si2168 successfully attached\n", 638 KBUILD_MODNAME); 639 return 0; 640err: 641 kfree(s); 642 dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret); 643 return ret; 644} 645 646static int si2168_remove(struct i2c_client *client) 647{ 648 struct si2168 *s = i2c_get_clientdata(client); 649 650 dev_dbg(&client->dev, "%s:\n", __func__); 651 652 i2c_del_mux_adapter(s->adapter); 653 654 s->fe.ops.release = NULL; 655 s->fe.demodulator_priv = NULL; 656 657 kfree(s); 658 659 return 0; 660} 661 662static const struct i2c_device_id si2168_id[] = { 663 {"si2168", 0}, 664 {} 665}; 666MODULE_DEVICE_TABLE(i2c, si2168_id); 667 668static struct i2c_driver si2168_driver = { 669 .driver = { 670 .owner = THIS_MODULE, 671 .name = "si2168", 672 }, 673 .probe = si2168_probe, 674 .remove = si2168_remove, 675 .id_table = si2168_id, 676}; 677 678module_i2c_driver(si2168_driver); 679 680MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 681MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver"); 682MODULE_LICENSE("GPL"); 683MODULE_FIRMWARE(SI2168_A30_FIRMWARE); 684MODULE_FIRMWARE(SI2168_B40_FIRMWARE); 685