linux/drivers/media/dvb-frontends/stv0288.c
<<
>>
Prefs
   1/*
   2        Driver for ST STV0288 demodulator
   3        Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
   4                for Reel Multimedia
   5        Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
   6        Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
   7                Removed stb6000 specific tuner code and revised some
   8                procedures.
   9        2010-09-01 Josef Pavlik <josef@pavlik.it>
  10                Fixed diseqc_msg, diseqc_burst and set_tone problems
  11
  12        This program is free software; you can redistribute it and/or modify
  13        it under the terms of the GNU General Public License as published by
  14        the Free Software Foundation; either version 2 of the License, or
  15        (at your option) any later version.
  16
  17        This program is distributed in the hope that it will be useful,
  18        but WITHOUT ANY WARRANTY; without even the implied warranty of
  19        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20        GNU General Public License for more details.
  21
  22        You should have received a copy of the GNU General Public License
  23        along with this program; if not, write to the Free Software
  24        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25
  26*/
  27
  28#include <linux/init.h>
  29#include <linux/kernel.h>
  30#include <linux/module.h>
  31#include <linux/string.h>
  32#include <linux/slab.h>
  33#include <linux/jiffies.h>
  34#include <asm/div64.h>
  35
  36#include "dvb_frontend.h"
  37#include "stv0288.h"
  38
  39struct stv0288_state {
  40        struct i2c_adapter *i2c;
  41        const struct stv0288_config *config;
  42        struct dvb_frontend frontend;
  43
  44        u8 initialised:1;
  45        u32 tuner_frequency;
  46        u32 symbol_rate;
  47        enum fe_code_rate fec_inner;
  48        int errmode;
  49};
  50
  51#define STATUS_BER 0
  52#define STATUS_UCBLOCKS 1
  53
  54static int debug;
  55static int debug_legacy_dish_switch;
  56#define dprintk(args...) \
  57        do { \
  58                if (debug) \
  59                        printk(KERN_DEBUG "stv0288: " args); \
  60        } while (0)
  61
  62
  63static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
  64{
  65        int ret;
  66        u8 buf[] = { reg, data };
  67        struct i2c_msg msg = {
  68                .addr = state->config->demod_address,
  69                .flags = 0,
  70                .buf = buf,
  71                .len = 2
  72        };
  73
  74        ret = i2c_transfer(state->i2c, &msg, 1);
  75
  76        if (ret != 1)
  77                dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
  78                        __func__, reg, data, ret);
  79
  80        return (ret != 1) ? -EREMOTEIO : 0;
  81}
  82
  83static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len)
  84{
  85        struct stv0288_state *state = fe->demodulator_priv;
  86
  87        if (len != 2)
  88                return -EINVAL;
  89
  90        return stv0288_writeregI(state, buf[0], buf[1]);
  91}
  92
  93static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
  94{
  95        int ret;
  96        u8 b0[] = { reg };
  97        u8 b1[] = { 0 };
  98        struct i2c_msg msg[] = {
  99                {
 100                        .addr = state->config->demod_address,
 101                        .flags = 0,
 102                        .buf = b0,
 103                        .len = 1
 104                }, {
 105                        .addr = state->config->demod_address,
 106                        .flags = I2C_M_RD,
 107                        .buf = b1,
 108                        .len = 1
 109                }
 110        };
 111
 112        ret = i2c_transfer(state->i2c, msg, 2);
 113
 114        if (ret != 2)
 115                dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
 116                                __func__, reg, ret);
 117
 118        return b1[0];
 119}
 120
 121static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
 122{
 123        struct stv0288_state *state = fe->demodulator_priv;
 124        unsigned int temp;
 125        unsigned char b[3];
 126
 127        if ((srate < 1000000) || (srate > 45000000))
 128                return -EINVAL;
 129
 130        stv0288_writeregI(state, 0x22, 0);
 131        stv0288_writeregI(state, 0x23, 0);
 132        stv0288_writeregI(state, 0x2b, 0xff);
 133        stv0288_writeregI(state, 0x2c, 0xf7);
 134
 135        temp = (unsigned int)srate / 1000;
 136
 137        temp = temp * 32768;
 138        temp = temp / 25;
 139        temp = temp / 125;
 140        b[0] = (unsigned char)((temp >> 12) & 0xff);
 141        b[1] = (unsigned char)((temp >> 4) & 0xff);
 142        b[2] = (unsigned char)((temp << 4) & 0xf0);
 143        stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
 144        stv0288_writeregI(state, 0x29, 0); /* SFRM */
 145        stv0288_writeregI(state, 0x2a, 0); /* SFRL */
 146
 147        stv0288_writeregI(state, 0x28, b[0]);
 148        stv0288_writeregI(state, 0x29, b[1]);
 149        stv0288_writeregI(state, 0x2a, b[2]);
 150        dprintk("stv0288: stv0288_set_symbolrate\n");
 151
 152        return 0;
 153}
 154
 155static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
 156                                    struct dvb_diseqc_master_cmd *m)
 157{
 158        struct stv0288_state *state = fe->demodulator_priv;
 159
 160        int i;
 161
 162        dprintk("%s\n", __func__);
 163
 164        stv0288_writeregI(state, 0x09, 0);
 165        msleep(30);
 166        stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */
 167
 168        for (i = 0; i < m->msg_len; i++) {
 169                if (stv0288_writeregI(state, 0x06, m->msg[i]))
 170                        return -EREMOTEIO;
 171        }
 172        msleep(m->msg_len*12);
 173        return 0;
 174}
 175
 176static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
 177                                     enum fe_sec_mini_cmd burst)
 178{
 179        struct stv0288_state *state = fe->demodulator_priv;
 180
 181        dprintk("%s\n", __func__);
 182
 183        if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */
 184                return -EREMOTEIO;
 185
 186        if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
 187                return -EREMOTEIO;
 188
 189        msleep(15);
 190        if (stv0288_writeregI(state, 0x05, 0x12))
 191                return -EREMOTEIO;
 192
 193        return 0;
 194}
 195
 196static int stv0288_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
 197{
 198        struct stv0288_state *state = fe->demodulator_priv;
 199
 200        switch (tone) {
 201        case SEC_TONE_ON:
 202                if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */
 203                        return -EREMOTEIO;
 204        break;
 205
 206        case SEC_TONE_OFF:
 207                if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/
 208                        return -EREMOTEIO;
 209        break;
 210
 211        default:
 212                return -EINVAL;
 213        }
 214        return 0;
 215}
 216
 217static u8 stv0288_inittab[] = {
 218        0x01, 0x15,
 219        0x02, 0x20,
 220        0x09, 0x0,
 221        0x0a, 0x4,
 222        0x0b, 0x0,
 223        0x0c, 0x0,
 224        0x0d, 0x0,
 225        0x0e, 0xd4,
 226        0x0f, 0x30,
 227        0x11, 0x80,
 228        0x12, 0x03,
 229        0x13, 0x48,
 230        0x14, 0x84,
 231        0x15, 0x45,
 232        0x16, 0xb7,
 233        0x17, 0x9c,
 234        0x18, 0x0,
 235        0x19, 0xa6,
 236        0x1a, 0x88,
 237        0x1b, 0x8f,
 238        0x1c, 0xf0,
 239        0x20, 0x0b,
 240        0x21, 0x54,
 241        0x22, 0x0,
 242        0x23, 0x0,
 243        0x2b, 0xff,
 244        0x2c, 0xf7,
 245        0x30, 0x0,
 246        0x31, 0x1e,
 247        0x32, 0x14,
 248        0x33, 0x0f,
 249        0x34, 0x09,
 250        0x35, 0x0c,
 251        0x36, 0x05,
 252        0x37, 0x2f,
 253        0x38, 0x16,
 254        0x39, 0xbe,
 255        0x3a, 0x0,
 256        0x3b, 0x13,
 257        0x3c, 0x11,
 258        0x3d, 0x30,
 259        0x40, 0x63,
 260        0x41, 0x04,
 261        0x42, 0x20,
 262        0x43, 0x00,
 263        0x44, 0x00,
 264        0x45, 0x00,
 265        0x46, 0x00,
 266        0x47, 0x00,
 267        0x4a, 0x00,
 268        0x50, 0x10,
 269        0x51, 0x38,
 270        0x52, 0x21,
 271        0x58, 0x54,
 272        0x59, 0x86,
 273        0x5a, 0x0,
 274        0x5b, 0x9b,
 275        0x5c, 0x08,
 276        0x5d, 0x7f,
 277        0x5e, 0x0,
 278        0x5f, 0xff,
 279        0x70, 0x0,
 280        0x71, 0x0,
 281        0x72, 0x0,
 282        0x74, 0x0,
 283        0x75, 0x0,
 284        0x76, 0x0,
 285        0x81, 0x0,
 286        0x82, 0x3f,
 287        0x83, 0x3f,
 288        0x84, 0x0,
 289        0x85, 0x0,
 290        0x88, 0x0,
 291        0x89, 0x0,
 292        0x8a, 0x0,
 293        0x8b, 0x0,
 294        0x8c, 0x0,
 295        0x90, 0x0,
 296        0x91, 0x0,
 297        0x92, 0x0,
 298        0x93, 0x0,
 299        0x94, 0x1c,
 300        0x97, 0x0,
 301        0xa0, 0x48,
 302        0xa1, 0x0,
 303        0xb0, 0xb8,
 304        0xb1, 0x3a,
 305        0xb2, 0x10,
 306        0xb3, 0x82,
 307        0xb4, 0x80,
 308        0xb5, 0x82,
 309        0xb6, 0x82,
 310        0xb7, 0x82,
 311        0xb8, 0x20,
 312        0xb9, 0x0,
 313        0xf0, 0x0,
 314        0xf1, 0x0,
 315        0xf2, 0xc0,
 316        0x51, 0x36,
 317        0x52, 0x09,
 318        0x53, 0x94,
 319        0x54, 0x62,
 320        0x55, 0x29,
 321        0x56, 0x64,
 322        0x57, 0x2b,
 323        0xff, 0xff,
 324};
 325
 326static int stv0288_set_voltage(struct dvb_frontend *fe,
 327                               enum fe_sec_voltage volt)
 328{
 329        dprintk("%s: %s\n", __func__,
 330                volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
 331                volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
 332
 333        return 0;
 334}
 335
 336static int stv0288_init(struct dvb_frontend *fe)
 337{
 338        struct stv0288_state *state = fe->demodulator_priv;
 339        int i;
 340        u8 reg;
 341        u8 val;
 342
 343        dprintk("stv0288: init chip\n");
 344        stv0288_writeregI(state, 0x41, 0x04);
 345        msleep(50);
 346
 347        /* we have default inittab */
 348        if (state->config->inittab == NULL) {
 349                for (i = 0; !(stv0288_inittab[i] == 0xff &&
 350                                stv0288_inittab[i + 1] == 0xff); i += 2)
 351                        stv0288_writeregI(state, stv0288_inittab[i],
 352                                        stv0288_inittab[i + 1]);
 353        } else {
 354                for (i = 0; ; i += 2)  {
 355                        reg = state->config->inittab[i];
 356                        val = state->config->inittab[i+1];
 357                        if (reg == 0xff && val == 0xff)
 358                                break;
 359                        stv0288_writeregI(state, reg, val);
 360                }
 361        }
 362        return 0;
 363}
 364
 365static int stv0288_read_status(struct dvb_frontend *fe, enum fe_status *status)
 366{
 367        struct stv0288_state *state = fe->demodulator_priv;
 368
 369        u8 sync = stv0288_readreg(state, 0x24);
 370        if (sync == 255)
 371                sync = 0;
 372
 373        dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
 374
 375        *status = 0;
 376        if (sync & 0x80)
 377                *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
 378        if (sync & 0x10)
 379                *status |= FE_HAS_VITERBI;
 380        if (sync & 0x08) {
 381                *status |= FE_HAS_LOCK;
 382                dprintk("stv0288 has locked\n");
 383        }
 384
 385        return 0;
 386}
 387
 388static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
 389{
 390        struct stv0288_state *state = fe->demodulator_priv;
 391
 392        if (state->errmode != STATUS_BER)
 393                return 0;
 394        *ber = (stv0288_readreg(state, 0x26) << 8) |
 395                                        stv0288_readreg(state, 0x27);
 396        dprintk("stv0288_read_ber %d\n", *ber);
 397
 398        return 0;
 399}
 400
 401
 402static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 403{
 404        struct stv0288_state *state = fe->demodulator_priv;
 405
 406        s32 signal =  0xffff - ((stv0288_readreg(state, 0x10) << 8));
 407
 408
 409        signal = signal * 5 / 4;
 410        *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
 411        dprintk("stv0288_read_signal_strength %d\n", *strength);
 412
 413        return 0;
 414}
 415static int stv0288_sleep(struct dvb_frontend *fe)
 416{
 417        struct stv0288_state *state = fe->demodulator_priv;
 418
 419        stv0288_writeregI(state, 0x41, 0x84);
 420        state->initialised = 0;
 421
 422        return 0;
 423}
 424static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
 425{
 426        struct stv0288_state *state = fe->demodulator_priv;
 427
 428        s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
 429                           | stv0288_readreg(state, 0x2e));
 430        xsnr = 3 * (xsnr - 0xa100);
 431        *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
 432        dprintk("stv0288_read_snr %d\n", *snr);
 433
 434        return 0;
 435}
 436
 437static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 438{
 439        struct stv0288_state *state = fe->demodulator_priv;
 440
 441        if (state->errmode != STATUS_BER)
 442                return 0;
 443        *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
 444                                        stv0288_readreg(state, 0x27);
 445        dprintk("stv0288_read_ber %d\n", *ucblocks);
 446
 447        return 0;
 448}
 449
 450static int stv0288_set_frontend(struct dvb_frontend *fe)
 451{
 452        struct stv0288_state *state = fe->demodulator_priv;
 453        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 454
 455        char tm;
 456        unsigned char tda[3];
 457        u8 reg, time_out = 0;
 458
 459        dprintk("%s : FE_SET_FRONTEND\n", __func__);
 460
 461        if (c->delivery_system != SYS_DVBS) {
 462                dprintk("%s: unsupported delivery system selected (%d)\n",
 463                        __func__, c->delivery_system);
 464                return -EOPNOTSUPP;
 465        }
 466
 467        if (state->config->set_ts_params)
 468                state->config->set_ts_params(fe, 0);
 469
 470        /* only frequency & symbol_rate are used for tuner*/
 471        if (fe->ops.tuner_ops.set_params) {
 472                fe->ops.tuner_ops.set_params(fe);
 473                if (fe->ops.i2c_gate_ctrl)
 474                        fe->ops.i2c_gate_ctrl(fe, 0);
 475        }
 476
 477        udelay(10);
 478        stv0288_set_symbolrate(fe, c->symbol_rate);
 479        /* Carrier lock control register */
 480        stv0288_writeregI(state, 0x15, 0xc5);
 481
 482        tda[2] = 0x0; /* CFRL */
 483        for (tm = -9; tm < 7;) {
 484                /* Viterbi status */
 485                reg = stv0288_readreg(state, 0x24);
 486                if (reg & 0x8)
 487                                break;
 488                if (reg & 0x80) {
 489                        time_out++;
 490                        if (time_out > 10)
 491                                break;
 492                        tda[2] += 40;
 493                        if (tda[2] < 40)
 494                                tm++;
 495                } else {
 496                        tm++;
 497                        tda[2] = 0;
 498                        time_out = 0;
 499                }
 500                tda[1] = (unsigned char)tm;
 501                stv0288_writeregI(state, 0x2b, tda[1]);
 502                stv0288_writeregI(state, 0x2c, tda[2]);
 503                msleep(30);
 504        }
 505        state->tuner_frequency = c->frequency;
 506        state->fec_inner = FEC_AUTO;
 507        state->symbol_rate = c->symbol_rate;
 508
 509        return 0;
 510}
 511
 512static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 513{
 514        struct stv0288_state *state = fe->demodulator_priv;
 515
 516        if (enable)
 517                stv0288_writeregI(state, 0x01, 0xb5);
 518        else
 519                stv0288_writeregI(state, 0x01, 0x35);
 520
 521        udelay(1);
 522
 523        return 0;
 524}
 525
 526static void stv0288_release(struct dvb_frontend *fe)
 527{
 528        struct stv0288_state *state = fe->demodulator_priv;
 529        kfree(state);
 530}
 531
 532static const struct dvb_frontend_ops stv0288_ops = {
 533        .delsys = { SYS_DVBS },
 534        .info = {
 535                .name                   = "ST STV0288 DVB-S",
 536                .frequency_min          = 950000,
 537                .frequency_max          = 2150000,
 538                .frequency_stepsize     = 1000,  /* kHz for QPSK frontends */
 539                .frequency_tolerance    = 0,
 540                .symbol_rate_min        = 1000000,
 541                .symbol_rate_max        = 45000000,
 542                .symbol_rate_tolerance  = 500,  /* ppm */
 543                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 544                      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
 545                      FE_CAN_QPSK |
 546                      FE_CAN_FEC_AUTO
 547        },
 548
 549        .release = stv0288_release,
 550        .init = stv0288_init,
 551        .sleep = stv0288_sleep,
 552        .write = stv0288_write,
 553        .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
 554        .read_status = stv0288_read_status,
 555        .read_ber = stv0288_read_ber,
 556        .read_signal_strength = stv0288_read_signal_strength,
 557        .read_snr = stv0288_read_snr,
 558        .read_ucblocks = stv0288_read_ucblocks,
 559        .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
 560        .diseqc_send_burst = stv0288_send_diseqc_burst,
 561        .set_tone = stv0288_set_tone,
 562        .set_voltage = stv0288_set_voltage,
 563
 564        .set_frontend = stv0288_set_frontend,
 565};
 566
 567struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
 568                                    struct i2c_adapter *i2c)
 569{
 570        struct stv0288_state *state = NULL;
 571        int id;
 572
 573        /* allocate memory for the internal state */
 574        state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
 575        if (state == NULL)
 576                goto error;
 577
 578        /* setup the state */
 579        state->config = config;
 580        state->i2c = i2c;
 581        state->initialised = 0;
 582        state->tuner_frequency = 0;
 583        state->symbol_rate = 0;
 584        state->fec_inner = 0;
 585        state->errmode = STATUS_BER;
 586
 587        stv0288_writeregI(state, 0x41, 0x04);
 588        msleep(200);
 589        id = stv0288_readreg(state, 0x00);
 590        dprintk("stv0288 id %x\n", id);
 591
 592        /* register 0x00 contains 0x11 for STV0288  */
 593        if (id != 0x11)
 594                goto error;
 595
 596        /* create dvb_frontend */
 597        memcpy(&state->frontend.ops, &stv0288_ops,
 598                        sizeof(struct dvb_frontend_ops));
 599        state->frontend.demodulator_priv = state;
 600        return &state->frontend;
 601
 602error:
 603        kfree(state);
 604
 605        return NULL;
 606}
 607EXPORT_SYMBOL(stv0288_attach);
 608
 609module_param(debug_legacy_dish_switch, int, 0444);
 610MODULE_PARM_DESC(debug_legacy_dish_switch,
 611                "Enable timing analysis for Dish Network legacy switches");
 612
 613module_param(debug, int, 0644);
 614MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 615
 616MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
 617MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
 618MODULE_LICENSE("GPL");
 619
 620