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