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