linux/drivers/media/dvb-frontends/si21xx.c
<<
>>
Prefs
   1/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
   2*
   3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
   4*
   5*       This program is free software; you can redistribute it and/or modify
   6*       it under the terms of the GNU General Public License as published by
   7*       the Free Software Foundation; either version 2 of the License, or
   8*       (at your option) any later version.
   9*
  10*/
  11#include <linux/init.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/string.h>
  15#include <linux/slab.h>
  16#include <linux/jiffies.h>
  17#include <asm/div64.h>
  18
  19#include "dvb_frontend.h"
  20#include "si21xx.h"
  21
  22#define REVISION_REG                    0x00
  23#define SYSTEM_MODE_REG                 0x01
  24#define TS_CTRL_REG_1                   0x02
  25#define TS_CTRL_REG_2                   0x03
  26#define PIN_CTRL_REG_1                  0x04
  27#define PIN_CTRL_REG_2                  0x05
  28#define LOCK_STATUS_REG_1               0x0f
  29#define LOCK_STATUS_REG_2               0x10
  30#define ACQ_STATUS_REG                  0x11
  31#define ACQ_CTRL_REG_1                  0x13
  32#define ACQ_CTRL_REG_2                  0x14
  33#define PLL_DIVISOR_REG                 0x15
  34#define COARSE_TUNE_REG                 0x16
  35#define FINE_TUNE_REG_L                 0x17
  36#define FINE_TUNE_REG_H                 0x18
  37
  38#define ANALOG_AGC_POWER_LEVEL_REG      0x28
  39#define CFO_ESTIMATOR_CTRL_REG_1        0x29
  40#define CFO_ESTIMATOR_CTRL_REG_2        0x2a
  41#define CFO_ESTIMATOR_CTRL_REG_3        0x2b
  42
  43#define SYM_RATE_ESTIMATE_REG_L         0x31
  44#define SYM_RATE_ESTIMATE_REG_M         0x32
  45#define SYM_RATE_ESTIMATE_REG_H         0x33
  46
  47#define CFO_ESTIMATOR_OFFSET_REG_L      0x36
  48#define CFO_ESTIMATOR_OFFSET_REG_H      0x37
  49#define CFO_ERROR_REG_L                 0x38
  50#define CFO_ERROR_REG_H                 0x39
  51#define SYM_RATE_ESTIMATOR_CTRL_REG     0x3a
  52
  53#define SYM_RATE_REG_L                  0x3f
  54#define SYM_RATE_REG_M                  0x40
  55#define SYM_RATE_REG_H                  0x41
  56#define SYM_RATE_ESTIMATOR_MAXIMUM_REG  0x42
  57#define SYM_RATE_ESTIMATOR_MINIMUM_REG  0x43
  58
  59#define C_N_ESTIMATOR_CTRL_REG          0x7c
  60#define C_N_ESTIMATOR_THRSHLD_REG       0x7d
  61#define C_N_ESTIMATOR_LEVEL_REG_L       0x7e
  62#define C_N_ESTIMATOR_LEVEL_REG_H       0x7f
  63
  64#define BLIND_SCAN_CTRL_REG             0x80
  65
  66#define LSA_CTRL_REG_1                  0x8D
  67#define SPCTRM_TILT_CORR_THRSHLD_REG    0x8f
  68#define ONE_DB_BNDWDTH_THRSHLD_REG      0x90
  69#define TWO_DB_BNDWDTH_THRSHLD_REG      0x91
  70#define THREE_DB_BNDWDTH_THRSHLD_REG    0x92
  71#define INBAND_POWER_THRSHLD_REG        0x93
  72#define REF_NOISE_LVL_MRGN_THRSHLD_REG  0x94
  73
  74#define VIT_SRCH_CTRL_REG_1             0xa0
  75#define VIT_SRCH_CTRL_REG_2             0xa1
  76#define VIT_SRCH_CTRL_REG_3             0xa2
  77#define VIT_SRCH_STATUS_REG             0xa3
  78#define VITERBI_BER_COUNT_REG_L         0xab
  79#define REED_SOLOMON_CTRL_REG           0xb0
  80#define REED_SOLOMON_ERROR_COUNT_REG_L  0xb1
  81#define PRBS_CTRL_REG                   0xb5
  82
  83#define LNB_CTRL_REG_1                  0xc0
  84#define LNB_CTRL_REG_2                  0xc1
  85#define LNB_CTRL_REG_3                  0xc2
  86#define LNB_CTRL_REG_4                  0xc3
  87#define LNB_CTRL_STATUS_REG             0xc4
  88#define LNB_FIFO_REGS_0                 0xc5
  89#define LNB_FIFO_REGS_1                 0xc6
  90#define LNB_FIFO_REGS_2                 0xc7
  91#define LNB_FIFO_REGS_3                 0xc8
  92#define LNB_FIFO_REGS_4                 0xc9
  93#define LNB_FIFO_REGS_5                 0xca
  94#define LNB_SUPPLY_CTRL_REG_1           0xcb
  95#define LNB_SUPPLY_CTRL_REG_2           0xcc
  96#define LNB_SUPPLY_CTRL_REG_3           0xcd
  97#define LNB_SUPPLY_CTRL_REG_4           0xce
  98#define LNB_SUPPLY_STATUS_REG           0xcf
  99
 100#define FAIL    -1
 101#define PASS    0
 102
 103#define ALLOWABLE_FS_COUNT      10
 104#define STATUS_BER              0
 105#define STATUS_UCBLOCKS         1
 106
 107static int debug;
 108#define dprintk(args...) \
 109        do { \
 110                if (debug) \
 111                        printk(KERN_DEBUG "si21xx: " args); \
 112        } while (0)
 113
 114enum {
 115        ACTIVE_HIGH,
 116        ACTIVE_LOW
 117};
 118enum {
 119        BYTE_WIDE,
 120        BIT_WIDE
 121};
 122enum {
 123        CLK_GAPPED_MODE,
 124        CLK_CONTINUOUS_MODE
 125};
 126enum {
 127        RISING_EDGE,
 128        FALLING_EDGE
 129};
 130enum {
 131        MSB_FIRST,
 132        LSB_FIRST
 133};
 134enum {
 135        SERIAL,
 136        PARALLEL
 137};
 138
 139struct si21xx_state {
 140        struct i2c_adapter *i2c;
 141        const struct si21xx_config *config;
 142        struct dvb_frontend frontend;
 143        u8 initialised:1;
 144        int errmode;
 145        int fs;                 /*Sampling rate of the ADC in MHz*/
 146};
 147
 148/*      register default initialization */
 149static u8 serit_sp1511lhb_inittab[] = {
 150        0x01, 0x28,     /* set i2c_inc_disable */
 151        0x20, 0x03,
 152        0x27, 0x20,
 153        0xe0, 0x45,
 154        0xe1, 0x08,
 155        0xfe, 0x01,
 156        0x01, 0x28,
 157        0x89, 0x09,
 158        0x04, 0x80,
 159        0x05, 0x01,
 160        0x06, 0x00,
 161        0x20, 0x03,
 162        0x24, 0x88,
 163        0x29, 0x09,
 164        0x2a, 0x0f,
 165        0x2c, 0x10,
 166        0x2d, 0x19,
 167        0x2e, 0x08,
 168        0x2f, 0x10,
 169        0x30, 0x19,
 170        0x34, 0x20,
 171        0x35, 0x03,
 172        0x45, 0x02,
 173        0x46, 0x45,
 174        0x47, 0xd0,
 175        0x48, 0x00,
 176        0x49, 0x40,
 177        0x4a, 0x03,
 178        0x4c, 0xfd,
 179        0x4f, 0x2e,
 180        0x50, 0x2e,
 181        0x51, 0x10,
 182        0x52, 0x10,
 183        0x56, 0x92,
 184        0x59, 0x00,
 185        0x5a, 0x2d,
 186        0x5b, 0x33,
 187        0x5c, 0x1f,
 188        0x5f, 0x76,
 189        0x62, 0xc0,
 190        0x63, 0xc0,
 191        0x64, 0xf3,
 192        0x65, 0xf3,
 193        0x79, 0x40,
 194        0x6a, 0x40,
 195        0x6b, 0x0a,
 196        0x6c, 0x80,
 197        0x6d, 0x27,
 198        0x71, 0x06,
 199        0x75, 0x60,
 200        0x78, 0x00,
 201        0x79, 0xb5,
 202        0x7c, 0x05,
 203        0x7d, 0x1a,
 204        0x87, 0x55,
 205        0x88, 0x72,
 206        0x8f, 0x08,
 207        0x90, 0xe0,
 208        0x94, 0x40,
 209        0xa0, 0x3f,
 210        0xa1, 0xc0,
 211        0xa4, 0xcc,
 212        0xa5, 0x66,
 213        0xa6, 0x66,
 214        0xa7, 0x7b,
 215        0xa8, 0x7b,
 216        0xa9, 0x7b,
 217        0xaa, 0x9a,
 218        0xed, 0x04,
 219        0xad, 0x00,
 220        0xae, 0x03,
 221        0xcc, 0xab,
 222        0x01, 0x08,
 223        0xff, 0xff
 224};
 225
 226/*      low level read/writes */
 227static int si21_writeregs(struct si21xx_state *state, u8 reg1,
 228                                                        u8 *data, int len)
 229{
 230        int ret;
 231        u8 buf[60];/* = { reg1, data };*/
 232        struct i2c_msg msg = {
 233                                .addr = state->config->demod_address,
 234                                .flags = 0,
 235                                .buf = buf,
 236                                .len = len + 1
 237        };
 238
 239        if (len > sizeof(buf) - 1)
 240                return -EINVAL;
 241
 242        msg.buf[0] =  reg1;
 243        memcpy(msg.buf + 1, data, len);
 244
 245        ret = i2c_transfer(state->i2c, &msg, 1);
 246
 247        if (ret != 1)
 248                dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, ret == %i)\n",
 249                        __func__, reg1, data[0], ret);
 250
 251        return (ret != 1) ? -EREMOTEIO : 0;
 252}
 253
 254static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
 255{
 256        int ret;
 257        u8 buf[] = { reg, data };
 258        struct i2c_msg msg = {
 259                                .addr = state->config->demod_address,
 260                                .flags = 0,
 261                                .buf = buf,
 262                                .len = 2
 263        };
 264
 265        ret = i2c_transfer(state->i2c, &msg, 1);
 266
 267        if (ret != 1)
 268                dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, ret == %i)\n",
 269                        __func__, reg, data, ret);
 270
 271        return (ret != 1) ? -EREMOTEIO : 0;
 272}
 273
 274static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
 275{
 276        struct si21xx_state *state = fe->demodulator_priv;
 277
 278        if (len != 2)
 279                return -EINVAL;
 280
 281        return si21_writereg(state, buf[0], buf[1]);
 282}
 283
 284static u8 si21_readreg(struct si21xx_state *state, u8 reg)
 285{
 286        int ret;
 287        u8 b0[] = { reg };
 288        u8 b1[] = { 0 };
 289        struct i2c_msg msg[] = {
 290                {
 291                        .addr = state->config->demod_address,
 292                        .flags = 0,
 293                        .buf = b0,
 294                        .len = 1
 295                }, {
 296                        .addr = state->config->demod_address,
 297                        .flags = I2C_M_RD,
 298                        .buf = b1,
 299                        .len = 1
 300                }
 301        };
 302
 303        ret = i2c_transfer(state->i2c, msg, 2);
 304
 305        if (ret != 2)
 306                dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
 307                        __func__, reg, ret);
 308
 309        return b1[0];
 310}
 311
 312static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
 313{
 314        int ret;
 315        struct i2c_msg msg[] = {
 316                {
 317                        .addr = state->config->demod_address,
 318                        .flags = 0,
 319                        .buf = &reg1,
 320                        .len = 1
 321                }, {
 322                        .addr = state->config->demod_address,
 323                        .flags = I2C_M_RD,
 324                        .buf = b,
 325                        .len = len
 326                }
 327        };
 328
 329        ret = i2c_transfer(state->i2c, msg, 2);
 330
 331        if (ret != 2)
 332                dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
 333
 334        return ret == 2 ? 0 : -1;
 335}
 336
 337static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
 338{
 339        unsigned long start = jiffies;
 340
 341        dprintk("%s\n", __func__);
 342
 343        while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
 344                if (jiffies - start > timeout) {
 345                        dprintk("%s: timeout!!\n", __func__);
 346                        return -ETIMEDOUT;
 347                }
 348                msleep(10);
 349        }
 350
 351        return 0;
 352}
 353
 354static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
 355{
 356        struct si21xx_state *state = fe->demodulator_priv;
 357        u32 sym_rate, data_rate;
 358        int i;
 359        u8 sym_rate_bytes[3];
 360
 361        dprintk("%s : srate = %i\n", __func__ , srate);
 362
 363        if ((srate < 1000000) || (srate > 45000000))
 364                return -EINVAL;
 365
 366        data_rate = srate;
 367        sym_rate = 0;
 368
 369        for (i = 0; i < 4; ++i) {
 370                sym_rate /= 100;
 371                sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
 372                                                                state->fs;
 373                data_rate /= 100;
 374        }
 375        for (i = 0; i < 3; ++i)
 376                sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
 377
 378        si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
 379
 380        return 0;
 381}
 382
 383static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
 384                                        struct dvb_diseqc_master_cmd *m)
 385{
 386        struct si21xx_state *state = fe->demodulator_priv;
 387        u8 lnb_status;
 388        u8 LNB_CTRL_1;
 389        int status;
 390
 391        dprintk("%s\n", __func__);
 392
 393        status = PASS;
 394        LNB_CTRL_1 = 0;
 395
 396        status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
 397        status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
 398
 399        /*fill the FIFO*/
 400        status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
 401
 402        LNB_CTRL_1 = (lnb_status & 0x70);
 403        LNB_CTRL_1 |= m->msg_len;
 404
 405        LNB_CTRL_1 |= 0x80;     /* begin LNB signaling */
 406
 407        status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
 408
 409        return status;
 410}
 411
 412static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
 413                                    enum fe_sec_mini_cmd burst)
 414{
 415        struct si21xx_state *state = fe->demodulator_priv;
 416        u8 val;
 417
 418        dprintk("%s\n", __func__);
 419
 420        if (si21xx_wait_diseqc_idle(state, 100) < 0)
 421                return -ETIMEDOUT;
 422
 423        val = (0x80 | si21_readreg(state, 0xc1));
 424        if (si21_writereg(state, LNB_CTRL_REG_1,
 425                        burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
 426                return -EREMOTEIO;
 427
 428        if (si21xx_wait_diseqc_idle(state, 100) < 0)
 429                return -ETIMEDOUT;
 430
 431        if (si21_writereg(state, LNB_CTRL_REG_1, val))
 432                return -EREMOTEIO;
 433
 434        return 0;
 435}
 436/*      30.06.2008 */
 437static int si21xx_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
 438{
 439        struct si21xx_state *state = fe->demodulator_priv;
 440        u8 val;
 441
 442        dprintk("%s\n", __func__);
 443        val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
 444
 445        switch (tone) {
 446        case SEC_TONE_ON:
 447                return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
 448
 449        case SEC_TONE_OFF:
 450                return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
 451
 452        default:
 453                return -EINVAL;
 454        }
 455}
 456
 457static int si21xx_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt)
 458{
 459        struct si21xx_state *state = fe->demodulator_priv;
 460
 461        u8 val;
 462        dprintk("%s: %s\n", __func__,
 463                volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
 464                volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
 465
 466
 467        val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
 468
 469        switch (volt) {
 470        case SEC_VOLTAGE_18:
 471                return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
 472                break;
 473        case SEC_VOLTAGE_13:
 474                return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
 475                break;
 476        default:
 477                return -EINVAL;
 478        }
 479}
 480
 481static int si21xx_init(struct dvb_frontend *fe)
 482{
 483        struct si21xx_state *state = fe->demodulator_priv;
 484        int i;
 485        int status = 0;
 486        u8 reg1;
 487        u8 val;
 488        u8 reg2[2];
 489
 490        dprintk("%s\n", __func__);
 491
 492        for (i = 0; ; i += 2) {
 493                reg1 = serit_sp1511lhb_inittab[i];
 494                val = serit_sp1511lhb_inittab[i+1];
 495                if (reg1 == 0xff && val == 0xff)
 496                        break;
 497                si21_writeregs(state, reg1, &val, 1);
 498        }
 499
 500        /*DVB QPSK SYSTEM MODE REG*/
 501        reg1 = 0x08;
 502        si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
 503
 504        /*transport stream config*/
 505        /*
 506        mode = PARALLEL;
 507        sdata_form = LSB_FIRST;
 508        clk_edge = FALLING_EDGE;
 509        clk_mode = CLK_GAPPED_MODE;
 510        strt_len = BYTE_WIDE;
 511        sync_pol = ACTIVE_HIGH;
 512        val_pol = ACTIVE_HIGH;
 513        err_pol = ACTIVE_HIGH;
 514        sclk_rate = 0x00;
 515        parity = 0x00 ;
 516        data_delay = 0x00;
 517        clk_delay = 0x00;
 518        pclk_smooth = 0x00;
 519        */
 520        reg2[0] =
 521                PARALLEL + (LSB_FIRST << 1)
 522                + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
 523                + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
 524                + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
 525
 526        reg2[1] = 0;
 527        /*      sclk_rate + (parity << 2)
 528                + (data_delay << 3) + (clk_delay << 4)
 529                + (pclk_smooth << 5);
 530        */
 531        status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
 532        if (status != 0)
 533                dprintk(" %s : TS Set Error\n", __func__);
 534
 535        return 0;
 536
 537}
 538
 539static int si21_read_status(struct dvb_frontend *fe, enum fe_status *status)
 540{
 541        struct si21xx_state *state = fe->demodulator_priv;
 542        u8 regs_read[2];
 543        u8 reg_read;
 544        u8 i;
 545        u8 lock;
 546        u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
 547
 548        si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
 549        reg_read = 0;
 550
 551        for (i = 0; i < 7; ++i)
 552                reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
 553
 554        lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
 555
 556        dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
 557        *status = 0;
 558
 559        if (signal > 10)
 560                *status |= FE_HAS_SIGNAL;
 561
 562        if (lock & 0x2)
 563                *status |= FE_HAS_CARRIER;
 564
 565        if (lock & 0x20)
 566                *status |= FE_HAS_VITERBI;
 567
 568        if (lock & 0x40)
 569                *status |= FE_HAS_SYNC;
 570
 571        if ((lock & 0x7b) == 0x7b)
 572                *status |= FE_HAS_LOCK;
 573
 574        return 0;
 575}
 576
 577static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 578{
 579        struct si21xx_state *state = fe->demodulator_priv;
 580
 581        /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
 582                                                (u8*)agclevel, 0x01);*/
 583
 584        u16 signal = (3 * si21_readreg(state, 0x27) *
 585                                        si21_readreg(state, 0x28));
 586
 587        dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
 588                si21_readreg(state, 0x27),
 589                si21_readreg(state, 0x28), (int) signal);
 590
 591        signal  <<= 4;
 592        *strength = signal;
 593
 594        return 0;
 595}
 596
 597static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
 598{
 599        struct si21xx_state *state = fe->demodulator_priv;
 600
 601        dprintk("%s\n", __func__);
 602
 603        if (state->errmode != STATUS_BER)
 604                return 0;
 605
 606        *ber = (si21_readreg(state, 0x1d) << 8) |
 607                                si21_readreg(state, 0x1e);
 608
 609        return 0;
 610}
 611
 612static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
 613{
 614        struct si21xx_state *state = fe->demodulator_priv;
 615
 616        s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
 617                                        si21_readreg(state, 0x25));
 618        xsnr = 3 * (xsnr - 0xa100);
 619        *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
 620
 621        dprintk("%s\n", __func__);
 622
 623        return 0;
 624}
 625
 626static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 627{
 628        struct si21xx_state *state = fe->demodulator_priv;
 629
 630        dprintk("%s\n", __func__);
 631
 632        if (state->errmode != STATUS_UCBLOCKS)
 633                *ucblocks = 0;
 634        else
 635                *ucblocks = (si21_readreg(state, 0x1d) << 8) |
 636                                        si21_readreg(state, 0x1e);
 637
 638        return 0;
 639}
 640
 641/*      initiates a channel acquisition sequence
 642        using the specified symbol rate and code rate */
 643static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
 644                             enum fe_code_rate crate)
 645{
 646
 647        struct si21xx_state *state = fe->demodulator_priv;
 648        u8 coderates[] = {
 649                                0x0, 0x01, 0x02, 0x04, 0x00,
 650                                0x8, 0x10, 0x20, 0x00, 0x3f
 651        };
 652
 653        u8 coderate_ptr;
 654        int status;
 655        u8 start_acq = 0x80;
 656        u8 reg, regs[3];
 657
 658        dprintk("%s\n", __func__);
 659
 660        status = PASS;
 661        coderate_ptr = coderates[crate];
 662
 663        si21xx_set_symbolrate(fe, symbrate);
 664
 665        /* write code rates to use in the Viterbi search */
 666        status |= si21_writeregs(state,
 667                                VIT_SRCH_CTRL_REG_1,
 668                                &coderate_ptr, 0x01);
 669
 670        /* clear acq_start bit */
 671        status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
 672        reg &= ~start_acq;
 673        status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
 674
 675        /* use new Carrier Frequency Offset Estimator (QuickLock) */
 676        regs[0] = 0xCB;
 677        regs[1] = 0x40;
 678        regs[2] = 0xCB;
 679
 680        status |= si21_writeregs(state,
 681                                TWO_DB_BNDWDTH_THRSHLD_REG,
 682                                &regs[0], 0x03);
 683        reg = 0x56;
 684        status |= si21_writeregs(state,
 685                                LSA_CTRL_REG_1, &reg, 1);
 686        reg = 0x05;
 687        status |= si21_writeregs(state,
 688                                BLIND_SCAN_CTRL_REG, &reg, 1);
 689        /* start automatic acq */
 690        status |= si21_writeregs(state,
 691                                ACQ_CTRL_REG_2, &start_acq, 0x01);
 692
 693        return status;
 694}
 695
 696static int si21xx_set_frontend(struct dvb_frontend *fe)
 697{
 698        struct si21xx_state *state = fe->demodulator_priv;
 699        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 700
 701        /* freq         Channel carrier frequency in KHz (i.e. 1550000 KHz)
 702         datarate       Channel symbol rate in Sps (i.e. 22500000 Sps)*/
 703
 704        /* in MHz */
 705        unsigned char coarse_tune_freq;
 706        int fine_tune_freq;
 707        unsigned char sample_rate = 0;
 708        /* boolean */
 709        bool inband_interferer_ind;
 710
 711        /* INTERMEDIATE VALUES */
 712        int icoarse_tune_freq; /* MHz */
 713        int ifine_tune_freq; /* MHz */
 714        unsigned int band_high;
 715        unsigned int band_low;
 716        unsigned int x1;
 717        unsigned int x2;
 718        int i;
 719        bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
 720        bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
 721        int status;
 722
 723        /* allowable sample rates for ADC in MHz */
 724        int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
 725                                        196, 204, 205, 206, 207
 726        };
 727        /* in MHz */
 728        int if_limit_high;
 729        int if_limit_low;
 730        int lnb_lo;
 731        int lnb_uncertanity;
 732
 733        int rf_freq;
 734        int data_rate;
 735        unsigned char regs[4];
 736
 737        dprintk("%s : FE_SET_FRONTEND\n", __func__);
 738
 739        if (c->delivery_system != SYS_DVBS) {
 740                        dprintk("%s: unsupported delivery system selected (%d)\n",
 741                                __func__, c->delivery_system);
 742                        return -EOPNOTSUPP;
 743        }
 744
 745        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
 746                inband_interferer_div2[i] = inband_interferer_div4[i] = false;
 747
 748        if_limit_high = -700000;
 749        if_limit_low = -100000;
 750        /* in MHz */
 751        lnb_lo = 0;
 752        lnb_uncertanity = 0;
 753
 754        rf_freq = 10 * c->frequency ;
 755        data_rate = c->symbol_rate / 100;
 756
 757        status = PASS;
 758
 759        band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
 760                                        + (data_rate * 135)) / 200;
 761
 762        band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
 763                                        + (data_rate * 135)) / 200;
 764
 765
 766        icoarse_tune_freq = 100000 *
 767                                (((rf_freq - lnb_lo) -
 768                                        (if_limit_low + if_limit_high) / 2)
 769                                                                / 100000);
 770
 771        ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
 772
 773        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 774                x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
 775                                        (afs[i] * 2500) + afs[i] * 2500;
 776
 777                x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
 778                                                        (afs[i] * 2500);
 779
 780                if (((band_low < x1) && (x1 < band_high)) ||
 781                                        ((band_low < x2) && (x2 < band_high)))
 782                                        inband_interferer_div4[i] = true;
 783
 784        }
 785
 786        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 787                x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
 788                                        (afs[i] * 5000) + afs[i] * 5000;
 789
 790                x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
 791                                        (afs[i] * 5000);
 792
 793                if (((band_low < x1) && (x1 < band_high)) ||
 794                                        ((band_low < x2) && (x2 < band_high)))
 795                                        inband_interferer_div2[i] = true;
 796        }
 797
 798        inband_interferer_ind = true;
 799        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 800                if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
 801                        inband_interferer_ind = false;
 802                        break;
 803                }
 804        }
 805
 806        if (inband_interferer_ind) {
 807                for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 808                        if (!inband_interferer_div2[i]) {
 809                                sample_rate = (u8) afs[i];
 810                                break;
 811                        }
 812                }
 813        } else {
 814                for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 815                        if ((inband_interferer_div2[i] ||
 816                             !inband_interferer_div4[i])) {
 817                                sample_rate = (u8) afs[i];
 818                                break;
 819                        }
 820                }
 821
 822        }
 823
 824        if (sample_rate > 207 || sample_rate < 192)
 825                sample_rate = 200;
 826
 827        fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
 828                                        ((sample_rate) * 1000));
 829
 830        coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
 831
 832        regs[0] = sample_rate;
 833        regs[1] = coarse_tune_freq;
 834        regs[2] = fine_tune_freq & 0xFF;
 835        regs[3] = fine_tune_freq >> 8 & 0xFF;
 836
 837        status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
 838
 839        state->fs = sample_rate;/*ADC MHz*/
 840        si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
 841
 842        return 0;
 843}
 844
 845static int si21xx_sleep(struct dvb_frontend *fe)
 846{
 847        struct si21xx_state *state = fe->demodulator_priv;
 848        u8 regdata;
 849
 850        dprintk("%s\n", __func__);
 851
 852        si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
 853        regdata |= 1 << 6;
 854        si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
 855        state->initialised = 0;
 856
 857        return 0;
 858}
 859
 860static void si21xx_release(struct dvb_frontend *fe)
 861{
 862        struct si21xx_state *state = fe->demodulator_priv;
 863
 864        dprintk("%s\n", __func__);
 865
 866        kfree(state);
 867}
 868
 869static const struct dvb_frontend_ops si21xx_ops = {
 870        .delsys = { SYS_DVBS },
 871        .info = {
 872                .name                   = "SL SI21XX DVB-S",
 873                .frequency_min          = 950000,
 874                .frequency_max          = 2150000,
 875                .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
 876                .frequency_tolerance    = 0,
 877                .symbol_rate_min        = 1000000,
 878                .symbol_rate_max        = 45000000,
 879                .symbol_rate_tolerance  = 500,  /* ppm */
 880                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 881                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
 882                FE_CAN_QPSK |
 883                FE_CAN_FEC_AUTO
 884        },
 885
 886        .release = si21xx_release,
 887        .init = si21xx_init,
 888        .sleep = si21xx_sleep,
 889        .write = si21_write,
 890        .read_status = si21_read_status,
 891        .read_ber = si21_read_ber,
 892        .read_signal_strength = si21_read_signal_strength,
 893        .read_snr = si21_read_snr,
 894        .read_ucblocks = si21_read_ucblocks,
 895        .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
 896        .diseqc_send_burst = si21xx_send_diseqc_burst,
 897        .set_tone = si21xx_set_tone,
 898        .set_voltage = si21xx_set_voltage,
 899
 900        .set_frontend = si21xx_set_frontend,
 901};
 902
 903struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
 904                                                struct i2c_adapter *i2c)
 905{
 906        struct si21xx_state *state = NULL;
 907        int id;
 908
 909        dprintk("%s\n", __func__);
 910
 911        /* allocate memory for the internal state */
 912        state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
 913        if (state == NULL)
 914                goto error;
 915
 916        /* setup the state */
 917        state->config = config;
 918        state->i2c = i2c;
 919        state->initialised = 0;
 920        state->errmode = STATUS_BER;
 921
 922        /* check if the demod is there */
 923        id = si21_readreg(state, SYSTEM_MODE_REG);
 924        si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
 925        msleep(200);
 926        id = si21_readreg(state, 0x00);
 927
 928        /* register 0x00 contains:
 929                0x34 for SI2107
 930                0x24 for SI2108
 931                0x14 for SI2109
 932                0x04 for SI2110
 933        */
 934        if (id != 0x04 && id != 0x14)
 935                goto error;
 936
 937        /* create dvb_frontend */
 938        memcpy(&state->frontend.ops, &si21xx_ops,
 939                                        sizeof(struct dvb_frontend_ops));
 940        state->frontend.demodulator_priv = state;
 941        return &state->frontend;
 942
 943error:
 944        kfree(state);
 945        return NULL;
 946}
 947EXPORT_SYMBOL(si21xx_attach);
 948
 949module_param(debug, int, 0644);
 950MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 951
 952MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
 953MODULE_AUTHOR("Igor M. Liplianin");
 954MODULE_LICENSE("GPL");
 955