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