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        struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
 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        /* TODO: get real readings from device */
 693
 694        /* bandwidth */
 695        fe_params->bandwidth_hz = 8000000;
 696
 697        fe_params->code_rate_HP = FEC_AUTO;
 698        fe_params->code_rate_LP = FEC_AUTO;
 699
 700        fe_params->modulation = QAM_AUTO;
 701
 702        /* transmission mode */
 703        fe_params->transmission_mode = TRANSMISSION_MODE_AUTO;
 704
 705        /* guard interval */
 706        fe_params->guard_interval = GUARD_INTERVAL_AUTO;
 707
 708        /* hierarchy */
 709        fe_params->hierarchy = HIERARCHY_NONE;
 710
 711        return 0;
 712}
 713
 714static
 715int lgs8gxx_get_tune_settings(struct dvb_frontend *fe,
 716                              struct dvb_frontend_tune_settings *fesettings)
 717{
 718        /* FIXME: copy from tda1004x.c */
 719        fesettings->min_delay_ms = 800;
 720        fesettings->step_size = 0;
 721        fesettings->max_drift = 0;
 722        return 0;
 723}
 724
 725static int lgs8gxx_read_status(struct dvb_frontend *fe,
 726                               enum fe_status *fe_status)
 727{
 728        struct lgs8gxx_state *priv = fe->demodulator_priv;
 729        s8 ret;
 730        u8 t, locked = 0;
 731
 732        dprintk("%s\n", __func__);
 733        *fe_status = 0;
 734
 735        lgs8gxx_get_afc_phase(priv);
 736        lgs8gxx_is_locked(priv, &locked);
 737        if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 738                if (locked)
 739                        *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
 740                                FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
 741                return 0;
 742        }
 743
 744        ret = lgs8gxx_read_reg(priv, 0x4B, &t);
 745        if (ret != 0)
 746                return -EIO;
 747
 748        dprintk("Reg 0x4B: 0x%02X\n", t);
 749
 750        *fe_status = 0;
 751        if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
 752                if ((t & 0x40) == 0x40)
 753                        *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
 754                if ((t & 0x80) == 0x80)
 755                        *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC |
 756                                FE_HAS_LOCK;
 757        } else {
 758                if ((t & 0x80) == 0x80)
 759                        *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
 760                                FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
 761        }
 762
 763        /* success */
 764        dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
 765        return 0;
 766}
 767
 768static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal)
 769{
 770        u16 v;
 771        u8 agc_lvl[2], cat;
 772
 773        dprintk("%s()\n", __func__);
 774        lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]);
 775        lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]);
 776
 777        v = agc_lvl[0];
 778        v <<= 8;
 779        v |= agc_lvl[1];
 780
 781        dprintk("agc_lvl: 0x%04X\n", v);
 782
 783        if (v < 0x100)
 784                cat = 0;
 785        else if (v < 0x190)
 786                cat = 5;
 787        else if (v < 0x2A8)
 788                cat = 4;
 789        else if (v < 0x381)
 790                cat = 3;
 791        else if (v < 0x400)
 792                cat = 2;
 793        else if (v == 0x400)
 794                cat = 1;
 795        else
 796                cat = 0;
 797
 798        *signal = cat * 65535 / 5;
 799
 800        return 0;
 801}
 802
 803static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
 804{
 805        u8 t; s8 ret;
 806        s16 max_strength = 0;
 807        u8 str;
 808        u16 i, gi = priv->curr_gi;
 809
 810        dprintk("%s\n", __func__);
 811
 812        ret = lgs8gxx_read_reg(priv, 0x4B, &t);
 813        if (ret != 0)
 814                return -EIO;
 815
 816        if (fake_signal_str) {
 817                if ((t & 0xC0) == 0xC0) {
 818                        dprintk("Fake signal strength\n");
 819                        *signal = 0x7FFF;
 820                } else
 821                        *signal = 0;
 822                return 0;
 823        }
 824
 825        dprintk("gi = %d\n", gi);
 826        for (i = 0; i < gi; i++) {
 827
 828                if ((i & 0xFF) == 0)
 829                        lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8));
 830                lgs8gxx_write_reg(priv, 0x83, i & 0xFF);
 831
 832                lgs8gxx_read_reg(priv, 0x94, &str);
 833                if (max_strength < str)
 834                        max_strength = str;
 835        }
 836
 837        *signal = max_strength;
 838        dprintk("%s: signal=0x%02X\n", __func__, *signal);
 839
 840        lgs8gxx_read_reg(priv, 0x95, &t);
 841        dprintk("%s: AVG Noise=0x%02X\n", __func__, t);
 842
 843        return 0;
 844}
 845
 846static int lgs8g75_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
 847{
 848        u8 t;
 849        s16 v = 0;
 850
 851        dprintk("%s\n", __func__);
 852
 853        lgs8gxx_read_reg(priv, 0xB1, &t);
 854        v |= t;
 855        v <<= 8;
 856        lgs8gxx_read_reg(priv, 0xB0, &t);
 857        v |= t;
 858
 859        *signal = v;
 860        dprintk("%s: signal=0x%02X\n", __func__, *signal);
 861
 862        return 0;
 863}
 864
 865static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
 866{
 867        struct lgs8gxx_state *priv = fe->demodulator_priv;
 868
 869        if (priv->config->prod == LGS8GXX_PROD_LGS8913)
 870                return lgs8913_read_signal_strength(priv, signal);
 871        else if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
 872                return lgs8g75_read_signal_strength(priv, signal);
 873        else
 874                return lgs8gxx_read_signal_agc(priv, signal);
 875}
 876
 877static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
 878{
 879        struct lgs8gxx_state *priv = fe->demodulator_priv;
 880        u8 t;
 881        *snr = 0;
 882
 883        if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
 884                lgs8gxx_read_reg(priv, 0x34, &t);
 885        else
 886                lgs8gxx_read_reg(priv, 0x95, &t);
 887        dprintk("AVG Noise=0x%02X\n", t);
 888        *snr = 256 - t;
 889        *snr <<= 8;
 890        dprintk("snr=0x%x\n", *snr);
 891
 892        return 0;
 893}
 894
 895static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 896{
 897        *ucblocks = 0;
 898        dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
 899        return 0;
 900}
 901
 902static void packet_counter_start(struct lgs8gxx_state *priv)
 903{
 904        u8 orig, t;
 905
 906        if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 907                lgs8gxx_read_reg(priv, 0x30, &orig);
 908                orig &= 0xE7;
 909                t = orig | 0x10;
 910                lgs8gxx_write_reg(priv, 0x30, t);
 911                t = orig | 0x18;
 912                lgs8gxx_write_reg(priv, 0x30, t);
 913                t = orig | 0x10;
 914                lgs8gxx_write_reg(priv, 0x30, t);
 915        } else {
 916                lgs8gxx_write_reg(priv, 0xC6, 0x01);
 917                lgs8gxx_write_reg(priv, 0xC6, 0x41);
 918                lgs8gxx_write_reg(priv, 0xC6, 0x01);
 919        }
 920}
 921
 922static void packet_counter_stop(struct lgs8gxx_state *priv)
 923{
 924        u8 t;
 925
 926        if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 927                lgs8gxx_read_reg(priv, 0x30, &t);
 928                t &= 0xE7;
 929                lgs8gxx_write_reg(priv, 0x30, t);
 930        } else {
 931                lgs8gxx_write_reg(priv, 0xC6, 0x81);
 932        }
 933}
 934
 935static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
 936{
 937        struct lgs8gxx_state *priv = fe->demodulator_priv;
 938        u8 reg_err, reg_total, t;
 939        u32 total_cnt = 0, err_cnt = 0;
 940        int i;
 941
 942        dprintk("%s\n", __func__);
 943
 944        packet_counter_start(priv);
 945        msleep(200);
 946        packet_counter_stop(priv);
 947
 948        if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
 949                reg_total = 0x28; reg_err = 0x2C;
 950        } else {
 951                reg_total = 0xD0; reg_err = 0xD4;
 952        }
 953
 954        for (i = 0; i < 4; i++) {
 955                total_cnt <<= 8;
 956                lgs8gxx_read_reg(priv, reg_total+3-i, &t);
 957                total_cnt |= t;
 958        }
 959        for (i = 0; i < 4; i++) {
 960                err_cnt <<= 8;
 961                lgs8gxx_read_reg(priv, reg_err+3-i, &t);
 962                err_cnt |= t;
 963        }
 964        dprintk("error=%d total=%d\n", err_cnt, total_cnt);
 965
 966        if (total_cnt == 0)
 967                *ber = 0;
 968        else
 969                *ber = err_cnt * 100 / total_cnt;
 970
 971        dprintk("%s: ber=0x%x\n", __func__, *ber);
 972        return 0;
 973}
 974
 975static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 976{
 977        struct lgs8gxx_state *priv = fe->demodulator_priv;
 978
 979        if (priv->config->tuner_address == 0)
 980                return 0;
 981        if (enable) {
 982                u8 v = 0x80 | priv->config->tuner_address;
 983                return lgs8gxx_write_reg(priv, 0x01, v);
 984        }
 985        return lgs8gxx_write_reg(priv, 0x01, 0);
 986}
 987
 988static struct dvb_frontend_ops lgs8gxx_ops = {
 989        .delsys = { SYS_DTMB },
 990        .info = {
 991                .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH",
 992                .frequency_min = 474000000,
 993                .frequency_max = 858000000,
 994                .frequency_stepsize = 10000,
 995                .caps =
 996                        FE_CAN_FEC_AUTO |
 997                        FE_CAN_QAM_AUTO |
 998                        FE_CAN_TRANSMISSION_MODE_AUTO |
 999                        FE_CAN_GUARD_INTERVAL_AUTO
1000        },
1001
1002        .release = lgs8gxx_release,
1003
1004        .init = lgs8gxx_init,
1005        .write = lgs8gxx_write,
1006        .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl,
1007
1008        .set_frontend = lgs8gxx_set_fe,
1009        .get_tune_settings = lgs8gxx_get_tune_settings,
1010
1011        .read_status = lgs8gxx_read_status,
1012        .read_ber = lgs8gxx_read_ber,
1013        .read_signal_strength = lgs8gxx_read_signal_strength,
1014        .read_snr = lgs8gxx_read_snr,
1015        .read_ucblocks = lgs8gxx_read_ucblocks,
1016};
1017
1018struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
1019        struct i2c_adapter *i2c)
1020{
1021        struct lgs8gxx_state *priv = NULL;
1022        u8 data = 0;
1023
1024        dprintk("%s()\n", __func__);
1025
1026        if (config == NULL || i2c == NULL)
1027                return NULL;
1028
1029        priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL);
1030        if (priv == NULL)
1031                goto error_out;
1032
1033        priv->config = config;
1034        priv->i2c = i2c;
1035
1036        /* check if the demod is there */
1037        if (lgs8gxx_read_reg(priv, 0, &data) != 0) {
1038                dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n",
1039                        __func__, priv->config->demod_address);
1040                goto error_out;
1041        }
1042
1043        lgs8gxx_read_reg(priv, 1, &data);
1044
1045        memcpy(&priv->frontend.ops, &lgs8gxx_ops,
1046               sizeof(struct dvb_frontend_ops));
1047        priv->frontend.demodulator_priv = priv;
1048
1049        if (config->prod == LGS8GXX_PROD_LGS8G75)
1050                lgs8g75_init_data(priv);
1051
1052        return &priv->frontend;
1053
1054error_out:
1055        dprintk("%s() error_out\n", __func__);
1056        kfree(priv);
1057        return NULL;
1058
1059}
1060EXPORT_SYMBOL(lgs8gxx_attach);
1061
1062MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver");
1063MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
1064MODULE_LICENSE("GPL");
1065MODULE_FIRMWARE(LGS8GXX_FIRMWARE);
1066