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        fe_code_rate_t 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, "
  78                        "ret == %i)\n", __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                                                fe_sec_mini_cmd_t 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, fe_sec_tone_mode_t 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, fe_sec_voltage_t volt)
 327{
 328        dprintk("%s: %s\n", __func__,
 329                volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
 330                volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
 331
 332        return 0;
 333}
 334
 335static int stv0288_init(struct dvb_frontend *fe)
 336{
 337        struct stv0288_state *state = fe->demodulator_priv;
 338        int i;
 339        u8 reg;
 340        u8 val;
 341
 342        dprintk("stv0288: init chip\n");
 343        stv0288_writeregI(state, 0x41, 0x04);
 344        msleep(50);
 345
 346        /* we have default inittab */
 347        if (state->config->inittab == NULL) {
 348                for (i = 0; !(stv0288_inittab[i] == 0xff &&
 349                                stv0288_inittab[i + 1] == 0xff); i += 2)
 350                        stv0288_writeregI(state, stv0288_inittab[i],
 351                                        stv0288_inittab[i + 1]);
 352        } else {
 353                for (i = 0; ; i += 2)  {
 354                        reg = state->config->inittab[i];
 355                        val = state->config->inittab[i+1];
 356                        if (reg == 0xff && val == 0xff)
 357                                break;
 358                        stv0288_writeregI(state, reg, val);
 359                }
 360        }
 361        return 0;
 362}
 363
 364static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
 365{
 366        struct stv0288_state *state = fe->demodulator_priv;
 367
 368        u8 sync = stv0288_readreg(state, 0x24);
 369        if (sync == 255)
 370                sync = 0;
 371
 372        dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
 373
 374        *status = 0;
 375        if (sync & 0x80)
 376                *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
 377        if (sync & 0x10)
 378                *status |= FE_HAS_VITERBI;
 379        if (sync & 0x08) {
 380                *status |= FE_HAS_LOCK;
 381                dprintk("stv0288 has locked\n");
 382        }
 383
 384        return 0;
 385}
 386
 387static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
 388{
 389        struct stv0288_state *state = fe->demodulator_priv;
 390
 391        if (state->errmode != STATUS_BER)
 392                return 0;
 393        *ber = (stv0288_readreg(state, 0x26) << 8) |
 394                                        stv0288_readreg(state, 0x27);
 395        dprintk("stv0288_read_ber %d\n", *ber);
 396
 397        return 0;
 398}
 399
 400
 401static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 402{
 403        struct stv0288_state *state = fe->demodulator_priv;
 404
 405        s32 signal =  0xffff - ((stv0288_readreg(state, 0x10) << 8));
 406
 407
 408        signal = signal * 5 / 4;
 409        *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
 410        dprintk("stv0288_read_signal_strength %d\n", *strength);
 411
 412        return 0;
 413}
 414static int stv0288_sleep(struct dvb_frontend *fe)
 415{
 416        struct stv0288_state *state = fe->demodulator_priv;
 417
 418        stv0288_writeregI(state, 0x41, 0x84);
 419        state->initialised = 0;
 420
 421        return 0;
 422}
 423static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
 424{
 425        struct stv0288_state *state = fe->demodulator_priv;
 426
 427        s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
 428                           | stv0288_readreg(state, 0x2e));
 429        xsnr = 3 * (xsnr - 0xa100);
 430        *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
 431        dprintk("stv0288_read_snr %d\n", *snr);
 432
 433        return 0;
 434}
 435
 436static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 437{
 438        struct stv0288_state *state = fe->demodulator_priv;
 439
 440        if (state->errmode != STATUS_BER)
 441                return 0;
 442        *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
 443                                        stv0288_readreg(state, 0x27);
 444        dprintk("stv0288_read_ber %d\n", *ucblocks);
 445
 446        return 0;
 447}
 448
 449static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
 450{
 451        dprintk("%s(..)\n", __func__);
 452        return 0;
 453}
 454
 455static int stv0288_set_frontend(struct dvb_frontend *fe)
 456{
 457        struct stv0288_state *state = fe->demodulator_priv;
 458        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 459
 460        char tm;
 461        unsigned char tda[3];
 462        u8 reg, time_out = 0;
 463
 464        dprintk("%s : FE_SET_FRONTEND\n", __func__);
 465
 466        if (c->delivery_system != SYS_DVBS) {
 467                        dprintk("%s: unsupported delivery "
 468                                "system selected (%d)\n",
 469                                __func__, c->delivery_system);
 470                        return -EOPNOTSUPP;
 471        }
 472
 473        if (state->config->set_ts_params)
 474                state->config->set_ts_params(fe, 0);
 475
 476        /* only frequency & symbol_rate are used for tuner*/
 477        if (fe->ops.tuner_ops.set_params) {
 478                fe->ops.tuner_ops.set_params(fe);
 479                if (fe->ops.i2c_gate_ctrl)
 480                        fe->ops.i2c_gate_ctrl(fe, 0);
 481        }
 482
 483        udelay(10);
 484        stv0288_set_symbolrate(fe, c->symbol_rate);
 485        /* Carrier lock control register */
 486        stv0288_writeregI(state, 0x15, 0xc5);
 487
 488        tda[2] = 0x0; /* CFRL */
 489        for (tm = -9; tm < 7;) {
 490                /* Viterbi status */
 491                reg = stv0288_readreg(state, 0x24);
 492                if (reg & 0x8)
 493                                break;
 494                if (reg & 0x80) {
 495                        time_out++;
 496                        if (time_out > 10)
 497                                break;
 498                        tda[2] += 40;
 499                        if (tda[2] < 40)
 500                                tm++;
 501                } else {
 502                        tm++;
 503                        tda[2] = 0;
 504                        time_out = 0;
 505                }
 506                tda[1] = (unsigned char)tm;
 507                stv0288_writeregI(state, 0x2b, tda[1]);
 508                stv0288_writeregI(state, 0x2c, tda[2]);
 509                msleep(30);
 510        }
 511        state->tuner_frequency = c->frequency;
 512        state->fec_inner = FEC_AUTO;
 513        state->symbol_rate = c->symbol_rate;
 514
 515        return 0;
 516}
 517
 518static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 519{
 520        struct stv0288_state *state = fe->demodulator_priv;
 521
 522        if (enable)
 523                stv0288_writeregI(state, 0x01, 0xb5);
 524        else
 525                stv0288_writeregI(state, 0x01, 0x35);
 526
 527        udelay(1);
 528
 529        return 0;
 530}
 531
 532static void stv0288_release(struct dvb_frontend *fe)
 533{
 534        struct stv0288_state *state = fe->demodulator_priv;
 535        kfree(state);
 536}
 537
 538static struct dvb_frontend_ops stv0288_ops = {
 539        .delsys = { SYS_DVBS },
 540        .info = {
 541                .name                   = "ST STV0288 DVB-S",
 542                .frequency_min          = 950000,
 543                .frequency_max          = 2150000,
 544                .frequency_stepsize     = 1000,  /* kHz for QPSK frontends */
 545                .frequency_tolerance    = 0,
 546                .symbol_rate_min        = 1000000,
 547                .symbol_rate_max        = 45000000,
 548                .symbol_rate_tolerance  = 500,  /* ppm */
 549                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 550                      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
 551                      FE_CAN_QPSK |
 552                      FE_CAN_FEC_AUTO
 553        },
 554
 555        .release = stv0288_release,
 556        .init = stv0288_init,
 557        .sleep = stv0288_sleep,
 558        .write = stv0288_write,
 559        .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
 560        .read_status = stv0288_read_status,
 561        .read_ber = stv0288_read_ber,
 562        .read_signal_strength = stv0288_read_signal_strength,
 563        .read_snr = stv0288_read_snr,
 564        .read_ucblocks = stv0288_read_ucblocks,
 565        .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
 566        .diseqc_send_burst = stv0288_send_diseqc_burst,
 567        .set_tone = stv0288_set_tone,
 568        .set_voltage = stv0288_set_voltage,
 569
 570        .set_property = stv0288_set_property,
 571        .set_frontend = stv0288_set_frontend,
 572};
 573
 574struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
 575                                    struct i2c_adapter *i2c)
 576{
 577        struct stv0288_state *state = NULL;
 578        int id;
 579
 580        /* allocate memory for the internal state */
 581        state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
 582        if (state == NULL)
 583                goto error;
 584
 585        /* setup the state */
 586        state->config = config;
 587        state->i2c = i2c;
 588        state->initialised = 0;
 589        state->tuner_frequency = 0;
 590        state->symbol_rate = 0;
 591        state->fec_inner = 0;
 592        state->errmode = STATUS_BER;
 593
 594        stv0288_writeregI(state, 0x41, 0x04);
 595        msleep(200);
 596        id = stv0288_readreg(state, 0x00);
 597        dprintk("stv0288 id %x\n", id);
 598
 599        /* register 0x00 contains 0x11 for STV0288  */
 600        if (id != 0x11)
 601                goto error;
 602
 603        /* create dvb_frontend */
 604        memcpy(&state->frontend.ops, &stv0288_ops,
 605                        sizeof(struct dvb_frontend_ops));
 606        state->frontend.demodulator_priv = state;
 607        return &state->frontend;
 608
 609error:
 610        kfree(state);
 611
 612        return NULL;
 613}
 614EXPORT_SYMBOL(stv0288_attach);
 615
 616module_param(debug_legacy_dish_switch, int, 0444);
 617MODULE_PARM_DESC(debug_legacy_dish_switch,
 618                "Enable timing analysis for Dish Network legacy switches");
 619
 620module_param(debug, int, 0644);
 621MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 622
 623MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
 624MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
 625MODULE_LICENSE("GPL");
 626
 627