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

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

DEFINITIONS

This source file includes following definitions.
  1. cx24123_i2c_writereg
  2. cx24123_i2c_readreg
  3. cx24123_set_inversion
  4. cx24123_get_inversion
  5. cx24123_set_fec
  6. cx24123_get_fec
  7. cx24123_int_log2
  8. cx24123_set_symbolrate
  9. cx24123_pll_calculate
  10. cx24123_pll_writereg
  11. cx24123_pll_tune
  12. cx24123_repeater_mode
  13. cx24123_initfe
  14. cx24123_set_voltage
  15. cx24123_wait_for_diseqc
  16. cx24123_send_diseqc_msg
  17. cx24123_diseqc_send_burst
  18. cx24123_read_status
  19. cx24123_read_ber
  20. cx24123_read_signal_strength
  21. cx24123_read_snr
  22. cx24123_set_frontend
  23. cx24123_get_frontend
  24. cx24123_set_tone
  25. cx24123_tune
  26. cx24123_get_algo
  27. cx24123_release
  28. cx24123_tuner_i2c_tuner_xfer
  29. cx24123_tuner_i2c_func
  30. cx24123_get_tuner_i2c_adapter
  31. cx24123_attach

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *   Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
   4  *
   5  *   Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
   6  *
   7  *   Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
   8  *
   9  *   Support for CX24123/CX24113-NIM by Patrick Boettcher <pb@linuxtv.org>
  10  */
  11 
  12 #include <linux/slab.h>
  13 #include <linux/kernel.h>
  14 #include <linux/module.h>
  15 #include <linux/init.h>
  16 #include <asm/div64.h>
  17 
  18 #include <media/dvb_frontend.h>
  19 #include "cx24123.h"
  20 
  21 #define XTAL 10111000
  22 
  23 static int force_band;
  24 module_param(force_band, int, 0644);
  25 MODULE_PARM_DESC(force_band, "Force a specific band select "\
  26         "(1-9, default:off).");
  27 
  28 static int debug;
  29 module_param(debug, int, 0644);
  30 MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
  31 
  32 #define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
  33 #define err(args...)  do { printk(KERN_ERR  "CX24123: " args); } while (0)
  34 
  35 #define dprintk(args...) \
  36         do { \
  37                 if (debug) { \
  38                         printk(KERN_DEBUG "CX24123: %s: ", __func__); \
  39                         printk(args); \
  40                 } \
  41         } while (0)
  42 
  43 struct cx24123_state {
  44         struct i2c_adapter *i2c;
  45         const struct cx24123_config *config;
  46 
  47         struct dvb_frontend frontend;
  48 
  49         /* Some PLL specifics for tuning */
  50         u32 VCAarg;
  51         u32 VGAarg;
  52         u32 bandselectarg;
  53         u32 pllarg;
  54         u32 FILTune;
  55 
  56         struct i2c_adapter tuner_i2c_adapter;
  57 
  58         u8 demod_rev;
  59 
  60         /* The Demod/Tuner can't easily provide these, we cache them */
  61         u32 currentfreq;
  62         u32 currentsymbolrate;
  63 };
  64 
  65 /* Various tuner defaults need to be established for a given symbol rate Sps */
  66 static struct cx24123_AGC_val {
  67         u32 symbolrate_low;
  68         u32 symbolrate_high;
  69         u32 VCAprogdata;
  70         u32 VGAprogdata;
  71         u32 FILTune;
  72 } cx24123_AGC_vals[] =
  73 {
  74         {
  75                 .symbolrate_low         = 1000000,
  76                 .symbolrate_high        = 4999999,
  77                 /* the specs recommend other values for VGA offsets,
  78                    but tests show they are wrong */
  79                 .VGAprogdata            = (1 << 19) | (0x180 << 9) | 0x1e0,
  80                 .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x07,
  81                 .FILTune                = 0x27f /* 0.41 V */
  82         },
  83         {
  84                 .symbolrate_low         =  5000000,
  85                 .symbolrate_high        = 14999999,
  86                 .VGAprogdata            = (1 << 19) | (0x180 << 9) | 0x1e0,
  87                 .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x1f,
  88                 .FILTune                = 0x317 /* 0.90 V */
  89         },
  90         {
  91                 .symbolrate_low         = 15000000,
  92                 .symbolrate_high        = 45000000,
  93                 .VGAprogdata            = (1 << 19) | (0x100 << 9) | 0x180,
  94                 .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x3f,
  95                 .FILTune                = 0x145 /* 2.70 V */
  96         },
  97 };
  98 
  99 /*
 100  * Various tuner defaults need to be established for a given frequency kHz.
 101  * fixme: The bounds on the bands do not match the doc in real life.
 102  * fixme: Some of them have been moved, other might need adjustment.
 103  */
 104 static struct cx24123_bandselect_val {
 105         u32 freq_low;
 106         u32 freq_high;
 107         u32 VCOdivider;
 108         u32 progdata;
 109 } cx24123_bandselect_vals[] =
 110 {
 111         /* band 1 */
 112         {
 113                 .freq_low       = 950000,
 114                 .freq_high      = 1074999,
 115                 .VCOdivider     = 4,
 116                 .progdata       = (0 << 19) | (0 << 9) | 0x40,
 117         },
 118 
 119         /* band 2 */
 120         {
 121                 .freq_low       = 1075000,
 122                 .freq_high      = 1177999,
 123                 .VCOdivider     = 4,
 124                 .progdata       = (0 << 19) | (0 << 9) | 0x80,
 125         },
 126 
 127         /* band 3 */
 128         {
 129                 .freq_low       = 1178000,
 130                 .freq_high      = 1295999,
 131                 .VCOdivider     = 2,
 132                 .progdata       = (0 << 19) | (1 << 9) | 0x01,
 133         },
 134 
 135         /* band 4 */
 136         {
 137                 .freq_low       = 1296000,
 138                 .freq_high      = 1431999,
 139                 .VCOdivider     = 2,
 140                 .progdata       = (0 << 19) | (1 << 9) | 0x02,
 141         },
 142 
 143         /* band 5 */
 144         {
 145                 .freq_low       = 1432000,
 146                 .freq_high      = 1575999,
 147                 .VCOdivider     = 2,
 148                 .progdata       = (0 << 19) | (1 << 9) | 0x04,
 149         },
 150 
 151         /* band 6 */
 152         {
 153                 .freq_low       = 1576000,
 154                 .freq_high      = 1717999,
 155                 .VCOdivider     = 2,
 156                 .progdata       = (0 << 19) | (1 << 9) | 0x08,
 157         },
 158 
 159         /* band 7 */
 160         {
 161                 .freq_low       = 1718000,
 162                 .freq_high      = 1855999,
 163                 .VCOdivider     = 2,
 164                 .progdata       = (0 << 19) | (1 << 9) | 0x10,
 165         },
 166 
 167         /* band 8 */
 168         {
 169                 .freq_low       = 1856000,
 170                 .freq_high      = 2035999,
 171                 .VCOdivider     = 2,
 172                 .progdata       = (0 << 19) | (1 << 9) | 0x20,
 173         },
 174 
 175         /* band 9 */
 176         {
 177                 .freq_low       = 2036000,
 178                 .freq_high      = 2150000,
 179                 .VCOdivider     = 2,
 180                 .progdata       = (0 << 19) | (1 << 9) | 0x40,
 181         },
 182 };
 183 
 184 static struct {
 185         u8 reg;
 186         u8 data;
 187 } cx24123_regdata[] =
 188 {
 189         {0x00, 0x03}, /* Reset system */
 190         {0x00, 0x00}, /* Clear reset */
 191         {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */
 192         {0x04, 0x10}, /* MPEG */
 193         {0x05, 0x04}, /* MPEG */
 194         {0x06, 0x31}, /* MPEG (default) */
 195         {0x0b, 0x00}, /* Freq search start point (default) */
 196         {0x0c, 0x00}, /* Demodulator sample gain (default) */
 197         {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */
 198         {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
 199         {0x0f, 0xfe}, /* FEC search mask (all supported codes) */
 200         {0x10, 0x01}, /* Default search inversion, no repeat (default) */
 201         {0x16, 0x00}, /* Enable reading of frequency */
 202         {0x17, 0x01}, /* Enable EsNO Ready Counter */
 203         {0x1c, 0x80}, /* Enable error counter */
 204         {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */
 205         {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */
 206         {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */
 207         {0x29, 0x00}, /* DiSEqC LNB_DC off */
 208         {0x2a, 0xb0}, /* DiSEqC Parameters (default) */
 209         {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */
 210         {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */
 211         {0x2d, 0x00},
 212         {0x2e, 0x00},
 213         {0x2f, 0x00},
 214         {0x30, 0x00},
 215         {0x31, 0x00},
 216         {0x32, 0x8c}, /* DiSEqC Parameters (default) */
 217         {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */
 218         {0x34, 0x00},
 219         {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */
 220         {0x36, 0x02}, /* DiSEqC Parameters (default) */
 221         {0x37, 0x3a}, /* DiSEqC Parameters (default) */
 222         {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */
 223         {0x44, 0x00}, /* Constellation (default) */
 224         {0x45, 0x00}, /* Symbol count (default) */
 225         {0x46, 0x0d}, /* Symbol rate estimator on (default) */
 226         {0x56, 0xc1}, /* Error Counter = Viterbi BER */
 227         {0x57, 0xff}, /* Error Counter Window (default) */
 228         {0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
 229         {0x67, 0x83}, /* Non-DCII symbol clock */
 230 };
 231 
 232 static int cx24123_i2c_writereg(struct cx24123_state *state,
 233         u8 i2c_addr, int reg, int data)
 234 {
 235         u8 buf[] = { reg, data };
 236         struct i2c_msg msg = {
 237                 .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
 238         };
 239         int err;
 240 
 241         /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */
 242 
 243         err = i2c_transfer(state->i2c, &msg, 1);
 244         if (err != 1) {
 245                 printk("%s: writereg error(err == %i, reg == 0x%02x, data == 0x%02x)\n",
 246                        __func__, err, reg, data);
 247                 return err;
 248         }
 249 
 250         return 0;
 251 }
 252 
 253 static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
 254 {
 255         int ret;
 256         u8 b = 0;
 257         struct i2c_msg msg[] = {
 258                 { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
 259                 { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 }
 260         };
 261 
 262         ret = i2c_transfer(state->i2c, msg, 2);
 263 
 264         if (ret != 2) {
 265                 err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
 266                 return ret;
 267         }
 268 
 269         /* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */
 270 
 271         return b;
 272 }
 273 
 274 #define cx24123_readreg(state, reg) \
 275         cx24123_i2c_readreg(state, state->config->demod_address, reg)
 276 #define cx24123_writereg(state, reg, val) \
 277         cx24123_i2c_writereg(state, state->config->demod_address, reg, val)
 278 
 279 static int cx24123_set_inversion(struct cx24123_state *state,
 280                                  enum fe_spectral_inversion inversion)
 281 {
 282         u8 nom_reg = cx24123_readreg(state, 0x0e);
 283         u8 auto_reg = cx24123_readreg(state, 0x10);
 284 
 285         switch (inversion) {
 286         case INVERSION_OFF:
 287                 dprintk("inversion off\n");
 288                 cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
 289                 cx24123_writereg(state, 0x10, auto_reg | 0x80);
 290                 break;
 291         case INVERSION_ON:
 292                 dprintk("inversion on\n");
 293                 cx24123_writereg(state, 0x0e, nom_reg | 0x80);
 294                 cx24123_writereg(state, 0x10, auto_reg | 0x80);
 295                 break;
 296         case INVERSION_AUTO:
 297                 dprintk("inversion auto\n");
 298                 cx24123_writereg(state, 0x10, auto_reg & ~0x80);
 299                 break;
 300         default:
 301                 return -EINVAL;
 302         }
 303 
 304         return 0;
 305 }
 306 
 307 static int cx24123_get_inversion(struct cx24123_state *state,
 308                                  enum fe_spectral_inversion *inversion)
 309 {
 310         u8 val;
 311 
 312         val = cx24123_readreg(state, 0x1b) >> 7;
 313 
 314         if (val == 0) {
 315                 dprintk("read inversion off\n");
 316                 *inversion = INVERSION_OFF;
 317         } else {
 318                 dprintk("read inversion on\n");
 319                 *inversion = INVERSION_ON;
 320         }
 321 
 322         return 0;
 323 }
 324 
 325 static int cx24123_set_fec(struct cx24123_state *state, enum fe_code_rate fec)
 326 {
 327         u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
 328 
 329         if (((int)fec < FEC_NONE) || (fec > FEC_AUTO))
 330                 fec = FEC_AUTO;
 331 
 332         /* Set the soft decision threshold */
 333         if (fec == FEC_1_2)
 334                 cx24123_writereg(state, 0x43,
 335                         cx24123_readreg(state, 0x43) | 0x01);
 336         else
 337                 cx24123_writereg(state, 0x43,
 338                         cx24123_readreg(state, 0x43) & ~0x01);
 339 
 340         switch (fec) {
 341         case FEC_1_2:
 342                 dprintk("set FEC to 1/2\n");
 343                 cx24123_writereg(state, 0x0e, nom_reg | 0x01);
 344                 cx24123_writereg(state, 0x0f, 0x02);
 345                 break;
 346         case FEC_2_3:
 347                 dprintk("set FEC to 2/3\n");
 348                 cx24123_writereg(state, 0x0e, nom_reg | 0x02);
 349                 cx24123_writereg(state, 0x0f, 0x04);
 350                 break;
 351         case FEC_3_4:
 352                 dprintk("set FEC to 3/4\n");
 353                 cx24123_writereg(state, 0x0e, nom_reg | 0x03);
 354                 cx24123_writereg(state, 0x0f, 0x08);
 355                 break;
 356         case FEC_4_5:
 357                 dprintk("set FEC to 4/5\n");
 358                 cx24123_writereg(state, 0x0e, nom_reg | 0x04);
 359                 cx24123_writereg(state, 0x0f, 0x10);
 360                 break;
 361         case FEC_5_6:
 362                 dprintk("set FEC to 5/6\n");
 363                 cx24123_writereg(state, 0x0e, nom_reg | 0x05);
 364                 cx24123_writereg(state, 0x0f, 0x20);
 365                 break;
 366         case FEC_6_7:
 367                 dprintk("set FEC to 6/7\n");
 368                 cx24123_writereg(state, 0x0e, nom_reg | 0x06);
 369                 cx24123_writereg(state, 0x0f, 0x40);
 370                 break;
 371         case FEC_7_8:
 372                 dprintk("set FEC to 7/8\n");
 373                 cx24123_writereg(state, 0x0e, nom_reg | 0x07);
 374                 cx24123_writereg(state, 0x0f, 0x80);
 375                 break;
 376         case FEC_AUTO:
 377                 dprintk("set FEC to auto\n");
 378                 cx24123_writereg(state, 0x0f, 0xfe);
 379                 break;
 380         default:
 381                 return -EOPNOTSUPP;
 382         }
 383 
 384         return 0;
 385 }
 386 
 387 static int cx24123_get_fec(struct cx24123_state *state, enum fe_code_rate *fec)
 388 {
 389         int ret;
 390 
 391         ret = cx24123_readreg(state, 0x1b);
 392         if (ret < 0)
 393                 return ret;
 394         ret = ret & 0x07;
 395 
 396         switch (ret) {
 397         case 1:
 398                 *fec = FEC_1_2;
 399                 break;
 400         case 2:
 401                 *fec = FEC_2_3;
 402                 break;
 403         case 3:
 404                 *fec = FEC_3_4;
 405                 break;
 406         case 4:
 407                 *fec = FEC_4_5;
 408                 break;
 409         case 5:
 410                 *fec = FEC_5_6;
 411                 break;
 412         case 6:
 413                 *fec = FEC_6_7;
 414                 break;
 415         case 7:
 416                 *fec = FEC_7_8;
 417                 break;
 418         default:
 419                 /* this can happen when there's no lock */
 420                 *fec = FEC_NONE;
 421         }
 422 
 423         return 0;
 424 }
 425 
 426 /* Approximation of closest integer of log2(a/b). It actually gives the
 427    lowest integer i such that 2^i >= round(a/b) */
 428 static u32 cx24123_int_log2(u32 a, u32 b)
 429 {
 430         u32 exp, nearest = 0;
 431         u32 div = a / b;
 432         if (a % b >= b / 2)
 433                 ++div;
 434         if (div < (1UL << 31)) {
 435                 for (exp = 1; div > exp; nearest++)
 436                         exp += exp;
 437         }
 438         return nearest;
 439 }
 440 
 441 static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
 442 {
 443         u64 tmp;
 444         u32 sample_rate, ratio, sample_gain;
 445         u8 pll_mult;
 446 
 447         /*  check if symbol rate is within limits */
 448         if ((srate > state->frontend.ops.info.symbol_rate_max) ||
 449             (srate < state->frontend.ops.info.symbol_rate_min))
 450                 return -EOPNOTSUPP;
 451 
 452         /* choose the sampling rate high enough for the required operation,
 453            while optimizing the power consumed by the demodulator */
 454         if (srate < (XTAL*2)/2)
 455                 pll_mult = 2;
 456         else if (srate < (XTAL*3)/2)
 457                 pll_mult = 3;
 458         else if (srate < (XTAL*4)/2)
 459                 pll_mult = 4;
 460         else if (srate < (XTAL*5)/2)
 461                 pll_mult = 5;
 462         else if (srate < (XTAL*6)/2)
 463                 pll_mult = 6;
 464         else if (srate < (XTAL*7)/2)
 465                 pll_mult = 7;
 466         else if (srate < (XTAL*8)/2)
 467                 pll_mult = 8;
 468         else
 469                 pll_mult = 9;
 470 
 471 
 472         sample_rate = pll_mult * XTAL;
 473 
 474         /* SYSSymbolRate[21:0] = (srate << 23) / sample_rate */
 475 
 476         tmp = ((u64)srate) << 23;
 477         do_div(tmp, sample_rate);
 478         ratio = (u32) tmp;
 479 
 480         cx24123_writereg(state, 0x01, pll_mult * 6);
 481 
 482         cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f);
 483         cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff);
 484         cx24123_writereg(state, 0x0a, ratio & 0xff);
 485 
 486         /* also set the demodulator sample gain */
 487         sample_gain = cx24123_int_log2(sample_rate, srate);
 488         tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
 489         cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);
 490 
 491         dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n",
 492                 srate, ratio, sample_rate, sample_gain);
 493 
 494         return 0;
 495 }
 496 
 497 /*
 498  * Based on the required frequency and symbolrate, the tuner AGC has
 499  * to be configured and the correct band selected.
 500  * Calculate those values.
 501  */
 502 static int cx24123_pll_calculate(struct dvb_frontend *fe)
 503 {
 504         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 505         struct cx24123_state *state = fe->demodulator_priv;
 506         u32 ndiv = 0, adiv = 0, vco_div = 0;
 507         int i = 0;
 508         int pump = 2;
 509         int band = 0;
 510         int num_bands = ARRAY_SIZE(cx24123_bandselect_vals);
 511         struct cx24123_bandselect_val *bsv = NULL;
 512         struct cx24123_AGC_val *agcv = NULL;
 513 
 514         /* Defaults for low freq, low rate */
 515         state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
 516         state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
 517         state->bandselectarg = cx24123_bandselect_vals[0].progdata;
 518         vco_div = cx24123_bandselect_vals[0].VCOdivider;
 519 
 520         /* For the given symbol rate, determine the VCA, VGA and
 521          * FILTUNE programming bits */
 522         for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) {
 523                 agcv = &cx24123_AGC_vals[i];
 524                 if ((agcv->symbolrate_low <= p->symbol_rate) &&
 525                     (agcv->symbolrate_high >= p->symbol_rate)) {
 526                         state->VCAarg = agcv->VCAprogdata;
 527                         state->VGAarg = agcv->VGAprogdata;
 528                         state->FILTune = agcv->FILTune;
 529                 }
 530         }
 531 
 532         /* determine the band to use */
 533         if (force_band < 1 || force_band > num_bands) {
 534                 for (i = 0; i < num_bands; i++) {
 535                         bsv = &cx24123_bandselect_vals[i];
 536                         if ((bsv->freq_low <= p->frequency) &&
 537                                 (bsv->freq_high >= p->frequency))
 538                                 band = i;
 539                 }
 540         } else
 541                 band = force_band - 1;
 542 
 543         state->bandselectarg = cx24123_bandselect_vals[band].progdata;
 544         vco_div = cx24123_bandselect_vals[band].VCOdivider;
 545 
 546         /* determine the charge pump current */
 547         if (p->frequency < (cx24123_bandselect_vals[band].freq_low +
 548                 cx24123_bandselect_vals[band].freq_high) / 2)
 549                 pump = 0x01;
 550         else
 551                 pump = 0x02;
 552 
 553         /* Determine the N/A dividers for the requested lband freq (in kHz). */
 554         /* Note: the reference divider R=10, frequency is in KHz,
 555          * XTAL is in Hz */
 556         ndiv = (((p->frequency * vco_div * 10) /
 557                 (2 * XTAL / 1000)) / 32) & 0x1ff;
 558         adiv = (((p->frequency * vco_div * 10) /
 559                 (2 * XTAL / 1000)) % 32) & 0x1f;
 560 
 561         if (adiv == 0 && ndiv > 0)
 562                 ndiv--;
 563 
 564         /* control bits 11, refdiv 11, charge pump polarity 1,
 565          * charge pump current, ndiv, adiv */
 566         state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) |
 567                 (pump << 14) | (ndiv << 5) | adiv;
 568 
 569         return 0;
 570 }
 571 
 572 /*
 573  * Tuner data is 21 bits long, must be left-aligned in data.
 574  * Tuner cx24109 is written through a dedicated 3wire interface
 575  * on the demod chip.
 576  */
 577 static int cx24123_pll_writereg(struct dvb_frontend *fe, u32 data)
 578 {
 579         struct cx24123_state *state = fe->demodulator_priv;
 580         unsigned long timeout;
 581 
 582         dprintk("pll writereg called, data=0x%08x\n", data);
 583 
 584         /* align the 21 bytes into to bit23 boundary */
 585         data = data << 3;
 586 
 587         /* Reset the demod pll word length to 0x15 bits */
 588         cx24123_writereg(state, 0x21, 0x15);
 589 
 590         /* write the msb 8 bits, wait for the send to be completed */
 591         timeout = jiffies + msecs_to_jiffies(40);
 592         cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
 593         while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
 594                 if (time_after(jiffies, timeout)) {
 595                         err("%s:  demodulator is not responding, "\
 596                                 "possibly hung, aborting.\n", __func__);
 597                         return -EREMOTEIO;
 598                 }
 599                 msleep(10);
 600         }
 601 
 602         /* send another 8 bytes, wait for the send to be completed */
 603         timeout = jiffies + msecs_to_jiffies(40);
 604         cx24123_writereg(state, 0x22, (data >> 8) & 0xff);
 605         while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
 606                 if (time_after(jiffies, timeout)) {
 607                         err("%s:  demodulator is not responding, "\
 608                                 "possibly hung, aborting.\n", __func__);
 609                         return -EREMOTEIO;
 610                 }
 611                 msleep(10);
 612         }
 613 
 614         /* send the lower 5 bits of this byte, padded with 3 LBB,
 615          * wait for the send to be completed */
 616         timeout = jiffies + msecs_to_jiffies(40);
 617         cx24123_writereg(state, 0x22, (data) & 0xff);
 618         while ((cx24123_readreg(state, 0x20) & 0x80)) {
 619                 if (time_after(jiffies, timeout)) {
 620                         err("%s:  demodulator is not responding," \
 621                                 "possibly hung, aborting.\n", __func__);
 622                         return -EREMOTEIO;
 623                 }
 624                 msleep(10);
 625         }
 626 
 627         /* Trigger the demod to configure the tuner */
 628         cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
 629         cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);
 630 
 631         return 0;
 632 }
 633 
 634 static int cx24123_pll_tune(struct dvb_frontend *fe)
 635 {
 636         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 637         struct cx24123_state *state = fe->demodulator_priv;
 638         u8 val;
 639 
 640         dprintk("frequency=%i\n", p->frequency);
 641 
 642         if (cx24123_pll_calculate(fe) != 0) {
 643                 err("%s: cx24123_pll_calculate failed\n", __func__);
 644                 return -EINVAL;
 645         }
 646 
 647         /* Write the new VCO/VGA */
 648         cx24123_pll_writereg(fe, state->VCAarg);
 649         cx24123_pll_writereg(fe, state->VGAarg);
 650 
 651         /* Write the new bandselect and pll args */
 652         cx24123_pll_writereg(fe, state->bandselectarg);
 653         cx24123_pll_writereg(fe, state->pllarg);
 654 
 655         /* set the FILTUNE voltage */
 656         val = cx24123_readreg(state, 0x28) & ~0x3;
 657         cx24123_writereg(state, 0x27, state->FILTune >> 2);
 658         cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));
 659 
 660         dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg,
 661                         state->bandselectarg, state->pllarg);
 662 
 663         return 0;
 664 }
 665 
 666 
 667 /*
 668  * 0x23:
 669  *    [7:7] = BTI enabled
 670  *    [6:6] = I2C repeater enabled
 671  *    [5:5] = I2C repeater start
 672  *    [0:0] = BTI start
 673  */
 674 
 675 /* mode == 1 -> i2c-repeater, 0 -> bti */
 676 static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
 677 {
 678         u8 r = cx24123_readreg(state, 0x23) & 0x1e;
 679         if (mode)
 680                 r |= (1 << 6) | (start << 5);
 681         else
 682                 r |= (1 << 7) | (start);
 683         return cx24123_writereg(state, 0x23, r);
 684 }
 685 
 686 static int cx24123_initfe(struct dvb_frontend *fe)
 687 {
 688         struct cx24123_state *state = fe->demodulator_priv;
 689         int i;
 690 
 691         dprintk("init frontend\n");
 692 
 693         /* Configure the demod to a good set of defaults */
 694         for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
 695                 cx24123_writereg(state, cx24123_regdata[i].reg,
 696                         cx24123_regdata[i].data);
 697 
 698         /* Set the LNB polarity */
 699         if (state->config->lnb_polarity)
 700                 cx24123_writereg(state, 0x32,
 701                         cx24123_readreg(state, 0x32) | 0x02);
 702 
 703         if (state->config->dont_use_pll)
 704                 cx24123_repeater_mode(state, 1, 0);
 705 
 706         return 0;
 707 }
 708 
 709 static int cx24123_set_voltage(struct dvb_frontend *fe,
 710                                enum fe_sec_voltage voltage)
 711 {
 712         struct cx24123_state *state = fe->demodulator_priv;
 713         u8 val;
 714 
 715         val = cx24123_readreg(state, 0x29) & ~0x40;
 716 
 717         switch (voltage) {
 718         case SEC_VOLTAGE_13:
 719                 dprintk("setting voltage 13V\n");
 720                 return cx24123_writereg(state, 0x29, val & 0x7f);
 721         case SEC_VOLTAGE_18:
 722                 dprintk("setting voltage 18V\n");
 723                 return cx24123_writereg(state, 0x29, val | 0x80);
 724         case SEC_VOLTAGE_OFF:
 725                 /* already handled in cx88-dvb */
 726                 return 0;
 727         default:
 728                 return -EINVAL;
 729         }
 730 
 731         return 0;
 732 }
 733 
 734 /* wait for diseqc queue to become ready (or timeout) */
 735 static void cx24123_wait_for_diseqc(struct cx24123_state *state)
 736 {
 737         unsigned long timeout = jiffies + msecs_to_jiffies(200);
 738         while (!(cx24123_readreg(state, 0x29) & 0x40)) {
 739                 if (time_after(jiffies, timeout)) {
 740                         err("%s: diseqc queue not ready, " \
 741                                 "command may be lost.\n", __func__);
 742                         break;
 743                 }
 744                 msleep(10);
 745         }
 746 }
 747 
 748 static int cx24123_send_diseqc_msg(struct dvb_frontend *fe,
 749         struct dvb_diseqc_master_cmd *cmd)
 750 {
 751         struct cx24123_state *state = fe->demodulator_priv;
 752         int i, val, tone;
 753 
 754         dprintk("\n");
 755 
 756         /* stop continuous tone if enabled */
 757         tone = cx24123_readreg(state, 0x29);
 758         if (tone & 0x10)
 759                 cx24123_writereg(state, 0x29, tone & ~0x50);
 760 
 761         /* wait for diseqc queue ready */
 762         cx24123_wait_for_diseqc(state);
 763 
 764         /* select tone mode */
 765         cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
 766 
 767         for (i = 0; i < cmd->msg_len; i++)
 768                 cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
 769 
 770         val = cx24123_readreg(state, 0x29);
 771         cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) |
 772                 ((cmd->msg_len-3) & 3));
 773 
 774         /* wait for diseqc message to finish sending */
 775         cx24123_wait_for_diseqc(state);
 776 
 777         /* restart continuous tone if enabled */
 778         if (tone & 0x10)
 779                 cx24123_writereg(state, 0x29, tone & ~0x40);
 780 
 781         return 0;
 782 }
 783 
 784 static int cx24123_diseqc_send_burst(struct dvb_frontend *fe,
 785                                      enum fe_sec_mini_cmd burst)
 786 {
 787         struct cx24123_state *state = fe->demodulator_priv;
 788         int val, tone;
 789 
 790         dprintk("\n");
 791 
 792         /* stop continuous tone if enabled */
 793         tone = cx24123_readreg(state, 0x29);
 794         if (tone & 0x10)
 795                 cx24123_writereg(state, 0x29, tone & ~0x50);
 796 
 797         /* wait for diseqc queue ready */
 798         cx24123_wait_for_diseqc(state);
 799 
 800         /* select tone mode */
 801         cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
 802         msleep(30);
 803         val = cx24123_readreg(state, 0x29);
 804         if (burst == SEC_MINI_A)
 805                 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
 806         else if (burst == SEC_MINI_B)
 807                 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08));
 808         else
 809                 return -EINVAL;
 810 
 811         cx24123_wait_for_diseqc(state);
 812         cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
 813 
 814         /* restart continuous tone if enabled */
 815         if (tone & 0x10)
 816                 cx24123_writereg(state, 0x29, tone & ~0x40);
 817 
 818         return 0;
 819 }
 820 
 821 static int cx24123_read_status(struct dvb_frontend *fe, enum fe_status *status)
 822 {
 823         struct cx24123_state *state = fe->demodulator_priv;
 824         int sync = cx24123_readreg(state, 0x14);
 825 
 826         *status = 0;
 827         if (state->config->dont_use_pll) {
 828                 u32 tun_status = 0;
 829                 if (fe->ops.tuner_ops.get_status)
 830                         fe->ops.tuner_ops.get_status(fe, &tun_status);
 831                 if (tun_status & TUNER_STATUS_LOCKED)
 832                         *status |= FE_HAS_SIGNAL;
 833         } else {
 834                 int lock = cx24123_readreg(state, 0x20);
 835                 if (lock & 0x01)
 836                         *status |= FE_HAS_SIGNAL;
 837         }
 838 
 839         if (sync & 0x02)
 840                 *status |= FE_HAS_CARRIER;      /* Phase locked */
 841         if (sync & 0x04)
 842                 *status |= FE_HAS_VITERBI;
 843 
 844         /* Reed-Solomon Status */
 845         if (sync & 0x08)
 846                 *status |= FE_HAS_SYNC;
 847         if (sync & 0x80)
 848                 *status |= FE_HAS_LOCK;         /*Full Sync */
 849 
 850         return 0;
 851 }
 852 
 853 /*
 854  * Configured to return the measurement of errors in blocks,
 855  * because no UCBLOCKS value is available, so this value doubles up
 856  * to satisfy both measurements.
 857  */
 858 static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber)
 859 {
 860         struct cx24123_state *state = fe->demodulator_priv;
 861 
 862         /* The true bit error rate is this value divided by
 863            the window size (set as 256 * 255) */
 864         *ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
 865                 (cx24123_readreg(state, 0x1d) << 8 |
 866                  cx24123_readreg(state, 0x1e));
 867 
 868         dprintk("BER = %d\n", *ber);
 869 
 870         return 0;
 871 }
 872 
 873 static int cx24123_read_signal_strength(struct dvb_frontend *fe,
 874         u16 *signal_strength)
 875 {
 876         struct cx24123_state *state = fe->demodulator_priv;
 877 
 878         /* larger = better */
 879         *signal_strength = cx24123_readreg(state, 0x3b) << 8;
 880 
 881         dprintk("Signal strength = %d\n", *signal_strength);
 882 
 883         return 0;
 884 }
 885 
 886 static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr)
 887 {
 888         struct cx24123_state *state = fe->demodulator_priv;
 889 
 890         /* Inverted raw Es/N0 count, totally bogus but better than the
 891            BER threshold. */
 892         *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
 893                          (u16)cx24123_readreg(state, 0x19));
 894 
 895         dprintk("read S/N index = %d\n", *snr);
 896 
 897         return 0;
 898 }
 899 
 900 static int cx24123_set_frontend(struct dvb_frontend *fe)
 901 {
 902         struct cx24123_state *state = fe->demodulator_priv;
 903         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 904 
 905         dprintk("\n");
 906 
 907         if (state->config->set_ts_params)
 908                 state->config->set_ts_params(fe, 0);
 909 
 910         state->currentfreq = p->frequency;
 911         state->currentsymbolrate = p->symbol_rate;
 912 
 913         cx24123_set_inversion(state, p->inversion);
 914         cx24123_set_fec(state, p->fec_inner);
 915         cx24123_set_symbolrate(state, p->symbol_rate);
 916 
 917         if (!state->config->dont_use_pll)
 918                 cx24123_pll_tune(fe);
 919         else if (fe->ops.tuner_ops.set_params)
 920                 fe->ops.tuner_ops.set_params(fe);
 921         else
 922                 err("it seems I don't have a tuner...");
 923 
 924         /* Enable automatic acquisition and reset cycle */
 925         cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
 926         cx24123_writereg(state, 0x00, 0x10);
 927         cx24123_writereg(state, 0x00, 0);
 928 
 929         if (state->config->agc_callback)
 930                 state->config->agc_callback(fe);
 931 
 932         return 0;
 933 }
 934 
 935 static int cx24123_get_frontend(struct dvb_frontend *fe,
 936                                 struct dtv_frontend_properties *p)
 937 {
 938         struct cx24123_state *state = fe->demodulator_priv;
 939 
 940         dprintk("\n");
 941 
 942         if (cx24123_get_inversion(state, &p->inversion) != 0) {
 943                 err("%s: Failed to get inversion status\n", __func__);
 944                 return -EREMOTEIO;
 945         }
 946         if (cx24123_get_fec(state, &p->fec_inner) != 0) {
 947                 err("%s: Failed to get fec status\n", __func__);
 948                 return -EREMOTEIO;
 949         }
 950         p->frequency = state->currentfreq;
 951         p->symbol_rate = state->currentsymbolrate;
 952 
 953         return 0;
 954 }
 955 
 956 static int cx24123_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
 957 {
 958         struct cx24123_state *state = fe->demodulator_priv;
 959         u8 val;
 960 
 961         /* wait for diseqc queue ready */
 962         cx24123_wait_for_diseqc(state);
 963 
 964         val = cx24123_readreg(state, 0x29) & ~0x40;
 965 
 966         switch (tone) {
 967         case SEC_TONE_ON:
 968                 dprintk("setting tone on\n");
 969                 return cx24123_writereg(state, 0x29, val | 0x10);
 970         case SEC_TONE_OFF:
 971                 dprintk("setting tone off\n");
 972                 return cx24123_writereg(state, 0x29, val & 0xef);
 973         default:
 974                 err("CASE reached default with tone=%d\n", tone);
 975                 return -EINVAL;
 976         }
 977 
 978         return 0;
 979 }
 980 
 981 static int cx24123_tune(struct dvb_frontend *fe,
 982                         bool re_tune,
 983                         unsigned int mode_flags,
 984                         unsigned int *delay,
 985                         enum fe_status *status)
 986 {
 987         int retval = 0;
 988 
 989         if (re_tune)
 990                 retval = cx24123_set_frontend(fe);
 991 
 992         if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
 993                 cx24123_read_status(fe, status);
 994         *delay = HZ/10;
 995 
 996         return retval;
 997 }
 998 
 999 static enum dvbfe_algo cx24123_get_algo(struct dvb_frontend *fe)
