root/drivers/media/dvb-frontends/stv0288.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. stv0288_writeregI
  2. stv0288_write
  3. stv0288_readreg
  4. stv0288_set_symbolrate
  5. stv0288_send_diseqc_msg
  6. stv0288_send_diseqc_burst
  7. stv0288_set_tone
  8. stv0288_set_voltage
  9. stv0288_init
  10. stv0288_read_status
  11. stv0288_read_ber
  12. stv0288_read_signal_strength
  13. stv0288_sleep
  14. stv0288_read_snr
  15. stv0288_read_ucblocks
  16. stv0288_set_frontend
  17. stv0288_i2c_gate_ctrl
  18. stv0288_release
  19. stv0288_attach

   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 
  27 struct 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 
  42 static int debug;
  43 static 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 
  51 static 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 
  71 static 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 
  81 static 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 
 109 static 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 
 143 static 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 
 164 static 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 
 184 static 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 
 205 static 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 
 314 static 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 
 324 static 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 
 353 static 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 
 376 static 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 
 390 static 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 }
 403 static 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 }
 412 static 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 
 425 static 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 
 438 static 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 
 500 static 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 
 514 static void stv0288_release(struct dvb_frontend *fe)
 515 {
 516         struct stv0288_state *state = fe->demodulator_priv;
 517         kfree(state);
 518 }
 519 
 520 static 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 
 554 struct 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 
 589 error:
 590         kfree(state);
 591 
 592         return NULL;
 593 }
 594 EXPORT_SYMBOL(stv0288_attach);
 595 
 596 module_param(debug_legacy_dish_switch, int, 0444);
 597 MODULE_PARM_DESC(debug_legacy_dish_switch,
 598                 "Enable timing analysis for Dish Network legacy switches");
 599 
 600 module_param(debug, int, 0644);
 601 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 602 
 603 MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
 604 MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
 605 MODULE_LICENSE("GPL");
 606 

/* [<][>][^][v][top][bottom][index][help] */