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