1000 {
1001         return DVBFE_ALGO_HW;
1002 }
1003 
1004 static void cx24123_release(struct dvb_frontend *fe)
1005 {
1006         struct cx24123_state *state = fe->demodulator_priv;
1007         dprintk("\n");
1008         i2c_del_adapter(&state->tuner_i2c_adapter);
1009         kfree(state);
1010 }
1011 
1012 static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap,
1013         struct i2c_msg msg[], int num)
1014 {
1015         struct cx24123_state *state = i2c_get_adapdata(i2c_adap);
1016         /* this repeater closes after the first stop */
1017         cx24123_repeater_mode(state, 1, 1);
1018         return i2c_transfer(state->i2c, msg, num);
1019 }
1020 
1021 static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter)
1022 {
1023         return I2C_FUNC_I2C;
1024 }
1025 
1026 static const struct i2c_algorithm cx24123_tuner_i2c_algo = {
1027         .master_xfer   = cx24123_tuner_i2c_tuner_xfer,
1028         .functionality = cx24123_tuner_i2c_func,
1029 };
1030 
1031 struct i2c_adapter *
1032         cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
1033 {
1034         struct cx24123_state *state = fe->demodulator_priv;
1035         return &state->tuner_i2c_adapter;
1036 }
1037 EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
1038 
1039 static const struct dvb_frontend_ops cx24123_ops;
1040 
1041 struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
1042                                     struct i2c_adapter *i2c)
1043 {
1044         /* allocate memory for the internal state */
1045         struct cx24123_state *state =
1046                 kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
1047 
1048         dprintk("\n");
1049         if (state == NULL) {
1050                 err("Unable to kzalloc\n");
1051                 goto error;
1052         }
1053 
1054         /* setup the state */
1055         state->config = config;
1056         state->i2c = i2c;
1057 
1058         /* check if the demod is there */
1059         state->demod_rev = cx24123_readreg(state, 0x00);
1060         switch (state->demod_rev) {
1061         case 0xe1:
1062                 info("detected CX24123C\n");
1063                 break;
1064         case 0xd1:
1065                 info("detected CX24123\n");
1066                 break;
1067         default:
1068                 err("wrong demod revision: %x\n", state->demod_rev);
1069                 goto error;
1070         }
1071 
1072         /* create dvb_frontend */
1073         memcpy(&state->frontend.ops, &cx24123_ops,
1074                 sizeof(struct dvb_frontend_ops));
1075         state->frontend.demodulator_priv = state;
1076 
1077         /* create tuner i2c adapter */
1078         if (config->dont_use_pll)
1079                 cx24123_repeater_mode(state, 1, 0);
1080 
1081         strscpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
1082                 sizeof(state->tuner_i2c_adapter.name));
1083         state->tuner_i2c_adapter.algo      = &cx24123_tuner_i2c_algo;
1084         state->tuner_i2c_adapter.algo_data = NULL;
1085         state->tuner_i2c_adapter.dev.parent = i2c->dev.parent;
1086         i2c_set_adapdata(&state->tuner_i2c_adapter, state);
1087         if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
1088                 err("tuner i2c bus could not be initialized\n");
1089                 goto error;
1090         }
1091 
1092         return &state->frontend;
1093 
1094 error:
1095         kfree(state);
1096 
1097         return NULL;
1098 }
1099 EXPORT_SYMBOL(cx24123_attach);
1100 
1101 static const struct dvb_frontend_ops cx24123_ops = {
1102         .delsys = { SYS_DVBS },
1103         .info = {
1104                 .name = "Conexant CX24123/CX24109",
1105                 .frequency_min_hz =  950 * MHz,
1106                 .frequency_max_hz = 2150 * MHz,
1107                 .frequency_stepsize_hz = 1011 * kHz,
1108                 .frequency_tolerance_hz = 5 * MHz,
1109                 .symbol_rate_min = 1000000,
1110                 .symbol_rate_max = 45000000,
1111                 .caps = FE_CAN_INVERSION_AUTO |
1112                         FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1113                         FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1114                         FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1115                         FE_CAN_QPSK | FE_CAN_RECOVER
1116         },
1117 
1118         .release = cx24123_release,
1119 
1120         .init = cx24123_initfe,
1121         .set_frontend = cx24123_set_frontend,
1122         .get_frontend = cx24123_get_frontend,
1123         .read_status = cx24123_read_status,
1124         .read_ber = cx24123_read_ber,
1125         .read_signal_strength = cx24123_read_signal_strength,
1126         .read_snr = cx24123_read_snr,
1127         .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
1128         .diseqc_send_burst = cx24123_diseqc_send_burst,
1129         .set_tone = cx24123_set_tone,
1130         .set_voltage = cx24123_set_voltage,
1131         .tune = cx24123_tune,
1132         .get_frontend_algo = cx24123_get_algo,
1133 };
1134 
1135 MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
1136         "CX24123/CX24109/CX24113 hardware");
1137 MODULE_AUTHOR("Steven Toth");
1138 MODULE_LICENSE("GPL");
1139 

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