linux/drivers/media/dvb-frontends/tda18271c2dd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * tda18271c2dd: Driver for the TDA18271C2 tuner
   4 *
   5 * Copyright (C) 2010 Digital Devices GmbH
   6 */
   7
   8#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <linux/init.h>
  11#include <linux/delay.h>
  12#include <linux/firmware.h>
  13#include <linux/i2c.h>
  14#include <asm/div64.h>
  15
  16#include <media/dvb_frontend.h>
  17#include "tda18271c2dd.h"
  18
  19/* Max transfer size done by I2C transfer functions */
  20#define MAX_XFER_SIZE  64
  21
  22struct SStandardParam {
  23        s32   m_IFFrequency;
  24        u32   m_BandWidth;
  25        u8    m_EP3_4_0;
  26        u8    m_EB22;
  27};
  28
  29struct SMap {
  30        u32   m_Frequency;
  31        u8    m_Param;
  32};
  33
  34struct SMapI {
  35        u32   m_Frequency;
  36        s32    m_Param;
  37};
  38
  39struct SMap2 {
  40        u32   m_Frequency;
  41        u8    m_Param1;
  42        u8    m_Param2;
  43};
  44
  45struct SRFBandMap {
  46        u32   m_RF_max;
  47        u32   m_RF1_Default;
  48        u32   m_RF2_Default;
  49        u32   m_RF3_Default;
  50};
  51
  52enum ERegister {
  53        ID = 0,
  54        TM,
  55        PL,
  56        EP1, EP2, EP3, EP4, EP5,
  57        CPD, CD1, CD2, CD3,
  58        MPD, MD1, MD2, MD3,
  59        EB1, EB2, EB3, EB4, EB5, EB6, EB7, EB8, EB9, EB10,
  60        EB11, EB12, EB13, EB14, EB15, EB16, EB17, EB18, EB19, EB20,
  61        EB21, EB22, EB23,
  62        NUM_REGS
  63};
  64
  65struct tda_state {
  66        struct i2c_adapter *i2c;
  67        u8 adr;
  68
  69        u32   m_Frequency;
  70        u32   IF;
  71
  72        u8    m_IFLevelAnalog;
  73        u8    m_IFLevelDigital;
  74        u8    m_IFLevelDVBC;
  75        u8    m_IFLevelDVBT;
  76
  77        u8    m_EP4;
  78        u8    m_EP3_Standby;
  79
  80        bool  m_bMaster;
  81
  82        s32   m_SettlingTime;
  83
  84        u8    m_Regs[NUM_REGS];
  85
  86        /* Tracking filter settings for band 0..6 */
  87        u32   m_RF1[7];
  88        s32   m_RF_A1[7];
  89        s32   m_RF_B1[7];
  90        u32   m_RF2[7];
  91        s32   m_RF_A2[7];
  92        s32   m_RF_B2[7];
  93        u32   m_RF3[7];
  94
  95        u8    m_TMValue_RFCal;    /* Calibration temperature */
  96
  97        bool  m_bFMInput;         /* true to use Pin 8 for FM Radio */
  98
  99};
 100
 101static int PowerScan(struct tda_state *state,
 102                     u8 RFBand, u32 RF_in,
 103                     u32 *pRF_Out, bool *pbcal);
 104
 105static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len)
 106{
 107        struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
 108                                   .buf  = data, .len   = len} };
 109        return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
 110}
 111
 112static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
 113{
 114        struct i2c_msg msg = {.addr = adr, .flags = 0,
 115                              .buf = data, .len = len};
 116
 117        if (i2c_transfer(adap, &msg, 1) != 1) {
 118                printk(KERN_ERR "tda18271c2dd: i2c write error at addr %i\n", adr);
 119                return -1;
 120        }
 121        return 0;
 122}
 123
 124static int WriteRegs(struct tda_state *state,
 125                     u8 SubAddr, u8 *Regs, u16 nRegs)
 126{
 127        u8 data[MAX_XFER_SIZE];
 128
 129        if (1 + nRegs > sizeof(data)) {
 130                printk(KERN_WARNING
 131                       "%s: i2c wr: len=%d is too big!\n",
 132                       KBUILD_MODNAME, nRegs);
 133                return -EINVAL;
 134        }
 135
 136        data[0] = SubAddr;
 137        memcpy(data + 1, Regs, nRegs);
 138        return i2c_write(state->i2c, state->adr, data, nRegs + 1);
 139}
 140
 141static int WriteReg(struct tda_state *state, u8 SubAddr, u8 Reg)
 142{
 143        u8 msg[2] = {SubAddr, Reg};
 144
 145        return i2c_write(state->i2c, state->adr, msg, 2);
 146}
 147
 148static int Read(struct tda_state *state, u8 * Regs)
 149{
 150        return i2c_readn(state->i2c, state->adr, Regs, 16);
 151}
 152
 153static int ReadExtented(struct tda_state *state, u8 * Regs)
 154{
 155        return i2c_readn(state->i2c, state->adr, Regs, NUM_REGS);
 156}
 157
 158static int UpdateRegs(struct tda_state *state, u8 RegFrom, u8 RegTo)
 159{
 160        return WriteRegs(state, RegFrom,
 161                         &state->m_Regs[RegFrom], RegTo-RegFrom+1);
 162}
 163static int UpdateReg(struct tda_state *state, u8 Reg)
 164{
 165        return WriteReg(state, Reg, state->m_Regs[Reg]);
 166}
 167
 168#include "tda18271c2dd_maps.h"
 169
 170static void reset(struct tda_state *state)
 171{
 172        u32   ulIFLevelAnalog = 0;
 173        u32   ulIFLevelDigital = 2;
 174        u32   ulIFLevelDVBC = 7;
 175        u32   ulIFLevelDVBT = 6;
 176        u32   ulXTOut = 0;
 177        u32   ulStandbyMode = 0x06;    /* Send in stdb, but leave osc on */
 178        u32   ulSlave = 0;
 179        u32   ulFMInput = 0;
 180        u32   ulSettlingTime = 100;
 181
 182        state->m_Frequency         = 0;
 183        state->m_SettlingTime = 100;
 184        state->m_IFLevelAnalog = (ulIFLevelAnalog & 0x07) << 2;
 185        state->m_IFLevelDigital = (ulIFLevelDigital & 0x07) << 2;
 186        state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07) << 2;
 187        state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07) << 2;
 188
 189        state->m_EP4 = 0x20;
 190        if (ulXTOut != 0)
 191                state->m_EP4 |= 0x40;
 192
 193        state->m_EP3_Standby = ((ulStandbyMode & 0x07) << 5) | 0x0F;
 194        state->m_bMaster = (ulSlave == 0);
 195
 196        state->m_SettlingTime = ulSettlingTime;
 197
 198        state->m_bFMInput = (ulFMInput == 2);
 199}
 200
 201static bool SearchMap1(const struct SMap map[], u32 frequency, u8 *param)
 202{
 203        int i = 0;
 204
 205        while ((map[i].m_Frequency != 0) && (frequency > map[i].m_Frequency))
 206                i += 1;
 207        if (map[i].m_Frequency == 0)
 208                return false;
 209        *param = map[i].m_Param;
 210        return true;
 211}
 212
 213static bool SearchMap2(const struct SMapI map[], u32 frequency, s32 *param)
 214{
 215        int i = 0;
 216
 217        while ((map[i].m_Frequency != 0) &&
 218               (frequency > map[i].m_Frequency))
 219                i += 1;
 220        if (map[i].m_Frequency == 0)
 221                return false;
 222        *param = map[i].m_Param;
 223        return true;
 224}
 225
 226static bool SearchMap3(const struct SMap2 map[], u32 frequency, u8 *param1,
 227                       u8 *param2)
 228{
 229        int i = 0;
 230
 231        while ((map[i].m_Frequency != 0) &&
 232               (frequency > map[i].m_Frequency))
 233                i += 1;
 234        if (map[i].m_Frequency == 0)
 235                return false;
 236        *param1 = map[i].m_Param1;
 237        *param2 = map[i].m_Param2;
 238        return true;
 239}
 240
 241static bool SearchMap4(const struct SRFBandMap map[], u32 frequency, u8 *rfband)
 242{
 243        int i = 0;
 244
 245        while (i < 7 && (frequency > map[i].m_RF_max))
 246                i += 1;
 247        if (i == 7)
 248                return false;
 249        *rfband = i;
 250        return true;
 251}
 252
 253static int ThermometerRead(struct tda_state *state, u8 *pTM_Value)
 254{
 255        int status = 0;
 256
 257        do {
 258                u8 Regs[16];
 259                state->m_Regs[TM] |= 0x10;
 260                status = UpdateReg(state, TM);
 261                if (status < 0)
 262                        break;
 263                status = Read(state, Regs);
 264                if (status < 0)
 265                        break;
 266                if (((Regs[TM] & 0x0F) == 0 && (Regs[TM] & 0x20) == 0x20) ||
 267                    ((Regs[TM] & 0x0F) == 8 && (Regs[TM] & 0x20) == 0x00)) {
 268                        state->m_Regs[TM] ^= 0x20;
 269                        status = UpdateReg(state, TM);
 270                        if (status < 0)
 271                                break;
 272                        msleep(10);
 273                        status = Read(state, Regs);
 274                        if (status < 0)
 275                                break;
 276                }
 277                *pTM_Value = (Regs[TM] & 0x20)
 278                                ? m_Thermometer_Map_2[Regs[TM] & 0x0F]
 279                                : m_Thermometer_Map_1[Regs[TM] & 0x0F] ;
 280                state->m_Regs[TM] &= ~0x10;        /* Thermometer off */
 281                status = UpdateReg(state, TM);
 282                if (status < 0)
 283                        break;
 284                state->m_Regs[EP4] &= ~0x03;       /* CAL_mode = 0 ????????? */
 285                status = UpdateReg(state, EP4);
 286                if (status < 0)
 287                        break;
 288        } while (0);
 289
 290        return status;
 291}
 292
 293static int StandBy(struct tda_state *state)
 294{
 295        int status = 0;
 296        do {
 297                state->m_Regs[EB12] &= ~0x20;  /* PD_AGC1_Det = 0 */
 298                status = UpdateReg(state, EB12);
 299                if (status < 0)
 300                        break;
 301                state->m_Regs[EB18] &= ~0x83;  /* AGC1_loop_off = 0, AGC1_Gain = 6 dB */
 302                status = UpdateReg(state, EB18);
 303                if (status < 0)
 304                        break;
 305                state->m_Regs[EB21] |= 0x03; /* AGC2_Gain = -6 dB */
 306                state->m_Regs[EP3] = state->m_EP3_Standby;
 307                status = UpdateReg(state, EP3);
 308                if (status < 0)
 309                        break;
 310                state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LP_Fc[2] = 0 */
 311                status = UpdateRegs(state, EB21, EB23);
 312                if (status < 0)
 313                        break;
 314        } while (0);
 315        return status;
 316}
 317
 318static int CalcMainPLL(struct tda_state *state, u32 freq)
 319{
 320
 321        u8  PostDiv;
 322        u8  Div;
 323        u64 OscFreq;
 324        u32 MainDiv;
 325
 326        if (!SearchMap3(m_Main_PLL_Map, freq, &PostDiv, &Div))
 327                return -EINVAL;
 328
 329        OscFreq = (u64) freq * (u64) Div;
 330        OscFreq *= (u64) 16384;
 331        do_div(OscFreq, (u64)16000000);
 332        MainDiv = OscFreq;
 333
 334        state->m_Regs[MPD] = PostDiv & 0x77;
 335        state->m_Regs[MD1] = ((MainDiv >> 16) & 0x7F);
 336        state->m_Regs[MD2] = ((MainDiv >>  8) & 0xFF);
 337        state->m_Regs[MD3] = (MainDiv & 0xFF);
 338
 339        return UpdateRegs(state, MPD, MD3);
 340}
 341
 342static int CalcCalPLL(struct tda_state *state, u32 freq)
 343{
 344        u8 PostDiv;
 345        u8 Div;
 346        u64 OscFreq;
 347        u32 CalDiv;
 348
 349        if (!SearchMap3(m_Cal_PLL_Map, freq, &PostDiv, &Div))
 350                return -EINVAL;
 351
 352        OscFreq = (u64)freq * (u64)Div;
 353        /* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
 354        OscFreq *= (u64)16384;
 355        do_div(OscFreq, (u64)16000000);
 356        CalDiv = OscFreq;
 357
 358        state->m_Regs[CPD] = PostDiv;
 359        state->m_Regs[CD1] = ((CalDiv >> 16) & 0xFF);
 360        state->m_Regs[CD2] = ((CalDiv >>  8) & 0xFF);
 361        state->m_Regs[CD3] = (CalDiv & 0xFF);
 362
 363        return UpdateRegs(state, CPD, CD3);
 364}
 365
 366static int CalibrateRF(struct tda_state *state,
 367                       u8 RFBand, u32 freq, s32 *pCprog)
 368{
 369        int status = 0;
 370        u8 Regs[NUM_REGS];
 371        do {
 372                u8 BP_Filter = 0;
 373                u8 GainTaper = 0;
 374                u8 RFC_K = 0;
 375                u8 RFC_M = 0;
 376
 377                state->m_Regs[EP4] &= ~0x03; /* CAL_mode = 0 */
 378                status = UpdateReg(state, EP4);
 379                if (status < 0)
 380                        break;
 381                state->m_Regs[EB18] |= 0x03;  /* AGC1_Gain = 3 */
 382                status = UpdateReg(state, EB18);
 383                if (status < 0)
 384                        break;
 385
 386                /* Switching off LT (as datasheet says) causes calibration on C1 to fail */
 387                /* (Readout of Cprog is always 255) */
 388                if (state->m_Regs[ID] != 0x83)    /* C1: ID == 83, C2: ID == 84 */
 389                        state->m_Regs[EP3] |= 0x40; /* SM_LT = 1 */
 390
 391                if (!(SearchMap1(m_BP_Filter_Map, freq, &BP_Filter) &&
 392                        SearchMap1(m_GainTaper_Map, freq, &GainTaper) &&
 393                        SearchMap3(m_KM_Map, freq, &RFC_K, &RFC_M)))
 394                        return -EINVAL;
 395
 396                state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | BP_Filter;
 397                state->m_Regs[EP2] = (RFBand << 5) | GainTaper;
 398
 399                state->m_Regs[EB13] = (state->m_Regs[EB13] & ~0x7C) | (RFC_K << 4) | (RFC_M << 2);
 400
 401                status = UpdateRegs(state, EP1, EP3);
 402                if (status < 0)
 403                        break;
 404                status = UpdateReg(state, EB13);
 405                if (status < 0)
 406                        break;
 407
 408                state->m_Regs[EB4] |= 0x20;    /* LO_ForceSrce = 1 */
 409                status = UpdateReg(state, EB4);
 410                if (status < 0)
 411                        break;
 412
 413                state->m_Regs[EB7] |= 0x20;    /* CAL_ForceSrce = 1 */
 414                status = UpdateReg(state, EB7);
 415                if (status < 0)
 416                        break;
 417
 418                state->m_Regs[EB14] = 0; /* RFC_Cprog = 0 */
 419                status = UpdateReg(state, EB14);
 420                if (status < 0)
 421                        break;
 422
 423                state->m_Regs[EB20] &= ~0x20;  /* ForceLock = 0; */
 424                status = UpdateReg(state, EB20);
 425                if (status < 0)
 426                        break;
 427
 428                state->m_Regs[EP4] |= 0x03;  /* CAL_Mode = 3 */
 429                status = UpdateRegs(state, EP4, EP5);
 430                if (status < 0)
 431                        break;
 432
 433                status = CalcCalPLL(state, freq);
 434                if (status < 0)
 435                        break;
 436                status = CalcMainPLL(state, freq + 1000000);
 437                if (status < 0)
 438                        break;
 439
 440                msleep(5);
 441                status = UpdateReg(state, EP2);
 442                if (status < 0)
 443                        break;
 444                status = UpdateReg(state, EP1);
 445                if (status < 0)
 446                        break;
 447                status = UpdateReg(state, EP2);
 448                if (status < 0)
 449                        break;
 450                status = UpdateReg(state, EP1);
 451                if (status < 0)
 452                        break;
 453
 454                state->m_Regs[EB4] &= ~0x20;    /* LO_ForceSrce = 0 */
 455                status = UpdateReg(state, EB4);
 456                if (status < 0)
 457                        break;
 458
 459                state->m_Regs[EB7] &= ~0x20;    /* CAL_ForceSrce = 0 */
 460                status = UpdateReg(state, EB7);
 461                if (status < 0)
 462                        break;
 463                msleep(10);
 464
 465                state->m_Regs[EB20] |= 0x20;  /* ForceLock = 1; */
 466                status = UpdateReg(state, EB20);
 467                if (status < 0)
 468                        break;
 469                msleep(60);
 470
 471                state->m_Regs[EP4] &= ~0x03;  /* CAL_Mode = 0 */
 472                state->m_Regs[EP3] &= ~0x40; /* SM_LT = 0 */
 473                state->m_Regs[EB18] &= ~0x03;  /* AGC1_Gain = 0 */
 474                status = UpdateReg(state, EB18);
 475                if (status < 0)
 476                        break;
 477                status = UpdateRegs(state, EP3, EP4);
 478                if (status < 0)
 479                        break;
 480                status = UpdateReg(state, EP1);
 481                if (status < 0)
 482                        break;
 483
 484                status = ReadExtented(state, Regs);
 485                if (status < 0)
 486                        break;
 487
 488                *pCprog = Regs[EB14];
 489
 490        } while (0);
 491        return status;
 492}
 493
 494static int RFTrackingFiltersInit(struct tda_state *state,
 495                                 u8 RFBand)
 496{
 497        int status = 0;
 498
 499        u32   RF1 = m_RF_Band_Map[RFBand].m_RF1_Default;
 500        u32   RF2 = m_RF_Band_Map[RFBand].m_RF2_Default;
 501        u32   RF3 = m_RF_Band_Map[RFBand].m_RF3_Default;
 502        bool    bcal = false;
 503
 504        s32    Cprog_cal1 = 0;
 505        s32    Cprog_table1 = 0;
 506        s32    Cprog_cal2 = 0;
 507        s32    Cprog_table2 = 0;
 508        s32    Cprog_cal3 = 0;
 509        s32    Cprog_table3 = 0;
 510
 511        state->m_RF_A1[RFBand] = 0;
 512        state->m_RF_B1[RFBand] = 0;
 513        state->m_RF_A2[RFBand] = 0;
 514        state->m_RF_B2[RFBand] = 0;
 515
 516        do {
 517                status = PowerScan(state, RFBand, RF1, &RF1, &bcal);
 518                if (status < 0)
 519                        break;
 520                if (bcal) {
 521                        status = CalibrateRF(state, RFBand, RF1, &Cprog_cal1);
 522                        if (status < 0)
 523                                break;
 524                }
 525                SearchMap2(m_RF_Cal_Map, RF1, &Cprog_table1);
 526                if (!bcal)
 527                        Cprog_cal1 = Cprog_table1;
 528                state->m_RF_B1[RFBand] = Cprog_cal1 - Cprog_table1;
 529                /* state->m_RF_A1[RF_Band] = ???? */
 530
 531                if (RF2 == 0)
 532                        break;
 533
 534                status = PowerScan(state, RFBand, RF2, &RF2, &bcal);
 535                if (status < 0)
 536                        break;
 537                if (bcal) {
 538                        status = CalibrateRF(state, RFBand, RF2, &Cprog_cal2);
 539                        if (status < 0)
 540                                break;
 541                }
 542                SearchMap2(m_RF_Cal_Map, RF2, &Cprog_table2);
 543                if (!bcal)
 544                        Cprog_cal2 = Cprog_table2;
 545
 546                state->m_RF_A1[RFBand] =
 547                        (Cprog_cal2 - Cprog_table2 - Cprog_cal1 + Cprog_table1) /
 548                        ((s32)(RF2) - (s32)(RF1));
 549
 550                if (RF3 == 0)
 551                        break;
 552
 553                status = PowerScan(state, RFBand, RF3, &RF3, &bcal);
 554                if (status < 0)
 555                        break;
 556                if (bcal) {
 557                        status = CalibrateRF(state, RFBand, RF3, &Cprog_cal3);
 558                        if (status < 0)
 559                                break;
 560                }
 561                SearchMap2(m_RF_Cal_Map, RF3, &Cprog_table3);
 562                if (!bcal)
 563                        Cprog_cal3 = Cprog_table3;
 564                state->m_RF_A2[RFBand] = (Cprog_cal3 - Cprog_table3 - Cprog_cal2 + Cprog_table2) / ((s32)(RF3) - (s32)(RF2));
 565                state->m_RF_B2[RFBand] = Cprog_cal2 - Cprog_table2;
 566
 567        } while (0);
 568
 569        state->m_RF1[RFBand] = RF1;
 570        state->m_RF2[RFBand] = RF2;
 571        state->m_RF3[RFBand] = RF3;
 572
 573#if 0
 574        printk(KERN_ERR "tda18271c2dd: %s %d RF1 = %d A1 = %d B1 = %d RF2 = %d A2 = %d B2 = %d RF3 = %d\n", __func__,
 575               RFBand, RF1, state->m_RF_A1[RFBand], state->m_RF_B1[RFBand], RF2,
 576               state->m_RF_A2[RFBand], state->m_RF_B2[RFBand], RF3);
 577#endif
 578
 579        return status;
 580}
 581
 582static int PowerScan(struct tda_state *state,
 583                     u8 RFBand, u32 RF_in, u32 *pRF_Out, bool *pbcal)
 584{
 585        int status = 0;
 586        do {
 587                u8   Gain_Taper = 0;
 588                s32  RFC_Cprog = 0;
 589                u8   CID_Target = 0;
 590                u8   CountLimit = 0;
 591                u32  freq_MainPLL;
 592                u8   Regs[NUM_REGS];
 593                u8   CID_Gain;
 594                s32  Count = 0;
 595                int  sign  = 1;
 596                bool wait = false;
 597
 598                if (!(SearchMap2(m_RF_Cal_Map, RF_in, &RFC_Cprog) &&
 599                      SearchMap1(m_GainTaper_Map, RF_in, &Gain_Taper) &&
 600                      SearchMap3(m_CID_Target_Map, RF_in, &CID_Target, &CountLimit))) {
 601
 602                        printk(KERN_ERR "tda18271c2dd: %s Search map failed\n", __func__);
 603                        return -EINVAL;
 604                }
 605
 606                state->m_Regs[EP2] = (RFBand << 5) | Gain_Taper;
 607                state->m_Regs[EB14] = (RFC_Cprog);
 608                status = UpdateReg(state, EP2);
 609                if (status < 0)
 610                        break;
 611                status = UpdateReg(state, EB14);
 612                if (status < 0)
 613                        break;
 614
 615                freq_MainPLL = RF_in + 1000000;
 616                status = CalcMainPLL(state, freq_MainPLL);
 617                if (status < 0)
 618                        break;
 619                msleep(5);
 620                state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x03) | 1;    /* CAL_mode = 1 */
 621                status = UpdateReg(state, EP4);
 622                if (status < 0)
 623                        break;
 624                status = UpdateReg(state, EP2);  /* Launch power measurement */
 625                if (status < 0)
 626                        break;
 627                status = ReadExtented(state, Regs);
 628                if (status < 0)
 629                        break;
 630                CID_Gain = Regs[EB10] & 0x3F;
 631                state->m_Regs[ID] = Regs[ID];  /* Chip version, (needed for C1 workaround in CalibrateRF) */
 632
 633                *pRF_Out = RF_in;
 634
 635                while (CID_Gain < CID_Target) {
 636                        freq_MainPLL = RF_in + sign * Count + 1000000;
 637                        status = CalcMainPLL(state, freq_MainPLL);
 638                        if (status < 0)
 639                                break;
 640                        msleep(wait ? 5 : 1);
 641                        wait = false;
 642                        status = UpdateReg(state, EP2);  /* Launch power measurement */
 643                        if (status < 0)
 644                                break;
 645                        status = ReadExtented(state, Regs);
 646                        if (status < 0)
 647                                break;
 648                        CID_Gain = Regs[EB10] & 0x3F;
 649                        Count += 200000;
 650
 651                        if (Count < CountLimit * 100000)
 652                                continue;
 653                        if (sign < 0)
 654                                break;
 655
 656                        sign = -sign;
 657                        Count = 200000;
 658                        wait = true;
 659                }
 660                if (status < 0)
 661                        break;
 662                if (CID_Gain >= CID_Target) {
 663                        *pbcal = true;
 664                        *pRF_Out = freq_MainPLL - 1000000;
 665                } else
 666                        *pbcal = false;
 667        } while (0);
 668
 669        return status;
 670}
 671
 672static int PowerScanInit(struct tda_state *state)
 673{
 674        int status = 0;
 675        do {
 676                state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | 0x12;
 677                state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x1F); /* If level = 0, Cal mode = 0 */
 678                status = UpdateRegs(state, EP3, EP4);
 679                if (status < 0)
 680                        break;
 681                state->m_Regs[EB18] = (state->m_Regs[EB18] & ~0x03); /* AGC 1 Gain = 0 */
 682                status = UpdateReg(state, EB18);
 683                if (status < 0)
 684                        break;
 685                state->m_Regs[EB21] = (state->m_Regs[EB21] & ~0x03); /* AGC 2 Gain = 0 (Datasheet = 3) */
 686                state->m_Regs[EB23] = (state->m_Regs[EB23] | 0x06); /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
 687                status = UpdateRegs(state, EB21, EB23);
 688                if (status < 0)
 689                        break;
 690        } while (0);
 691        return status;
 692}
 693
 694static int CalcRFFilterCurve(struct tda_state *state)
 695{
 696        int status = 0;
 697        do {
 698                msleep(200);      /* Temperature stabilisation */
 699                status = PowerScanInit(state);
 700                if (status < 0)
 701                        break;
 702                status = RFTrackingFiltersInit(state, 0);
 703                if (status < 0)
 704                        break;
 705                status = RFTrackingFiltersInit(state, 1);
 706                if (status < 0)
 707                        break;
 708                status = RFTrackingFiltersInit(state, 2);
 709                if (status < 0)
 710                        break;
 711                status = RFTrackingFiltersInit(state, 3);
 712                if (status < 0)
 713                        break;
 714                status = RFTrackingFiltersInit(state, 4);
 715                if (status < 0)
 716                        break;
 717                status = RFTrackingFiltersInit(state, 5);
 718                if (status < 0)
 719                        break;
 720                status = RFTrackingFiltersInit(state, 6);
 721                if (status < 0)
 722                        break;
 723                status = ThermometerRead(state, &state->m_TMValue_RFCal); /* also switches off Cal mode !!! */
 724                if (status < 0)
 725                        break;
 726        } while (0);
 727
 728        return status;
 729}
 730
 731static int FixedContentsI2CUpdate(struct tda_state *state)
 732{
 733        static u8 InitRegs[] = {
 734                0x08, 0x80, 0xC6,
 735                0xDF, 0x16, 0x60, 0x80,
 736                0x80, 0x00, 0x00, 0x00,
 737                0x00, 0x00, 0x00, 0x00,
 738                0xFC, 0x01, 0x84, 0x41,
 739                0x01, 0x84, 0x40, 0x07,
 740                0x00, 0x00, 0x96, 0x3F,
 741                0xC1, 0x00, 0x8F, 0x00,
 742                0x00, 0x8C, 0x00, 0x20,
 743                0xB3, 0x48, 0xB0,
 744        };
 745        int status = 0;
 746        memcpy(&state->m_Regs[TM], InitRegs, EB23 - TM + 1);
 747        do {
 748                status = UpdateRegs(state, TM, EB23);
 749                if (status < 0)
 750                        break;
 751
 752                /* AGC1 gain setup */
 753                state->m_Regs[EB17] = 0x00;
 754                status = UpdateReg(state, EB17);
 755                if (status < 0)
 756                        break;
 757                state->m_Regs[EB17] = 0x03;
 758                status = UpdateReg(state, EB17);
 759                if (status < 0)
 760                        break;
 761                state->m_Regs[EB17] = 0x43;
 762                status = UpdateReg(state, EB17);
 763                if (status < 0)
 764                        break;
 765                state->m_Regs[EB17] = 0x4C;
 766                status = UpdateReg(state, EB17);
 767                if (status < 0)
 768                        break;
 769
 770                /* IRC Cal Low band */
 771                state->m_Regs[EP3] = 0x1F;
 772                state->m_Regs[EP4] = 0x66;
 773                state->m_Regs[EP5] = 0x81;
 774                state->m_Regs[CPD] = 0xCC;
 775                state->m_Regs[CD1] = 0x6C;
 776                state->m_Regs[CD2] = 0x00;
 777                state->m_Regs[CD3] = 0x00;
 778                state->m_Regs[MPD] = 0xC5;
 779                state->m_Regs[MD1] = 0x77;
 780                state->m_Regs[MD2] = 0x08;
 781                state->m_Regs[MD3] = 0x00;
 782                status = UpdateRegs(state, EP2, MD3); /* diff between sw and datasheet (ep3-md3) */
 783                if (status < 0)
 784                        break;
 785
 786#if 0
 787                state->m_Regs[EB4] = 0x61;          /* missing in sw */
 788                status = UpdateReg(state, EB4);
 789                if (status < 0)
 790                        break;
 791                msleep(1);
 792                state->m_Regs[EB4] = 0x41;
 793                status = UpdateReg(state, EB4);
 794                if (status < 0)
 795                        break;
 796#endif
 797
 798                msleep(5);
 799                status = UpdateReg(state, EP1);
 800                if (status < 0)
 801                        break;
 802                msleep(5);
 803
 804                state->m_Regs[EP5] = 0x85;
 805                state->m_Regs[CPD] = 0xCB;
 806                state->m_Regs[CD1] = 0x66;
 807                state->m_Regs[CD2] = 0x70;
 808                status = UpdateRegs(state, EP3, CD3);
 809                if (status < 0)
 810                        break;
 811                msleep(5);
 812                status = UpdateReg(state, EP2);
 813                if (status < 0)
 814                        break;
 815                msleep(30);
 816
 817                /* IRC Cal mid band */
 818                state->m_Regs[EP5] = 0x82;
 819                state->m_Regs[CPD] = 0xA8;
 820                state->m_Regs[CD2] = 0x00;
 821                state->m_Regs[MPD] = 0xA1; /* Datasheet = 0xA9 */
 822                state->m_Regs[MD1] = 0x73;
 823                state->m_Regs[MD2] = 0x1A;
 824                status = UpdateRegs(state, EP3, MD3);
 825                if (status < 0)
 826                        break;
 827
 828                msleep(5);
 829                status = UpdateReg(state, EP1);
 830                if (status < 0)
 831                        break;
 832                msleep(5);
 833
 834                state->m_Regs[EP5] = 0x86;
 835                state->m_Regs[CPD] = 0xA8;
 836                state->m_Regs[CD1] = 0x66;
 837                state->m_Regs[CD2] = 0xA0;
 838                status = UpdateRegs(state, EP3, CD3);
 839                if (status < 0)
 840                        break;
 841                msleep(5);
 842                status = UpdateReg(state, EP2);
 843                if (status < 0)
 844                        break;
 845                msleep(30);
 846
 847                /* IRC Cal high band */
 848                state->m_Regs[EP5] = 0x83;
 849                state->m_Regs[CPD] = 0x98;
 850                state->m_Regs[CD1] = 0x65;
 851                state->m_Regs[CD2] = 0x00;
 852                state->m_Regs[MPD] = 0x91;  /* Datasheet = 0x91 */
 853                state->m_Regs[MD1] = 0x71;
 854                state->m_Regs[MD2] = 0xCD;
 855                status = UpdateRegs(state, EP3, MD3);
 856                if (status < 0)
 857                        break;
 858                msleep(5);
 859                status = UpdateReg(state, EP1);
 860                if (status < 0)
 861                        break;
 862                msleep(5);
 863                state->m_Regs[EP5] = 0x87;
 864                state->m_Regs[CD1] = 0x65;
 865                state->m_Regs[CD2] = 0x50;
 866                status = UpdateRegs(state, EP3, CD3);
 867                if (status < 0)
 868                        break;
 869                msleep(5);
 870                status = UpdateReg(state, EP2);
 871                if (status < 0)
 872                        break;
 873                msleep(30);
 874
 875                /* Back to normal */
 876                state->m_Regs[EP4] = 0x64;
 877                status = UpdateReg(state, EP4);
 878                if (status < 0)
 879                        break;
 880                status = UpdateReg(state, EP1);
 881                if (status < 0)
 882                        break;
 883
 884        } while (0);
 885        return status;
 886}
 887
 888static int InitCal(struct tda_state *state)
 889{
 890        int status = 0;
 891
 892        do {
 893                status = FixedContentsI2CUpdate(state);
 894                if (status < 0)
 895                        break;
 896                status = CalcRFFilterCurve(state);
 897                if (status < 0)
 898                        break;
 899                status = StandBy(state);
 900                if (status < 0)
 901                        break;
 902                /* m_bInitDone = true; */
 903        } while (0);
 904        return status;
 905};
 906
 907static int RFTrackingFiltersCorrection(struct tda_state *state,
 908                                       u32 Frequency)
 909{
 910        int status = 0;
 911        s32 Cprog_table;
 912        u8 RFBand;
 913        u8 dCoverdT;
 914
 915        if (!SearchMap2(m_RF_Cal_Map, Frequency, &Cprog_table) ||
 916            !SearchMap4(m_RF_Band_Map, Frequency, &RFBand) ||
 917            !SearchMap1(m_RF_Cal_DC_Over_DT_Map, Frequency, &dCoverdT))
 918
 919                return -EINVAL;
 920
 921        do {
 922                u8 TMValue_Current;
 923                u32   RF1 = state->m_RF1[RFBand];
 924                u32   RF2 = state->m_RF1[RFBand];
 925                u32   RF3 = state->m_RF1[RFBand];
 926                s32    RF_A1 = state->m_RF_A1[RFBand];
 927                s32    RF_B1 = state->m_RF_B1[RFBand];
 928                s32    RF_A2 = state->m_RF_A2[RFBand];
 929                s32    RF_B2 = state->m_RF_B2[RFBand];
 930                s32 Capprox = 0;
 931                int TComp;
 932
 933                state->m_Regs[EP3] &= ~0xE0;  /* Power up */
 934                status = UpdateReg(state, EP3);
 935                if (status < 0)
 936                        break;
 937
 938                status = ThermometerRead(state, &TMValue_Current);
 939                if (status < 0)
 940                        break;
 941
 942                if (RF3 == 0 || Frequency < RF2)
 943                        Capprox = RF_A1 * ((s32)(Frequency) - (s32)(RF1)) + RF_B1 + Cprog_table;
 944                else
 945                        Capprox = RF_A2 * ((s32)(Frequency) - (s32)(RF2)) + RF_B2 + Cprog_table;
 946
 947                TComp = (int)(dCoverdT) * ((int)(TMValue_Current) - (int)(state->m_TMValue_RFCal))/1000;
 948
 949                Capprox += TComp;
 950
 951                if (Capprox < 0)
 952                        Capprox = 0;
 953                else if (Capprox > 255)
 954                        Capprox = 255;
 955
 956
 957                /* TODO Temperature compensation. There is defenitely a scale factor */
 958                /*      missing in the datasheet, so leave it out for now.           */
 959                state->m_Regs[EB14] = Capprox;
 960
 961                status = UpdateReg(state, EB14);
 962                if (status < 0)
 963                        break;
 964
 965        } while (0);
 966        return status;
 967}
 968
 969static int ChannelConfiguration(struct tda_state *state,
 970                                u32 Frequency, int Standard)
 971{
 972
 973        s32 IntermediateFrequency = m_StandardTable[Standard].m_IFFrequency;
 974        int status = 0;
 975
 976        u8 BP_Filter = 0;
 977        u8 RF_Band = 0;
 978        u8 GainTaper = 0;
 979        u8 IR_Meas = 0;
 980
 981        state->IF = IntermediateFrequency;
 982        /* printk("tda18271c2dd: %s Freq = %d Standard = %d IF = %d\n", __func__, Frequency, Standard, IntermediateFrequency); */
 983        /* get values from tables */
 984
 985        if (!(SearchMap1(m_BP_Filter_Map, Frequency, &BP_Filter) &&
 986               SearchMap1(m_GainTaper_Map, Frequency, &GainTaper) &&
 987               SearchMap1(m_IR_Meas_Map, Frequency, &IR_Meas) &&
 988               SearchMap4(m_RF_Band_Map, Frequency, &RF_Band))) {
 989
 990                printk(KERN_ERR "tda18271c2dd: %s SearchMap failed\n", __func__);
 991                return -EINVAL;
 992        }
 993
 994        do {
 995                state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | m_StandardTable[Standard].m_EP3_4_0;
 996                state->m_Regs[EP3] &= ~0x04;   /* switch RFAGC to high speed mode */
 997
 998                /* m_EP4 default for XToutOn, CAL_Mode (0) */
 999                state->m_Regs[EP4] = state->m_EP4 | ((Standard > HF_AnalogMax) ? state->m_IFLevelDigital : state->m_IFLevelAnalog);
1000                /* state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; */
1001                if (Standard <= HF_AnalogMax)
1002                        state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelAnalog;
1003                else if (Standard <= HF_ATSC)
1004                        state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBT;
1005                else if (Standard <= HF_DVBC)
1006                        state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBC;
1007                else
1008                        state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
1009
1010                if ((Standard == HF_FM_Radio) && state->m_bFMInput)
1011                        state->m_Regs[EP4] |= 0x80;
1012
1013                state->m_Regs[MPD] &= ~0x80;
1014                if (Standard > HF_AnalogMax)
1015                        state->m_Regs[MPD] |= 0x80; /* Add IF_notch for digital */
1016
1017                state->m_Regs[EB22] = m_StandardTable[Standard].m_EB22;
1018
1019                /* Note: This is missing from flowchart in TDA18271 specification ( 1.5 MHz cutoff for FM ) */
1020                if (Standard == HF_FM_Radio)
1021                        state->m_Regs[EB23] |=  0x06; /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
1022                else
1023                        state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LPFc[2] = 0 */
1024
1025                status = UpdateRegs(state, EB22, EB23);
1026                if (status < 0)
1027                        break;
1028
1029                state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | 0x40 | BP_Filter;   /* Dis_Power_level = 1, Filter */
1030                state->m_Regs[EP5] = (state->m_Regs[EP5] & ~0x07) | IR_Meas;
1031                state->m_Regs[EP2] = (RF_Band << 5) | GainTaper;
1032
1033                state->m_Regs[EB1] = (state->m_Regs[EB1] & ~0x07) |
1034                        (state->m_bMaster ? 0x04 : 0x00); /* CALVCO_FortLOn = MS */
1035                /* AGC1_always_master = 0 */
1036                /* AGC_firstn = 0 */
1037                status = UpdateReg(state, EB1);
1038                if (status < 0)
1039                        break;
1040
1041                if (state->m_bMaster) {
1042                        status = CalcMainPLL(state, Frequency + IntermediateFrequency);
1043                        if (status < 0)
1044                                break;
1045                        status = UpdateRegs(state, TM, EP5);
1046                        if (status < 0)
1047                                break;
1048                        state->m_Regs[EB4] |= 0x20;    /* LO_forceSrce = 1 */
1049                        status = UpdateReg(state, EB4);
1050                        if (status < 0)
1051                                break;
1052                        msleep(1);
1053                        state->m_Regs[EB4] &= ~0x20;   /* LO_forceSrce = 0 */
1054                        status = UpdateReg(state, EB4);
1055                        if (status < 0)
1056                                break;
1057                } else {
1058                        u8 PostDiv = 0;
1059                        u8 Div;
1060                        status = CalcCalPLL(state, Frequency + IntermediateFrequency);
1061                        if (status < 0)
1062                                break;
1063
1064                        SearchMap3(m_Cal_PLL_Map, Frequency + IntermediateFrequency, &PostDiv, &Div);
1065                        state->m_Regs[MPD] = (state->m_Regs[MPD] & ~0x7F) | (PostDiv & 0x77);
1066                        status = UpdateReg(state, MPD);
1067                        if (status < 0)
1068                                break;
1069                        status = UpdateRegs(state, TM, EP5);
1070                        if (status < 0)
1071                                break;
1072
1073                        state->m_Regs[EB7] |= 0x20;    /* CAL_forceSrce = 1 */
1074                        status = UpdateReg(state, EB7);
1075                        if (status < 0)
1076                                break;
1077                        msleep(1);
1078                        state->m_Regs[EB7] &= ~0x20;   /* CAL_forceSrce = 0 */
1079                        status = UpdateReg(state, EB7);
1080                        if (status < 0)
1081                                break;
1082                }
1083                msleep(20);
1084                if (Standard != HF_FM_Radio)
1085                        state->m_Regs[EP3] |= 0x04;    /* RFAGC to normal mode */
1086                status = UpdateReg(state, EP3);
1087                if (status < 0)
1088                        break;
1089
1090        } while (0);
1091        return status;
1092}
1093
1094static int sleep(struct dvb_frontend *fe)
1095{
1096        struct tda_state *state = fe->tuner_priv;
1097
1098        StandBy(state);
1099        return 0;
1100}
1101
1102static int init(struct dvb_frontend *fe)
1103{
1104        return 0;
1105}
1106
1107static void release(struct dvb_frontend *fe)
1108{
1109        kfree(fe->tuner_priv);
1110        fe->tuner_priv = NULL;
1111}
1112
1113
1114static int set_params(struct dvb_frontend *fe)
1115{
1116        struct tda_state *state = fe->tuner_priv;
1117        int status = 0;
1118        int Standard;
1119        u32 bw = fe->dtv_property_cache.bandwidth_hz;
1120        u32 delsys  = fe->dtv_property_cache.delivery_system;
1121
1122        state->m_Frequency = fe->dtv_property_cache.frequency;
1123
1124        switch (delsys) {
1125        case  SYS_DVBT:
1126        case  SYS_DVBT2:
1127                switch (bw) {
1128                case 6000000:
1129                        Standard = HF_DVBT_6MHZ;
1130                        break;
1131                case 7000000:
1132                        Standard = HF_DVBT_7MHZ;
1133                        break;
1134                case 8000000:
1135                        Standard = HF_DVBT_8MHZ;
1136                        break;
1137                default:
1138                        return -EINVAL;
1139                }
1140                break;
1141        case SYS_DVBC_ANNEX_A:
1142        case SYS_DVBC_ANNEX_C:
1143                if (bw <= 6000000)
1144                        Standard = HF_DVBC_6MHZ;
1145                else if (bw <= 7000000)
1146                        Standard = HF_DVBC_7MHZ;
1147                else
1148                        Standard = HF_DVBC_8MHZ;
1149                break;
1150        default:
1151                return -EINVAL;
1152        }
1153        do {
1154                status = RFTrackingFiltersCorrection(state, state->m_Frequency);
1155                if (status < 0)
1156                        break;
1157                status = ChannelConfiguration(state, state->m_Frequency,
1158                                              Standard);
1159                if (status < 0)
1160                        break;
1161
1162                msleep(state->m_SettlingTime);  /* Allow AGC's to settle down */
1163        } while (0);
1164        return status;
1165}
1166
1167#if 0
1168static int GetSignalStrength(s32 *pSignalStrength, u32 RFAgc, u32 IFAgc)
1169{
1170        if (IFAgc < 500) {
1171                /* Scale this from 0 to 50000 */
1172                *pSignalStrength = IFAgc * 100;
1173        } else {
1174                /* Scale range 500-1500 to 50000-80000 */
1175                *pSignalStrength = 50000 + (IFAgc - 500) * 30;
1176        }
1177
1178        return 0;
1179}
1180#endif
1181
1182static int get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
1183{
1184        struct tda_state *state = fe->tuner_priv;
1185
1186        *frequency = state->IF;
1187        return 0;
1188}
1189
1190static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1191{
1192        /* struct tda_state *state = fe->tuner_priv; */
1193        /* *bandwidth = priv->bandwidth; */
1194        return 0;
1195}
1196
1197
1198static const struct dvb_tuner_ops tuner_ops = {
1199        .info = {
1200                .name = "NXP TDA18271C2D",
1201                .frequency_min_hz  =  47125 * kHz,
1202                .frequency_max_hz  =    865 * MHz,
1203                .frequency_step_hz =  62500
1204        },
1205        .init              = init,
1206        .sleep             = sleep,
1207        .set_params        = set_params,
1208        .release           = release,
1209        .get_if_frequency  = get_if_frequency,
1210        .get_bandwidth     = get_bandwidth,
1211};
1212
1213struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
1214                                         struct i2c_adapter *i2c, u8 adr)
1215{
1216        struct tda_state *state;
1217
1218        state = kzalloc(sizeof(struct tda_state), GFP_KERNEL);
1219        if (!state)
1220                return NULL;
1221
1222        fe->tuner_priv = state;
1223        state->adr = adr;
1224        state->i2c = i2c;
1225        memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops));
1226        reset(state);
1227        InitCal(state);
1228
1229        return fe;
1230}
1231EXPORT_SYMBOL_GPL(tda18271c2dd_attach);
1232
1233MODULE_DESCRIPTION("TDA18271C2 driver");
1234MODULE_AUTHOR("DD");
1235MODULE_LICENSE("GPL");
1236