linux/drivers/media/dvb-frontends/nxt200x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *    Support for NXT2002 and NXT2004 - VSB/QAM
   4 *
   5 *    Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
   6 *    Copyright (C) 2006-2014 Michael Krufky <mkrufky@linuxtv.org>
   7 *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
   8 *    and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com>
   9*/
  10
  11/*
  12 *                      NOTES ABOUT THIS DRIVER
  13 *
  14 * This Linux driver supports:
  15 *   B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
  16 *   AverTVHD MCE A180 (NXT2004)
  17 *   ATI HDTV Wonder (NXT2004)
  18 *
  19 * This driver needs external firmware. Please use the command
  20 * "<kerneldir>/scripts/get_dvb_firmware nxt2002" or
  21 * "<kerneldir>/scripts/get_dvb_firmware nxt2004" to
  22 * download/extract the appropriate firmware, and then copy it to
  23 * /usr/lib/hotplug/firmware/ or /lib/firmware/
  24 * (depending on configuration of firmware hotplug).
  25 */
  26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  27
  28/* Max transfer size done by I2C transfer functions */
  29#define MAX_XFER_SIZE  256
  30
  31#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
  32#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
  33#define CRC_CCIT_MASK 0x1021
  34
  35#include <linux/kernel.h>
  36#include <linux/init.h>
  37#include <linux/module.h>
  38#include <linux/slab.h>
  39#include <linux/string.h>
  40
  41#include <media/dvb_frontend.h>
  42#include "nxt200x.h"
  43
  44struct nxt200x_state {
  45
  46        struct i2c_adapter* i2c;
  47        const struct nxt200x_config* config;
  48        struct dvb_frontend frontend;
  49
  50        /* demodulator private data */
  51        nxt_chip_type demod_chip;
  52        u8 initialised:1;
  53};
  54
  55static int debug;
  56#define dprintk(args...)        do { if (debug) pr_debug(args); } while (0)
  57
  58static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
  59{
  60        int err;
  61        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
  62
  63        if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
  64                pr_warn("%s: i2c write error (addr 0x%02x, err == %i)\n",
  65                        __func__, addr, err);
  66                return -EREMOTEIO;
  67        }
  68        return 0;
  69}
  70
  71static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len)
  72{
  73        int err;
  74        struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
  75
  76        if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
  77                pr_warn("%s: i2c read error (addr 0x%02x, err == %i)\n",
  78                        __func__, addr, err);
  79                return -EREMOTEIO;
  80        }
  81        return 0;
  82}
  83
  84static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
  85                               const u8 *buf, u8 len)
  86{
  87        u8 buf2[MAX_XFER_SIZE];
  88        int err;
  89        struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
  90
  91        if (1 + len > sizeof(buf2)) {
  92                pr_warn("%s: i2c wr reg=%04x: len=%d is too big!\n",
  93                         __func__, reg, len);
  94                return -EINVAL;
  95        }
  96
  97        buf2[0] = reg;
  98        memcpy(&buf2[1], buf, len);
  99
 100        if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
 101                pr_warn("%s: i2c write error (addr 0x%02x, err == %i)\n",
 102                        __func__, state->config->demod_address, err);
 103                return -EREMOTEIO;
 104        }
 105        return 0;
 106}
 107
 108static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len)
 109{
 110        u8 reg2 [] = { reg };
 111
 112        struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
 113                        { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
 114
 115        int err;
 116
 117        if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
 118                pr_warn("%s: i2c read error (addr 0x%02x, err == %i)\n",
 119                        __func__, state->config->demod_address, err);
 120                return -EREMOTEIO;
 121        }
 122        return 0;
 123}
 124
 125static u16 nxt200x_crc(u16 crc, u8 c)
 126{
 127        u8 i;
 128        u16 input = (u16) c & 0xFF;
 129
 130        input<<=8;
 131        for(i=0; i<8; i++) {
 132                if((crc^input) & 0x8000)
 133                        crc=(crc<<1)^CRC_CCIT_MASK;
 134                else
 135                        crc<<=1;
 136                input<<=1;
 137        }
 138        return crc;
 139}
 140
 141static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
 142{
 143        u8 attr, len2, buf;
 144        dprintk("%s\n", __func__);
 145
 146        /* set multi register register */
 147        nxt200x_writebytes(state, 0x35, &reg, 1);
 148
 149        /* send the actual data */
 150        nxt200x_writebytes(state, 0x36, data, len);
 151
 152        switch (state->demod_chip) {
 153                case NXT2002:
 154                        len2 = len;
 155                        buf = 0x02;
 156                        break;
 157                case NXT2004:
 158                        /* probably not right, but gives correct values */
 159                        attr = 0x02;
 160                        if (reg & 0x80) {
 161                                attr = attr << 1;
 162                                if (reg & 0x04)
 163                                        attr = attr >> 1;
 164                        }
 165                        /* set write bit */
 166                        len2 = ((attr << 4) | 0x10) | len;
 167                        buf = 0x80;
 168                        break;
 169                default:
 170                        return -EINVAL;
 171        }
 172
 173        /* set multi register length */
 174        nxt200x_writebytes(state, 0x34, &len2, 1);
 175
 176        /* toggle the multireg write bit */
 177        nxt200x_writebytes(state, 0x21, &buf, 1);
 178
 179        nxt200x_readbytes(state, 0x21, &buf, 1);
 180
 181        switch (state->demod_chip) {
 182                case NXT2002:
 183                        if ((buf & 0x02) == 0)
 184                                return 0;
 185                        break;
 186                case NXT2004:
 187                        if (buf == 0)
 188                                return 0;
 189                        break;
 190                default:
 191                        return -EINVAL;
 192        }
 193
 194        pr_warn("Error writing multireg register 0x%02X\n", reg);
 195
 196        return 0;
 197}
 198
 199static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
 200{
 201        int i;
 202        u8 buf, len2, attr;
 203        dprintk("%s\n", __func__);
 204
 205        /* set multi register register */
 206        nxt200x_writebytes(state, 0x35, &reg, 1);
 207
 208        switch (state->demod_chip) {
 209                case NXT2002:
 210                        /* set multi register length */
 211                        len2 = len & 0x80;
 212                        nxt200x_writebytes(state, 0x34, &len2, 1);
 213
 214                        /* read the actual data */
 215                        nxt200x_readbytes(state, reg, data, len);
 216                        return 0;
 217                case NXT2004:
 218                        /* probably not right, but gives correct values */
 219                        attr = 0x02;
 220                        if (reg & 0x80) {
 221                                attr = attr << 1;
 222                                if (reg & 0x04)
 223                                        attr = attr >> 1;
 224                        }
 225
 226                        /* set multi register length */
 227                        len2 = (attr << 4) | len;
 228                        nxt200x_writebytes(state, 0x34, &len2, 1);
 229
 230                        /* toggle the multireg bit*/
 231                        buf = 0x80;
 232                        nxt200x_writebytes(state, 0x21, &buf, 1);
 233
 234                        /* read the actual data */
 235                        for(i = 0; i < len; i++) {
 236                                nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
 237                        }
 238                        return 0;
 239                default:
 240                        return -EINVAL;
 241        }
 242}
 243
 244static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
 245{
 246        u8 buf, stopval, counter = 0;
 247        dprintk("%s\n", __func__);
 248
 249        /* set correct stop value */
 250        switch (state->demod_chip) {
 251                case NXT2002:
 252                        stopval = 0x40;
 253                        break;
 254                case NXT2004:
 255                        stopval = 0x10;
 256                        break;
 257                default:
 258                        stopval = 0;
 259                        break;
 260        }
 261
 262        buf = 0x80;
 263        nxt200x_writebytes(state, 0x22, &buf, 1);
 264
 265        while (counter < 20) {
 266                nxt200x_readbytes(state, 0x31, &buf, 1);
 267                if (buf & stopval)
 268                        return;
 269                msleep(10);
 270                counter++;
 271        }
 272
 273        pr_warn("Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
 274        return;
 275}
 276
 277static void nxt200x_microcontroller_start (struct nxt200x_state* state)
 278{
 279        u8 buf;
 280        dprintk("%s\n", __func__);
 281
 282        buf = 0x00;
 283        nxt200x_writebytes(state, 0x22, &buf, 1);
 284}
 285
 286static void nxt2004_microcontroller_init (struct nxt200x_state* state)
 287{
 288        u8 buf[9];
 289        u8 counter = 0;
 290        dprintk("%s\n", __func__);
 291
 292        buf[0] = 0x00;
 293        nxt200x_writebytes(state, 0x2b, buf, 1);
 294        buf[0] = 0x70;
 295        nxt200x_writebytes(state, 0x34, buf, 1);
 296        buf[0] = 0x04;
 297        nxt200x_writebytes(state, 0x35, buf, 1);
 298        buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
 299        buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
 300        nxt200x_writebytes(state, 0x36, buf, 9);
 301        buf[0] = 0x80;
 302        nxt200x_writebytes(state, 0x21, buf, 1);
 303
 304        while (counter < 20) {
 305                nxt200x_readbytes(state, 0x21, buf, 1);
 306                if (buf[0] == 0)
 307                        return;
 308                msleep(10);
 309                counter++;
 310        }
 311
 312        pr_warn("Timeout waiting for nxt2004 to init.\n");
 313
 314        return;
 315}
 316
 317static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
 318{
 319        u8 buf, count = 0;
 320
 321        dprintk("%s\n", __func__);
 322
 323        dprintk("Tuner Bytes: %*ph\n", 4, data + 1);
 324
 325        /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
 326         * direct write is required for Philips TUV1236D and ALPS TDHU2 */
 327        switch (state->demod_chip) {
 328                case NXT2004:
 329                        if (i2c_writebytes(state, data[0], data+1, 4))
 330                                pr_warn("error writing to tuner\n");
 331                        /* wait until we have a lock */
 332                        while (count < 20) {
 333                                i2c_readbytes(state, data[0], &buf, 1);
 334                                if (buf & 0x40)
 335                                        return 0;
 336                                msleep(100);
 337                                count++;
 338                        }
 339                        pr_warn("timeout waiting for tuner lock\n");
 340                        break;
 341                case NXT2002:
 342                        /* set the i2c transfer speed to the tuner */
 343                        buf = 0x03;
 344                        nxt200x_writebytes(state, 0x20, &buf, 1);
 345
 346                        /* setup to transfer 4 bytes via i2c */
 347                        buf = 0x04;
 348                        nxt200x_writebytes(state, 0x34, &buf, 1);
 349
 350                        /* write actual tuner bytes */
 351                        nxt200x_writebytes(state, 0x36, data+1, 4);
 352
 353                        /* set tuner i2c address */
 354                        buf = data[0] << 1;
 355                        nxt200x_writebytes(state, 0x35, &buf, 1);
 356
 357                        /* write UC Opmode to begin transfer */
 358                        buf = 0x80;
 359                        nxt200x_writebytes(state, 0x21, &buf, 1);
 360
 361                        while (count < 20) {
 362                                nxt200x_readbytes(state, 0x21, &buf, 1);
 363                                if ((buf & 0x80)== 0x00)
 364                                        return 0;
 365                                msleep(100);
 366                                count++;
 367                        }
 368                        pr_warn("timeout error writing to tuner\n");
 369                        break;
 370                default:
 371                        return -EINVAL;
 372        }
 373        return 0;
 374}
 375
 376static void nxt200x_agc_reset(struct nxt200x_state* state)
 377{
 378        u8 buf;
 379        dprintk("%s\n", __func__);
 380
 381        switch (state->demod_chip) {
 382                case NXT2002:
 383                        buf = 0x08;
 384                        nxt200x_writebytes(state, 0x08, &buf, 1);
 385                        buf = 0x00;
 386                        nxt200x_writebytes(state, 0x08, &buf, 1);
 387                        break;
 388                case NXT2004:
 389                        nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
 390                        buf = 0x08;
 391                        nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
 392                        buf = 0x00;
 393                        nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
 394                        break;
 395                default:
 396                        break;
 397        }
 398        return;
 399}
 400
 401static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
 402{
 403
 404        struct nxt200x_state* state = fe->demodulator_priv;
 405        u8 buf[3], written = 0, chunkpos = 0;
 406        u16 rambase, position, crc = 0;
 407
 408        dprintk("%s\n", __func__);
 409        dprintk("Firmware is %zu bytes\n", fw->size);
 410
 411        /* Get the RAM base for this nxt2002 */
 412        nxt200x_readbytes(state, 0x10, buf, 1);
 413
 414        if (buf[0] & 0x10)
 415                rambase = 0x1000;
 416        else
 417                rambase = 0x0000;
 418
 419        dprintk("rambase on this nxt2002 is %04X\n", rambase);
 420
 421        /* Hold the micro in reset while loading firmware */
 422        buf[0] = 0x80;
 423        nxt200x_writebytes(state, 0x2B, buf, 1);
 424
 425        for (position = 0; position < fw->size; position++) {
 426                if (written == 0) {
 427                        crc = 0;
 428                        chunkpos = 0x28;
 429                        buf[0] = ((rambase + position) >> 8);
 430                        buf[1] = (rambase + position) & 0xFF;
 431                        buf[2] = 0x81;
 432                        /* write starting address */
 433                        nxt200x_writebytes(state, 0x29, buf, 3);
 434                }
 435                written++;
 436                chunkpos++;
 437
 438                if ((written % 4) == 0)
 439                        nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
 440
 441                crc = nxt200x_crc(crc, fw->data[position]);
 442
 443                if ((written == 255) || (position+1 == fw->size)) {
 444                        /* write remaining bytes of firmware */
 445                        nxt200x_writebytes(state, chunkpos+4-(written %4),
 446                                &fw->data[position-(written %4) + 1],
 447                                written %4);
 448                        buf[0] = crc << 8;
 449                        buf[1] = crc & 0xFF;
 450
 451                        /* write crc */
 452                        nxt200x_writebytes(state, 0x2C, buf, 2);
 453
 454                        /* do a read to stop things */
 455                        nxt200x_readbytes(state, 0x2A, buf, 1);
 456
 457                        /* set transfer mode to complete */
 458                        buf[0] = 0x80;
 459                        nxt200x_writebytes(state, 0x2B, buf, 1);
 460
 461                        written = 0;
 462                }
 463        }
 464
 465        return 0;
 466};
 467
 468static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
 469{
 470
 471        struct nxt200x_state* state = fe->demodulator_priv;
 472        u8 buf[3];
 473        u16 rambase, position, crc=0;
 474
 475        dprintk("%s\n", __func__);
 476        dprintk("Firmware is %zu bytes\n", fw->size);
 477
 478        /* set rambase */
 479        rambase = 0x1000;
 480
 481        /* hold the micro in reset while loading firmware */
 482        buf[0] = 0x80;
 483        nxt200x_writebytes(state, 0x2B, buf,1);
 484
 485        /* calculate firmware CRC */
 486        for (position = 0; position < fw->size; position++) {
 487                crc = nxt200x_crc(crc, fw->data[position]);
 488        }
 489
 490        buf[0] = rambase >> 8;
 491        buf[1] = rambase & 0xFF;
 492        buf[2] = 0x81;
 493        /* write starting address */
 494        nxt200x_writebytes(state,0x29,buf,3);
 495
 496        for (position = 0; position < fw->size;) {
 497                nxt200x_writebytes(state, 0x2C, &fw->data[position],
 498                        fw->size-position > 255 ? 255 : fw->size-position);
 499                position += (fw->size-position > 255 ? 255 : fw->size-position);
 500        }
 501        buf[0] = crc >> 8;
 502        buf[1] = crc & 0xFF;
 503
 504        dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
 505
 506        /* write crc */
 507        nxt200x_writebytes(state, 0x2C, buf,2);
 508
 509        /* do a read to stop things */
 510        nxt200x_readbytes(state, 0x2C, buf, 1);
 511
 512        /* set transfer mode to complete */
 513        buf[0] = 0x80;
 514        nxt200x_writebytes(state, 0x2B, buf,1);
 515
 516        return 0;
 517};
 518
 519static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
 520{
 521        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 522        struct nxt200x_state* state = fe->demodulator_priv;
 523        u8 buf[5];
 524
 525        /* stop the micro first */
 526        nxt200x_microcontroller_stop(state);
 527
 528        if (state->demod_chip == NXT2004) {
 529                /* make sure demod is set to digital */
 530                buf[0] = 0x04;
 531                nxt200x_writebytes(state, 0x14, buf, 1);
 532                buf[0] = 0x00;
 533                nxt200x_writebytes(state, 0x17, buf, 1);
 534        }
 535
 536        /* set additional params */
 537        switch (p->modulation) {
 538                case QAM_64:
 539                case QAM_256:
 540                        /* Set punctured clock for QAM */
 541                        /* This is just a guess since I am unable to test it */
 542                        if (state->config->set_ts_params)
 543                                state->config->set_ts_params(fe, 1);
 544                        break;
 545                case VSB_8:
 546                        /* Set non-punctured clock for VSB */
 547                        if (state->config->set_ts_params)
 548                                state->config->set_ts_params(fe, 0);
 549                        break;
 550                default:
 551                        return -EINVAL;
 552        }
 553
 554        if (fe->ops.tuner_ops.calc_regs) {
 555                /* get tuning information */
 556                fe->ops.tuner_ops.calc_regs(fe, buf, 5);
 557
 558                /* write frequency information */
 559                nxt200x_writetuner(state, buf);
 560        }
 561
 562        /* reset the agc now that tuning has been completed */
 563        nxt200x_agc_reset(state);
 564
 565        /* set target power level */
 566        switch (p->modulation) {
 567                case QAM_64:
 568                case QAM_256:
 569                        buf[0] = 0x74;
 570                        break;
 571                case VSB_8:
 572                        buf[0] = 0x70;
 573                        break;
 574                default:
 575                        return -EINVAL;
 576        }
 577        nxt200x_writebytes(state, 0x42, buf, 1);
 578
 579        /* configure sdm */
 580        switch (state->demod_chip) {
 581                case NXT2002:
 582                        buf[0] = 0x87;
 583                        break;
 584                case NXT2004:
 585                        buf[0] = 0x07;
 586                        break;
 587                default:
 588                        return -EINVAL;
 589        }
 590        nxt200x_writebytes(state, 0x57, buf, 1);
 591
 592        /* write sdm1 input */
 593        buf[0] = 0x10;
 594        buf[1] = 0x00;
 595        switch (state->demod_chip) {
 596                case NXT2002:
 597                        nxt200x_writereg_multibyte(state, 0x58, buf, 2);
 598                        break;
 599                case NXT2004:
 600                        nxt200x_writebytes(state, 0x58, buf, 2);
 601                        break;
 602                default:
 603                        return -EINVAL;
 604        }
 605
 606        /* write sdmx input */
 607        switch (p->modulation) {
 608                case QAM_64:
 609                                buf[0] = 0x68;
 610                                break;
 611                case QAM_256:
 612                                buf[0] = 0x64;
 613                                break;
 614                case VSB_8:
 615                                buf[0] = 0x60;
 616                                break;
 617                default:
 618                                return -EINVAL;
 619        }
 620        buf[1] = 0x00;
 621        switch (state->demod_chip) {
 622                case NXT2002:
 623                        nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
 624                        break;
 625                case NXT2004:
 626                        nxt200x_writebytes(state, 0x5C, buf, 2);
 627                        break;
 628                default:
 629                        return -EINVAL;
 630        }
 631
 632        /* write adc power lpf fc */
 633        buf[0] = 0x05;
 634        nxt200x_writebytes(state, 0x43, buf, 1);
 635
 636        if (state->demod_chip == NXT2004) {
 637                /* write ??? */
 638                buf[0] = 0x00;
 639                buf[1] = 0x00;
 640                nxt200x_writebytes(state, 0x46, buf, 2);
 641        }
 642
 643        /* write accumulator2 input */
 644        buf[0] = 0x80;
 645        buf[1] = 0x00;
 646        switch (state->demod_chip) {
 647                case NXT2002:
 648                        nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
 649                        break;
 650                case NXT2004:
 651                        nxt200x_writebytes(state, 0x4B, buf, 2);
 652                        break;
 653                default:
 654                        return -EINVAL;
 655        }
 656
 657        /* write kg1 */
 658        buf[0] = 0x00;
 659        nxt200x_writebytes(state, 0x4D, buf, 1);
 660
 661        /* write sdm12 lpf fc */
 662        buf[0] = 0x44;
 663        nxt200x_writebytes(state, 0x55, buf, 1);
 664
 665        /* write agc control reg */
 666        buf[0] = 0x04;
 667        nxt200x_writebytes(state, 0x41, buf, 1);
 668
 669        if (state->demod_chip == NXT2004) {
 670                nxt200x_readreg_multibyte(state, 0x80, buf, 1);
 671                buf[0] = 0x24;
 672                nxt200x_writereg_multibyte(state, 0x80, buf, 1);
 673
 674                /* soft reset? */
 675                nxt200x_readreg_multibyte(state, 0x08, buf, 1);
 676                buf[0] = 0x10;
 677                nxt200x_writereg_multibyte(state, 0x08, buf, 1);
 678                nxt200x_readreg_multibyte(state, 0x08, buf, 1);
 679                buf[0] = 0x00;
 680                nxt200x_writereg_multibyte(state, 0x08, buf, 1);
 681
 682                nxt200x_readreg_multibyte(state, 0x80, buf, 1);
 683                buf[0] = 0x04;
 684                nxt200x_writereg_multibyte(state, 0x80, buf, 1);
 685                buf[0] = 0x00;
 686                nxt200x_writereg_multibyte(state, 0x81, buf, 1);
 687                buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
 688                nxt200x_writereg_multibyte(state, 0x82, buf, 3);
 689                nxt200x_readreg_multibyte(state, 0x88, buf, 1);
 690                buf[0] = 0x11;
 691                nxt200x_writereg_multibyte(state, 0x88, buf, 1);
 692                nxt200x_readreg_multibyte(state, 0x80, buf, 1);
 693                buf[0] = 0x44;
 694                nxt200x_writereg_multibyte(state, 0x80, buf, 1);
 695        }
 696
 697        /* write agc ucgp0 */
 698        switch (p->modulation) {
 699                case QAM_64:
 700                                buf[0] = 0x02;
 701                                break;
 702                case QAM_256:
 703                                buf[0] = 0x03;
 704                                break;
 705                case VSB_8:
 706                                buf[0] = 0x00;
 707                                break;
 708                default:
 709                                return -EINVAL;
 710        }
 711        nxt200x_writebytes(state, 0x30, buf, 1);
 712
 713        /* write agc control reg */
 714        buf[0] = 0x00;
 715        nxt200x_writebytes(state, 0x41, buf, 1);
 716
 717        /* write accumulator2 input */
 718        buf[0] = 0x80;
 719        buf[1] = 0x00;
 720        switch (state->demod_chip) {
 721                case NXT2002:
 722                        nxt200x_writereg_multibyte(state, 0x49, buf, 2);
 723                        nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
 724                        break;
 725                case NXT2004:
 726                        nxt200x_writebytes(state, 0x49, buf, 2);
 727                        nxt200x_writebytes(state, 0x4B, buf, 2);
 728                        break;
 729                default:
 730                        return -EINVAL;
 731        }
 732
 733        /* write agc control reg */
 734        buf[0] = 0x04;
 735        nxt200x_writebytes(state, 0x41, buf, 1);
 736
 737        nxt200x_microcontroller_start(state);
 738
 739        if (state->demod_chip == NXT2004) {
 740                nxt2004_microcontroller_init(state);
 741
 742                /* ???? */
 743                buf[0] = 0xF0;
 744                buf[1] = 0x00;
 745                nxt200x_writebytes(state, 0x5C, buf, 2);
 746        }
 747
 748        /* adjacent channel detection should be done here, but I don't
 749        have any stations with this need so I cannot test it */
 750
 751        return 0;
 752}
 753
 754static int nxt200x_read_status(struct dvb_frontend *fe, enum fe_status *status)
 755{
 756        struct nxt200x_state* state = fe->demodulator_priv;
 757        u8 lock;
 758        nxt200x_readbytes(state, 0x31, &lock, 1);
 759
 760        *status = 0;
 761        if (lock & 0x20) {
 762                *status |= FE_HAS_SIGNAL;
 763                *status |= FE_HAS_CARRIER;
 764                *status |= FE_HAS_VITERBI;
 765                *status |= FE_HAS_SYNC;
 766                *status |= FE_HAS_LOCK;
 767        }
 768        return 0;
 769}
 770
 771static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
 772{
 773        struct nxt200x_state* state = fe->demodulator_priv;
 774        u8 b[3];
 775
 776        nxt200x_readreg_multibyte(state, 0xE6, b, 3);
 777
 778        *ber = ((b[0] << 8) + b[1]) * 8;
 779
 780        return 0;
 781}
 782
 783static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 784{
 785        struct nxt200x_state* state = fe->demodulator_priv;
 786        u8 b[2];
 787        u16 temp = 0;
 788
 789        /* setup to read cluster variance */
 790        b[0] = 0x00;
 791        nxt200x_writebytes(state, 0xA1, b, 1);
 792
 793        /* get multreg val */
 794        nxt200x_readreg_multibyte(state, 0xA6, b, 2);
 795
 796        temp = (b[0] << 8) | b[1];
 797        *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
 798
 799        return 0;
 800}
 801
 802static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
 803{
 804
 805        struct nxt200x_state* state = fe->demodulator_priv;
 806        u8 b[2];
 807        u16 temp = 0, temp2;
 808        u32 snrdb = 0;
 809
 810        /* setup to read cluster variance */
 811        b[0] = 0x00;
 812        nxt200x_writebytes(state, 0xA1, b, 1);
 813
 814        /* get multreg val from 0xA6 */
 815        nxt200x_readreg_multibyte(state, 0xA6, b, 2);
 816
 817        temp = (b[0] << 8) | b[1];
 818        temp2 = 0x7FFF - temp;
 819
 820        /* snr will be in db */
 821        if (temp2 > 0x7F00)
 822                snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
 823        else if (temp2 > 0x7EC0)
 824                snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
 825        else if (temp2 > 0x7C00)
 826                snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
 827        else
 828                snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
 829
 830        /* the value reported back from the frontend will be FFFF=32db 0000=0db */
 831        *snr = snrdb * (0xFFFF/32000);
 832
 833        return 0;
 834}
 835
 836static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 837{
 838        struct nxt200x_state* state = fe->demodulator_priv;
 839        u8 b[3];
 840
 841        nxt200x_readreg_multibyte(state, 0xE6, b, 3);
 842        *ucblocks = b[2];
 843
 844        return 0;
 845}
 846
 847static int nxt200x_sleep(struct dvb_frontend* fe)
 848{
 849        return 0;
 850}
 851
 852static int nxt2002_init(struct dvb_frontend* fe)
 853{
 854        struct nxt200x_state* state = fe->demodulator_priv;
 855        const struct firmware *fw;
 856        int ret;
 857        u8 buf[2];
 858
 859        /* request the firmware, this will block until someone uploads it */
 860        pr_debug("%s: Waiting for firmware upload (%s)...\n",
 861                 __func__, NXT2002_DEFAULT_FIRMWARE);
 862        ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE,
 863                               state->i2c->dev.parent);
 864        pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
 865        if (ret) {
 866                pr_err("%s: No firmware uploaded (timeout or file not found?)\n",
 867                       __func__);
 868                return ret;
 869        }
 870
 871        ret = nxt2002_load_firmware(fe, fw);
 872        release_firmware(fw);
 873        if (ret) {
 874                pr_err("%s: Writing firmware to device failed\n", __func__);
 875                return ret;
 876        }
 877        pr_info("%s: Firmware upload complete\n", __func__);
 878
 879        /* Put the micro into reset */
 880        nxt200x_microcontroller_stop(state);
 881
 882        /* ensure transfer is complete */
 883        buf[0]=0x00;
 884        nxt200x_writebytes(state, 0x2B, buf, 1);
 885
 886        /* Put the micro into reset for real this time */
 887        nxt200x_microcontroller_stop(state);
 888
 889        /* soft reset everything (agc,frontend,eq,fec)*/
 890        buf[0] = 0x0F;
 891        nxt200x_writebytes(state, 0x08, buf, 1);
 892        buf[0] = 0x00;
 893        nxt200x_writebytes(state, 0x08, buf, 1);
 894
 895        /* write agc sdm configure */
 896        buf[0] = 0xF1;
 897        nxt200x_writebytes(state, 0x57, buf, 1);
 898
 899        /* write mod output format */
 900        buf[0] = 0x20;
 901        nxt200x_writebytes(state, 0x09, buf, 1);
 902
 903        /* write fec mpeg mode */
 904        buf[0] = 0x7E;
 905        buf[1] = 0x00;
 906        nxt200x_writebytes(state, 0xE9, buf, 2);
 907
 908        /* write mux selection */
 909        buf[0] = 0x00;
 910        nxt200x_writebytes(state, 0xCC, buf, 1);
 911
 912        return 0;
 913}
 914
 915static int nxt2004_init(struct dvb_frontend* fe)
 916{
 917        struct nxt200x_state* state = fe->demodulator_priv;
 918        const struct firmware *fw;
 919        int ret;
 920        u8 buf[3];
 921
 922        /* ??? */
 923        buf[0]=0x00;
 924        nxt200x_writebytes(state, 0x1E, buf, 1);
 925
 926        /* request the firmware, this will block until someone uploads it */
 927        pr_debug("%s: Waiting for firmware upload (%s)...\n",
 928                 __func__, NXT2004_DEFAULT_FIRMWARE);
 929        ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE,
 930                               state->i2c->dev.parent);
 931        pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
 932        if (ret) {
 933                pr_err("%s: No firmware uploaded (timeout or file not found?)\n",
 934                       __func__);
 935                return ret;
 936        }
 937
 938        ret = nxt2004_load_firmware(fe, fw);
 939        release_firmware(fw);
 940        if (ret) {
 941                pr_err("%s: Writing firmware to device failed\n", __func__);
 942                return ret;
 943        }
 944        pr_info("%s: Firmware upload complete\n", __func__);
 945
 946        /* ensure transfer is complete */
 947        buf[0] = 0x01;
 948        nxt200x_writebytes(state, 0x19, buf, 1);
 949
 950        nxt2004_microcontroller_init(state);
 951        nxt200x_microcontroller_stop(state);
 952        nxt200x_microcontroller_stop(state);
 953        nxt2004_microcontroller_init(state);
 954        nxt200x_microcontroller_stop(state);
 955
 956        /* soft reset everything (agc,frontend,eq,fec)*/
 957        buf[0] = 0xFF;
 958        nxt200x_writereg_multibyte(state, 0x08, buf, 1);
 959        buf[0] = 0x00;
 960        nxt200x_writereg_multibyte(state, 0x08, buf, 1);
 961
 962        /* write agc sdm configure */
 963        buf[0] = 0xD7;
 964        nxt200x_writebytes(state, 0x57, buf, 1);
 965
 966        /* ???*/
 967        buf[0] = 0x07;
 968        buf[1] = 0xfe;
 969        nxt200x_writebytes(state, 0x35, buf, 2);
 970        buf[0] = 0x12;
 971        nxt200x_writebytes(state, 0x34, buf, 1);
 972        buf[0] = 0x80;
 973        nxt200x_writebytes(state, 0x21, buf, 1);
 974
 975        /* ???*/
 976        buf[0] = 0x21;
 977        nxt200x_writebytes(state, 0x0A, buf, 1);
 978
 979        /* ???*/
 980        buf[0] = 0x01;
 981        nxt200x_writereg_multibyte(state, 0x80, buf, 1);
 982
 983        /* write fec mpeg mode */
 984        buf[0] = 0x7E;
 985        buf[1] = 0x00;
 986        nxt200x_writebytes(state, 0xE9, buf, 2);
 987
 988        /* write mux selection */
 989        buf[0] = 0x00;
 990        nxt200x_writebytes(state, 0xCC, buf, 1);
 991
 992        /* ???*/
 993        nxt200x_readreg_multibyte(state, 0x80, buf, 1);
 994        buf[0] = 0x00;
 995        nxt200x_writereg_multibyte(state, 0x80, buf, 1);
 996
 997        /* soft reset? */
 998        nxt200x_readreg_multibyte(state, 0x08, buf, 1);
 999        buf[0] = 0x10;
