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