1 /* $NetBSD: zl10353.c,v 1.5 2017/06/01 02:45:10 chs Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jukka Ruohonen. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: zl10353.c,v 1.5 2017/06/01 02:45:10 chs Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/kmem.h> 37 #include <sys/module.h> 38 39 #include <dev/dtv/dtvif.h> 40 41 #include <dev/i2c/i2cvar.h> 42 #include <dev/i2c/zl10353reg.h> 43 #include <dev/i2c/zl10353var.h> 44 45 /* 46 * Zarlink ZL10353 demodulator (now known as Intel CE623x). 47 * 48 * An incomplete datasheet: 49 * 50 * Intel Corporation: CE6230 - COFDM demodulator with 51 * USB interface for PC-TV. Data Sheet, Revision 1.1. 52 * March 29, 2007. 53 */ 54 55 static int zl10353_probe(struct zl10353 *); 56 static int zl10353_read(struct zl10353 *, uint8_t, uint8_t *); 57 static int zl10353_write(struct zl10353 *, uint8_t, uint8_t); 58 static int zl10353_reset(struct zl10353 *, bool); 59 static int zl10353_set_agc(struct zl10353 *, 60 const struct dvb_frontend_parameters *); 61 static int zl10353_set_bw(struct zl10353 *, fe_bandwidth_t); 62 static int zl10353_set_rate(struct zl10353 *); 63 static int zl10353_set_freq(struct zl10353 *); 64 static int zl10353_set_tps(struct zl10353 *, 65 const struct dvb_frontend_parameters *); 66 static int zl10353_get_guard(fe_guard_interval_t, uint16_t *); 67 static int zl10353_get_mode(fe_transmit_mode_t, uint16_t *); 68 static int zl10353_get_fec(fe_code_rate_t, bool, uint16_t *); 69 static int zl10353_get_modulation(fe_modulation_t, uint16_t *); 70 static int zl10353_get_hier(fe_hierarchy_t, uint16_t *); 71 72 struct zl10353 * 73 zl10353_open(device_t parent, i2c_tag_t i2c, i2c_addr_t addr) 74 { 75 struct zl10353 *zl; 76 77 zl = kmem_zalloc(sizeof(*zl), KM_SLEEP); 78 zl->zl_i2c = i2c; 79 zl->zl_i2c_addr = addr; 80 zl->zl_parent = parent; 81 82 zl->zl_freq = ZL10353_DEFAULT_INPUT_FREQ; 83 zl->zl_clock = ZL10353_DEFAULT_CLOCK_MHZ; 84 85 if (zl10353_reset(zl, true) != 0) { 86 zl10353_close(zl); 87 return NULL; 88 } 89 90 if (zl10353_probe(zl) != 0) { 91 zl10353_close(zl); 92 return NULL; 93 } 94 95 return zl; 96 } 97 98 void 99 zl10353_close(struct zl10353 *zl) 100 { 101 kmem_free(zl, sizeof(*zl)); 102 } 103 104 static int 105 zl10353_probe(struct zl10353 *zl) 106 { 107 uint8_t val; 108 int rv; 109 110 if ((rv = zl10353_read(zl, ZL10353_REG_ID, &val)) != 0) 111 return rv; 112 113 switch (val) { 114 115 case ZL10353_ID_CE6230: 116 zl->zl_name = "Intel CE6230"; 117 break; 118 119 case ZL10353_ID_CE6231: 120 zl->zl_name = "Intel CE6231"; 121 break; 122 123 case ZL10353_ID_ZL10353: 124 zl->zl_name = "Zarlink ZL10353"; 125 break; 126 127 default: 128 aprint_error_dev(zl->zl_parent, "unknown chip 0x%02x\n", val); 129 return ENOTSUP; 130 } 131 132 aprint_verbose_dev(zl->zl_parent, "found %s at i2c " 133 "addr 0x%02x\n", zl->zl_name, zl->zl_i2c_addr); 134 135 return 0; 136 } 137 138 static int 139 zl10353_read(struct zl10353 *zl, uint8_t reg, uint8_t *valp) 140 { 141 static const i2c_op_t op = I2C_OP_READ; 142 int rv; 143 144 if ((rv = iic_acquire_bus(zl->zl_i2c, 0)) != 0) 145 return rv; 146 147 rv = iic_exec(zl->zl_i2c, op, zl->zl_i2c_addr, ®, 1, valp, 1, 0); 148 iic_release_bus(zl->zl_i2c, 0); 149 150 return rv; 151 } 152 153 static int 154 zl10353_write(struct zl10353 *zl, uint8_t reg, uint8_t val) 155 { 156 static const i2c_op_t op = I2C_OP_WRITE; 157 const uint8_t cmd[2] = { reg, val }; 158 int rv; 159 160 if ((rv = iic_acquire_bus(zl->zl_i2c, 0)) != 0) 161 return rv; 162 163 rv = iic_exec(zl->zl_i2c, op, zl->zl_i2c_addr, cmd, 2, NULL, 0, 0); 164 iic_release_bus(zl->zl_i2c, 0); 165 166 return rv; 167 } 168 169 static int 170 zl10353_reset(struct zl10353 *zl, bool hard) 171 { 172 size_t i = 0, len = 5; 173 int rv; 174 175 static const struct { 176 uint8_t reg; 177 uint8_t val; 178 } reset[] = { 179 { 0x50, 0x03 }, /* Hard */ 180 { 0x03, 0x44 }, 181 { 0x44, 0x46 }, 182 { 0x46, 0x15 }, 183 { 0x15, 0x0f }, 184 { 0x55, 0x80 }, /* Soft */ 185 { 0xea, 0x01 }, 186 { 0xea, 0x00 }, 187 }; 188 189 if (hard != true) { 190 len = __arraycount(reset); 191 i = 5; 192 } 193 194 while (i < len) { 195 196 if ((rv = zl10353_write(zl, reset[i].reg, reset[i].val)) != 0) 197 return rv; 198 else { 199 delay(100); 200 } 201 202 i++; 203 204 } 205 206 return 0; 207 } 208 209 void 210 zl10353_get_devinfo(struct dvb_frontend_info *fi) 211 { 212 213 fi->type = FE_OFDM; 214 215 fi->frequency_min = 174000000; 216 fi->frequency_max = 862000000; 217 218 fi->frequency_tolerance = 0; 219 fi->frequency_stepsize = 166667; 220 221 fi->caps |= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 222 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_QPSK | 223 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_RECOVER | 224 FE_CAN_MUTE_TS; 225 226 fi->caps |= FE_CAN_FEC_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | 227 FE_CAN_QAM_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | 228 FE_CAN_HIERARCHY_AUTO; 229 } 230 231 int 232 zl10353_set_params(struct zl10353 *zl,const struct dvb_frontend_parameters *fp) 233 { 234 int rv; 235 236 /* 1. Soft reset. */ 237 if ((rv = zl10353_reset(zl, false)) != 0) 238 return rv; 239 240 /* 2. Set AGC. */ 241 if ((rv = zl10353_set_agc(zl, fp)) != 0) 242 return rv; 243 244 /* 3. Set bandwidth. */ 245 if ((rv = zl10353_set_bw(zl, fp->u.ofdm.bandwidth)) != 0) 246 return rv; 247 248 /* 4. Set nominal rate. */ 249 if ((rv = zl10353_set_rate(zl)) != 0) 250 return rv; 251 252 /* 5. Set input frequency. */ 253 if ((rv = zl10353_set_freq(zl)) != 0) 254 return rv; 255 256 /* 6. Set TPS parameters. */ 257 if ((rv = zl10353_set_tps(zl, fp)) != 0) 258 return rv; 259 260 return 0; 261 } 262 263 int 264 zl10353_set_fsm(struct zl10353 *zl) 265 { 266 return zl10353_write(zl, ZL10353_REG_FSM, ZL10353_FSM_START); 267 } 268 269 int 270 zl10353_set_gate(void *aux, bool enable) 271 { 272 uint8_t val = ZL10353_GATE_DISABLE; 273 274 if (enable != false) 275 val = ZL10353_GATE_ENABLE; 276 277 return zl10353_write(aux, ZL10353_REG_GATE, val); 278 } 279 280 static int 281 zl10353_set_agc(struct zl10353 *zl, const struct dvb_frontend_parameters *fp) 282 { 283 const struct dvb_ofdm_parameters *ofdm = &fp->u.ofdm; 284 uint8_t val = ZL10353_AGC_TARGET_DEFAULT; 285 int rv; 286 287 if ((rv = zl10353_write(zl, ZL10353_REG_AGC_TARGET, val)) != 0) 288 return rv; 289 else { 290 val = 0; 291 } 292 293 if (ofdm->guard_interval != GUARD_INTERVAL_AUTO) 294 val |= ZL10353_AGC_CTRL_GUARD_NONAUTO; 295 296 if (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO) 297 val |= ZL10353_AGC_CTRL_MODE_NONAUTO; 298 299 return zl10353_write(zl, ZL10353_REG_AGC_CTRL, val); 300 } 301 302 static int 303 zl10353_set_bw(struct zl10353 *zl, fe_bandwidth_t bw) 304 { 305 uint8_t val[3]; 306 int rv; 307 308 switch (bw) { 309 310 case BANDWIDTH_6_MHZ: 311 val[0] = ZL10353_BW_1_6_MHZ; 312 val[1] = ZL10353_BW_2_6_MHZ; 313 val[2] = ZL10353_BW_3_6_MHZ; 314 zl->zl_bw = 6; 315 break; 316 317 case BANDWIDTH_7_MHZ: 318 val[0] = ZL10353_BW_1_7_MHZ; 319 val[1] = ZL10353_BW_2_7_MHZ; 320 val[2] = ZL10353_BW_3_7_MHZ; 321 zl->zl_bw = 7; 322 break; 323 324 case BANDWIDTH_8_MHZ: 325 val[0] = ZL10353_BW_1_8_MHZ; 326 val[1] = ZL10353_BW_2_8_MHZ; 327 val[2] = ZL10353_BW_3_8_MHZ; 328 zl->zl_bw = 8; 329 break; 330 331 default: 332 zl->zl_bw = 0; 333 return EINVAL; 334 } 335 336 if ((rv = zl10353_write(zl, ZL10353_REG_BW_1, val[0])) != 0) 337 return rv; 338 339 if ((rv = zl10353_write(zl, ZL10353_REG_BW_2, val[1])) != 0) 340 return rv; 341 342 if ((rv = zl10353_write(zl, ZL10353_REG_BW_3, val[2])) != 0) 343 return rv; 344 345 return 0; 346 } 347 348 static int 349 zl10353_set_rate(struct zl10353 *zl) 350 { 351 static const uint64_t c = 1497965625; 352 uint64_t val; 353 int rv; 354 355 KASSERT(zl->zl_bw >= 6 && zl->zl_bw <= 8); 356 KASSERT(zl->zl_clock > 0 && zl->zl_freq > 0); 357 358 val = zl->zl_bw * c; 359 val += zl->zl_clock >> 1; 360 val /= zl->zl_clock; 361 val = val & 0xffff; 362 363 if ((rv = zl10353_write(zl, ZL10353_REG_RATE_1, val >> 8)) != 0) 364 return rv; 365 366 return zl10353_write(zl, ZL10353_REG_RATE_2, val & 0xff); 367 } 368 369 static int 370 zl10353_set_freq(struct zl10353 *zl) 371 { 372 const uint16_t val = zl->zl_freq; 373 int rv; 374 375 if ((rv = zl10353_write(zl, ZL10353_REG_FREQ_1, val >> 8)) != 0) 376 return rv; 377 378 return zl10353_write(zl, ZL10353_REG_FREQ_2, val & 0xff); 379 } 380 381 static int 382 zl10353_set_tps(struct zl10353 *zl, const struct dvb_frontend_parameters *fp) 383 { 384 const struct dvb_ofdm_parameters *ofdm = &fp->u.ofdm; 385 uint16_t val = 0; 386 int rv; 387 388 if ((rv = zl10353_get_guard(ofdm->guard_interval, &val)) != 0) 389 goto fail; 390 391 if ((rv = zl10353_get_mode(ofdm->transmission_mode, &val)) != 0) 392 goto fail; 393 394 if ((rv = zl10353_get_fec(ofdm->code_rate_HP, true, &val)) != 0) 395 goto fail; 396 397 if ((rv = zl10353_get_fec(ofdm->code_rate_LP, false, &val)) != 0) 398 goto fail; 399 400 if ((rv = zl10353_get_modulation(ofdm->constellation, &val)) != 0) 401 goto fail; 402 403 if ((rv = zl10353_get_hier(ofdm->hierarchy_information, &val)) != 0) 404 goto fail; 405 406 if ((rv = zl10353_write(zl, ZL10353_REG_TPS_1, val >> 8)) != 0) 407 goto fail; 408 409 if ((rv = zl10353_write(zl, ZL10353_REG_TPS_2, val & 0xff)) != 0) 410 goto fail; 411 412 return 0; 413 414 fail: 415 aprint_error_dev(zl->zl_parent, "failed to set " 416 "tps for %s (err %d)\n", zl->zl_name, rv); 417 418 return rv; 419 } 420 421 static int 422 zl10353_get_guard(fe_guard_interval_t fg, uint16_t *valp) 423 { 424 425 switch (fg) { 426 427 case GUARD_INTERVAL_1_4: 428 *valp |= ZL10353_TPS_GUARD_1_4; 429 break; 430 431 case GUARD_INTERVAL_1_8: 432 *valp |= ZL10353_TPS_GUARD_1_8; 433 break; 434 435 case GUARD_INTERVAL_1_16: 436 *valp |= ZL10353_TPS_GUARD_1_16; 437 break; 438 439 case GUARD_INTERVAL_1_32: 440 *valp |= ZL10353_TPS_GUARD_1_32; 441 break; 442 443 case GUARD_INTERVAL_AUTO: 444 *valp |= ZL10353_TPS_GUARD_AUTO; 445 break; 446 447 default: 448 return EINVAL; 449 } 450 451 return 0; 452 } 453 454 static int 455 zl10353_get_mode(fe_transmit_mode_t fm, uint16_t *valp) 456 { 457 458 switch (fm) { 459 460 case TRANSMISSION_MODE_2K: 461 *valp |= ZL10353_TPS_MODE_2K; 462 break; 463 464 case TRANSMISSION_MODE_8K: 465 *valp |= ZL10353_TPS_MODE_8K; 466 break; 467 468 case TRANSMISSION_MODE_AUTO: 469 *valp |= ZL10353_TPS_MODE_AUTO; 470 break; 471 472 default: 473 return EINVAL; 474 } 475 476 return 0; 477 } 478 479 static int 480 zl10353_get_fec(fe_code_rate_t fc, bool hp, uint16_t *valp) 481 { 482 uint16_t hpval = 0, lpval = 0; 483 484 switch (fc) { 485 486 case FEC_1_2: 487 hpval = ZL10353_TPS_HP_FEC_1_2; 488 lpval = ZL10353_TPS_LP_FEC_1_2; 489 break; 490 491 case FEC_2_3: 492 hpval = ZL10353_TPS_HP_FEC_2_3; 493 lpval = ZL10353_TPS_LP_FEC_2_3; 494 break; 495 496 case FEC_3_4: 497 hpval = ZL10353_TPS_HP_FEC_3_4; 498 lpval = ZL10353_TPS_LP_FEC_3_4; 499 break; 500 501 case FEC_5_6: 502 hpval = ZL10353_TPS_HP_FEC_5_6; 503 lpval = ZL10353_TPS_LP_FEC_5_6; 504 break; 505 506 case FEC_7_8: 507 hpval = ZL10353_TPS_HP_FEC_7_8; 508 lpval = ZL10353_TPS_LP_FEC_7_8; 509 break; 510 511 case FEC_AUTO: 512 hpval = ZL10353_TPS_HP_FEC_AUTO; 513 lpval = ZL10353_TPS_LP_FEC_AUTO; 514 break; 515 516 case FEC_NONE: 517 return EOPNOTSUPP; 518 519 default: 520 return EINVAL; 521 } 522 523 *valp |= (hp != false) ? hpval : lpval; 524 525 return 0; 526 } 527 528 static int 529 zl10353_get_modulation(fe_modulation_t fm, uint16_t *valp) 530 { 531 532 switch (fm) { 533 534 case QPSK: 535 *valp |= ZL10353_TPS_MODULATION_QPSK; 536 break; 537 538 case QAM_16: 539 *valp |= ZL10353_TPS_MODULATION_QAM_16; 540 break; 541 542 case QAM_64: 543 *valp |= ZL10353_TPS_MODULATION_QAM_64; 544 break; 545 546 case QAM_AUTO: 547 *valp |= ZL10353_TPS_MODULATION_QAM_AUTO; 548 break; 549 550 default: 551 return EINVAL; 552 } 553 554 return 0; 555 } 556 557 static int 558 zl10353_get_hier(fe_hierarchy_t fh, uint16_t *valp) 559 { 560 561 switch (fh) { 562 563 case HIERARCHY_1: 564 *valp |= ZL10353_TPS_HIERARCHY_1; 565 break; 566 567 case HIERARCHY_2: 568 *valp |= ZL10353_TPS_HIERARCHY_2; 569 break; 570 571 case HIERARCHY_4: 572 *valp |= ZL10353_TPS_HIERARCHY_4; 573 break; 574 575 case HIERARCHY_NONE: 576 *valp |= ZL10353_TPS_HIERARCHY_NONE; 577 break; 578 579 case HIERARCHY_AUTO: 580 *valp |= ZL10353_TPS_HIERARCHY_AUTO; 581 break; 582 583 default: 584 return EINVAL; 585 } 586 587 return 0; 588 } 589 590 fe_status_t 591 zl10353_get_status(struct zl10353 *zl) 592 { 593 const uint8_t lock = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC; 594 fe_status_t fs = 0; 595 uint8_t val; 596 597 if (zl10353_read(zl, ZL10353_REG_STATUS_LOCK, &val) == 0) { 598 599 if ((val & ZL10353_STATUS_LOCK_ON) != 0) 600 fs |= FE_HAS_LOCK; 601 602 if ((val & ZL10353_STATUS_LOCK_CARRIER) != 0) 603 fs |= FE_HAS_CARRIER; 604 605 if ((val & ZL10353_STATUS_LOCK_VITERBI) != 0) 606 fs |= FE_HAS_VITERBI; 607 } 608 609 if (zl10353_read(zl, ZL10353_REG_STATUS_SYNC, &val) == 0) { 610 611 if ((val & ZL10353_STATUS_SYNC_ON) != 0) 612 fs |= FE_HAS_SYNC; 613 } 614 615 if (zl10353_read(zl, ZL10353_REG_STATUS_SIGNAL, &val) == 0) { 616 617 if ((val & ZL10353_STATUS_SIGNAL_ON) != 0) 618 fs |= FE_HAS_SIGNAL; 619 } 620 621 return ((fs & lock) != lock) ? fs & ~FE_HAS_LOCK : fs; 622 }; 623 624 uint16_t 625 zl10353_get_signal_strength(struct zl10353 *zl) 626 { 627 uint8_t val1, val2; 628 629 if (zl10353_read(zl, ZL10353_REG_SIGSTR_1, &val1) != 0) 630 return 0; 631 632 if (zl10353_read(zl, ZL10353_REG_SIGSTR_2, &val2) != 0) 633 return 0; 634 635 return val1 << 10 | val2 << 2 | 0x03; 636 } 637 638 uint16_t 639 zl10353_get_snr(struct zl10353 *zl) 640 { 641 uint8_t val; 642 643 if (zl10353_read(zl, ZL10353_REG_SNR, &val) != 0) 644 return 0; 645 646 return (val << 8) | val; 647 } 648 649 MODULE(MODULE_CLASS_DRIVER, zl10353, "i2cexec"); 650 651 static int 652 zl10353_modcmd(modcmd_t cmd, void *aux) 653 { 654 655 if (cmd != MODULE_CMD_INIT && cmd != MODULE_CMD_FINI) 656 return ENOTTY; 657 658 return 0; 659 } 660