1000        nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1001        nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1002        buf[0] = 0x00;
1003        nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1004
1005        /* ???*/
1006        nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1007        buf[0] = 0x01;
1008        nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1009        buf[0] = 0x70;
1010        nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1011        buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
1012        nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1013
1014        nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1015        buf[0] = 0x11;
1016        nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1017        nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1018        buf[0] = 0x40;
1019        nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1020
1021        nxt200x_readbytes(state, 0x10, buf, 1);
1022        buf[0] = 0x10;
1023        nxt200x_writebytes(state, 0x10, buf, 1);
1024        nxt200x_readbytes(state, 0x0A, buf, 1);
1025        buf[0] = 0x21;
1026        nxt200x_writebytes(state, 0x0A, buf, 1);
1027
1028        nxt2004_microcontroller_init(state);
1029
1030        buf[0] = 0x21;
1031        nxt200x_writebytes(state, 0x0A, buf, 1);
1032        buf[0] = 0x7E;
1033        nxt200x_writebytes(state, 0xE9, buf, 1);
1034        buf[0] = 0x00;
1035        nxt200x_writebytes(state, 0xEA, buf, 1);
1036
1037        nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1038        buf[0] = 0x00;
1039        nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1040        nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1041        buf[0] = 0x00;
1042        nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1043
1044        /* soft reset? */
1045        nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1046        buf[0] = 0x10;
1047        nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1048        nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1049        buf[0] = 0x00;
1050        nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1051
1052        nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1053        buf[0] = 0x04;
1054        nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1055        buf[0] = 0x00;
1056        nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1057        buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
1058        nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1059
1060        nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1061        buf[0] = 0x11;
1062        nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1063
1064        nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1065        buf[0] = 0x44;
1066        nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1067
1068        /* initialize tuner */
1069        nxt200x_readbytes(state, 0x10, buf, 1);
1070        buf[0] = 0x12;
1071        nxt200x_writebytes(state, 0x10, buf, 1);
1072        buf[0] = 0x04;
1073        nxt200x_writebytes(state, 0x13, buf, 1);
1074        buf[0] = 0x00;
1075        nxt200x_writebytes(state, 0x16, buf, 1);
1076        buf[0] = 0x04;
1077        nxt200x_writebytes(state, 0x14, buf, 1);
1078        buf[0] = 0x00;
1079        nxt200x_writebytes(state, 0x14, buf, 1);
1080        nxt200x_writebytes(state, 0x17, buf, 1);
1081        nxt200x_writebytes(state, 0x14, buf, 1);
1082        nxt200x_writebytes(state, 0x17, buf, 1);
1083
1084        return 0;
1085}
1086
1087static int nxt200x_init(struct dvb_frontend* fe)
1088{
1089        struct nxt200x_state* state = fe->demodulator_priv;
1090        int ret = 0;
1091
1092        if (!state->initialised) {
1093                switch (state->demod_chip) {
1094                        case NXT2002:
1095                                ret = nxt2002_init(fe);
1096                                break;
1097                        case NXT2004:
1098                                ret = nxt2004_init(fe);
1099                                break;
1100                        default:
1101                                return -EINVAL;
1102                }
1103                state->initialised = 1;
1104        }
1105        return ret;
1106}
1107
1108static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1109{
1110        fesettings->min_delay_ms = 500;
1111        fesettings->step_size = 0;
1112        fesettings->max_drift = 0;
1113        return 0;
1114}
1115
1116static void nxt200x_release(struct dvb_frontend* fe)
1117{
1118        struct nxt200x_state* state = fe->demodulator_priv;
1119        kfree(state);
1120}
1121
1122static const struct dvb_frontend_ops nxt200x_ops;
1123
1124struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1125                                   struct i2c_adapter* i2c)
1126{
1127        struct nxt200x_state* state = NULL;
1128        u8 buf [] = {0,0,0,0,0};
1129
1130        /* allocate memory for the internal state */
1131        state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
1132        if (state == NULL)
1133                goto error;
1134
1135        /* setup the state */
1136        state->config = config;
1137        state->i2c = i2c;
1138        state->initialised = 0;
1139
1140        /* read card id */
1141        nxt200x_readbytes(state, 0x00, buf, 5);
1142        dprintk("NXT info: %*ph\n", 5, buf);
1143
1144        /* set demod chip */
1145        switch (buf[0]) {
1146                case 0x04:
1147                        state->demod_chip = NXT2002;
1148                        pr_info("NXT2002 Detected\n");
1149                        break;
1150                case 0x05:
1151                        state->demod_chip = NXT2004;
1152                        pr_info("NXT2004 Detected\n");
1153                        break;
1154                default:
1155                        goto error;
1156        }
1157
1158        /* make sure demod chip is supported */
1159        switch (state->demod_chip) {
1160                case NXT2002:
1161                        if (buf[0] != 0x04) goto error;         /* device id */
1162                        if (buf[1] != 0x02) goto error;         /* fab id */
1163                        if (buf[2] != 0x11) goto error;         /* month */
1164                        if (buf[3] != 0x20) goto error;         /* year msb */
1165                        if (buf[4] != 0x00) goto error;         /* year lsb */
1166                        break;
1167                case NXT2004:
1168                        if (buf[0] != 0x05) goto error;         /* device id */
1169                        break;
1170                default:
1171                        goto error;
1172        }
1173
1174        /* create dvb_frontend */
1175        memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1176        state->frontend.demodulator_priv = state;
1177        return &state->frontend;
1178
1179error:
1180        kfree(state);
1181        pr_err("Unknown/Unsupported NXT chip: %*ph\n", 5, buf);
1182        return NULL;
1183}
1184
1185static const struct dvb_frontend_ops nxt200x_ops = {
1186        .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
1187        .info = {
1188                .name = "Nextwave NXT200X VSB/QAM frontend",
1189                .frequency_min_hz =  54 * MHz,
1190                .frequency_max_hz = 860 * MHz,
1191                .frequency_stepsize_hz = 166666,        /* stepsize is just a guess */
1192                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1193                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1194                        FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
1195        },
1196
1197        .release = nxt200x_release,
1198
1199        .init = nxt200x_init,
1200        .sleep = nxt200x_sleep,
1201
1202        .set_frontend = nxt200x_setup_frontend_parameters,
1203        .get_tune_settings = nxt200x_get_tune_settings,
1204
1205        .read_status = nxt200x_read_status,
1206        .read_ber = nxt200x_read_ber,
1207        .read_signal_strength = nxt200x_read_signal_strength,
1208        .read_snr = nxt200x_read_snr,
1209        .read_ucblocks = nxt200x_read_ucblocks,
1210};
1211
1212module_param(debug, int, 0644);
1213MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1214
1215MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
1216MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
1217MODULE_LICENSE("GPL");
1218
1219EXPORT_SYMBOL(nxt200x_attach);
1220
1221