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        temp = (unsigned int)srate / 1000;
 131
 132                temp = temp * 32768;
 133                temp = temp / 25;
 134                temp = temp / 125;
 135                b[0] = (unsigned char)((temp >> 12) & 0xff);
 136                b[1] = (unsigned char)((temp >> 4) & 0xff);
 137                b[2] = (unsigned char)((temp << 4) & 0xf0);
 138                stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
 139                stv0288_writeregI(state, 0x29, 0); /* SFRM */
 140                stv0288_writeregI(state, 0x2a, 0); /* SFRL */
 141
 142                stv0288_writeregI(state, 0x28, b[0]);
 143                stv0288_writeregI(state, 0x29, b[1]);
 144                stv0288_writeregI(state, 0x2a, b[2]);
 145                dprintk("stv0288: stv0288_set_symbolrate\n");
 146
 147        return 0;
 148}
 149
 150static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
 151                                    struct dvb_diseqc_master_cmd *m)
 152{
 153        struct stv0288_state *state = fe->demodulator_priv;
 154
 155        int i;
 156
 157        dprintk("%s\n", __func__);
 158
 159        stv0288_writeregI(state, 0x09, 0);
 160        msleep(30);
 161        stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */
 162
 163        for (i = 0; i < m->msg_len; i++) {
 164                if (stv0288_writeregI(state, 0x06, m->msg[i]))
 165                        return -EREMOTEIO;
 166        }
 167        msleep(m->msg_len*12);
 168        return 0;
 169}
 170
 171static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
 172                                                fe_sec_mini_cmd_t burst)
 173{
 174        struct stv0288_state *state = fe->demodulator_priv;
 175
 176        dprintk("%s\n", __func__);
 177
 178        if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */
 179                return -EREMOTEIO;
 180
 181        if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
 182                return -EREMOTEIO;
 183
 184        msleep(15);
 185        if (stv0288_writeregI(state, 0x05, 0x12))
 186                return -EREMOTEIO;
 187
 188        return 0;
 189}
 190
 191static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
 192{
 193        struct stv0288_state *state = fe->demodulator_priv;
 194
 195        switch (tone) {
 196        case SEC_TONE_ON:
 197                if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */
 198                        return -EREMOTEIO;
 199        break;
 200
 201        case SEC_TONE_OFF:
 202                if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/
 203                        return -EREMOTEIO;
 204        break;
 205
 206        default:
 207                return -EINVAL;
 208        }
 209        return 0;
 210}
 211
 212static u8 stv0288_inittab[] = {
 213        0x01, 0x15,
 214        0x02, 0x20,
 215        0x09, 0x0,
 216        0x0a, 0x4,
 217        0x0b, 0x0,
 218        0x0c, 0x0,
 219        0x0d, 0x0,
 220        0x0e, 0xd4,
 221        0x0f, 0x30,
 222        0x11, 0x80,
 223        0x12, 0x03,
 224        0x13, 0x48,
 225        0x14, 0x84,
 226        0x15, 0x45,
 227        0x16, 0xb7,
 228        0x17, 0x9c,
 229        0x18, 0x0,
 230        0x19, 0xa6,
 231        0x1a, 0x88,
 232        0x1b, 0x8f,
 233        0x1c, 0xf0,
 234        0x20, 0x0b,
 235        0x21, 0x54,
 236        0x22, 0x0,
 237        0x23, 0x0,
 238        0x2b, 0xff,
 239        0x2c, 0xf7,
 240        0x30, 0x0,
 241        0x31, 0x1e,
 242        0x32, 0x14,
 243        0x33, 0x0f,
 244        0x34, 0x09,
 245        0x35, 0x0c,
 246        0x36, 0x05,
 247        0x37, 0x2f,
 248        0x38, 0x16,
 249        0x39, 0xbe,
 250        0x3a, 0x0,
 251        0x3b, 0x13,
 252        0x3c, 0x11,
 253        0x3d, 0x30,
 254        0x40, 0x63,
 255        0x41, 0x04,
 256        0x42, 0x60,
 257        0x43, 0x00,
 258        0x44, 0x00,
 259        0x45, 0x00,
 260        0x46, 0x00,
 261        0x47, 0x00,
 262        0x4a, 0x00,
 263        0x50, 0x10,
 264        0x51, 0x38,
 265        0x52, 0x21,
 266        0x58, 0x54,
 267        0x59, 0x86,
 268        0x5a, 0x0,
 269        0x5b, 0x9b,
 270        0x5c, 0x08,
 271        0x5d, 0x7f,
 272        0x5e, 0x0,
 273        0x5f, 0xff,
 274        0x70, 0x0,
 275        0x71, 0x0,
 276        0x72, 0x0,
 277        0x74, 0x0,
 278        0x75, 0x0,
 279        0x76, 0x0,
 280        0x81, 0x0,
 281        0x82, 0x3f,
 282        0x83, 0x3f,
 283        0x84, 0x0,
 284        0x85, 0x0,
 285        0x88, 0x0,
 286        0x89, 0x0,
 287        0x8a, 0x0,
 288        0x8b, 0x0,
 289        0x8c, 0x0,
 290        0x90, 0x0,
 291        0x91, 0x0,
 292        0x92, 0x0,
 293        0x93, 0x0,
 294        0x94, 0x1c,
 295        0x97, 0x0,
 296        0xa0, 0x48,
 297        0xa1, 0x0,
 298        0xb0, 0xb8,
 299        0xb1, 0x3a,
 300        0xb2, 0x10,
 301        0xb3, 0x82,
 302        0xb4, 0x80,
 303        0xb5, 0x82,
 304        0xb6, 0x82,
 305        0xb7, 0x82,
 306        0xb8, 0x20,
 307        0xb9, 0x0,
 308        0xf0, 0x0,
 309        0xf1, 0x0,
 310        0xf2, 0xc0,
 311        0x51, 0x36,
 312        0x52, 0x09,
 313        0x53, 0x94,
 314        0x54, 0x62,
 315        0x55, 0x29,
 316        0x56, 0x64,
 317        0x57, 0x2b,
 318        0xff, 0xff,
 319};
 320
 321static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
 322{
 323        dprintk("%s: %s\n", __func__,
 324                volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
 325                volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
 326
 327        return 0;
 328}
 329
 330static int stv0288_init(struct dvb_frontend *fe)
 331{
 332        struct stv0288_state *state = fe->demodulator_priv;
 333        int i;
 334        u8 reg;
 335        u8 val;
 336
 337        dprintk("stv0288: init chip\n");
 338        stv0288_writeregI(state, 0x41, 0x04);
 339        msleep(50);
 340
 341        /* we have default inittab */
 342        if (state->config->inittab == NULL) {
 343                for (i = 0; !(stv0288_inittab[i] == 0xff &&
 344                                stv0288_inittab[i + 1] == 0xff); i += 2)
 345                        stv0288_writeregI(state, stv0288_inittab[i],
 346                                        stv0288_inittab[i + 1]);
 347        } else {
 348                for (i = 0; ; i += 2)  {
 349                        reg = state->config->inittab[i];
 350                        val = state->config->inittab[i+1];
 351                        if (reg == 0xff && val == 0xff)
 352                                break;
 353                        stv0288_writeregI(state, reg, val);
 354                }
 355        }
 356        return 0;
 357}
 358
 359static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
 360{
 361        struct stv0288_state *state = fe->demodulator_priv;
 362
 363        u8 sync = stv0288_readreg(state, 0x24);
 364        if (sync == 255)
 365                sync = 0;
 366
 367        dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
 368
 369        *status = 0;
 370
 371        if ((sync & 0x08) == 0x08) {
 372                *status |= FE_HAS_LOCK;
 373                dprintk("stv0288 has locked\n");
 374        }
 375
 376        return 0;
 377}
 378
 379static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
 380{
 381        struct stv0288_state *state = fe->demodulator_priv;
 382
 383        if (state->errmode != STATUS_BER)
 384                return 0;
 385        *ber = (stv0288_readreg(state, 0x26) << 8) |
 386                                        stv0288_readreg(state, 0x27);
 387        dprintk("stv0288_read_ber %d\n", *ber);
 388
 389        return 0;
 390}
 391
 392
 393static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 394{
 395        struct stv0288_state *state = fe->demodulator_priv;
 396
 397        s32 signal =  0xffff - ((stv0288_readreg(state, 0x10) << 8));
 398
 399
 400        signal = signal * 5 / 4;
 401        *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
 402        dprintk("stv0288_read_signal_strength %d\n", *strength);
 403
 404        return 0;
 405}
 406static int stv0288_sleep(struct dvb_frontend *fe)
 407{
 408        struct stv0288_state *state = fe->demodulator_priv;
 409
 410        stv0288_writeregI(state, 0x41, 0x84);
 411        state->initialised = 0;
 412
 413        return 0;
 414}
 415static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
 416{
 417        struct stv0288_state *state = fe->demodulator_priv;
 418
 419        s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
 420                           | stv0288_readreg(state, 0x2e));
 421        xsnr = 3 * (xsnr - 0xa100);
 422        *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
 423        dprintk("stv0288_read_snr %d\n", *snr);
 424
 425        return 0;
 426}
 427
 428static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 429{
 430        struct stv0288_state *state = fe->demodulator_priv;
 431
 432        if (state->errmode != STATUS_BER)
 433                return 0;
 434        *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
 435                                        stv0288_readreg(state, 0x27);
 436        dprintk("stv0288_read_ber %d\n", *ucblocks);
 437
 438        return 0;
 439}
 440
 441static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
 442{
 443        dprintk("%s(..)\n", __func__);
 444        return 0;
 445}
 446
 447static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p)
 448{
 449        dprintk("%s(..)\n", __func__);
 450        return 0;
 451}
 452
 453static int stv0288_set_frontend(struct dvb_frontend *fe,
 454                                        struct dvb_frontend_parameters *dfp)
 455{
 456        struct stv0288_state *state = fe->demodulator_priv;
 457        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 458
 459        char tm;
 460        unsigned char tda[3];
 461
 462        dprintk("%s : FE_SET_FRONTEND\n", __func__);
 463
 464        if (c->delivery_system != SYS_DVBS) {
 465                        dprintk("%s: unsupported delivery "
 466                                "system selected (%d)\n",
 467                                __func__, c->delivery_system);
 468                        return -EOPNOTSUPP;
 469        }
 470
 471        if (state->config->set_ts_params)
 472                state->config->set_ts_params(fe, 0);
 473
 474        /* only frequency & symbol_rate are used for tuner*/
 475        dfp->frequency = c->frequency;
 476        dfp->u.qpsk.symbol_rate = c->symbol_rate;
 477        if (fe->ops.tuner_ops.set_params) {
 478                fe->ops.tuner_ops.set_params(fe, dfp);
 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[0] = 0x2b; /* CFRM */
 489        tda[2] = 0x0; /* CFRL */
 490        for (tm = -6; tm < 7;) {
 491                /* Viterbi status */
 492                if (stv0288_readreg(state, 0x24) & 0x8)
 493                        break;
 494
 495                tda[2] += 40;
 496                if (tda[2] < 40)
 497                        tm++;
 498                tda[1] = (unsigned char)tm;
 499                stv0288_writeregI(state, 0x2b, tda[1]);
 500                stv0288_writeregI(state, 0x2c, tda[2]);
 501                udelay(30);
 502        }
 503
 504        state->tuner_frequency = c->frequency;
 505        state->fec_inner = FEC_AUTO;
 506        state->symbol_rate = c->symbol_rate;
 507
 508        return 0;
 509}
 510
 511static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 512{
 513        struct stv0288_state *state = fe->demodulator_priv;
 514
 515        if (enable)
 516                stv0288_writeregI(state, 0x01, 0xb5);
 517        else
 518                stv0288_writeregI(state, 0x01, 0x35);
 519
 520        udelay(1);
 521
 522        return 0;
 523}
 524
 525static void stv0288_release(struct dvb_frontend *fe)
 526{
 527        struct stv0288_state *state = fe->demodulator_priv;
 528        kfree(state);
 529}
 530
 531static struct dvb_frontend_ops stv0288_ops = {
 532
 533        .info = {
 534                .name                   = "ST STV0288 DVB-S",
 535                .type                   = FE_QPSK,
 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_property = stv0288_set_property,
 565        .get_property = stv0288_get_property,
 566        .set_frontend = stv0288_set_frontend,
 567};
 568
 569struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
 570                                    struct i2c_adapter *i2c)
 571{
 572        struct stv0288_state *state = NULL;
 573        int id;
 574
 575        /* allocate memory for the internal state */
 576        state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
 577        if (state == NULL)
 578                goto error;
 579
 580        /* setup the state */
 581        state->config = config;
 582        state->i2c = i2c;
 583        state->initialised = 0;
 584        state->tuner_frequency = 0;
 585        state->symbol_rate = 0;
 586        state->fec_inner = 0;
 587        state->errmode = STATUS_BER;
 588
 589        stv0288_writeregI(state, 0x41, 0x04);
 590        msleep(200);
 591        id = stv0288_readreg(state, 0x00);
 592        dprintk("stv0288 id %x\n", id);
 593
 594        /* register 0x00 contains 0x11 for STV0288  */
 595        if (id != 0x11)
 596                goto error;
 597
 598        /* create dvb_frontend */
 599        memcpy(&state->frontend.ops, &stv0288_ops,
 600                        sizeof(struct dvb_frontend_ops));
 601        state->frontend.demodulator_priv = state;
 602        return &state->frontend;
 603
 604error:
 605        kfree(state);
 606
 607        return NULL;
 608}
 609EXPORT_SYMBOL(stv0288_attach);
 610
 611module_param(debug_legacy_dish_switch, int, 0444);
 612MODULE_PARM_DESC(debug_legacy_dish_switch,
 613                "Enable timing analysis for Dish Network legacy switches");
 614
 615module_param(debug, int, 0644);
 616MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 617
 618MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
 619MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
 620MODULE_LICENSE("GPL");
 621
 622