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

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

DEFINITIONS

This source file includes following definitions.
  1. lgs8gxx_write_reg
  2. lgs8gxx_read_reg
  3. lgs8gxx_soft_reset
  4. wait_reg_mask
  5. lgs8gxx_set_ad_mode
  6. lgs8gxx_set_if_freq
  7. lgs8gxx_get_afc_phase
  8. lgs8gxx_set_mode_auto
  9. lgs8gxx_set_mode_manual
  10. lgs8gxx_is_locked
  11. lgs8gxx_wait_ca_lock
  12. lgs8gxx_is_autodetect_finished
  13. lgs8gxx_autolock_gi
  14. lgs8gxx_auto_detect
  15. lgs8gxx_auto_lock
  16. lgs8gxx_set_mpeg_mode
  17. lgs8g75_set_adc_vpp
  18. lgs8913_init
  19. lgs8g75_init_data
  20. lgs8gxx_init
  21. lgs8gxx_release
  22. lgs8gxx_write
  23. lgs8gxx_set_fe
  24. lgs8gxx_get_tune_settings
  25. lgs8gxx_read_status
  26. lgs8gxx_read_signal_agc
  27. lgs8913_read_signal_strength
  28. lgs8g75_read_signal_strength
  29. lgs8gxx_read_signal_strength
  30. lgs8gxx_read_snr
  31. lgs8gxx_read_ucblocks
  32. packet_counter_start
  33. packet_counter_stop
  34. lgs8gxx_read_ber
  35. lgs8gxx_i2c_gate_ctrl
  36. lgs8gxx_attach

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
   4  *    LGS8913, LGS8GL5, LGS8G75
   5  *    experimental support LGS8G42, LGS8G52
   6  *
   7  *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
   8  *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
   9  *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
  10  */
  11 
  12 #include <asm/div64.h>
  13 #include <linux/firmware.h>
  14 
  15 #include <media/dvb_frontend.h>
  16 
  17 #include "lgs8gxx.h"
  18 #include "lgs8gxx_priv.h"
  19 
  20 #define dprintk(args...) \
  21         do { \
  22                 if (debug) \
  23                         printk(KERN_DEBUG "lgs8gxx: " args); \
  24         } while (0)
  25 
  26 static int debug;
  27 static int fake_signal_str = 1;
  28 
  29 #define LGS8GXX_FIRMWARE "lgs8g75.fw"
  30 
  31 module_param(debug, int, 0644);
  32 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
  33 
  34 module_param(fake_signal_str, int, 0644);
  35 MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
  36 "Signal strength calculation is slow.(default:on).");
  37 
  38 /* LGS8GXX internal helper functions */
  39 
  40 static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
  41 {
  42         int ret;
  43         u8 buf[] = { reg, data };
  44         struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
  45 
  46         msg.addr = priv->config->demod_address;
  47         if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
  48                 msg.addr += 0x02;
  49 
  50         if (debug >= 2)
  51                 dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
  52 
  53         ret = i2c_transfer(priv->i2c, &msg, 1);
  54 
  55         if (ret != 1)
  56                 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
  57                         __func__, reg, data, ret);
  58 
  59         return (ret != 1) ? -1 : 0;
  60 }
  61 
  62 static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
  63 {
  64         int ret;
  65         u8 dev_addr;
  66 
  67         u8 b0[] = { reg };
  68         u8 b1[] = { 0 };
  69         struct i2c_msg msg[] = {
  70                 { .flags = 0, .buf = b0, .len = 1 },
  71                 { .flags = I2C_M_RD, .buf = b1, .len = 1 },
  72         };
  73 
  74         dev_addr = priv->config->demod_address;
  75         if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
  76                 dev_addr += 0x02;
  77         msg[1].addr =  msg[0].addr = dev_addr;
  78 
  79         ret = i2c_transfer(priv->i2c, msg, 2);
  80         if (ret != 2) {
  81                 dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
  82                 return -1;
  83         }
  84 
  85         *p_data = b1[0];
  86         if (debug >= 2)
  87                 dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, b1[0]);
  88         return 0;
  89 }
  90 
  91 static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv)
  92 {
  93         lgs8gxx_write_reg(priv, 0x02, 0x00);
  94         msleep(1);
  95         lgs8gxx_write_reg(priv, 0x02, 0x01);
  96         msleep(100);
  97 
  98         return 0;
  99 }
 100 
 101 static int wait_reg_mask(struct lgs8gxx_state *priv, u8 reg, u8 mask,
 102         u8 val, u8 delay, u8 tries)
 103 {
 104         u8 t;
 105         int i;
 106 
 107         for (i = 0; i < tries; i++) {
 108                 lgs8gxx_read_reg(priv, reg, &t);
 109 
 110                 if ((t & mask) == val)
 111                         return 0;
 112                 msleep(delay);
 113         }
 114 
 115         return 1;
 116 }
 117 
 118 static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv)
 119 {
 120         const struct lgs8gxx_config *config = priv->config;
 121         u8 if_conf;
 122 
 123         if_conf = 0x10; /* AGC output on, RF_AGC output off; */
 124 
 125         if_conf |=
 126                 ((config->ext_adc) ? 0x80 : 0x00) |
 127                 ((config->if_neg_center) ? 0x04 : 0x00) |
 128                 ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */
 129                 ((config->adc_signed) ? 0x02 : 0x00) |
 130                 ((config->if_neg_edge) ? 0x01 : 0x00);
 131 
 132         if (config->ext_adc &&
 133                 (config->prod == LGS8GXX_PROD_LGS8G52)) {
 134                 lgs8gxx_write_reg(priv, 0xBA, 0x40);
 135         }
 136 
 137         lgs8gxx_write_reg(priv, 0x07, if_conf);
 138 
 139         return 0;
 140 }
 141 
 142 static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
 143 {
 144         u64 val;
 145         u32 v32;
 146         u32 if_clk;
 147 
 148         if_clk = priv->config->if_clk_freq;
 149 
 150         val = freq;
 151         if (freq != 0) {
 152                 val <<= 32;
 153                 if (if_clk != 0)
 154                         do_div(val, if_clk);
 155                 v32 = val & 0xFFFFFFFF;
 156                 dprintk("Set IF Freq to %dkHz\n", freq);
 157         } else {
 158                 v32 = 0;
 159                 dprintk("Set IF Freq to baseband\n");
 160         }
 161         dprintk("AFC_INIT_FREQ = 0x%08X\n", v32);
 162 
 163         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 164                 lgs8gxx_write_reg(priv, 0x08, 0xFF & (v32));
 165                 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32 >> 8));
 166                 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 16));
 167                 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 24));
 168         } else {
 169                 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
 170                 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
 171                 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
 172                 lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
 173         }
 174 
 175         return 0;
 176 }
 177 
 178 static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv)
 179 {
 180         u64 val;
 181         u32 v32 = 0;
 182         u8 reg_addr, t;
 183         int i;
 184 
 185         if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
 186                 reg_addr = 0x23;
 187         else
 188                 reg_addr = 0x48;
 189 
 190         for (i = 0; i < 4; i++) {
 191                 lgs8gxx_read_reg(priv, reg_addr, &t);
 192                 v32 <<= 8;
 193                 v32 |= t;
 194                 reg_addr--;
 195         }
 196 
 197         val = v32;
 198         val *= priv->config->if_clk_freq;
 199         val >>= 32;
 200         dprintk("AFC = %u kHz\n", (u32)val);
 201         return 0;
 202 }
 203 
 204 static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
 205 {
 206         u8 t;
 207         u8 prod = priv->config->prod;
 208 
 209         if (prod == LGS8GXX_PROD_LGS8913)
 210                 lgs8gxx_write_reg(priv, 0xC6, 0x01);
 211 
 212         if (prod == LGS8GXX_PROD_LGS8G75) {
 213                 lgs8gxx_read_reg(priv, 0x0C, &t);
 214                 t &= (~0x04);
 215                 lgs8gxx_write_reg(priv, 0x0C, t | 0x80);
 216                 lgs8gxx_write_reg(priv, 0x39, 0x00);
 217                 lgs8gxx_write_reg(priv, 0x3D, 0x04);
 218         } else if (prod == LGS8GXX_PROD_LGS8913 ||
 219                 prod == LGS8GXX_PROD_LGS8GL5 ||
 220                 prod == LGS8GXX_PROD_LGS8G42 ||
 221                 prod == LGS8GXX_PROD_LGS8G52 ||
 222                 prod == LGS8GXX_PROD_LGS8G54) {
 223                 lgs8gxx_read_reg(priv, 0x7E, &t);
 224                 lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
 225 
 226                 /* clear FEC self reset */
 227                 lgs8gxx_read_reg(priv, 0xC5, &t);
 228                 lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
 229         }
 230 
 231         if (prod == LGS8GXX_PROD_LGS8913) {
 232                 /* FEC auto detect */
 233                 lgs8gxx_write_reg(priv, 0xC1, 0x03);
 234 
 235                 lgs8gxx_read_reg(priv, 0x7C, &t);
 236                 t = (t & 0x8C) | 0x03;
 237                 lgs8gxx_write_reg(priv, 0x7C, t);
 238 
 239                 /* BER test mode */
 240                 lgs8gxx_read_reg(priv, 0xC3, &t);
 241                 t = (t & 0xEF) |  0x10;
 242                 lgs8gxx_write_reg(priv, 0xC3, t);
 243         }
 244 
 245         if (priv->config->prod == LGS8GXX_PROD_LGS8G52)
 246                 lgs8gxx_write_reg(priv, 0xD9, 0x40);
 247 
 248         return 0;
 249 }
 250 
 251 static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
 252 {
 253         u8 t;
 254 
 255         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 256                 u8 t2;
 257                 lgs8gxx_read_reg(priv, 0x0C, &t);
 258                 t &= (~0x80);
 259                 lgs8gxx_write_reg(priv, 0x0C, t);
 260 
 261                 lgs8gxx_read_reg(priv, 0x0C, &t);
 262                 lgs8gxx_read_reg(priv, 0x19, &t2);
 263 
 264                 if (((t&0x03) == 0x01) && (t2&0x01)) {
 265                         lgs8gxx_write_reg(priv, 0x6E, 0x05);
 266                         lgs8gxx_write_reg(priv, 0x39, 0x02);
 267                         lgs8gxx_write_reg(priv, 0x39, 0x03);
 268                         lgs8gxx_write_reg(priv, 0x3D, 0x05);
 269                         lgs8gxx_write_reg(priv, 0x3E, 0x28);
 270                         lgs8gxx_write_reg(priv, 0x53, 0x80);
 271                 } else {
 272                         lgs8gxx_write_reg(priv, 0x6E, 0x3F);
 273                         lgs8gxx_write_reg(priv, 0x39, 0x00);
 274                         lgs8gxx_write_reg(priv, 0x3D, 0x04);
 275                 }
 276 
 277                 lgs8gxx_soft_reset(priv);
 278                 return 0;
 279         }
 280 
 281         /* turn off auto-detect; manual settings */
 282         lgs8gxx_write_reg(priv, 0x7E, 0);
 283         if (priv->config->prod == LGS8GXX_PROD_LGS8913)
 284                 lgs8gxx_write_reg(priv, 0xC1, 0);
 285 
 286         lgs8gxx_read_reg(priv, 0xC5, &t);
 287         t = (t & 0xE0) | 0x06;
 288         lgs8gxx_write_reg(priv, 0xC5, t);
 289 
 290         lgs8gxx_soft_reset(priv);
 291 
 292         return 0;
 293 }
 294 
 295 static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked)
 296 {
 297         int ret = 0;
 298         u8 t;
 299 
 300         if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
 301                 ret = lgs8gxx_read_reg(priv, 0x13, &t);
 302         else
 303                 ret = lgs8gxx_read_reg(priv, 0x4B, &t);
 304         if (ret != 0)
 305                 return ret;
 306 
 307         if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
 308                 *locked = ((t & 0x80) == 0x80) ? 1 : 0;
 309         else
 310                 *locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
 311         return 0;
 312 }
 313 
 314 /* Wait for Code Acquisition Lock */
 315 static int lgs8gxx_wait_ca_lock(struct lgs8gxx_state *priv, u8 *locked)
 316 {
 317         int ret = 0;
 318         u8 reg, mask, val;
 319 
 320         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 321                 reg = 0x13;
 322                 mask = 0x80;
 323                 val = 0x80;
 324         } else {
 325                 reg = 0x4B;
 326                 mask = 0xC0;
 327                 val = 0xC0;
 328         }
 329 
 330         ret = wait_reg_mask(priv, reg, mask, val, 50, 40);
 331         *locked = (ret == 0) ? 1 : 0;
 332 
 333         return 0;
 334 }
 335 
 336 static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv,
 337                                           u8 *finished)
 338 {
 339         int ret = 0;
 340         u8 reg, mask, val;
 341 
 342         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 343                 reg = 0x1f;
 344                 mask = 0xC0;
 345                 val = 0x80;
 346         } else {
 347                 reg = 0xA4;
 348                 mask = 0x03;
 349                 val = 0x01;
 350         }
 351 
 352         ret = wait_reg_mask(priv, reg, mask, val, 10, 20);
 353         *finished = (ret == 0) ? 1 : 0;
 354 
 355         return 0;
 356 }
 357 
 358 static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 cpn,
 359         u8 *locked)
 360 {
 361         int err = 0;
 362         u8 ad_fini = 0;
 363         u8 t1, t2;
 364 
 365         if (gi == GI_945)
 366                 dprintk("try GI 945\n");
 367         else if (gi == GI_595)
 368                 dprintk("try GI 595\n");
 369         else if (gi == GI_420)
 370                 dprintk("try GI 420\n");
 371         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 372                 lgs8gxx_read_reg(priv, 0x0C, &t1);
 373                 lgs8gxx_read_reg(priv, 0x18, &t2);
 374                 t1 &= ~(GI_MASK);
 375                 t1 |= gi;
 376                 t2 &= 0xFE;
 377                 t2 |= cpn ? 0x01 : 0x00;
 378                 lgs8gxx_write_reg(priv, 0x0C, t1);
 379                 lgs8gxx_write_reg(priv, 0x18, t2);
 380         } else {
 381                 lgs8gxx_write_reg(priv, 0x04, gi);
 382         }
 383         lgs8gxx_soft_reset(priv);
 384         err = lgs8gxx_wait_ca_lock(priv, locked);
 385         if (err || !(*locked))
 386                 return err;
 387         err = lgs8gxx_is_autodetect_finished(priv, &ad_fini);
 388         if (err != 0)
 389                 return err;
 390         if (ad_fini) {
 391                 dprintk("auto detect finished\n");
 392         } else
 393                 *locked = 0;
 394 
 395         return 0;
 396 }
 397 
 398 static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
 399                                u8 *detected_param, u8 *gi)
 400 {
 401         int i, j;
 402         int err = 0;
 403         u8 locked = 0, tmp_gi;
 404 
 405         dprintk("%s\n", __func__);
 406 
 407         lgs8gxx_set_mode_auto(priv);
 408         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 409                 lgs8gxx_write_reg(priv, 0x67, 0xAA);
 410                 lgs8gxx_write_reg(priv, 0x6E, 0x3F);
 411         } else {
 412                 /* Guard Interval */
 413                 lgs8gxx_write_reg(priv, 0x03, 00);
 414         }
 415 
 416         for (i = 0; i < 2; i++) {
 417                 for (j = 0; j < 2; j++) {
 418                         tmp_gi = GI_945;
 419                         err = lgs8gxx_autolock_gi(priv, GI_945, j, &locked);
 420                         if (err)
 421                                 goto out;
 422                         if (locked)
 423                                 goto locked;
 424                 }
 425                 for (j = 0; j < 2; j++) {
 426                         tmp_gi = GI_420;
 427                         err = lgs8gxx_autolock_gi(priv, GI_420, j, &locked);
 428                         if (err)
 429                                 goto out;
 430                         if (locked)
 431                                 goto locked;
 432                 }
 433                 tmp_gi = GI_595;
 434                 err = lgs8gxx_autolock_gi(priv, GI_595, 1, &locked);
 435                 if (err)
 436                         goto out;
 437                 if (locked)
 438                         goto locked;
 439         }
 440 
 441 locked:
 442         if ((err == 0) && (locked == 1)) {
 443                 u8 t;
 444 
 445                 if (priv->config->prod != LGS8GXX_PROD_LGS8G75) {
 446                         lgs8gxx_read_reg(priv, 0xA2, &t);
 447                         *detected_param = t;
 448                 } else {
 449                         lgs8gxx_read_reg(priv, 0x1F, &t);
 450                         *detected_param = t & 0x3F;
 451                 }
 452 
 453                 if (tmp_gi == GI_945)
 454                         dprintk("GI 945 locked\n");
 455                 else if (tmp_gi == GI_595)
 456                         dprintk("GI 595 locked\n");
 457                 else if (tmp_gi == GI_420)
 458                         dprintk("GI 420 locked\n");
 459                 *gi = tmp_gi;
 460         }
 461         if (!locked)
 462                 err = -1;
 463 
 464 out:
 465         return err;
 466 }
 467 
 468 static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv)
 469 {
 470         s8 err;
 471         u8 gi = 0x2;
 472         u8 detected_param = 0;
 473 
 474         err = lgs8gxx_auto_detect(priv, &detected_param, &gi);
 475 
 476         if (err != 0) {
 477                 dprintk("lgs8gxx_auto_detect failed\n");
 478         } else
 479                 dprintk("detected param = 0x%02X\n", detected_param);
 480 
 481         /* Apply detected parameters */
 482         if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
 483                 u8 inter_leave_len = detected_param & TIM_MASK ;
 484                 /* Fix 8913 time interleaver detection bug */
 485                 inter_leave_len = (inter_leave_len == TIM_MIDDLE) ? 0x60 : 0x40;
 486                 detected_param &= CF_MASK | SC_MASK  | LGS_FEC_MASK;
 487                 detected_param |= inter_leave_len;
 488         }
 489         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 490                 u8 t;
 491                 lgs8gxx_read_reg(priv, 0x19, &t);
 492                 t &= 0x81;
 493                 t |= detected_param << 1;
 494                 lgs8gxx_write_reg(priv, 0x19, t);
 495         } else {
 496                 lgs8gxx_write_reg(priv, 0x7D, detected_param);
 497                 if (priv->config->prod == LGS8GXX_PROD_LGS8913)
 498                         lgs8gxx_write_reg(priv, 0xC0, detected_param);
 499         }
 500         /* lgs8gxx_soft_reset(priv); */
 501 
 502         /* Enter manual mode */
 503         lgs8gxx_set_mode_manual(priv);
 504 
 505         switch (gi) {
 506         case GI_945:
 507                 priv->curr_gi = 945; break;
 508         case GI_595:
 509                 priv->curr_gi = 595; break;
 510         case GI_420:
 511                 priv->curr_gi = 420; break;
 512         default:
 513                 priv->curr_gi = 945; break;
 514         }
 515 }
 516 
 517 static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
 518         u8 serial, u8 clk_pol, u8 clk_gated)
 519 {
 520         int ret = 0;
 521         u8 t, reg_addr;
 522 
 523         reg_addr = (priv->config->prod == LGS8GXX_PROD_LGS8G75) ? 0x30 : 0xC2;
 524         ret = lgs8gxx_read_reg(priv, reg_addr, &t);
 525         if (ret != 0)
 526                 return ret;
 527 
 528         t &= 0xF8;
 529         t |= serial ? TS_SERIAL : TS_PARALLEL;
 530         t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL;
 531         t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN;
 532 
 533         ret = lgs8gxx_write_reg(priv, reg_addr, t);
 534         if (ret != 0)
 535                 return ret;
 536 
 537         return 0;
 538 }
 539 
 540 /* A/D input peak-to-peak voltage range */
 541 static int lgs8g75_set_adc_vpp(struct lgs8gxx_state *priv,
 542         u8 sel)
 543 {
 544         u8 r26 = 0x73, r27 = 0x90;
 545 
 546         if (priv->config->prod != LGS8GXX_PROD_LGS8G75)
 547                 return 0;
 548 
 549         r26 |= (sel & 0x01) << 7;
 550         r27 |= (sel & 0x02) >> 1;
 551         lgs8gxx_write_reg(priv, 0x26, r26);
 552         lgs8gxx_write_reg(priv, 0x27, r27);
 553 
 554         return 0;
 555 }
 556 
 557 /* LGS8913 demod frontend functions */
 558 
 559 static int lgs8913_init(struct lgs8gxx_state *priv)
 560 {
 561         u8 t;
 562 
 563         /* LGS8913 specific */
 564         lgs8gxx_write_reg(priv, 0xc1, 0x3);
 565 
 566         lgs8gxx_read_reg(priv, 0x7c, &t);
 567         lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3);
 568 
 569         /* LGS8913 specific */
 570         lgs8gxx_read_reg(priv, 0xc3, &t);
 571         lgs8gxx_write_reg(priv, 0xc3, t&0x10);
 572 
 573 
 574         return 0;
 575 }
 576 
 577 static int lgs8g75_init_data(struct lgs8gxx_state *priv)
 578 {
 579         const struct firmware *fw;
 580         int rc;
 581         int i;
 582 
 583         rc = request_firmware(&fw, LGS8GXX_FIRMWARE, &priv->i2c->dev);
 584         if (rc)
 585                 return rc;
 586 
 587         lgs8gxx_write_reg(priv, 0xC6, 0x40);
 588 
 589         lgs8gxx_write_reg(priv, 0x3D, 0x04);
 590         lgs8gxx_write_reg(priv, 0x39, 0x00);
 591 
 592         lgs8gxx_write_reg(priv, 0x3A, 0x00);
 593         lgs8gxx_write_reg(priv, 0x38, 0x00);
 594         lgs8gxx_write_reg(priv, 0x3B, 0x00);
 595         lgs8gxx_write_reg(priv, 0x38, 0x00);
 596 
 597         for (i = 0; i < fw->size; i++) {
 598                 lgs8gxx_write_reg(priv, 0x38, 0x00);
 599                 lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff));
 600                 lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8));
 601                 lgs8gxx_write_reg(priv, 0x3C, fw->data[i]);
 602         }
 603 
 604         lgs8gxx_write_reg(priv, 0x38, 0x00);
 605 
 606         release_firmware(fw);
 607         return 0;
 608 }
 609 
 610 static int lgs8gxx_init(struct dvb_frontend *fe)
 611 {
 612         struct lgs8gxx_state *priv =
 613                 (struct lgs8gxx_state *)fe->demodulator_priv;
 614         const struct lgs8gxx_config *config = priv->config;
 615         u8 data = 0;
 616         s8 err;
 617         dprintk("%s\n", __func__);
 618 
 619         lgs8gxx_read_reg(priv, 0, &data);
 620         dprintk("reg 0 = 0x%02X\n", data);
 621 
 622         if (config->prod == LGS8GXX_PROD_LGS8G75)
 623                 lgs8g75_set_adc_vpp(priv, config->adc_vpp);
 624 
 625         /* Setup MPEG output format */
 626         err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts,
 627                                     config->ts_clk_pol,
 628                                     config->ts_clk_gated);
 629         if (err != 0)
 630                 return -EIO;
 631 
 632         if (config->prod == LGS8GXX_PROD_LGS8913)
 633                 lgs8913_init(priv);
 634         lgs8gxx_set_if_freq(priv, priv->config->if_freq);
 635         lgs8gxx_set_ad_mode(priv);
 636 
 637         return 0;
 638 }
 639 
 640 static void lgs8gxx_release(struct dvb_frontend *fe)
 641 {
 642         struct lgs8gxx_state *state = fe->demodulator_priv;
 643         dprintk("%s\n", __func__);
 644 
 645         kfree(state);
 646 }
 647 
 648 
 649 static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len)
 650 {
 651         struct lgs8gxx_state *priv = fe->demodulator_priv;
 652 
 653         if (len != 2)
 654                 return -EINVAL;
 655 
 656         return lgs8gxx_write_reg(priv, buf[0], buf[1]);
 657 }
 658 
 659 static int lgs8gxx_set_fe(struct dvb_frontend *fe)
 660 {
 661         struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
 662         struct lgs8gxx_state *priv = fe->demodulator_priv;
 663 
 664         dprintk("%s\n", __func__);
 665 
 666         /* set frequency */
 667         if (fe->ops.tuner_ops.set_params) {
 668                 fe->ops.tuner_ops.set_params(fe);
 669                 if (fe->ops.i2c_gate_ctrl)
 670                         fe->ops.i2c_gate_ctrl(fe, 0);
 671         }
 672 
 673         /* start auto lock */
 674         lgs8gxx_auto_lock(priv);
 675 
 676         msleep(10);
 677 
 678         /* TODO: get real readings from device */
 679 
 680         /* bandwidth */
 681         fe_params->bandwidth_hz = 8000000;
 682 
 683         fe_params->code_rate_HP = FEC_AUTO;
 684         fe_params->code_rate_LP = FEC_AUTO;
 685 
 686         fe_params->modulation = QAM_AUTO;
 687 
 688         /* transmission mode */
 689         fe_params->transmission_mode = TRANSMISSION_MODE_AUTO;
 690 
 691         /* guard interval */
 692         fe_params->guard_interval = GUARD_INTERVAL_AUTO;
 693 
 694         /* hierarchy */
 695         fe_params->hierarchy = HIERARCHY_NONE;
 696 
 697         return 0;
 698 }
 699 
 700 static
 701 int lgs8gxx_get_tune_settings(struct dvb_frontend *fe,
 702                               struct dvb_frontend_tune_settings *fesettings)
 703 {
 704         /* FIXME: copy from tda1004x.c */
 705         fesettings->min_delay_ms = 800;
 706         fesettings->step_size = 0;
 707         fesettings->max_drift = 0;
 708         return 0;
 709 }
 710 
 711 static int lgs8gxx_read_status(struct dvb_frontend *fe,
 712                                enum fe_status *fe_status)
 713 {
 714         struct lgs8gxx_state *priv = fe->demodulator_priv;
 715         s8 ret;
 716         u8 t, locked = 0;
 717 
 718         dprintk("%s\n", __func__);
 719         *fe_status = 0;
 720 
 721         lgs8gxx_get_afc_phase(priv);
 722         lgs8gxx_is_locked(priv, &locked);
 723         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 724                 if (locked)
 725                         *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
 726                                 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
 727                 return 0;
 728         }
 729 
 730         ret = lgs8gxx_read_reg(priv, 0x4B, &t);
 731         if (ret != 0)
 732                 return -EIO;
 733 
 734         dprintk("Reg 0x4B: 0x%02X\n", t);
 735 
 736         *fe_status = 0;
 737         if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
 738                 if ((t & 0x40) == 0x40)
 739                         *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
 740                 if ((t & 0x80) == 0x80)
 741                         *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC |
 742                                 FE_HAS_LOCK;
 743         } else {
 744                 if ((t & 0x80) == 0x80)
 745                         *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
 746                                 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
 747         }
 748 
 749         /* success */
 750         dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
 751         return 0;
 752 }
 753 
 754 static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal)
 755 {
 756         u16 v;
 757         u8 agc_lvl[2], cat;
 758 
 759         dprintk("%s()\n", __func__);
 760         lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]);
 761         lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]);
 762 
 763         v = agc_lvl[0];
 764         v <<= 8;
 765         v |= agc_lvl[1];
 766 
 767         dprintk("agc_lvl: 0x%04X\n", v);
 768 
 769         if (v < 0x100)
 770                 cat = 0;
 771         else if (v < 0x190)
 772                 cat = 5;
 773         else if (v < 0x2A8)
 774                 cat = 4;
 775         else if (v < 0x381)
 776                 cat = 3;
 777         else if (v < 0x400)
 778                 cat = 2;
 779         else if (v == 0x400)
 780                 cat = 1;
 781         else
 782                 cat = 0;
 783 
 784         *signal = cat * 65535 / 5;
 785 
 786         return 0;
 787 }
 788 
 789 static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
 790 {
 791         u8 t; s8 ret;
 792         s16 max_strength = 0;
 793         u8 str;
 794         u16 i, gi = priv->curr_gi;
 795 
 796         dprintk("%s\n", __func__);
 797 
 798         ret = lgs8gxx_read_reg(priv, 0x4B, &t);
 799         if (ret != 0)
 800                 return -EIO;
 801 
 802         if (fake_signal_str) {
 803                 if ((t & 0xC0) == 0xC0) {
 804                         dprintk("Fake signal strength\n");
 805                         *signal = 0x7FFF;
 806                 } else
 807                         *signal = 0;
 808                 return 0;
 809         }
 810 
 811         dprintk("gi = %d\n", gi);
 812         for (i = 0; i < gi; i++) {
 813 
 814                 if ((i & 0xFF) == 0)
 815                         lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8));
 816                 lgs8gxx_write_reg(priv, 0x83, i & 0xFF);
 817 
 818                 lgs8gxx_read_reg(priv, 0x94, &str);
 819                 if (max_strength < str)
 820                         max_strength = str;
 821         }
 822 
 823         *signal = max_strength;
 824         dprintk("%s: signal=0x%02X\n", __func__, *signal);
 825 
 826         lgs8gxx_read_reg(priv, 0x95, &t);
 827         dprintk("%s: AVG Noise=0x%02X\n", __func__, t);
 828 
 829         return 0;
 830 }
 831 
 832 static int lgs8g75_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
 833 {
 834         u8 t;
 835         s16 v = 0;
 836 
 837         dprintk("%s\n", __func__);
 838 
 839         lgs8gxx_read_reg(priv, 0xB1, &t);
 840         v |= t;
 841         v <<= 8;
 842         lgs8gxx_read_reg(priv, 0xB0, &t);
 843         v |= t;
 844 
 845         *signal = v;
 846         dprintk("%s: signal=0x%02X\n", __func__, *signal);
 847 
 848         return 0;
 849 }
 850 
 851 static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
 852 {
 853         struct lgs8gxx_state *priv = fe->demodulator_priv;
 854 
 855         if (priv->config->prod == LGS8GXX_PROD_LGS8913)
 856                 return lgs8913_read_signal_strength(priv, signal);
 857         else if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
 858                 return lgs8g75_read_signal_strength(priv, signal);
 859         else
 860                 return lgs8gxx_read_signal_agc(priv, signal);
 861 }
 862 
 863 static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
 864 {
 865         struct lgs8gxx_state *priv = fe->demodulator_priv;
 866         u8 t;
 867         *snr = 0;
 868 
 869         if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
 870                 lgs8gxx_read_reg(priv, 0x34, &t);
 871         else
 872                 lgs8gxx_read_reg(priv, 0x95, &t);
 873         dprintk("AVG Noise=0x%02X\n", t);
 874         *snr = 256 - t;
 875         *snr <<= 8;
 876         dprintk("snr=0x%x\n", *snr);
 877 
 878         return 0;
 879 }
 880 
 881 static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 882 {
 883         *ucblocks = 0;
 884         dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
 885         return 0;
 886 }
 887 
 888 static void packet_counter_start(struct lgs8gxx_state *priv)
 889 {
 890         u8 orig, t;
 891 
 892         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 893                 lgs8gxx_read_reg(priv, 0x30, &orig);
 894                 orig &= 0xE7;
 895                 t = orig | 0x10;
 896                 lgs8gxx_write_reg(priv, 0x30, t);
 897                 t = orig | 0x18;
 898                 lgs8gxx_write_reg(priv, 0x30, t);
 899                 t = orig | 0x10;
 900                 lgs8gxx_write_reg(priv, 0x30, t);
 901         } else {
 902                 lgs8gxx_write_reg(priv, 0xC6, 0x01);
 903                 lgs8gxx_write_reg(priv, 0xC6, 0x41);
 904                 lgs8gxx_write_reg(priv, 0xC6, 0x01);
 905         }
 906 }
 907 
 908 static void packet_counter_stop(struct lgs8gxx_state *priv)
 909 {
 910         u8 t;
 911 
 912         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 913                 lgs8gxx_read_reg(priv, 0x30, &t);
 914                 t &= 0xE7;
 915                 lgs8gxx_write_reg(priv, 0x30, t);
 916         } else {
 917                 lgs8gxx_write_reg(priv, 0xC6, 0x81);
 918         }
 919 }
 920 
 921 static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
 922 {
 923         struct lgs8gxx_state *priv = fe->demodulator_priv;
 924         u8 reg_err, reg_total, t;
 925         u32 total_cnt = 0, err_cnt = 0;
 926         int i;
 927 
 928         dprintk("%s\n", __func__);
 929 
 930         packet_counter_start(priv);
 931         msleep(200);
 932         packet_counter_stop(priv);
 933 
 934         if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 935                 reg_total = 0x28; reg_err = 0x2C;
 936         } else {
 937                 reg_total = 0xD0; reg_err = 0xD4;
 938         }
 939 
 940         for (i = 0; i < 4; i++) {
 941                 total_cnt <<= 8;
 942                 lgs8gxx_read_reg(priv, reg_total+3-i, &t);
 943                 total_cnt |= t;
 944         }
 945         for (i = 0; i < 4; i++) {
 946                 err_cnt <<= 8;
 947                 lgs8gxx_read_reg(priv, reg_err+3-i, &t);
 948                 err_cnt |= t;
 949         }
 950         dprintk("error=%d total=%d\n", err_cnt, total_cnt);
 951 
 952         if (total_cnt == 0)
 953                 *ber = 0;
 954         else
 955                 *ber = err_cnt * 100 / total_cnt;
 956 
 957         dprintk("%s: ber=0x%x\n", __func__, *ber);
 958         return 0;
 959 }
 960 
 961 static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 962 {
 963         struct lgs8gxx_state *priv = fe->demodulator_priv;
 964 
 965         if (priv->config->tuner_address == 0)
 966                 return 0;
 967         if (enable) {
 968                 u8 v = 0x80 | priv->config->tuner_address;
 969                 return lgs8gxx_write_reg(priv, 0x01, v);
 970         }
 971         return lgs8gxx_write_reg(priv, 0x01, 0);
 972 }
 973 
 974 static const struct dvb_frontend_ops lgs8gxx_ops = {
 975         .delsys = { SYS_DTMB },
 976         .info = {
 977                 .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH",
 978                 .frequency_min_hz = 474 * MHz,
 979                 .frequency_max_hz = 858 * MHz,
 980                 .frequency_stepsize_hz = 10 * kHz,
 981                 .caps =
 982                         FE_CAN_FEC_AUTO |
 983                         FE_CAN_QAM_AUTO |
 984                         FE_CAN_TRANSMISSION_MODE_AUTO |
 985                         FE_CAN_GUARD_INTERVAL_AUTO
 986         },
 987 
 988         .release = lgs8gxx_release,
 989 
 990         .init = lgs8gxx_init,
 991         .write = lgs8gxx_write,
 992         .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl,
 993 
 994         .set_frontend = lgs8gxx_set_fe,
 995         .get_tune_settings = lgs8gxx_get_tune_settings,
 996 
 997         .read_status = lgs8gxx_read_status,
 998         .read_ber = lgs8gxx_read_ber,
 999         .read_signal_strength = lgs8gxx_read_signal_strength,
1000         .read_snr = lgs8gxx_read_snr,
1001         .read_ucblocks = lgs8gxx_read_ucblocks,
1002 };
1003 
1004 struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
1005         struct i2c_adapter *i2c)
1006 {
1007         struct lgs8gxx_state *priv = NULL;
1008         u8 data = 0;
1009 
1010         dprintk("%s()\n", __func__);
1011 
1012         if (config == NULL || i2c == NULL)
1013                 return NULL;
1014 
1015         priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL);
1016         if (priv == NULL)
1017                 goto error_out;
1018 
1019         priv->config = config;
1020         priv->i2c = i2c;
1021 
1022         /* check if the demod is there */
1023         if (lgs8gxx_read_reg(priv, 0, &data) != 0) {
1024                 dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n",
1025                         __func__, priv->config->demod_address);
1026                 goto error_out;
1027         }
1028 
1029         lgs8gxx_read_reg(priv, 1, &data);
1030 
1031         memcpy(&priv->frontend.ops, &lgs8gxx_ops,
1032                sizeof(struct dvb_frontend_ops));
1033         priv->frontend.demodulator_priv = priv;
1034 
1035         if (config->prod == LGS8GXX_PROD_LGS8G75)
1036                 lgs8g75_init_data(priv);
1037 
1038         return &priv->frontend;
1039 
1040 error_out:
1041         dprintk("%s() error_out\n", __func__);
1042         kfree(priv);
1043         return NULL;
1044 
1045 }
1046 EXPORT_SYMBOL(lgs8gxx_attach);
1047 
1048 MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver");
1049 MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
1050 MODULE_LICENSE("GPL");
1051 MODULE_FIRMWARE(LGS8GXX_FIRMWARE);

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