linux/drivers/media/tuners/mt2063.c
<<
>>
Prefs
   1/*
   2 * Driver for mt2063 Micronas tuner
   3 *
   4 * Copyright (c) 2011 Mauro Carvalho Chehab
   5 *
   6 * This driver came from a driver originally written by:
   7 *              Henry Wang <Henry.wang@AzureWave.com>
   8 * Made publicly available by Terratec, at:
   9 *      http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
  10 * The original driver's license is GPL, as declared with MODULE_LICENSE()
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation under version 2 of the License.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 */
  21
  22#include <linux/init.h>
  23#include <linux/kernel.h>
  24#include <linux/module.h>
  25#include <linux/string.h>
  26#include <linux/videodev2.h>
  27#include <linux/gcd.h>
  28
  29#include "mt2063.h"
  30
  31static unsigned int debug;
  32module_param(debug, int, 0644);
  33MODULE_PARM_DESC(debug, "Set Verbosity level");
  34
  35#define dprintk(level, fmt, arg...) do {                                \
  36if (debug >= level)                                                     \
  37        printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
  38} while (0)
  39
  40
  41/* positive error codes used internally */
  42
  43/*  Info: Unavoidable LO-related spur may be present in the output  */
  44#define MT2063_SPUR_PRESENT_ERR             (0x00800000)
  45
  46/*  Info: Mask of bits used for # of LO-related spurs that were avoided during tuning  */
  47#define MT2063_SPUR_CNT_MASK                (0x001f0000)
  48#define MT2063_SPUR_SHIFT                   (16)
  49
  50/*  Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
  51#define MT2063_UPC_RANGE                    (0x04000000)
  52
  53/*  Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
  54#define MT2063_DNC_RANGE                    (0x08000000)
  55
  56/*
  57 *  Constant defining the version of the following structure
  58 *  and therefore the API for this code.
  59 *
  60 *  When compiling the tuner driver, the preprocessor will
  61 *  check against this version number to make sure that
  62 *  it matches the version that the tuner driver knows about.
  63 */
  64
  65/* DECT Frequency Avoidance */
  66#define MT2063_DECT_AVOID_US_FREQS      0x00000001
  67
  68#define MT2063_DECT_AVOID_EURO_FREQS    0x00000002
  69
  70#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
  71
  72#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
  73
  74enum MT2063_DECT_Avoid_Type {
  75        MT2063_NO_DECT_AVOIDANCE = 0,                           /* Do not create DECT exclusion zones.     */
  76        MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS,      /* Avoid US DECT frequencies.              */
  77        MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS,  /* Avoid European DECT frequencies.        */
  78        MT2063_AVOID_BOTH                                       /* Avoid both regions. Not typically used. */
  79};
  80
  81#define MT2063_MAX_ZONES 48
  82
  83struct MT2063_ExclZone_t {
  84        u32 min_;
  85        u32 max_;
  86        struct MT2063_ExclZone_t *next_;
  87};
  88
  89/*
  90 *  Structure of data needed for Spur Avoidance
  91 */
  92struct MT2063_AvoidSpursData_t {
  93        u32 f_ref;
  94        u32 f_in;
  95        u32 f_LO1;
  96        u32 f_if1_Center;
  97        u32 f_if1_Request;
  98        u32 f_if1_bw;
  99        u32 f_LO2;
 100        u32 f_out;
 101        u32 f_out_bw;
 102        u32 f_LO1_Step;
 103        u32 f_LO2_Step;
 104        u32 f_LO1_FracN_Avoid;
 105        u32 f_LO2_FracN_Avoid;
 106        u32 f_zif_bw;
 107        u32 f_min_LO_Separation;
 108        u32 maxH1;
 109        u32 maxH2;
 110        enum MT2063_DECT_Avoid_Type avoidDECT;
 111        u32 bSpurPresent;
 112        u32 bSpurAvoided;
 113        u32 nSpursFound;
 114        u32 nZones;
 115        struct MT2063_ExclZone_t *freeZones;
 116        struct MT2063_ExclZone_t *usedZones;
 117        struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
 118};
 119
 120/*
 121 * Parameter for function MT2063_SetPowerMask that specifies the power down
 122 * of various sections of the MT2063.
 123 */
 124enum MT2063_Mask_Bits {
 125        MT2063_REG_SD = 0x0040,         /* Shutdown regulator                 */
 126        MT2063_SRO_SD = 0x0020,         /* Shutdown SRO                       */
 127        MT2063_AFC_SD = 0x0010,         /* Shutdown AFC A/D                   */
 128        MT2063_PD_SD = 0x0002,          /* Enable power detector shutdown     */
 129        MT2063_PDADC_SD = 0x0001,       /* Enable power detector A/D shutdown */
 130        MT2063_VCO_SD = 0x8000,         /* Enable VCO shutdown                */
 131        MT2063_LTX_SD = 0x4000,         /* Enable LTX shutdown                */
 132        MT2063_LT1_SD = 0x2000,         /* Enable LT1 shutdown                */
 133        MT2063_LNA_SD = 0x1000,         /* Enable LNA shutdown                */
 134        MT2063_UPC_SD = 0x0800,         /* Enable upconverter shutdown        */
 135        MT2063_DNC_SD = 0x0400,         /* Enable downconverter shutdown      */
 136        MT2063_VGA_SD = 0x0200,         /* Enable VGA shutdown                */
 137        MT2063_AMP_SD = 0x0100,         /* Enable AMP shutdown                */
 138        MT2063_ALL_SD = 0xFF73,         /* All shutdown bits for this tuner   */
 139        MT2063_NONE_SD = 0x0000         /* No shutdown bits                   */
 140};
 141
 142/*
 143 *  Possible values for MT2063_DNC_OUTPUT
 144 */
 145enum MT2063_DNC_Output_Enable {
 146        MT2063_DNC_NONE = 0,
 147        MT2063_DNC_1,
 148        MT2063_DNC_2,
 149        MT2063_DNC_BOTH
 150};
 151
 152/*
 153 *  Two-wire serial bus subaddresses of the tuner registers.
 154 *  Also known as the tuner's register addresses.
 155 */
 156enum MT2063_Register_Offsets {
 157        MT2063_REG_PART_REV = 0,        /*  0x00: Part/Rev Code         */
 158        MT2063_REG_LO1CQ_1,             /*  0x01: LO1C Queued Byte 1    */
 159        MT2063_REG_LO1CQ_2,             /*  0x02: LO1C Queued Byte 2    */
 160        MT2063_REG_LO2CQ_1,             /*  0x03: LO2C Queued Byte 1    */
 161        MT2063_REG_LO2CQ_2,             /*  0x04: LO2C Queued Byte 2    */
 162        MT2063_REG_LO2CQ_3,             /*  0x05: LO2C Queued Byte 3    */
 163        MT2063_REG_RSVD_06,             /*  0x06: Reserved              */
 164        MT2063_REG_LO_STATUS,           /*  0x07: LO Status             */
 165        MT2063_REG_FIFFC,               /*  0x08: FIFF Center           */
 166        MT2063_REG_CLEARTUNE,           /*  0x09: ClearTune Filter      */
 167        MT2063_REG_ADC_OUT,             /*  0x0A: ADC_OUT               */
 168        MT2063_REG_LO1C_1,              /*  0x0B: LO1C Byte 1           */
 169        MT2063_REG_LO1C_2,              /*  0x0C: LO1C Byte 2           */
 170        MT2063_REG_LO2C_1,              /*  0x0D: LO2C Byte 1           */
 171        MT2063_REG_LO2C_2,              /*  0x0E: LO2C Byte 2           */
 172        MT2063_REG_LO2C_3,              /*  0x0F: LO2C Byte 3           */
 173        MT2063_REG_RSVD_10,             /*  0x10: Reserved              */
 174        MT2063_REG_PWR_1,               /*  0x11: PWR Byte 1            */
 175        MT2063_REG_PWR_2,               /*  0x12: PWR Byte 2            */
 176        MT2063_REG_TEMP_STATUS,         /*  0x13: Temp Status           */
 177        MT2063_REG_XO_STATUS,           /*  0x14: Crystal Status        */
 178        MT2063_REG_RF_STATUS,           /*  0x15: RF Attn Status        */
 179        MT2063_REG_FIF_STATUS,          /*  0x16: FIF Attn Status       */
 180        MT2063_REG_LNA_OV,              /*  0x17: LNA Attn Override     */
 181        MT2063_REG_RF_OV,               /*  0x18: RF Attn Override      */
 182        MT2063_REG_FIF_OV,              /*  0x19: FIF Attn Override     */
 183        MT2063_REG_LNA_TGT,             /*  0x1A: Reserved              */
 184        MT2063_REG_PD1_TGT,             /*  0x1B: Pwr Det 1 Target      */
 185        MT2063_REG_PD2_TGT,             /*  0x1C: Pwr Det 2 Target      */
 186        MT2063_REG_RSVD_1D,             /*  0x1D: Reserved              */
 187        MT2063_REG_RSVD_1E,             /*  0x1E: Reserved              */
 188        MT2063_REG_RSVD_1F,             /*  0x1F: Reserved              */
 189        MT2063_REG_RSVD_20,             /*  0x20: Reserved              */
 190        MT2063_REG_BYP_CTRL,            /*  0x21: Bypass Control        */
 191        MT2063_REG_RSVD_22,             /*  0x22: Reserved              */
 192        MT2063_REG_RSVD_23,             /*  0x23: Reserved              */
 193        MT2063_REG_RSVD_24,             /*  0x24: Reserved              */
 194        MT2063_REG_RSVD_25,             /*  0x25: Reserved              */
 195        MT2063_REG_RSVD_26,             /*  0x26: Reserved              */
 196        MT2063_REG_RSVD_27,             /*  0x27: Reserved              */
 197        MT2063_REG_FIFF_CTRL,           /*  0x28: FIFF Control          */
 198        MT2063_REG_FIFF_OFFSET,         /*  0x29: FIFF Offset           */
 199        MT2063_REG_CTUNE_CTRL,          /*  0x2A: Reserved              */
 200        MT2063_REG_CTUNE_OV,            /*  0x2B: Reserved              */
 201        MT2063_REG_CTRL_2C,             /*  0x2C: Reserved              */
 202        MT2063_REG_FIFF_CTRL2,          /*  0x2D: Fiff Control          */
 203        MT2063_REG_RSVD_2E,             /*  0x2E: Reserved              */
 204        MT2063_REG_DNC_GAIN,            /*  0x2F: DNC Control           */
 205        MT2063_REG_VGA_GAIN,            /*  0x30: VGA Gain Ctrl         */
 206        MT2063_REG_RSVD_31,             /*  0x31: Reserved              */
 207        MT2063_REG_TEMP_SEL,            /*  0x32: Temperature Selection */
 208        MT2063_REG_RSVD_33,             /*  0x33: Reserved              */
 209        MT2063_REG_RSVD_34,             /*  0x34: Reserved              */
 210        MT2063_REG_RSVD_35,             /*  0x35: Reserved              */
 211        MT2063_REG_RSVD_36,             /*  0x36: Reserved              */
 212        MT2063_REG_RSVD_37,             /*  0x37: Reserved              */
 213        MT2063_REG_RSVD_38,             /*  0x38: Reserved              */
 214        MT2063_REG_RSVD_39,             /*  0x39: Reserved              */
 215        MT2063_REG_RSVD_3A,             /*  0x3A: Reserved              */
 216        MT2063_REG_RSVD_3B,             /*  0x3B: Reserved              */
 217        MT2063_REG_RSVD_3C,             /*  0x3C: Reserved              */
 218        MT2063_REG_END_REGS
 219};
 220
 221struct mt2063_state {
 222        struct i2c_adapter *i2c;
 223
 224        bool init;
 225
 226        const struct mt2063_config *config;
 227        struct dvb_tuner_ops ops;
 228        struct dvb_frontend *frontend;
 229
 230        u32 frequency;
 231        u32 srate;
 232        u32 bandwidth;
 233        u32 reference;
 234
 235        u32 tuner_id;
 236        struct MT2063_AvoidSpursData_t AS_Data;
 237        u32 f_IF1_actual;
 238        u32 rcvr_mode;
 239        u32 ctfilt_sw;
 240        u32 CTFiltMax[31];
 241        u32 num_regs;
 242        u8 reg[MT2063_REG_END_REGS];
 243};
 244
 245/*
 246 * mt2063_write - Write data into the I2C bus
 247 */
 248static int mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
 249{
 250        struct dvb_frontend *fe = state->frontend;
 251        int ret;
 252        u8 buf[60];
 253        struct i2c_msg msg = {
 254                .addr = state->config->tuner_address,
 255                .flags = 0,
 256                .buf = buf,
 257                .len = len + 1
 258        };
 259
 260        dprintk(2, "\n");
 261
 262        msg.buf[0] = reg;
 263        memcpy(msg.buf + 1, data, len);
 264
 265        if (fe->ops.i2c_gate_ctrl)
 266                fe->ops.i2c_gate_ctrl(fe, 1);
 267        ret = i2c_transfer(state->i2c, &msg, 1);
 268        if (fe->ops.i2c_gate_ctrl)
 269                fe->ops.i2c_gate_ctrl(fe, 0);
 270
 271        if (ret < 0)
 272                printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
 273
 274        return ret;
 275}
 276
 277/*
 278 * mt2063_write - Write register data into the I2C bus, caching the value
 279 */
 280static int mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
 281{
 282        int status;
 283
 284        dprintk(2, "\n");
 285
 286        if (reg >= MT2063_REG_END_REGS)
 287                return -ERANGE;
 288
 289        status = mt2063_write(state, reg, &val, 1);
 290        if (status < 0)
 291                return status;
 292
 293        state->reg[reg] = val;
 294
 295        return 0;
 296}
 297
 298/*
 299 * mt2063_read - Read data from the I2C bus
 300 */
 301static int mt2063_read(struct mt2063_state *state,
 302                           u8 subAddress, u8 *pData, u32 cnt)
 303{
 304        int status = 0; /* Status to be returned        */
 305        struct dvb_frontend *fe = state->frontend;
 306        u32 i = 0;
 307
 308        dprintk(2, "addr 0x%02x, cnt %d\n", subAddress, cnt);
 309
 310        if (fe->ops.i2c_gate_ctrl)
 311                fe->ops.i2c_gate_ctrl(fe, 1);
 312
 313        for (i = 0; i < cnt; i++) {
 314                u8 b0[] = { subAddress + i };
 315                struct i2c_msg msg[] = {
 316                        {
 317                                .addr = state->config->tuner_address,
 318                                .flags = 0,
 319                                .buf = b0,
 320                                .len = 1
 321                        }, {
 322                                .addr = state->config->tuner_address,
 323                                .flags = I2C_M_RD,
 324                                .buf = pData + i,
 325                                .len = 1
 326                        }
 327                };
 328
 329                status = i2c_transfer(state->i2c, msg, 2);
 330                dprintk(2, "addr 0x%02x, ret = %d, val = 0x%02x\n",
 331                           subAddress + i, status, *(pData + i));
 332                if (status < 0)
 333                        break;
 334        }
 335        if (fe->ops.i2c_gate_ctrl)
 336                fe->ops.i2c_gate_ctrl(fe, 0);
 337
 338        if (status < 0)
 339                printk(KERN_ERR "Can't read from address 0x%02x,\n",
 340                       subAddress + i);
 341
 342        return status;
 343}
 344
 345/*
 346 * FIXME: Is this really needed?
 347 */
 348static int MT2063_Sleep(struct dvb_frontend *fe)
 349{
 350        /*
 351         *  ToDo:  Add code here to implement a OS blocking
 352         */
 353        msleep(100);
 354
 355        return 0;
 356}
 357
 358/*
 359 * Microtune spur avoidance
 360 */
 361
 362/*  Implement ceiling, floor functions.  */
 363#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
 364#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
 365
 366struct MT2063_FIFZone_t {
 367        s32 min_;
 368        s32 max_;
 369};
 370
 371static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
 372                                            *pAS_Info,
 373                                            struct MT2063_ExclZone_t *pPrevNode)
 374{
 375        struct MT2063_ExclZone_t *pNode;
 376
 377        dprintk(2, "\n");
 378
 379        /*  Check for a node in the free list  */
 380        if (pAS_Info->freeZones != NULL) {
 381                /*  Use one from the free list  */
 382                pNode = pAS_Info->freeZones;
 383                pAS_Info->freeZones = pNode->next_;
 384        } else {
 385                /*  Grab a node from the array  */
 386                pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
 387        }
 388
 389        if (pPrevNode != NULL) {
 390                pNode->next_ = pPrevNode->next_;
 391                pPrevNode->next_ = pNode;
 392        } else {                /*  insert at the beginning of the list  */
 393
 394                pNode->next_ = pAS_Info->usedZones;
 395                pAS_Info->usedZones = pNode;
 396        }
 397
 398        pAS_Info->nZones++;
 399        return pNode;
 400}
 401
 402static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
 403                                            *pAS_Info,
 404                                            struct MT2063_ExclZone_t *pPrevNode,
 405                                            struct MT2063_ExclZone_t
 406                                            *pNodeToRemove)
 407{
 408        struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
 409
 410        dprintk(2, "\n");
 411
 412        /*  Make previous node point to the subsequent node  */
 413        if (pPrevNode != NULL)
 414                pPrevNode->next_ = pNext;
 415
 416        /*  Add pNodeToRemove to the beginning of the freeZones  */
 417        pNodeToRemove->next_ = pAS_Info->freeZones;
 418        pAS_Info->freeZones = pNodeToRemove;
 419
 420        /*  Decrement node count  */
 421        pAS_Info->nZones--;
 422
 423        return pNext;
 424}
 425
 426/*
 427 * MT_AddExclZone()
 428 *
 429 * Add (and merge) an exclusion zone into the list.
 430 * If the range (f_min, f_max) is totally outside the
 431 * 1st IF BW, ignore the entry.
 432 * If the range (f_min, f_max) is negative, ignore the entry.
 433 */
 434static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
 435                               u32 f_min, u32 f_max)
 436{
 437        struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
 438        struct MT2063_ExclZone_t *pPrev = NULL;
 439        struct MT2063_ExclZone_t *pNext = NULL;
 440
 441        dprintk(2, "\n");
 442
 443        /*  Check to see if this overlaps the 1st IF filter  */
 444        if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
 445            && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
 446            && (f_min < f_max)) {
 447                /*
 448                 *                1        2         3      4       5        6
 449                 *
 450                 *   New entry:  |---|    |--|      |--|    |-|    |---|    |--|
 451                 *                or       or        or     or      or
 452                 *   Existing:  |--|      |--|      |--|    |---|  |-|      |--|
 453                 */
 454
 455                /*  Check for our place in the list  */
 456                while ((pNode != NULL) && (pNode->max_ < f_min)) {
 457                        pPrev = pNode;
 458                        pNode = pNode->next_;
 459                }
 460
 461                if ((pNode != NULL) && (pNode->min_ < f_max)) {
 462                        /*  Combine me with pNode  */
 463                        if (f_min < pNode->min_)
 464                                pNode->min_ = f_min;
 465                        if (f_max > pNode->max_)
 466                                pNode->max_ = f_max;
 467                } else {
 468                        pNode = InsertNode(pAS_Info, pPrev);
 469                        pNode->min_ = f_min;
 470                        pNode->max_ = f_max;
 471                }
 472
 473                /*  Look for merging possibilities  */
 474                pNext = pNode->next_;
 475                while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
 476                        if (pNext->max_ > pNode->max_)
 477                                pNode->max_ = pNext->max_;
 478                        /*  Remove pNext, return ptr to pNext->next  */
 479                        pNext = RemoveNode(pAS_Info, pNode, pNext);
 480                }
 481        }
 482}
 483
 484/*
 485 *  Reset all exclusion zones.
 486 *  Add zones to protect the PLL FracN regions near zero
 487 */
 488static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
 489{
 490        u32 center;
 491
 492        dprintk(2, "\n");
 493
 494        pAS_Info->nZones = 0;   /*  this clears the used list  */
 495        pAS_Info->usedZones = NULL;     /*  reset ptr                  */
 496        pAS_Info->freeZones = NULL;     /*  reset ptr                  */
 497
 498        center =
 499            pAS_Info->f_ref *
 500            ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
 501              pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
 502        while (center <
 503               pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
 504               pAS_Info->f_LO1_FracN_Avoid) {
 505                /*  Exclude LO1 FracN  */
 506                MT2063_AddExclZone(pAS_Info,
 507                                   center - pAS_Info->f_LO1_FracN_Avoid,
 508                                   center - 1);
 509                MT2063_AddExclZone(pAS_Info, center + 1,
 510                                   center + pAS_Info->f_LO1_FracN_Avoid);
 511                center += pAS_Info->f_ref;
 512        }
 513
 514        center =
 515            pAS_Info->f_ref *
 516            ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
 517              pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
 518        while (center <
 519               pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
 520               pAS_Info->f_LO2_FracN_Avoid) {
 521                /*  Exclude LO2 FracN  */
 522                MT2063_AddExclZone(pAS_Info,
 523                                   center - pAS_Info->f_LO2_FracN_Avoid,
 524                                   center - 1);
 525                MT2063_AddExclZone(pAS_Info, center + 1,
 526                                   center + pAS_Info->f_LO2_FracN_Avoid);
 527                center += pAS_Info->f_ref;
 528        }
 529
 530        if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
 531                /*  Exclude LO1 values that conflict with DECT channels */
 532                MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */
 533                MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */
 534                MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */
 535                MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */
 536                MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */
 537        }
 538
 539        if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
 540                MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */
 541                MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */
 542                MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */
 543                MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16  */
 544                MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */
 545                MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */
 546                MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */
 547                MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */
 548                MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52  */
 549                MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */
 550        }
 551}
 552
 553/*
 554 * MT_ChooseFirstIF - Choose the best available 1st IF
 555 *                    If f_Desired is not excluded, choose that first.
 556 *                    Otherwise, return the value closest to f_Center that is
 557 *                    not excluded
 558 */
 559static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
 560{
 561        /*
 562         * Update "f_Desired" to be the nearest "combinational-multiple" of
 563         * "f_LO1_Step".
 564         * The resulting number, F_LO1 must be a multiple of f_LO1_Step.
 565         * And F_LO1 is the arithmetic sum of f_in + f_Center.
 566         * Neither f_in, nor f_Center must be a multiple of f_LO1_Step.
 567         * However, the sum must be.
 568         */
 569        const u32 f_Desired =
 570            pAS_Info->f_LO1_Step *
 571            ((pAS_Info->f_if1_Request + pAS_Info->f_in +
 572              pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
 573            pAS_Info->f_in;
 574        const u32 f_Step =
 575            (pAS_Info->f_LO1_Step >
 576             pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
 577            f_LO2_Step;
 578        u32 f_Center;
 579        s32 i;
 580        s32 j = 0;
 581        u32 bDesiredExcluded = 0;
 582        u32 bZeroExcluded = 0;
 583        s32 tmpMin, tmpMax;
 584        s32 bestDiff;
 585        struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
 586        struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
 587
 588        dprintk(2, "\n");
 589
 590        if (pAS_Info->nZones == 0)
 591                return f_Desired;
 592
 593        /*
 594         *  f_Center needs to be an integer multiple of f_Step away
 595         *  from f_Desired
 596         */
 597        if (pAS_Info->f_if1_Center > f_Desired)
 598                f_Center =
 599                    f_Desired +
 600                    f_Step *
 601                    ((pAS_Info->f_if1_Center - f_Desired +
 602                      f_Step / 2) / f_Step);
 603        else
 604                f_Center =
 605                    f_Desired -
 606                    f_Step *
 607                    ((f_Desired - pAS_Info->f_if1_Center +
 608                      f_Step / 2) / f_Step);
 609
 610        /*
 611         * Take MT_ExclZones, center around f_Center and change the
 612         * resolution to f_Step
 613         */
 614        while (pNode != NULL) {
 615                /*  floor function  */
 616                tmpMin =
 617                    floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
 618
 619                /*  ceil function  */
 620                tmpMax =
 621                    ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
 622
 623                if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
 624                        bDesiredExcluded = 1;
 625
 626                if ((tmpMin < 0) && (tmpMax > 0))
 627                        bZeroExcluded = 1;
 628
 629                /*  See if this zone overlaps the previous  */
 630                if ((j > 0) && (tmpMin < zones[j - 1].max_))
 631                        zones[j - 1].max_ = tmpMax;
 632                else {
 633                        /*  Add new zone  */
 634                        zones[j].min_ = tmpMin;
 635                        zones[j].max_ = tmpMax;
 636                        j++;
 637                }
 638                pNode = pNode->next_;
 639        }
 640
 641        /*
 642         *  If the desired is okay, return with it
 643         */
 644        if (bDesiredExcluded == 0)
 645                return f_Desired;
 646
 647        /*
 648         *  If the desired is excluded and the center is okay, return with it
 649         */
 650        if (bZeroExcluded == 0)
 651                return f_Center;
 652
 653        /*  Find the value closest to 0 (f_Center)  */
 654        bestDiff = zones[0].min_;
 655        for (i = 0; i < j; i++) {
 656                if (abs(zones[i].min_) < abs(bestDiff))
 657                        bestDiff = zones[i].min_;
 658                if (abs(zones[i].max_) < abs(bestDiff))
 659                        bestDiff = zones[i].max_;
 660        }
 661
 662        if (bestDiff < 0)
 663                return f_Center - ((u32) (-bestDiff) * f_Step);
 664
 665        return f_Center + (bestDiff * f_Step);
 666}
 667
 668/**
 669 * IsSpurInBand() - Checks to see if a spur will be present within the IF's
 670 *                  bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
 671 *
 672 *                    ma   mb                                     mc   md
 673 *                  <--+-+-+-------------------+-------------------+-+-+-->
 674 *                     |   ^                   0                   ^   |
 675 *                     ^   b=-fIFOut+fIFBW/2      -b=+fIFOut-fIFBW/2   ^
 676 *                     a=-fIFOut-fIFBW/2              -a=+fIFOut+fIFBW/2
 677 *
 678 *                  Note that some equations are doubled to prevent round-off
 679 *                  problems when calculating fIFBW/2
 680 *
 681 * @pAS_Info:   Avoid Spurs information block
 682 * @fm:         If spur, amount f_IF1 has to move negative
 683 * @fp:         If spur, amount f_IF1 has to move positive
 684 *
 685 *  Returns 1 if an LO spur would be present, otherwise 0.
 686 */
 687static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
 688                        u32 *fm, u32 * fp)
 689{
 690        /*
 691         **  Calculate LO frequency settings.
 692         */
 693        u32 n, n0;
 694        const u32 f_LO1 = pAS_Info->f_LO1;
 695        const u32 f_LO2 = pAS_Info->f_LO2;
 696        const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
 697        const u32 c = d - pAS_Info->f_out_bw;
 698        const u32 f = pAS_Info->f_zif_bw / 2;
 699        const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
 700        s32 f_nsLO1, f_nsLO2;
 701        s32 f_Spur;
 702        u32 ma, mb, mc, md, me, mf;
 703        u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
 704
 705        dprintk(2, "\n");
 706
 707        *fm = 0;
 708
 709        /*
 710         ** For each edge (d, c & f), calculate a scale, based on the gcd
 711         ** of f_LO1, f_LO2 and the edge value.  Use the larger of this
 712         ** gcd-based scale factor or f_Scale.
 713         */
 714        lo_gcd = gcd(f_LO1, f_LO2);
 715        gd_Scale = max((u32) gcd(lo_gcd, d), f_Scale);
 716        hgds = gd_Scale / 2;
 717        gc_Scale = max((u32) gcd(lo_gcd, c), f_Scale);
 718        hgcs = gc_Scale / 2;
 719        gf_Scale = max((u32) gcd(lo_gcd, f), f_Scale);
 720        hgfs = gf_Scale / 2;
 721
 722        n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
 723
 724        /*  Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic  */
 725        for (n = n0; n <= pAS_Info->maxH1; ++n) {
 726                md = (n * ((f_LO1 + hgds) / gd_Scale) -
 727                      ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
 728
 729                /*  If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present  */
 730                if (md >= pAS_Info->maxH1)
 731                        break;
 732
 733                ma = (n * ((f_LO1 + hgds) / gd_Scale) +
 734                      ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
 735
 736                /*  If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic  */
 737                if (md == ma)
 738                        continue;
 739
 740                mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
 741                      ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
 742                if (mc != md) {
 743                        f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
 744                        f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
 745                        f_Spur =
 746                            (gc_Scale * (f_nsLO1 - f_nsLO2)) +
 747                            n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
 748
 749                        *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
 750                        *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
 751                        return 1;
 752                }
 753
 754                /*  Location of Zero-IF-spur to be checked  */
 755                me = (n * ((f_LO1 + hgfs) / gf_Scale) +
 756                      ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
 757                mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
 758                      ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
 759                if (me != mf) {
 760                        f_nsLO1 = n * (f_LO1 / gf_Scale);
 761                        f_nsLO2 = me * (f_LO2 / gf_Scale);
 762                        f_Spur =
 763                            (gf_Scale * (f_nsLO1 - f_nsLO2)) +
 764                            n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
 765
 766                        *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
 767                        *fm = (((s32) f - f_Spur) / (me - n)) + 1;
 768                        return 1;
 769                }
 770
 771                mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
 772                      ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
 773                if (ma != mb) {
 774                        f_nsLO1 = n * (f_LO1 / gc_Scale);
 775                        f_nsLO2 = ma * (f_LO2 / gc_Scale);
 776                        f_Spur =
 777                            (gc_Scale * (f_nsLO1 - f_nsLO2)) +
 778                            n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
 779
 780                        *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
 781                        *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
 782                        return 1;
 783                }
 784        }
 785
 786        /*  No spurs found  */
 787        return 0;
 788}
 789
 790/*
 791 * MT_AvoidSpurs() - Main entry point to avoid spurs.
 792 *                   Checks for existing spurs in present LO1, LO2 freqs
 793 *                   and if present, chooses spur-free LO1, LO2 combination
 794 *                   that tunes the same input/output frequencies.
 795 */
 796static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
 797{
 798        int status = 0;
 799        u32 fm, fp;             /*  restricted range on LO's        */
 800        pAS_Info->bSpurAvoided = 0;
 801        pAS_Info->nSpursFound = 0;
 802
 803        dprintk(2, "\n");
 804
 805        if (pAS_Info->maxH1 == 0)
 806                return 0;
 807
 808        /*
 809         * Avoid LO Generated Spurs
 810         *
 811         * Make sure that have no LO-related spurs within the IF output
 812         * bandwidth.
 813         *
 814         * If there is an LO spur in this band, start at the current IF1 frequency
 815         * and work out until we find a spur-free frequency or run up against the
 816         * 1st IF SAW band edge.  Use temporary copies of fLO1 and fLO2 so that they
 817         * will be unchanged if a spur-free setting is not found.
 818         */
 819        pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
 820        if (pAS_Info->bSpurPresent) {
 821                u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in;   /*  current attempt at a 1st IF  */
 822                u32 zfLO1 = pAS_Info->f_LO1;    /*  current attempt at an LO1 freq  */
 823                u32 zfLO2 = pAS_Info->f_LO2;    /*  current attempt at an LO2 freq  */
 824                u32 delta_IF1;
 825                u32 new_IF1;
 826
 827                /*
 828                 **  Spur was found, attempt to find a spur-free 1st IF
 829                 */
 830                do {
 831                        pAS_Info->nSpursFound++;
 832
 833                        /*  Raise f_IF1_upper, if needed  */
 834                        MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
 835
 836                        /*  Choose next IF1 that is closest to f_IF1_CENTER              */
 837                        new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
 838
 839                        if (new_IF1 > zfIF1) {
 840                                pAS_Info->f_LO1 += (new_IF1 - zfIF1);
 841                                pAS_Info->f_LO2 += (new_IF1 - zfIF1);
 842                        } else {
 843                                pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
 844                                pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
 845                        }
 846                        zfIF1 = new_IF1;
 847
 848                        if (zfIF1 > pAS_Info->f_if1_Center)
 849                                delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
 850                        else
 851                                delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
 852
 853                        pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
 854                /*
 855                 *  Continue while the new 1st IF is still within the 1st IF bandwidth
 856                 *  and there is a spur in the band (again)
 857                 */
 858                } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
 859
 860                /*
 861                 * Use the LO-spur free values found.  If the search went all
 862                 * the way to the 1st IF band edge and always found spurs, just
 863                 * leave the original choice.  It's as "good" as any other.
 864                 */
 865                if (pAS_Info->bSpurPresent == 1) {
 866                        status |= MT2063_SPUR_PRESENT_ERR;
 867                        pAS_Info->f_LO1 = zfLO1;
 868                        pAS_Info->f_LO2 = zfLO2;
 869                } else
 870                        pAS_Info->bSpurAvoided = 1;
 871        }
 872
 873        status |=
 874            ((pAS_Info->
 875              nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
 876
 877        return status;
 878}
 879
 880/*
 881 * Constants used by the tuning algorithm
 882 */
 883#define MT2063_REF_FREQ          (16000000UL)   /* Reference oscillator Frequency (in Hz) */
 884#define MT2063_IF1_BW            (22000000UL)   /* The IF1 filter bandwidth (in Hz) */
 885#define MT2063_TUNE_STEP_SIZE       (50000UL)   /* Tune in steps of 50 kHz */
 886#define MT2063_SPUR_STEP_HZ        (250000UL)   /* Step size (in Hz) to move IF1 when avoiding spurs */
 887#define MT2063_ZIF_BW             (2000000UL)   /* Zero-IF spur-free bandwidth (in Hz) */
 888#define MT2063_MAX_HARMONICS_1         (15UL)   /* Highest intra-tuner LO Spur Harmonic to be avoided */
 889#define MT2063_MAX_HARMONICS_2          (5UL)   /* Highest inter-tuner LO Spur Harmonic to be avoided */
 890#define MT2063_MIN_LO_SEP         (1000000UL)   /* Minimum inter-tuner LO frequency separation */
 891#define MT2063_LO1_FRACN_AVOID          (0UL)   /* LO1 FracN numerator avoid region (in Hz) */
 892#define MT2063_LO2_FRACN_AVOID     (199999UL)   /* LO2 FracN numerator avoid region (in Hz) */
 893#define MT2063_MIN_FIN_FREQ      (44000000UL)   /* Minimum input frequency (in Hz) */
 894#define MT2063_MAX_FIN_FREQ    (1100000000UL)   /* Maximum input frequency (in Hz) */
 895#define MT2063_MIN_FOUT_FREQ     (36000000UL)   /* Minimum output frequency (in Hz) */
 896#define MT2063_MAX_FOUT_FREQ     (57000000UL)   /* Maximum output frequency (in Hz) */
 897#define MT2063_MIN_DNC_FREQ    (1293000000UL)   /* Minimum LO2 frequency (in Hz) */
 898#define MT2063_MAX_DNC_FREQ    (1614000000UL)   /* Maximum LO2 frequency (in Hz) */
 899#define MT2063_MIN_UPC_FREQ    (1396000000UL)   /* Minimum LO1 frequency (in Hz) */
 900#define MT2063_MAX_UPC_FREQ    (2750000000UL)   /* Maximum LO1 frequency (in Hz) */
 901
 902/*
 903 *  Define the supported Part/Rev codes for the MT2063
 904 */
 905#define MT2063_B0       (0x9B)
 906#define MT2063_B1       (0x9C)
 907#define MT2063_B2       (0x9D)
 908#define MT2063_B3       (0x9E)
 909
 910/**
 911 * mt2063_lockStatus - Checks to see if LO1 and LO2 are locked
 912 *
 913 * @state:      struct mt2063_state pointer
 914 *
 915 * This function returns 0, if no lock, 1 if locked and a value < 1 if error
 916 */
 917static int mt2063_lockStatus(struct mt2063_state *state)
 918{
 919        const u32 nMaxWait = 100;       /*  wait a maximum of 100 msec   */
 920        const u32 nPollRate = 2;        /*  poll status bits every 2 ms */
 921        const u32 nMaxLoops = nMaxWait / nPollRate;
 922        const u8 LO1LK = 0x80;
 923        u8 LO2LK = 0x08;
 924        int status;
 925        u32 nDelays = 0;
 926
 927        dprintk(2, "\n");
 928
 929        /*  LO2 Lock bit was in a different place for B0 version  */
 930        if (state->tuner_id == MT2063_B0)
 931                LO2LK = 0x40;
 932
 933        do {
 934                status = mt2063_read(state, MT2063_REG_LO_STATUS,
 935                                     &state->reg[MT2063_REG_LO_STATUS], 1);
 936
 937                if (status < 0)
 938                        return status;
 939
 940                if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
 941                    (LO1LK | LO2LK)) {
 942                        return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
 943                }
 944                msleep(nPollRate);      /*  Wait between retries  */
 945        } while (++nDelays < nMaxLoops);
 946
 947        /*
 948         * Got no lock or partial lock
 949         */
 950        return 0;
 951}
 952
 953/*
 954 *  Constants for setting receiver modes.
 955 *  (6 modes defined at this time, enumerated by mt2063_delivery_sys)
 956 *  (DNC1GC & DNC2GC are the values, which are used, when the specific
 957 *   DNC Output is selected, the other is always off)
 958 *
 959 *                enum mt2063_delivery_sys
 960 * -------------+----------------------------------------------
 961 * Mode 0 :     | MT2063_CABLE_QAM
 962 * Mode 1 :     | MT2063_CABLE_ANALOG
 963 * Mode 2 :     | MT2063_OFFAIR_COFDM
 964 * Mode 3 :     | MT2063_OFFAIR_COFDM_SAWLESS
 965 * Mode 4 :     | MT2063_OFFAIR_ANALOG
 966 * Mode 5 :     | MT2063_OFFAIR_8VSB
 967 * --------------+----------------------------------------------
 968 *
 969 *                |<----------   Mode  -------------->|
 970 *    Reg Field   |  0  |  1  |  2  |  3  |  4  |  5  |
 971 *    ------------+-----+-----+-----+-----+-----+-----+
 972 *    RFAGCen     | OFF | OFF | OFF | OFF | OFF | OFF
 973 *    LNARin      |   0 |   0 |   3 |   3 |  3  |  3
 974 *    FIFFQen     |   1 |   1 |   1 |   1 |  1  |  1
 975 *    FIFFq       |   0 |   0 |   0 |   0 |  0  |  0
 976 *    DNC1gc      |   0 |   0 |   0 |   0 |  0  |  0
 977 *    DNC2gc      |   0 |   0 |   0 |   0 |  0  |  0
 978 *    GCU Auto    |   1 |   1 |   1 |   1 |  1  |  1
 979 *    LNA max Atn |  31 |  31 |  31 |  31 | 31  | 31
 980 *    LNA Target  |  44 |  43 |  43 |  43 | 43  | 43
 981 *    ign  RF Ovl |   0 |   0 |   0 |   0 |  0  |  0
 982 *    RF  max Atn |  31 |  31 |  31 |  31 | 31  | 31
 983 *    PD1 Target  |  36 |  36 |  38 |  38 | 36  | 38
 984 *    ign FIF Ovl |   0 |   0 |   0 |   0 |  0  |  0
 985 *    FIF max Atn |   5 |   5 |   5 |   5 |  5  |  5
 986 *    PD2 Target  |  40 |  33 |  42 |  42 | 33  | 42
 987 */
 988
 989enum mt2063_delivery_sys {
 990        MT2063_CABLE_QAM = 0,
 991        MT2063_CABLE_ANALOG,
 992        MT2063_OFFAIR_COFDM,
 993        MT2063_OFFAIR_COFDM_SAWLESS,
 994        MT2063_OFFAIR_ANALOG,
 995        MT2063_OFFAIR_8VSB,
 996        MT2063_NUM_RCVR_MODES
 997};
 998
 999static const char *mt2063_mode_name[] = {
1000        [MT2063_CABLE_QAM]              = "digital cable",
1001        [MT2063_CABLE_ANALOG]           = "analog cable",
1002        [MT2063_OFFAIR_COFDM]           = "digital offair",
1003        [MT2063_OFFAIR_COFDM_SAWLESS]   = "digital offair without SAW",
1004        [MT2063_OFFAIR_ANALOG]          = "analog offair",
1005        [MT2063_OFFAIR_8VSB]            = "analog offair 8vsb",
1006};
1007
1008static const u8 RFAGCEN[]       = {  0,  0,  0,  0,  0,  0 };
1009static const u8 LNARIN[]        = {  0,  0,  3,  3,  3,  3 };
1010static const u8 FIFFQEN[]       = {  1,  1,  1,  1,  1,  1 };
1011static const u8 FIFFQ[]         = {  0,  0,  0,  0,  0,  0 };
1012static const u8 DNC1GC[]        = {  0,  0,  0,  0,  0,  0 };
1013static const u8 DNC2GC[]        = {  0,  0,  0,  0,  0,  0 };
1014static const u8 ACLNAMAX[]      = { 31, 31, 31, 31, 31, 31 };
1015static const u8 LNATGT[]        = { 44, 43, 43, 43, 43, 43 };
1016static const u8 RFOVDIS[]       = {  0,  0,  0,  0,  0,  0 };
1017static const u8 ACRFMAX[]       = { 31, 31, 31, 31, 31, 31 };
1018static const u8 PD1TGT[]        = { 36, 36, 38, 38, 36, 38 };
1019static const u8 FIFOVDIS[]      = {  0,  0,  0,  0,  0,  0 };
1020static const u8 ACFIFMAX[]      = { 29, 29, 29, 29, 29, 29 };
1021static const u8 PD2TGT[]        = { 40, 33, 38, 42, 30, 38 };
1022
1023/*
1024 * mt2063_set_dnc_output_enable()
1025 */
1026static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
1027                                        enum MT2063_DNC_Output_Enable *pValue)
1028{
1029        dprintk(2, "\n");
1030
1031        if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */
1032                if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)   /* if DNC2 is off */
1033                        *pValue = MT2063_DNC_NONE;
1034                else
1035                        *pValue = MT2063_DNC_2;
1036        } else {        /* DNC1 is on */
1037                if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)   /* if DNC2 is off */
1038                        *pValue = MT2063_DNC_1;
1039                else
1040                        *pValue = MT2063_DNC_BOTH;
1041        }
1042        return 0;
1043}
1044
1045/*
1046 * mt2063_set_dnc_output_enable()
1047 */
1048static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
1049                                        enum MT2063_DNC_Output_Enable nValue)
1050{
1051        int status = 0; /* Status to be returned        */
1052        u8 val = 0;
1053
1054        dprintk(2, "\n");
1055
1056        /* selects, which DNC output is used */
1057        switch (nValue) {
1058        case MT2063_DNC_NONE:
1059                val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;  /* Set DNC1GC=3 */
1060                if (state->reg[MT2063_REG_DNC_GAIN] !=
1061                    val)
1062                        status |=
1063                            mt2063_setreg(state,
1064                                          MT2063_REG_DNC_GAIN,
1065                                          val);
1066
1067                val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;  /* Set DNC2GC=3 */
1068                if (state->reg[MT2063_REG_VGA_GAIN] !=
1069                    val)
1070                        status |=
1071                            mt2063_setreg(state,
1072                                          MT2063_REG_VGA_GAIN,
1073                                          val);
1074
1075                val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
1076                if (state->reg[MT2063_REG_RSVD_20] !=
1077                    val)
1078                        status |=
1079                            mt2063_setreg(state,
1080                                          MT2063_REG_RSVD_20,
1081                                          val);
1082
1083                break;
1084        case MT2063_DNC_1:
1085                val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);     /* Set DNC1GC=x */
1086                if (state->reg[MT2063_REG_DNC_GAIN] !=
1087                    val)
1088                        status |=
1089                            mt2063_setreg(state,
1090                                          MT2063_REG_DNC_GAIN,
1091                                          val);
1092
1093                val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;  /* Set DNC2GC=3 */
1094                if (state->reg[MT2063_REG_VGA_GAIN] !=
1095                    val)
1096                        status |=
1097                            mt2063_setreg(state,
1098                                          MT2063_REG_VGA_GAIN,
1099                                          val);
1100
1101                val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
1102                if (state->reg[MT2063_REG_RSVD_20] !=
1103                    val)
1104                        status |=
1105                            mt2063_setreg(state,
1106                                          MT2063_REG_RSVD_20,
1107                                          val);
1108
1109                break;
1110        case MT2063_DNC_2:
1111                val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;  /* Set DNC1GC=3 */
1112                if (state->reg[MT2063_REG_DNC_GAIN] !=
1113                    val)
1114                        status |=
1115                            mt2063_setreg(state,
1116                                          MT2063_REG_DNC_GAIN,
1117                                          val);
1118
1119                val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);     /* Set DNC2GC=x */
1120                if (state->reg[MT2063_REG_VGA_GAIN] !=
1121                    val)
1122                        status |=
1123                            mt2063_setreg(state,
1124                                          MT2063_REG_VGA_GAIN,
1125                                          val);
1126
1127                val = (state->reg[MT2063_REG_RSVD_20] | 0x40);  /* Set PD2MUX=1 */
1128                if (state->reg[MT2063_REG_RSVD_20] !=
1129                    val)
1130                        status |=
1131                            mt2063_setreg(state,
1132                                          MT2063_REG_RSVD_20,
1133                                          val);
1134
1135                break;
1136        case MT2063_DNC_BOTH:
1137                val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);     /* Set DNC1GC=x */
1138                if (state->reg[MT2063_REG_DNC_GAIN] !=
1139                    val)
1140                        status |=
1141                            mt2063_setreg(state,
1142                                          MT2063_REG_DNC_GAIN,
1143                                          val);
1144
1145                val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);     /* Set DNC2GC=x */
1146                if (state->reg[MT2063_REG_VGA_GAIN] !=
1147                    val)
1148                        status |=
1149                            mt2063_setreg(state,
1150                                          MT2063_REG_VGA_GAIN,
1151                                          val);
1152
1153                val = (state->reg[MT2063_REG_RSVD_20] | 0x40);  /* Set PD2MUX=1 */
1154                if (state->reg[MT2063_REG_RSVD_20] !=
1155                    val)
1156                        status |=
1157                            mt2063_setreg(state,
1158                                          MT2063_REG_RSVD_20,
1159                                          val);
1160
1161                break;
1162        default:
1163                break;
1164        }
1165
1166        return status;
1167}
1168
1169/*
1170 * MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
1171 *                            the selected enum mt2063_delivery_sys type.
1172 *
1173 *  (DNC1GC & DNC2GC are the values, which are used, when the specific
1174 *   DNC Output is selected, the other is always off)
1175 *
1176 * @state:      ptr to mt2063_state structure
1177 * @Mode:       desired receiver delivery system
1178 *
1179 * Note: Register cache must be valid for it to work
1180 */
1181
1182static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
1183                                  enum mt2063_delivery_sys Mode)
1184{
1185        int status = 0; /* Status to be returned        */
1186        u8 val;
1187        u32 longval;
1188
1189        dprintk(2, "\n");
1190
1191        if (Mode >= MT2063_NUM_RCVR_MODES)
1192                status = -ERANGE;
1193
1194        /* RFAGCen */
1195        if (status >= 0) {
1196                val =
1197                    (state->
1198                     reg[MT2063_REG_PD1_TGT] & ~0x40) | (RFAGCEN[Mode]
1199                                                                   ? 0x40 :
1200                                                                   0x00);
1201                if (state->reg[MT2063_REG_PD1_TGT] != val)
1202                        status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1203        }
1204
1205        /* LNARin */
1206        if (status >= 0) {
1207                u8 val = (state->reg[MT2063_REG_CTRL_2C] & ~0x03) |
1208                         (LNARIN[Mode] & 0x03);
1209                if (state->reg[MT2063_REG_CTRL_2C] != val)
1210                        status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
1211        }
1212
1213        /* FIFFQEN and FIFFQ */
1214        if (status >= 0) {
1215                val =
1216                    (state->
1217                     reg[MT2063_REG_FIFF_CTRL2] & ~0xF0) |
1218                    (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
1219                if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
1220                        status |=
1221                            mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
1222                        /* trigger FIFF calibration, needed after changing FIFFQ */
1223                        val =
1224                            (state->reg[MT2063_REG_FIFF_CTRL] | 0x01);
1225                        status |=
1226                            mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1227                        val =
1228                            (state->
1229                             reg[MT2063_REG_FIFF_CTRL] & ~0x01);
1230                        status |=
1231                            mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1232                }
1233        }
1234
1235        /* DNC1GC & DNC2GC */
1236        status |= mt2063_get_dnc_output_enable(state, &longval);
1237        status |= mt2063_set_dnc_output_enable(state, longval);
1238
1239        /* acLNAmax */
1240        if (status >= 0) {
1241                u8 val = (state->reg[MT2063_REG_LNA_OV] & ~0x1F) |
1242                         (ACLNAMAX[Mode] & 0x1F);
1243                if (state->reg[MT2063_REG_LNA_OV] != val)
1244                        status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
1245        }
1246
1247        /* LNATGT */
1248        if (status >= 0) {
1249                u8 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x3F) |
1250                         (LNATGT[Mode] & 0x3F);
1251                if (state->reg[MT2063_REG_LNA_TGT] != val)
1252                        status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1253        }
1254
1255        /* ACRF */
1256        if (status >= 0) {
1257                u8 val = (state->reg[MT2063_REG_RF_OV] & ~0x1F) |
1258                         (ACRFMAX[Mode] & 0x1F);
1259                if (state->reg[MT2063_REG_RF_OV] != val)
1260                        status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
1261        }
1262
1263        /* PD1TGT */
1264        if (status >= 0) {
1265                u8 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x3F) |
1266                         (PD1TGT[Mode] & 0x3F);
1267                if (state->reg[MT2063_REG_PD1_TGT] != val)
1268                        status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1269        }
1270
1271        /* FIFATN */
1272        if (status >= 0) {
1273                u8 val = ACFIFMAX[Mode];
1274                if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
1275                        val = 5;
1276                val = (state->reg[MT2063_REG_FIF_OV] & ~0x1F) |
1277                      (val & 0x1F);
1278                if (state->reg[MT2063_REG_FIF_OV] != val)
1279                        status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
1280        }
1281
1282        /* PD2TGT */
1283        if (status >= 0) {
1284                u8 val = (state->reg[MT2063_REG_PD2_TGT] & ~0x3F) |
1285                    (PD2TGT[Mode] & 0x3F);
1286                if (state->reg[MT2063_REG_PD2_TGT] != val)
1287                        status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
1288        }
1289
1290        /* Ignore ATN Overload */
1291        if (status >= 0) {
1292                val = (state->reg[MT2063_REG_LNA_TGT] & ~0x80) |
1293                      (RFOVDIS[Mode] ? 0x80 : 0x00);
1294                if (state->reg[MT2063_REG_LNA_TGT] != val)
1295                        status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1296        }
1297
1298        /* Ignore FIF Overload */
1299        if (status >= 0) {
1300                val = (state->reg[MT2063_REG_PD1_TGT] & ~0x80) |
1301                      (FIFOVDIS[Mode] ? 0x80 : 0x00);
1302                if (state->reg[MT2063_REG_PD1_TGT] != val)
1303                        status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1304        }
1305
1306        if (status >= 0) {
1307                state->rcvr_mode = Mode;
1308                dprintk(1, "mt2063 mode changed to %s\n",
1309                        mt2063_mode_name[state->rcvr_mode]);
1310        }
1311
1312        return status;
1313}
1314
1315/*
1316 * MT2063_ClearPowerMaskBits () - Clears the power-down mask bits for various
1317 *                                sections of the MT2063
1318 *
1319 * @Bits:               Mask bits to be cleared.
1320 *
1321 * See definition of MT2063_Mask_Bits type for description
1322 * of each of the power bits.
1323 */
1324static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
1325                                     enum MT2063_Mask_Bits Bits)
1326{
1327        int status = 0;
1328
1329        dprintk(2, "\n");
1330        Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD);   /* Only valid bits for this tuner */
1331        if ((Bits & 0xFF00) != 0) {
1332                state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
1333                status |=
1334                    mt2063_write(state,
1335                                    MT2063_REG_PWR_2,
1336                                    &state->reg[MT2063_REG_PWR_2], 1);
1337        }
1338        if ((Bits & 0xFF) != 0) {
1339                state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
1340                status |=
1341                    mt2063_write(state,
1342                                    MT2063_REG_PWR_1,
1343                                    &state->reg[MT2063_REG_PWR_1], 1);
1344        }
1345
1346        return status;
1347}
1348
1349/*
1350 * MT2063_SoftwareShutdown() - Enables or disables software shutdown function.
1351 *                             When Shutdown is 1, any section whose power
1352 *                             mask is set will be shutdown.
1353 */
1354static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
1355{
1356        int status;
1357
1358        dprintk(2, "\n");
1359        if (Shutdown == 1)
1360                state->reg[MT2063_REG_PWR_1] |= 0x04;
1361        else
1362                state->reg[MT2063_REG_PWR_1] &= ~0x04;
1363
1364        status = mt2063_write(state,
1365                            MT2063_REG_PWR_1,
1366                            &state->reg[MT2063_REG_PWR_1], 1);
1367
1368        if (Shutdown != 1) {
1369                state->reg[MT2063_REG_BYP_CTRL] =
1370                    (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
1371                status |=
1372                    mt2063_write(state,
1373                                    MT2063_REG_BYP_CTRL,
1374                                    &state->reg[MT2063_REG_BYP_CTRL],
1375                                    1);
1376                state->reg[MT2063_REG_BYP_CTRL] =
1377                    (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
1378                status |=
1379                    mt2063_write(state,
1380                                    MT2063_REG_BYP_CTRL,
1381                                    &state->reg[MT2063_REG_BYP_CTRL],
1382                                    1);
1383        }
1384
1385        return status;
1386}
1387
1388static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
1389{
1390        return f_ref * (f_LO / f_ref)
1391            + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1392}
1393
1394/**
1395 * fLO_FractionalTerm() - Calculates the portion contributed by FracN / denom.
1396 *                        This function preserves maximum precision without
1397 *                        risk of overflow.  It accurately calculates
1398 *                        f_ref * num / denom to within 1 HZ with fixed math.
1399 *
1400 * @f_ref:      SRO frequency.
1401 * @num:        Fractional portion of the multiplier
1402 * @denom:      denominator portion of the ratio
1403 *
1404 * This calculation handles f_ref as two separate 14-bit fields.
1405 * Therefore, a maximum value of 2^28-1 may safely be used for f_ref.
1406 * This is the genesis of the magic number "14" and the magic mask value of
1407 * 0x03FFF.
1408 *
1409 * This routine successfully handles denom values up to and including 2^18.
1410 *  Returns:        f_ref * num / denom
1411 */
1412static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
1413{
1414        u32 t1 = (f_ref >> 14) * num;
1415        u32 term1 = t1 / denom;
1416        u32 loss = t1 % denom;
1417        u32 term2 =
1418            (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1419        return (term1 << 14) + term2;
1420}
1421
1422/*
1423 * CalcLO1Mult()- Calculates Integer divider value and the numerator
1424 *                value for a FracN PLL.
1425 *
1426 *                This function assumes that the f_LO and f_Ref are
1427 *                evenly divisible by f_LO_Step.
1428 *
1429 * @Div:        OUTPUT: Whole number portion of the multiplier
1430 * @FracN:      OUTPUT: Fractional portion of the multiplier
1431 * @f_LO:       desired LO frequency.
1432 * @f_LO_Step:  Minimum step size for the LO (in Hz).
1433 * @f_Ref:      SRO frequency.
1434 * @f_Avoid:    Range of PLL frequencies to avoid near integer multiples
1435 *              of f_Ref (in Hz).
1436 *
1437 * Returns:        Recalculated LO frequency.
1438 */
1439static u32 MT2063_CalcLO1Mult(u32 *Div,
1440                              u32 *FracN,
1441                              u32 f_LO,
1442                              u32 f_LO_Step, u32 f_Ref)
1443{
1444        /*  Calculate the whole number portion of the divider */
1445        *Div = f_LO / f_Ref;
1446
1447        /*  Calculate the numerator value (round to nearest f_LO_Step) */
1448        *FracN =
1449            (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1450             (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1451
1452        return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1453}
1454
1455/**
1456 * CalcLO2Mult() - Calculates Integer divider value and the numerator
1457 *                 value for a FracN PLL.
1458 *
1459 *                  This function assumes that the f_LO and f_Ref are
1460 *                  evenly divisible by f_LO_Step.
1461 *
1462 * @Div:        OUTPUT: Whole number portion of the multiplier
1463 * @FracN:      OUTPUT: Fractional portion of the multiplier
1464 * @f_LO:       desired LO frequency.
1465 * @f_LO_Step:  Minimum step size for the LO (in Hz).
1466 * @f_Ref:      SRO frequency.
1467 *
1468 * Returns: Recalculated LO frequency.
1469 */
1470static u32 MT2063_CalcLO2Mult(u32 *Div,
1471                              u32 *FracN,
1472                              u32 f_LO,
1473                              u32 f_LO_Step, u32 f_Ref)
1474{
1475        /*  Calculate the whole number portion of the divider */
1476        *Div = f_LO / f_Ref;
1477
1478        /*  Calculate the numerator value (round to nearest f_LO_Step) */
1479        *FracN =
1480            (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1481             (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1482
1483        return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1484                                                            8191);
1485}
1486
1487/*
1488 * FindClearTuneFilter() - Calculate the corrrect ClearTune filter to be
1489 *                         used for a given input frequency.
1490 *
1491 * @state:      ptr to tuner data structure
1492 * @f_in:       RF input center frequency (in Hz).
1493 *
1494 * Returns: ClearTune filter number (0-31)
1495 */
1496static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
1497{
1498        u32 RFBand;
1499        u32 idx;                /*  index loop                      */
1500
1501        /*
1502         **  Find RF Band setting
1503         */
1504        RFBand = 31;            /*  def when f_in > all    */
1505        for (idx = 0; idx < 31; ++idx) {
1506                if (state->CTFiltMax[idx] >= f_in) {
1507                        RFBand = idx;
1508                        break;
1509                }
1510        }
1511        return RFBand;
1512}
1513
1514/*
1515 * MT2063_Tune() - Change the tuner's tuned frequency to RFin.
1516 */
1517static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
1518{                               /* RF input center frequency   */
1519
1520        int status = 0;
1521        u32 LO1;                /*  1st LO register value           */
1522        u32 Num1;               /*  Numerator for LO1 reg. value    */
1523        u32 f_IF1;              /*  1st IF requested                */
1524        u32 LO2;                /*  2nd LO register value           */
1525        u32 Num2;               /*  Numerator for LO2 reg. value    */
1526        u32 ofLO1, ofLO2;       /*  last time's LO frequencies      */
1527        u8 fiffc = 0x80;        /*  FIFF center freq from tuner     */
1528        u32 fiffof;             /*  Offset from FIFF center freq    */
1529        const u8 LO1LK = 0x80;  /*  Mask for LO1 Lock bit           */
1530        u8 LO2LK = 0x08;        /*  Mask for LO2 Lock bit           */
1531        u8 val;
1532        u32 RFBand;
1533
1534        dprintk(2, "\n");
1535        /*  Check the input and output frequency ranges                   */
1536        if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
1537                return -EINVAL;
1538
1539        if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
1540            || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
1541                return -EINVAL;
1542
1543        /*
1544         * Save original LO1 and LO2 register values
1545         */
1546        ofLO1 = state->AS_Data.f_LO1;
1547        ofLO2 = state->AS_Data.f_LO2;
1548
1549        /*
1550         * Find and set RF Band setting
1551         */
1552        if (state->ctfilt_sw == 1) {
1553                val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
1554                if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
1555                        status |=
1556                            mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
1557                }
1558                val = state->reg[MT2063_REG_CTUNE_OV];
1559                RFBand = FindClearTuneFilter(state, f_in);
1560                state->reg[MT2063_REG_CTUNE_OV] =
1561                    (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
1562                              | RFBand);
1563                if (state->reg[MT2063_REG_CTUNE_OV] != val) {
1564                        status |=
1565                            mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
1566                }
1567        }
1568
1569        /*
1570         * Read the FIFF Center Frequency from the tuner
1571         */
1572        if (status >= 0) {
1573                status |=
1574                    mt2063_read(state,
1575                                   MT2063_REG_FIFFC,
1576                                   &state->reg[MT2063_REG_FIFFC], 1);
1577                fiffc = state->reg[MT2063_REG_FIFFC];
1578        }
1579        /*
1580         * Assign in the requested values
1581         */
1582        state->AS_Data.f_in = f_in;
1583        /*  Request a 1st IF such that LO1 is on a step size */
1584        state->AS_Data.f_if1_Request =
1585            MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
1586                             state->AS_Data.f_LO1_Step,
1587                             state->AS_Data.f_ref) - f_in;
1588
1589        /*
1590         * Calculate frequency settings.  f_IF1_FREQ + f_in is the
1591         * desired LO1 frequency
1592         */
1593        MT2063_ResetExclZones(&state->AS_Data);
1594
1595        f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
1596
1597        state->AS_Data.f_LO1 =
1598            MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
1599                             state->AS_Data.f_ref);
1600
1601        state->AS_Data.f_LO2 =
1602            MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1603                             state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1604
1605        /*
1606         * Check for any LO spurs in the output bandwidth and adjust
1607         * the LO settings to avoid them if needed
1608         */
1609        status |= MT2063_AvoidSpurs(&state->AS_Data);
1610        /*
1611         * MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
1612         * Recalculate the LO frequencies and the values to be placed
1613         * in the tuning registers.
1614         */
1615        state->AS_Data.f_LO1 =
1616            MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
1617                               state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
1618        state->AS_Data.f_LO2 =
1619            MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1620                             state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1621        state->AS_Data.f_LO2 =
1622            MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
1623                               state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1624
1625        /*
1626         *  Check the upconverter and downconverter frequency ranges
1627         */
1628        if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
1629            || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
1630                status |= MT2063_UPC_RANGE;
1631        if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
1632            || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
1633                status |= MT2063_DNC_RANGE;
1634        /*  LO2 Lock bit was in a different place for B0 version  */
1635        if (state->tuner_id == MT2063_B0)
1636                LO2LK = 0x40;
1637
1638        /*
1639         *  If we have the same LO frequencies and we're already locked,
1640         *  then skip re-programming the LO registers.
1641         */
1642        if ((ofLO1 != state->AS_Data.f_LO1)
1643            || (ofLO2 != state->AS_Data.f_LO2)
1644            || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
1645                (LO1LK | LO2LK))) {
1646                /*
1647                 * Calculate the FIFFOF register value
1648                 *
1649                 *           IF1_Actual
1650                 * FIFFOF = ------------ - 8 * FIFFC - 4992
1651                 *            f_ref/64
1652                 */
1653                fiffof =
1654                    (state->AS_Data.f_LO1 -
1655                     f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
1656                    4992;
1657                if (fiffof > 0xFF)
1658                        fiffof = 0xFF;
1659
1660                /*
1661                 * Place all of the calculated values into the local tuner
1662                 * register fields.
1663                 */
1664                if (status >= 0) {
1665                        state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF);     /* DIV1q */
1666                        state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F);    /* NUM1q */
1667                        state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1)      /* DIV2q */
1668                                                                   |(Num2 >> 12));      /* NUM2q (hi) */
1669                        state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4);   /* NUM2q (mid) */
1670                        state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
1671
1672                        /*
1673                         * Now write out the computed register values
1674                         * IMPORTANT: There is a required order for writing
1675                         *            (0x05 must follow all the others).
1676                         */
1677                        status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5);  /* 0x01 - 0x05 */
1678                        if (state->tuner_id == MT2063_B0) {
1679                                /* Re-write the one-shot bits to trigger the tune operation */
1680                                status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1);  /* 0x05 */
1681                        }
1682                        /* Write out the FIFF offset only if it's changing */
1683                        if (state->reg[MT2063_REG_FIFF_OFFSET] !=
1684                            (u8) fiffof) {
1685                                state->reg[MT2063_REG_FIFF_OFFSET] =
1686                                    (u8) fiffof;
1687                                status |=
1688                                    mt2063_write(state,
1689                                                    MT2063_REG_FIFF_OFFSET,
1690                                                    &state->
1691                                                    reg[MT2063_REG_FIFF_OFFSET],
1692                                                    1);
1693                        }
1694                }
1695
1696                /*
1697                 * Check for LO's locking
1698                 */
1699
1700                if (status < 0)
1701                        return status;
1702
1703                status = mt2063_lockStatus(state);
1704                if (status < 0)
1705                        return status;
1706                if (!status)
1707                        return -EINVAL;         /* Couldn't lock */
1708
1709                /*
1710                 * If we locked OK, assign calculated data to mt2063_state structure
1711                 */
1712                state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
1713        }
1714
1715        return status;
1716}
1717
1718static const u8 MT2063B0_defaults[] = {
1719        /* Reg,  Value */
1720        0x19, 0x05,
1721        0x1B, 0x1D,
1722        0x1C, 0x1F,
1723        0x1D, 0x0F,
1724        0x1E, 0x3F,
1725        0x1F, 0x0F,
1726        0x20, 0x3F,
1727        0x22, 0x21,
1728        0x23, 0x3F,
1729        0x24, 0x20,
1730        0x25, 0x3F,
1731        0x27, 0xEE,
1732        0x2C, 0x27,     /*  bit at 0x20 is cleared below  */
1733        0x30, 0x03,
1734        0x2C, 0x07,     /*  bit at 0x20 is cleared here   */
1735        0x2D, 0x87,
1736        0x2E, 0xAA,
1737        0x28, 0xE1,     /*  Set the FIFCrst bit here      */
1738        0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
1739        0x00
1740};
1741
1742/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
1743static const u8 MT2063B1_defaults[] = {
1744        /* Reg,  Value */
1745        0x05, 0xF0,
1746        0x11, 0x10,     /* New Enable AFCsd */
1747        0x19, 0x05,
1748        0x1A, 0x6C,
1749        0x1B, 0x24,
1750        0x1C, 0x28,
1751        0x1D, 0x8F,
1752        0x1E, 0x14,
1753        0x1F, 0x8F,
1754        0x20, 0x57,
1755        0x22, 0x21,     /* New - ver 1.03 */
1756        0x23, 0x3C,     /* New - ver 1.10 */
1757        0x24, 0x20,     /* New - ver 1.03 */
1758        0x2C, 0x24,     /*  bit at 0x20 is cleared below  */
1759        0x2D, 0x87,     /*  FIFFQ=0  */
1760        0x2F, 0xF3,
1761        0x30, 0x0C,     /* New - ver 1.11 */
1762        0x31, 0x1B,     /* New - ver 1.11 */
1763        0x2C, 0x04,     /*  bit at 0x20 is cleared here  */
1764        0x28, 0xE1,     /*  Set the FIFCrst bit here      */
1765        0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
1766        0x00
1767};
1768
1769/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
1770static const u8 MT2063B3_defaults[] = {
1771        /* Reg,  Value */
1772        0x05, 0xF0,
1773        0x19, 0x3D,
1774        0x2C, 0x24,     /*  bit at 0x20 is cleared below  */
1775        0x2C, 0x04,     /*  bit at 0x20 is cleared here  */
1776        0x28, 0xE1,     /*  Set the FIFCrst bit here      */
1777        0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
1778        0x00
1779};
1780
1781static int mt2063_init(struct dvb_frontend *fe)
1782{
1783        int status;
1784        struct mt2063_state *state = fe->tuner_priv;
1785        u8 all_resets = 0xF0;   /* reset/load bits */
1786        const u8 *def = NULL;
1787        char *step;
1788        u32 FCRUN;
1789        s32 maxReads;
1790        u32 fcu_osc;
1791        u32 i;
1792
1793        dprintk(2, "\n");
1794
1795        state->rcvr_mode = MT2063_CABLE_QAM;
1796
1797        /*  Read the Part/Rev code from the tuner */
1798        status = mt2063_read(state, MT2063_REG_PART_REV,
1799                             &state->reg[MT2063_REG_PART_REV], 1);
1800        if (status < 0) {
1801                printk(KERN_ERR "Can't read mt2063 part ID\n");
1802                return status;
1803        }
1804
1805        /* Check the part/rev code */
1806        switch (state->reg[MT2063_REG_PART_REV]) {
1807        case MT2063_B0:
1808                step = "B0";
1809                break;
1810        case MT2063_B1:
1811                step = "B1";
1812                break;
1813        case MT2063_B2:
1814                step = "B2";
1815                break;
1816        case MT2063_B3:
1817                step = "B3";
1818                break;
1819        default:
1820                printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
1821                       state->reg[MT2063_REG_PART_REV]);
1822                return -ENODEV; /*  Wrong tuner Part/Rev code */
1823        }
1824
1825        /*  Check the 2nd byte of the Part/Rev code from the tuner */
1826        status = mt2063_read(state, MT2063_REG_RSVD_3B,
1827                             &state->reg[MT2063_REG_RSVD_3B], 1);
1828
1829        /* b7 != 0 ==> NOT MT2063 */
1830        if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
1831                printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
1832                       state->reg[MT2063_REG_PART_REV],
1833                       state->reg[MT2063_REG_RSVD_3B]);
1834                return -ENODEV; /*  Wrong tuner Part/Rev code */
1835        }
1836
1837        printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
1838
1839        /*  Reset the tuner  */
1840        status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
1841        if (status < 0)
1842                return status;
1843
1844        /* change all of the default values that vary from the HW reset values */
1845        /*  def = (state->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
1846        switch (state->reg[MT2063_REG_PART_REV]) {
1847        case MT2063_B3:
1848                def = MT2063B3_defaults;
1849                break;
1850
1851        case MT2063_B1:
1852                def = MT2063B1_defaults;
1853                break;
1854
1855        case MT2063_B0:
1856                def = MT2063B0_defaults;
1857                break;
1858
1859        default:
1860                return -ENODEV;
1861                break;
1862        }
1863
1864        while (status >= 0 && *def) {
1865                u8 reg = *def++;
1866                u8 val = *def++;
1867                status = mt2063_write(state, reg, &val, 1);
1868        }
1869        if (status < 0)
1870                return status;
1871
1872        /*  Wait for FIFF location to complete.  */
1873        FCRUN = 1;
1874        maxReads = 10;
1875        while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
1876                msleep(2);
1877                status = mt2063_read(state,
1878                                         MT2063_REG_XO_STATUS,
1879                                         &state->
1880                                         reg[MT2063_REG_XO_STATUS], 1);
1881                FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
1882        }
1883
1884        if (FCRUN != 0 || status < 0)
1885                return -ENODEV;
1886
1887        status = mt2063_read(state,
1888                           MT2063_REG_FIFFC,
1889                           &state->reg[MT2063_REG_FIFFC], 1);
1890        if (status < 0)
1891                return status;
1892
1893        /* Read back all the registers from the tuner */
1894        status = mt2063_read(state,
1895                                MT2063_REG_PART_REV,
1896                                state->reg, MT2063_REG_END_REGS);
1897        if (status < 0)
1898                return status;
1899
1900        /*  Initialize the tuner state.  */
1901        state->tuner_id = state->reg[MT2063_REG_PART_REV];
1902        state->AS_Data.f_ref = MT2063_REF_FREQ;
1903        state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
1904                                      ((u32) state->reg[MT2063_REG_FIFFC] + 640);
1905        state->AS_Data.f_if1_bw = MT2063_IF1_BW;
1906        state->AS_Data.f_out = 43750000UL;
1907        state->AS_Data.f_out_bw = 6750000UL;
1908        state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
1909        state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
1910        state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
1911        state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
1912        state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
1913        state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
1914        state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
1915        state->AS_Data.f_LO1 = 2181000000UL;
1916        state->AS_Data.f_LO2 = 1486249786UL;
1917        state->f_IF1_actual = state->AS_Data.f_if1_Center;
1918        state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
1919        state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
1920        state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
1921        state->num_regs = MT2063_REG_END_REGS;
1922        state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
1923        state->ctfilt_sw = 0;
1924
1925        state->CTFiltMax[0] = 69230000;
1926        state->CTFiltMax[1] = 105770000;
1927        state->CTFiltMax[2] = 140350000;
1928        state->CTFiltMax[3] = 177110000;
1929        state->CTFiltMax[4] = 212860000;
1930        state->CTFiltMax[5] = 241130000;
1931        state->CTFiltMax[6] = 274370000;
1932        state->CTFiltMax[7] = 309820000;
1933        state->CTFiltMax[8] = 342450000;
1934        state->CTFiltMax[9] = 378870000;
1935        state->CTFiltMax[10] = 416210000;
1936        state->CTFiltMax[11] = 456500000;
1937        state->CTFiltMax[12] = 495790000;
1938        state->CTFiltMax[13] = 534530000;
1939        state->CTFiltMax[14] = 572610000;
1940        state->CTFiltMax[15] = 598970000;
1941        state->CTFiltMax[16] = 635910000;
1942        state->CTFiltMax[17] = 672130000;
1943        state->CTFiltMax[18] = 714840000;
1944        state->CTFiltMax[19] = 739660000;
1945        state->CTFiltMax[20] = 770410000;
1946        state->CTFiltMax[21] = 814660000;
1947        state->CTFiltMax[22] = 846950000;
1948        state->CTFiltMax[23] = 867820000;
1949        state->CTFiltMax[24] = 915980000;
1950        state->CTFiltMax[25] = 947450000;
1951        state->CTFiltMax[26] = 983110000;
1952        state->CTFiltMax[27] = 1021630000;
1953        state->CTFiltMax[28] = 1061870000;
1954        state->CTFiltMax[29] = 1098330000;
1955        state->CTFiltMax[30] = 1138990000;
1956
1957        /*
1958         **   Fetch the FCU osc value and use it and the fRef value to
1959         **   scale all of the Band Max values
1960         */
1961
1962        state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
1963        status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1964                              &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1965        if (status < 0)
1966                return status;
1967
1968        /*  Read the ClearTune filter calibration value  */
1969        status = mt2063_read(state, MT2063_REG_FIFFC,
1970                             &state->reg[MT2063_REG_FIFFC], 1);
1971        if (status < 0)
1972                return status;
1973
1974        fcu_osc = state->reg[MT2063_REG_FIFFC];
1975
1976        state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
1977        status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1978                              &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1979        if (status < 0)
1980                return status;
1981
1982        /*  Adjust each of the values in the ClearTune filter cross-over table  */
1983        for (i = 0; i < 31; i++)
1984                state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
1985
1986        status = MT2063_SoftwareShutdown(state, 1);
1987        if (status < 0)
1988                return status;
1989        status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
1990        if (status < 0)
1991                return status;
1992
1993        state->init = true;
1994
1995        return 0;
1996}
1997
1998static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
1999{
2000        struct mt2063_state *state = fe->tuner_priv;
2001        int status;
2002
2003        dprintk(2, "\n");
2004
2005        if (!state->init)
2006                return -ENODEV;
2007
2008        *tuner_status = 0;
2009        status = mt2063_lockStatus(state);
2010        if (status < 0)
2011                return status;
2012        if (status)
2013                *tuner_status = TUNER_STATUS_LOCKED;
2014
2015        dprintk(1, "Tuner status: %d", *tuner_status);
2016
2017        return 0;
2018}
2019
2020static void mt2063_release(struct dvb_frontend *fe)
2021{
2022        struct mt2063_state *state = fe->tuner_priv;
2023
2024        dprintk(2, "\n");
2025
2026        fe->tuner_priv = NULL;
2027        kfree(state);
2028}
2029
2030static int mt2063_set_analog_params(struct dvb_frontend *fe,
2031                                    struct analog_parameters *params)
2032{
2033        struct mt2063_state *state = fe->tuner_priv;
2034        s32 pict_car;
2035        s32 pict2chanb_vsb;
2036        s32 ch_bw;
2037        s32 if_mid;
2038        s32 rcvr_mode;
2039        int status;
2040
2041        dprintk(2, "\n");
2042
2043        if (!state->init) {
2044                status = mt2063_init(fe);
2045                if (status < 0)
2046                        return status;
2047        }
2048
2049        switch (params->mode) {
2050        case V4L2_TUNER_RADIO:
2051                pict_car = 38900000;
2052                ch_bw = 8000000;
2053                pict2chanb_vsb = -(ch_bw / 2);
2054                rcvr_mode = MT2063_OFFAIR_ANALOG;
2055                break;
2056        case V4L2_TUNER_ANALOG_TV:
2057                rcvr_mode = MT2063_CABLE_ANALOG;
2058                if (params->std & ~V4L2_STD_MN) {
2059                        pict_car = 38900000;
2060                        ch_bw = 6000000;
2061                        pict2chanb_vsb = -1250000;
2062                } else if (params->std & V4L2_STD_PAL_G) {
2063                        pict_car = 38900000;
2064                        ch_bw = 7000000;
2065                        pict2chanb_vsb = -1250000;
2066                } else {                /* PAL/SECAM standards */
2067                        pict_car = 38900000;
2068                        ch_bw = 8000000;
2069                        pict2chanb_vsb = -1250000;
2070                }
2071                break;
2072        default:
2073                return -EINVAL;
2074        }
2075        if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2076
2077        state->AS_Data.f_LO2_Step = 125000;     /* FIXME: probably 5000 for FM */
2078        state->AS_Data.f_out = if_mid;
2079        state->AS_Data.f_out_bw = ch_bw + 750000;
2080        status = MT2063_SetReceiverMode(state, rcvr_mode);
2081        if (status < 0)
2082                return status;
2083
2084        dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2085                params->frequency, ch_bw, pict2chanb_vsb);
2086
2087        status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2088        if (status < 0)
2089                return status;
2090
2091        state->frequency = params->frequency;
2092        return 0;
2093}
2094
2095/*
2096 * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
2097 * So, the amount of the needed bandwidth is given by:
2098 *      Bw = Symbol_rate * (1 + 0.15)
2099 * As such, the maximum symbol rate supported by 6 MHz is given by:
2100 *      max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
2101 */
2102#define MAX_SYMBOL_RATE_6MHz    5217391
2103
2104static int mt2063_set_params(struct dvb_frontend *fe)
2105{
2106        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2107        struct mt2063_state *state = fe->tuner_priv;
2108        int status;
2109        s32 pict_car;
2110        s32 pict2chanb_vsb;
2111        s32 ch_bw;
2112        s32 if_mid;
2113        s32 rcvr_mode;
2114
2115        if (!state->init) {
2116                status = mt2063_init(fe);
2117                if (status < 0)
2118                        return status;
2119        }
2120
2121        dprintk(2, "\n");
2122
2123        if (c->bandwidth_hz == 0)
2124                return -EINVAL;
2125        if (c->bandwidth_hz <= 6000000)
2126                ch_bw = 6000000;
2127        else if (c->bandwidth_hz <= 7000000)
2128                ch_bw = 7000000;
2129        else
2130                ch_bw = 8000000;
2131
2132        switch (c->delivery_system) {
2133        case SYS_DVBT:
2134                rcvr_mode = MT2063_OFFAIR_COFDM;
2135                pict_car = 36125000;
2136                pict2chanb_vsb = -(ch_bw / 2);
2137                break;
2138        case SYS_DVBC_ANNEX_A:
2139        case SYS_DVBC_ANNEX_C:
2140                rcvr_mode = MT2063_CABLE_QAM;
2141                pict_car = 36125000;
2142                pict2chanb_vsb = -(ch_bw / 2);
2143                break;
2144        default:
2145                return -EINVAL;
2146        }
2147        if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2148
2149        state->AS_Data.f_LO2_Step = 125000;     /* FIXME: probably 5000 for FM */
2150        state->AS_Data.f_out = if_mid;
2151        state->AS_Data.f_out_bw = ch_bw + 750000;
2152        status = MT2063_SetReceiverMode(state, rcvr_mode);
2153        if (status < 0)
2154                return status;
2155
2156        dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2157                c->frequency, ch_bw, pict2chanb_vsb);
2158
2159        status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2160
2161        if (status < 0)
2162                return status;
2163
2164        state->frequency = c->frequency;
2165        return 0;
2166}
2167
2168static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
2169{
2170        struct mt2063_state *state = fe->tuner_priv;
2171
2172        dprintk(2, "\n");
2173
2174        if (!state->init)
2175                return -ENODEV;
2176
2177        *freq = state->AS_Data.f_out;
2178
2179        dprintk(1, "IF frequency: %d\n", *freq);
2180
2181        return 0;
2182}
2183
2184static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
2185{
2186        struct mt2063_state *state = fe->tuner_priv;
2187
2188        dprintk(2, "\n");
2189
2190        if (!state->init)
2191                return -ENODEV;
2192
2193        *bw = state->AS_Data.f_out_bw - 750000;
2194
2195        dprintk(1, "bandwidth: %d\n", *bw);
2196
2197        return 0;
2198}
2199
2200static const struct dvb_tuner_ops mt2063_ops = {
2201        .info = {
2202                 .name = "MT2063 Silicon Tuner",
2203                 .frequency_min = 45000000,
2204                 .frequency_max = 865000000,
2205                 .frequency_step = 0,
2206                 },
2207
2208        .init = mt2063_init,
2209        .sleep = MT2063_Sleep,
2210        .get_status = mt2063_get_status,
2211        .set_analog_params = mt2063_set_analog_params,
2212        .set_params    = mt2063_set_params,
2213        .get_if_frequency = mt2063_get_if_frequency,
2214        .get_bandwidth = mt2063_get_bandwidth,
2215        .release = mt2063_release,
2216};
2217
2218struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
2219                                   struct mt2063_config *config,
2220                                   struct i2c_adapter *i2c)
2221{
2222        struct mt2063_state *state = NULL;
2223
2224        dprintk(2, "\n");
2225
2226        state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
2227        if (!state)
2228                return NULL;
2229
2230        state->config = config;
2231        state->i2c = i2c;
2232        state->frontend = fe;
2233        state->reference = config->refclock / 1000;     /* kHz */
2234        fe->tuner_priv = state;
2235        fe->ops.tuner_ops = mt2063_ops;
2236
2237        printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
2238        return fe;
2239}
2240EXPORT_SYMBOL_GPL(mt2063_attach);
2241
2242#if 0
2243/*
2244 * Ancillary routines visible outside mt2063
2245 * FIXME: Remove them in favor of using standard tuner callbacks
2246 */
2247static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
2248{
2249        struct mt2063_state *state = fe->tuner_priv;
2250        int err = 0;
2251
2252        dprintk(2, "\n");
2253
2254        err = MT2063_SoftwareShutdown(state, 1);
2255        if (err < 0)
2256                printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
2257
2258        return err;
2259}
2260
2261static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
2262{
2263        struct mt2063_state *state = fe->tuner_priv;
2264        int err = 0;
2265
2266        dprintk(2, "\n");
2267
2268        err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2269        if (err < 0)
2270                printk(KERN_ERR "%s: Invalid parameter\n", __func__);
2271
2272        return err;
2273}
2274#endif
2275
2276MODULE_AUTHOR("Mauro Carvalho Chehab");
2277MODULE_DESCRIPTION("MT2063 Silicon tuner");
2278MODULE_LICENSE("GPL");
2279