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        msg.buf[0] =  reg1;
 240        memcpy(msg.buf + 1, data, len);
 241
 242        ret = i2c_transfer(state->i2c, &msg, 1);
 243
 244        if (ret != 1)
 245                dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
 246                        "ret == %i)\n", __func__, reg1, data[0], ret);
 247
 248        return (ret != 1) ? -EREMOTEIO : 0;
 249}
 250
 251static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
 252{
 253        int ret;
 254        u8 buf[] = { reg, data };
 255        struct i2c_msg msg = {
 256                                .addr = state->config->demod_address,
 257                                .flags = 0,
 258                                .buf = buf,
 259                                .len = 2
 260        };
 261
 262        ret = i2c_transfer(state->i2c, &msg, 1);
 263
 264        if (ret != 1)
 265                dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
 266                        "ret == %i)\n", __func__, reg, data, ret);
 267
 268        return (ret != 1) ? -EREMOTEIO : 0;
 269}
 270
 271static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
 272{
 273        struct si21xx_state *state = fe->demodulator_priv;
 274
 275        if (len != 2)
 276                return -EINVAL;
 277
 278        return si21_writereg(state, buf[0], buf[1]);
 279}
 280
 281static u8 si21_readreg(struct si21xx_state *state, u8 reg)
 282{
 283        int ret;
 284        u8 b0[] = { reg };
 285        u8 b1[] = { 0 };
 286        struct i2c_msg msg[] = {
 287                {
 288                        .addr = state->config->demod_address,
 289                        .flags = 0,
 290                        .buf = b0,
 291                        .len = 1
 292                }, {
 293                        .addr = state->config->demod_address,
 294                        .flags = I2C_M_RD,
 295                        .buf = b1,
 296                        .len = 1
 297                }
 298        };
 299
 300        ret = i2c_transfer(state->i2c, msg, 2);
 301
 302        if (ret != 2)
 303                dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
 304                        __func__, reg, ret);
 305
 306        return b1[0];
 307}
 308
 309static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
 310{
 311        int ret;
 312        struct i2c_msg msg[] = {
 313                {
 314                        .addr = state->config->demod_address,
 315                        .flags = 0,
 316                        .buf = &reg1,
 317                        .len = 1
 318                }, {
 319                        .addr = state->config->demod_address,
 320                        .flags = I2C_M_RD,
 321                        .buf = b,
 322                        .len = len
 323                }
 324        };
 325
 326        ret = i2c_transfer(state->i2c, msg, 2);
 327
 328        if (ret != 2)
 329                dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
 330
 331        return ret == 2 ? 0 : -1;
 332}
 333
 334static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
 335{
 336        unsigned long start = jiffies;
 337
 338        dprintk("%s\n", __func__);
 339
 340        while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
 341                if (jiffies - start > timeout) {
 342                        dprintk("%s: timeout!!\n", __func__);
 343                        return -ETIMEDOUT;
 344                }
 345                msleep(10);
 346        };
 347
 348        return 0;
 349}
 350
 351static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
 352{
 353        struct si21xx_state *state = fe->demodulator_priv;
 354        u32 sym_rate, data_rate;
 355        int i;
 356        u8 sym_rate_bytes[3];
 357
 358        dprintk("%s : srate = %i\n", __func__ , srate);
 359
 360        if ((srate < 1000000) || (srate > 45000000))
 361                return -EINVAL;
 362
 363        data_rate = srate;
 364        sym_rate = 0;
 365
 366        for (i = 0; i < 4; ++i) {
 367                sym_rate /= 100;
 368                sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
 369                                                                state->fs;
 370                data_rate /= 100;
 371        }
 372        for (i = 0; i < 3; ++i)
 373                sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
 374
 375        si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
 376
 377        return 0;
 378}
 379
 380static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
 381                                        struct dvb_diseqc_master_cmd *m)
 382{
 383        struct si21xx_state *state = fe->demodulator_priv;
 384        u8 lnb_status;
 385        u8 LNB_CTRL_1;
 386        int status;
 387
 388        dprintk("%s\n", __func__);
 389
 390        status = PASS;
 391        LNB_CTRL_1 = 0;
 392
 393        status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
 394        status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
 395
 396        /*fill the FIFO*/
 397        status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
 398
 399        LNB_CTRL_1 = (lnb_status & 0x70);
 400        LNB_CTRL_1 |= m->msg_len;
 401
 402        LNB_CTRL_1 |= 0x80;     /* begin LNB signaling */
 403
 404        status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
 405
 406        return status;
 407}
 408
 409static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
 410                                                fe_sec_mini_cmd_t burst)
 411{
 412        struct si21xx_state *state = fe->demodulator_priv;
 413        u8 val;
 414
 415        dprintk("%s\n", __func__);
 416
 417        if (si21xx_wait_diseqc_idle(state, 100) < 0)
 418                return -ETIMEDOUT;
 419
 420        val = (0x80 | si21_readreg(state, 0xc1));
 421        if (si21_writereg(state, LNB_CTRL_REG_1,
 422                        burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
 423                return -EREMOTEIO;
 424
 425        if (si21xx_wait_diseqc_idle(state, 100) < 0)
 426                return -ETIMEDOUT;
 427
 428        if (si21_writereg(state, LNB_CTRL_REG_1, val))
 429                return -EREMOTEIO;
 430
 431        return 0;
 432}
 433/*      30.06.2008 */
 434static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
 435{
 436        struct si21xx_state *state = fe->demodulator_priv;
 437        u8 val;
 438
 439        dprintk("%s\n", __func__);
 440        val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
 441
 442        switch (tone) {
 443        case SEC_TONE_ON:
 444                return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
 445
 446        case SEC_TONE_OFF:
 447                return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
 448
 449        default:
 450                return -EINVAL;
 451        }
 452}
 453
 454static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
 455{
 456        struct si21xx_state *state = fe->demodulator_priv;
 457
 458        u8 val;
 459        dprintk("%s: %s\n", __func__,
 460                volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
 461                volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
 462
 463
 464        val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
 465
 466        switch (volt) {
 467        case SEC_VOLTAGE_18:
 468                return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
 469                break;
 470        case SEC_VOLTAGE_13:
 471                return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
 472                break;
 473        default:
 474                return -EINVAL;
 475        };
 476}
 477
 478static int si21xx_init(struct dvb_frontend *fe)
 479{
 480        struct si21xx_state *state = fe->demodulator_priv;
 481        int i;
 482        int status = 0;
 483        u8 reg1;
 484        u8 val;
 485        u8 reg2[2];
 486
 487        dprintk("%s\n", __func__);
 488
 489        for (i = 0; ; i += 2) {
 490                reg1 = serit_sp1511lhb_inittab[i];
 491                val = serit_sp1511lhb_inittab[i+1];
 492                if (reg1 == 0xff && val == 0xff)
 493                        break;
 494                si21_writeregs(state, reg1, &val, 1);
 495        }
 496
 497        /*DVB QPSK SYSTEM MODE REG*/
 498        reg1 = 0x08;
 499        si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
 500
 501        /*transport stream config*/
 502        /*
 503        mode = PARALLEL;
 504        sdata_form = LSB_FIRST;
 505        clk_edge = FALLING_EDGE;
 506        clk_mode = CLK_GAPPED_MODE;
 507        strt_len = BYTE_WIDE;
 508        sync_pol = ACTIVE_HIGH;
 509        val_pol = ACTIVE_HIGH;
 510        err_pol = ACTIVE_HIGH;
 511        sclk_rate = 0x00;
 512        parity = 0x00 ;
 513        data_delay = 0x00;
 514        clk_delay = 0x00;
 515        pclk_smooth = 0x00;
 516        */
 517        reg2[0] =
 518                PARALLEL + (LSB_FIRST << 1)
 519                + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
 520                + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
 521                + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
 522
 523        reg2[1] = 0;
 524        /*      sclk_rate + (parity << 2)
 525                + (data_delay << 3) + (clk_delay << 4)
 526                + (pclk_smooth << 5);
 527        */
 528        status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
 529        if (status != 0)
 530                dprintk(" %s : TS Set Error\n", __func__);
 531
 532        return 0;
 533
 534}
 535
 536static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
 537{
 538        struct si21xx_state *state = fe->demodulator_priv;
 539        u8 regs_read[2];
 540        u8 reg_read;
 541        u8 i;
 542        u8 lock;
 543        u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
 544
 545        si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
 546        reg_read = 0;
 547
 548        for (i = 0; i < 7; ++i)
 549                reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
 550
 551        lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
 552
 553        dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
 554        *status = 0;
 555
 556        if (signal > 10)
 557                *status |= FE_HAS_SIGNAL;
 558
 559        if (lock & 0x2)
 560                *status |= FE_HAS_CARRIER;
 561
 562        if (lock & 0x20)
 563                *status |= FE_HAS_VITERBI;
 564
 565        if (lock & 0x40)
 566                *status |= FE_HAS_SYNC;
 567
 568        if ((lock & 0x7b) == 0x7b)
 569                *status |= FE_HAS_LOCK;
 570
 571        return 0;
 572}
 573
 574static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 575{
 576        struct si21xx_state *state = fe->demodulator_priv;
 577
 578        /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
 579                                                (u8*)agclevel, 0x01);*/
 580
 581        u16 signal = (3 * si21_readreg(state, 0x27) *
 582                                        si21_readreg(state, 0x28));
 583
 584        dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
 585                si21_readreg(state, 0x27),
 586                si21_readreg(state, 0x28), (int) signal);
 587
 588        signal  <<= 4;
 589        *strength = signal;
 590
 591        return 0;
 592}
 593
 594static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
 595{
 596        struct si21xx_state *state = fe->demodulator_priv;
 597
 598        dprintk("%s\n", __func__);
 599
 600        if (state->errmode != STATUS_BER)
 601                return 0;
 602
 603        *ber = (si21_readreg(state, 0x1d) << 8) |
 604                                si21_readreg(state, 0x1e);
 605
 606        return 0;
 607}
 608
 609static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
 610{
 611        struct si21xx_state *state = fe->demodulator_priv;
 612
 613        s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
 614                                        si21_readreg(state, 0x25));
 615        xsnr = 3 * (xsnr - 0xa100);
 616        *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
 617
 618        dprintk("%s\n", __func__);
 619
 620        return 0;
 621}
 622
 623static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 624{
 625        struct si21xx_state *state = fe->demodulator_priv;
 626
 627        dprintk("%s\n", __func__);
 628
 629        if (state->errmode != STATUS_UCBLOCKS)
 630                *ucblocks = 0;
 631        else
 632                *ucblocks = (si21_readreg(state, 0x1d) << 8) |
 633                                        si21_readreg(state, 0x1e);
 634
 635        return 0;
 636}
 637
 638/*      initiates a channel acquisition sequence
 639        using the specified symbol rate and code rate */
 640static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
 641                                                fe_code_rate_t crate)
 642{
 643
 644        struct si21xx_state *state = fe->demodulator_priv;
 645        u8 coderates[] = {
 646                                0x0, 0x01, 0x02, 0x04, 0x00,
 647                                0x8, 0x10, 0x20, 0x00, 0x3f
 648        };
 649
 650        u8 coderate_ptr;
 651        int status;
 652        u8 start_acq = 0x80;
 653        u8 reg, regs[3];
 654
 655        dprintk("%s\n", __func__);
 656
 657        status = PASS;
 658        coderate_ptr = coderates[crate];
 659
 660        si21xx_set_symbolrate(fe, symbrate);
 661
 662        /* write code rates to use in the Viterbi search */
 663        status |= si21_writeregs(state,
 664                                VIT_SRCH_CTRL_REG_1,
 665                                &coderate_ptr, 0x01);
 666
 667        /* clear acq_start bit */
 668        status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
 669        reg &= ~start_acq;
 670        status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
 671
 672        /* use new Carrier Frequency Offset Estimator (QuickLock) */
 673        regs[0] = 0xCB;
 674        regs[1] = 0x40;
 675        regs[2] = 0xCB;
 676
 677        status |= si21_writeregs(state,
 678                                TWO_DB_BNDWDTH_THRSHLD_REG,
 679                                &regs[0], 0x03);
 680        reg = 0x56;
 681        status |= si21_writeregs(state,
 682                                LSA_CTRL_REG_1, &reg, 1);
 683        reg = 0x05;
 684        status |= si21_writeregs(state,
 685                                BLIND_SCAN_CTRL_REG, &reg, 1);
 686        /* start automatic acq */
 687        status |= si21_writeregs(state,
 688                                ACQ_CTRL_REG_2, &start_acq, 0x01);
 689
 690        return status;
 691}
 692
 693static int si21xx_set_frontend(struct dvb_frontend *fe)
 694{
 695        struct si21xx_state *state = fe->demodulator_priv;
 696        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 697
 698        /* freq         Channel carrier frequency in KHz (i.e. 1550000 KHz)
 699         datarate       Channel symbol rate in Sps (i.e. 22500000 Sps)*/
 700
 701        /* in MHz */
 702        unsigned char coarse_tune_freq;
 703        int fine_tune_freq;
 704        unsigned char sample_rate = 0;
 705        /* boolean */
 706        bool inband_interferer_ind;
 707
 708        /* INTERMEDIATE VALUES */
 709        int icoarse_tune_freq; /* MHz */
 710        int ifine_tune_freq; /* MHz */
 711        unsigned int band_high;
 712        unsigned int band_low;
 713        unsigned int x1;
 714        unsigned int x2;
 715        int i;
 716        bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
 717        bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
 718        int status;
 719
 720        /* allowable sample rates for ADC in MHz */
 721        int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
 722                                        196, 204, 205, 206, 207
 723        };
 724        /* in MHz */
 725        int if_limit_high;
 726        int if_limit_low;
 727        int lnb_lo;
 728        int lnb_uncertanity;
 729
 730        int rf_freq;
 731        int data_rate;
 732        unsigned char regs[4];
 733
 734        dprintk("%s : FE_SET_FRONTEND\n", __func__);
 735
 736        if (c->delivery_system != SYS_DVBS) {
 737                        dprintk("%s: unsupported delivery system selected (%d)\n",
 738                                __func__, c->delivery_system);
 739                        return -EOPNOTSUPP;
 740        }
 741
 742        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
 743                inband_interferer_div2[i] = inband_interferer_div4[i] = false;
 744
 745        if_limit_high = -700000;
 746        if_limit_low = -100000;
 747        /* in MHz */
 748        lnb_lo = 0;
 749        lnb_uncertanity = 0;
 750
 751        rf_freq = 10 * c->frequency ;
 752        data_rate = c->symbol_rate / 100;
 753
 754        status = PASS;
 755
 756        band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
 757                                        + (data_rate * 135)) / 200;
 758
 759        band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
 760                                        + (data_rate * 135)) / 200;
 761
 762
 763        icoarse_tune_freq = 100000 *
 764                                (((rf_freq - lnb_lo) -
 765                                        (if_limit_low + if_limit_high) / 2)
 766                                                                / 100000);
 767
 768        ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
 769
 770        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 771                x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
 772                                        (afs[i] * 2500) + afs[i] * 2500;
 773
 774                x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
 775                                                        (afs[i] * 2500);
 776
 777                if (((band_low < x1) && (x1 < band_high)) ||
 778                                        ((band_low < x2) && (x2 < band_high)))
 779                                        inband_interferer_div4[i] = true;
 780
 781        }
 782
 783        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 784                x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
 785                                        (afs[i] * 5000) + afs[i] * 5000;
 786
 787                x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
 788                                        (afs[i] * 5000);
 789
 790                if (((band_low < x1) && (x1 < band_high)) ||
 791                                        ((band_low < x2) && (x2 < band_high)))
 792                                        inband_interferer_div2[i] = true;
 793        }
 794
 795        inband_interferer_ind = true;
 796        for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 797                if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
 798                        inband_interferer_ind = false;
 799                        break;
 800                }
 801        }
 802
 803        if (inband_interferer_ind) {
 804                for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 805                        if (!inband_interferer_div2[i]) {
 806                                sample_rate = (u8) afs[i];
 807                                break;
 808                        }
 809                }
 810        } else {
 811                for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
 812                        if ((inband_interferer_div2[i] ||
 813                             !inband_interferer_div4[i])) {
 814                                sample_rate = (u8) afs[i];
 815                                break;
 816                        }
 817                }
 818
 819        }
 820
 821        if (sample_rate > 207 || sample_rate < 192)
 822                sample_rate = 200;
 823
 824        fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
 825                                        ((sample_rate) * 1000));
 826
 827        coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
 828
 829        regs[0] = sample_rate;
 830        regs[1] = coarse_tune_freq;
 831        regs[2] = fine_tune_freq & 0xFF;
 832        regs[3] = fine_tune_freq >> 8 & 0xFF;
 833
 834        status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
 835
 836        state->fs = sample_rate;/*ADC MHz*/
 837        si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
 838
 839        return 0;
 840}
 841
 842static int si21xx_sleep(struct dvb_frontend *fe)
 843{
 844        struct si21xx_state *state = fe->demodulator_priv;
 845        u8 regdata;
 846
 847        dprintk("%s\n", __func__);
 848
 849        si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
 850        regdata |= 1 << 6;
 851        si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
 852        state->initialised = 0;
 853
 854        return 0;
 855}
 856
 857static void si21xx_release(struct dvb_frontend *fe)
 858{
 859        struct si21xx_state *state = fe->demodulator_priv;
 860
 861        dprintk("%s\n", __func__);
 862
 863        kfree(state);
 864}
 865
 866static struct dvb_frontend_ops si21xx_ops = {
 867        .delsys = { SYS_DVBS },
 868        .info = {
 869                .name                   = "SL SI21XX DVB-S",
 870                .frequency_min          = 950000,
 871                .frequency_max          = 2150000,
 872                .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
 873                .frequency_tolerance    = 0,
 874                .symbol_rate_min        = 1000000,
 875                .symbol_rate_max        = 45000000,
 876                .symbol_rate_tolerance  = 500,  /* ppm */
 877                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 878                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
 879                FE_CAN_QPSK |
 880                FE_CAN_FEC_AUTO
 881        },
 882
 883        .release = si21xx_release,
 884        .init = si21xx_init,
 885        .sleep = si21xx_sleep,
 886        .write = si21_write,
 887        .read_status = si21_read_status,
 888        .read_ber = si21_read_ber,
 889        .read_signal_strength = si21_read_signal_strength,
 890        .read_snr = si21_read_snr,
 891        .read_ucblocks = si21_read_ucblocks,
 892        .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
 893        .diseqc_send_burst = si21xx_send_diseqc_burst,
 894        .set_tone = si21xx_set_tone,
 895        .set_voltage = si21xx_set_voltage,
 896
 897        .set_frontend = si21xx_set_frontend,
 898};
 899
 900struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
 901                                                struct i2c_adapter *i2c)
 902{
 903        struct si21xx_state *state = NULL;
 904        int id;
 905
 906        dprintk("%s\n", __func__);
 907
 908        /* allocate memory for the internal state */
 909        state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
 910        if (state == NULL)
 911                goto error;
 912
 913        /* setup the state */
 914        state->config = config;
 915        state->i2c = i2c;
 916        state->initialised = 0;
 917        state->errmode = STATUS_BER;
 918
 919        /* check if the demod is there */
 920        id = si21_readreg(state, SYSTEM_MODE_REG);
 921        si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
 922        msleep(200);
 923        id = si21_readreg(state, 0x00);
 924
 925        /* register 0x00 contains:
 926                0x34 for SI2107
 927                0x24 for SI2108
 928                0x14 for SI2109
 929                0x04 for SI2110
 930        */
 931        if (id != 0x04 && id != 0x14)
 932                goto error;
 933
 934        /* create dvb_frontend */
 935        memcpy(&state->frontend.ops, &si21xx_ops,
 936                                        sizeof(struct dvb_frontend_ops));
 937        state->frontend.demodulator_priv = state;
 938        return &state->frontend;
 939
 940error:
 941        kfree(state);
 942        return NULL;
 943}
 944EXPORT_SYMBOL(si21xx_attach);
 945
 946module_param(debug, int, 0644);
 947MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 948
 949MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
 950MODULE_AUTHOR("Igor M. Liplianin");
 951MODULE_LICENSE("GPL");
 952