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                break;
 468        case SEC_VOLTAGE_13:
 469                return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
 470                break;
 471        default:
 472                return -EINVAL;
 473        }
 474}
 475
 476static int si21xx_init(struct dvb_frontend *fe)
 477{
 478        struct si21xx_state *state = fe->demodulator_priv;
 479        int i;
 480        int status = 0;
 481        u8 reg1;
 482        u8 val;
 483        u8 reg2[2];
 484
 485        dprintk("%s\n", __func__);
 486
 487        for (i = 0; ; i += 2) {
 488                reg1 = serit_sp1511lhb_inittab[i];
 489                val = serit_sp1511lhb_inittab[i+1];
 490                if (reg1 == 0xff && val == 0xff)
 491                        break;
 492                si21_writeregs(state, reg1, &val, 1);
 493        }
 494
 495        /*DVB QPSK SYSTEM MODE REG*/
 496        reg1 = 0x08;
 497        si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
 498
 499        /*transport stream config*/
 500        /*
 501        mode = PARALLEL;
 502        sdata_form = LSB_FIRST;
 503        clk_edge = FALLING_EDGE;
 504        clk_mode = CLK_GAPPED_MODE;
 505        strt_len = BYTE_WIDE;
 506        sync_pol = ACTIVE_HIGH;
 507        val_pol = ACTIVE_HIGH;
 508        err_pol = ACTIVE_HIGH;
 509        sclk_rate = 0x00;
 510        parity = 0x00 ;
 511        data_delay = 0x00;
 512        clk_delay = 0x00;
 513        pclk_smooth = 0x00;
 514        */
 515        reg2[0] =
 516                PARALLEL + (LSB_FIRST << 1)
 517                + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
 518                + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
 519                + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
 520
 521        reg2[1] = 0;
 522        /*      sclk_rate + (parity << 2)
 523                + (data_delay << 3) + (clk_delay << 4)
 524                + (pclk_smooth << 5);
 525        */
 526        status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
 527        if (status != 0)
 528                dprintk(" %s : TS Set Error\n", __func__);
 529
 530        return 0;
 531
 532}
 533
 534static int si21_read_status(struct dvb_frontend *fe, enum fe_status *status)
 535{
 536        struct si21xx_state *state = fe->demodulator_priv;
 537        u8 regs_read[2];
 538        u8 reg_read;
 539        u8 i;
 540        u8 lock;
 541        u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
 542
 543        si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
 544        reg_read = 0;
 545
 546        for (i = 0; i < 7; ++i)
 547                reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
 548
 549        lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
 550
 551        dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
 552        *status = 0;
 553
 554        if (signal > 10)
 555                *status |= FE_HAS_SIGNAL;
 556
 557        if (lock & 0x2)
 558                *status |= FE_HAS_CARRIER;
 559
 560        if (lock & 0x20)
 561                *status |= FE_HAS_VITERBI;
 562
 563        if (lock & 0x40)
 564                *status |= FE_HAS_SYNC;
 565
 566        if ((lock & 0x7b) == 0x7b)
 567                *status |= FE_HAS_LOCK;
 568
 569        return 0;
 570}
 571
 572static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 573{
 574        struct si21xx_state *state = fe->demodulator_priv;
 575
 576        /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
 577                                                (u8*)agclevel, 0x01);*/
 578
 579        u16 signal = (3 * si21_readreg(state, 0x27) *
 580                                        si21_readreg(state, 0x28));
 581
 582        dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
 583                si21_readreg(state, 0x27),
 584                si21_readreg(state, 0x28), (int) signal);
 585
 586        signal  <<= 4;
 587        *strength = signal;
 588
 589        return 0;
 590}
 591
 592static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
 593{
 594        struct si21xx_state *state = fe->demodulator_priv;
 595
 596        dprintk("%s\n", __func__);
 597
 598        if (state->errmode != STATUS_BER)
 599                return 0;
 600
 601        *ber = (si21_readreg(state, 0x1d) << 8) |
 602                                si21_readreg(state, 0x1e);
 603
 604        return 0;
 605}
 606
 607static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
 608{
 609        struct si21xx_state *state = fe->demodulator_priv;
 610
 611        s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
 612                                        si21_readreg(state, 0x25));
 613        xsnr = 3 * (xsnr - 0xa100);
 614        *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
 615
 616        dprintk("%s\n", __func__);
 617
 618        return 0;
 619}
 620
 621static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 622{
 623        struct si21xx_state *state = fe->demodulator_priv;
 624
 625        dprintk("%s\n", __func__);
 626
 627        if (state->errmode != STATUS_UCBLOCKS)
 628                *ucblocks = 0;
 629        else
 630                *ucblocks = (si21_readreg(state, 0x1d) << 8) |
 631                                        si21_readreg(state, 0x1e);
 632
 633        return 0;
 634}
 635
 636/*      initiates a channel acquisition sequence
 637        using the specified symbol rate and code rate */
 638static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
 639                             enum fe_code_rate crate)
 640{
 641
 642        struct si21xx_state *state = fe->demodulator_priv;
 643        u8 coderates[] = {
 644                                0x0, 0x01, 0x02, 0x04, 0x00,
 645                                0x8, 0x10, 0x20, 0x00, 0x3f
 646        };
 647
 648        u8 coderate_ptr;
 649        int status;
 650        u8 start_acq = 0x80;
 651        u8 reg, regs[3];
 652
 653        dprintk("%s\n", __func__);
 654
 655        status = PASS;
 656        coderate_ptr = coderates[crate];
 657
 658        si21xx_set_symbolrate(fe, symbrate);
 659
 660        /* write code rates to use in the Viterbi search */
 661        status |= si21_writeregs(state,
 662                                VIT_SRCH_CTRL_REG_1,
 663                                &coderate_ptr, 0x01);
 664
 665        /* clear acq_start bit */
 666        status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
 667        reg &= ~start_acq;
 668        status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
 669
 670        /* use new Carrier Frequency Offset Estimator (QuickLock) */
 671        regs[0] = 0xCB;
 672        regs[1] = 0x40;
 673        regs[2] = 0xCB;
 674
 675        status |= si21_writeregs(state,
 676                                TWO_DB_BNDWDTH_THRSHLD_REG,
 677                                &regs[0], 0x03);
 678        reg = 0x56;
 679        status |= si21_writeregs(state,
 680                                LSA_CTRL_REG_1, &reg, 1);
 681        reg = 0x05;
 682        status |= si21_writeregs(state,
 683                                BLIND_SCAN_CTRL_REG, &reg, 1);
 684        /* start automatic acq */
 685        status |= si21_writeregs(state,
 686                                ACQ_CTRL_REG_2, &start_acq, 0x01);
 687
 688        return status;
 689}
 690
 691static int si21xx_set_frontend(struct dvb_frontend *fe)
 692{
 693        struct si21xx_state *state = fe->demodulator_priv;
 694        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 695
 696        /* freq         Channel carrier frequency in KHz (i.e. 1550000 KHz)
 697         datarate       Channel symbol rate in Sps (i.e. 22500000 Sps)*/
 698
 699        /* in MHz */
 700        unsigned char coarse_tune_freq;
 701        int fine_tune_freq;
 702        unsigned char sample_rate = 0;
 703        /* boolean */
 704        bool inband_interferer_ind;
 705
 706        /* INTERMEDIATE VALUES */
 707        int icoarse_tune_freq; /* MHz */
 708        int ifine_tune_freq; /* MHz */
 709        unsigned int band_high;
 710        unsigned int band_low;
 711        unsigned int x1;
 712        unsigned int x2;
 713        int i;
 714        bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
 715        bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
 716        int status;
 717
 718        /* allowable sample rates for ADC in MHz */
 719        int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
 720                                        196, 204, 205, 206, 207
 721        };
 722        /* in MHz */
 723        int if_limit_high;
 724        int if_limit_low;
 725        int lnb_lo;
 726        int lnb_uncertanity;
 727
 728        int rf_freq;
 729        int data_rate;
 730        unsigned char regs[4];
 731
 732        dprintk("%s : FE_SET_FRONTEND\n", __func__);
 733
 734        if (c->delivery_system != SYS_DVBS) {
 735                        dprintk("%s: unsupported delivery system selected (%d)\n",
 736                                __func__, c->delivery_system);
 737                        return -EOPNOTSUPP;
 738        }
 739
 740        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
 741                inband_interferer_div2[i] = inband_interferer_div4[i] = false;
 742
 743        if_limit_high = -700000;
 744        if_limit_low = -100000;
 745        /* in MHz */
 746        lnb_lo = 0;
 747        lnb_uncertanity = 0;
 748
 749        rf_freq = 10 * c->frequency ;
 750        data_rate = c->symbol_rate / 100;
 751
 752        status = PASS;
 753
 754        band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
 755                                        + (data_rate * 135)) / 200;
 756
 757        band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
 758                                        + (data_rate * 135)) / 200;
 759
 760
 761        icoarse_tune_freq = 100000 *
 762                                (((rf_freq - lnb_lo) -
 763                                        (if_limit_low + if_limit_high) / 2)
 764                                                                / 100000);
 765
 766        ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
 767
 768        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 769                x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
 770                                        (afs[i] * 2500) + afs[i] * 2500;
 771
 772                x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
 773                                                        (afs[i] * 2500);
 774
 775                if (((band_low < x1) && (x1 < band_high)) ||
 776                                        ((band_low < x2) && (x2 < band_high)))
 777                                        inband_interferer_div4[i] = true;
 778
 779        }
 780
 781        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 782                x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
 783                                        (afs[i] * 5000) + afs[i] * 5000;
 784
 785                x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
 786                                        (afs[i] * 5000);
 787
 788                if (((band_low < x1) && (x1 < band_high)) ||
 789                                        ((band_low < x2) && (x2 < band_high)))
 790                                        inband_interferer_div2[i] = true;
 791        }
 792
 793        inband_interferer_ind = true;
 794        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 795                if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
 796                        inband_interferer_ind = false;
 797                        break;
 798                }
 799        }
 800
 801        if (inband_interferer_ind) {
 802                for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 803                        if (!inband_interferer_div2[i]) {
 804                                sample_rate = (u8) afs[i];
 805                                break;
 806                        }
 807                }
 808        } else {
 809                for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 810                        if ((inband_interferer_div2[i] ||
 811                             !inband_interferer_div4[i])) {
 812                                sample_rate = (u8) afs[i];
 813                                break;
 814                        }
 815                }
 816
 817        }
 818
 819        if (sample_rate > 207 || sample_rate < 192)
 820                sample_rate = 200;
 821
 822        fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
 823                                        ((sample_rate) * 1000));
 824
 825        coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
 826
 827        regs[0] = sample_rate;
 828        regs[1] = coarse_tune_freq;
 829        regs[2] = fine_tune_freq & 0xFF;
 830        regs[3] = fine_tune_freq >> 8 & 0xFF;
 831
 832        status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
 833
 834        state->fs = sample_rate;/*ADC MHz*/
 835        si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
 836
 837        return 0;
 838}
 839
 840static int si21xx_sleep(struct dvb_frontend *fe)
 841{
 842        struct si21xx_state *state = fe->demodulator_priv;
 843        u8 regdata;
 844
 845        dprintk("%s\n", __func__);
 846
 847        si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
 848        regdata |= 1 << 6;
 849        si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
 850        state->initialised = 0;
 851
 852        return 0;
 853}
 854
 855static void si21xx_release(struct dvb_frontend *fe)
 856{
 857        struct si21xx_state *state = fe->demodulator_priv;
 858
 859        dprintk("%s\n", __func__);
 860
 861        kfree(state);
 862}
 863
 864static const struct dvb_frontend_ops si21xx_ops = {
 865        .delsys = { SYS_DVBS },
 866        .info = {
 867                .name                   = "SL SI21XX DVB-S",
 868                .frequency_min_hz       =  950 * MHz,
 869                .frequency_max_hz       = 2150 * MHz,
 870                .frequency_stepsize_hz  =  125 * kHz,
 871                .symbol_rate_min        = 1000000,
 872                .symbol_rate_max        = 45000000,
 873                .symbol_rate_tolerance  = 500,  /* ppm */
 874                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 875                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
 876                FE_CAN_QPSK |
 877                FE_CAN_FEC_AUTO
 878        },
 879
 880        .release = si21xx_release,
 881        .init = si21xx_init,
 882        .sleep = si21xx_sleep,
 883        .write = si21_write,
 884        .read_status = si21_read_status,
 885        .read_ber = si21_read_ber,
 886        .read_signal_strength = si21_read_signal_strength,
 887        .read_snr = si21_read_snr,
 888        .read_ucblocks = si21_read_ucblocks,
 889        .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
 890        .diseqc_send_burst = si21xx_send_diseqc_burst,
 891        .set_tone = si21xx_set_tone,
 892        .set_voltage = si21xx_set_voltage,
 893
 894        .set_frontend = si21xx_set_frontend,
 895};
 896
 897struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
 898                                                struct i2c_adapter *i2c)
 899{
 900        struct si21xx_state *state = NULL;
 901        int id;
 902
 903        dprintk("%s\n", __func__);
 904
 905        /* allocate memory for the internal state */
 906        state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
 907        if (state == NULL)
 908                goto error;
 909
 910        /* setup the state */
 911        state->config = config;
 912        state->i2c = i2c;
 913        state->initialised = 0;
 914        state->errmode = STATUS_BER;
 915
 916        /* check if the demod is there */
 917        id = si21_readreg(state, SYSTEM_MODE_REG);
 918        si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
 919        msleep(200);
 920        id = si21_readreg(state, 0x00);
 921
 922        /* register 0x00 contains:
 923                0x34 for SI2107
 924                0x24 for SI2108
 925                0x14 for SI2109
 926                0x04 for SI2110
 927        */
 928        if (id != 0x04 && id != 0x14)
 929                goto error;
 930
 931        /* create dvb_frontend */
 932        memcpy(&state->frontend.ops, &si21xx_ops,
 933                                        sizeof(struct dvb_frontend_ops));
 934        state->frontend.demodulator_priv = state;
 935        return &state->frontend;
 936
 937error:
 938        kfree(state);
 939        return NULL;
 940}
 941EXPORT_SYMBOL(si21xx_attach);
 942
 943module_param(debug, int, 0644);
 944MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 945
 946MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
 947MODULE_AUTHOR("Igor M. Liplianin");
 948MODULE_LICENSE("GPL");
 949