linux/drivers/media/tuners/tda827x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *
   4 * (c) 2005 Hartmut Hackmann
   5 * (c) 2007 Michael Krufky
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/slab.h>
  10#include <asm/types.h>
  11#include <linux/dvb/frontend.h>
  12#include <linux/videodev2.h>
  13
  14#include "tda827x.h"
  15
  16static int debug;
  17module_param(debug, int, 0644);
  18MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
  19
  20#define dprintk(args...) \
  21        do {                                        \
  22                if (debug) printk(KERN_DEBUG "tda827x: " args); \
  23        } while (0)
  24
  25struct tda827x_priv {
  26        int i2c_addr;
  27        struct i2c_adapter *i2c_adap;
  28        struct tda827x_config *cfg;
  29
  30        unsigned int sgIF;
  31        unsigned char lpsel;
  32
  33        u32 frequency;
  34        u32 bandwidth;
  35};
  36
  37static void tda827x_set_std(struct dvb_frontend *fe,
  38                            struct analog_parameters *params)
  39{
  40        struct tda827x_priv *priv = fe->tuner_priv;
  41        char *mode;
  42
  43        priv->lpsel = 0;
  44        if (params->std & V4L2_STD_MN) {
  45                priv->sgIF = 92;
  46                priv->lpsel = 1;
  47                mode = "MN";
  48        } else if (params->std & V4L2_STD_B) {
  49                priv->sgIF = 108;
  50                mode = "B";
  51        } else if (params->std & V4L2_STD_GH) {
  52                priv->sgIF = 124;
  53                mode = "GH";
  54        } else if (params->std & V4L2_STD_PAL_I) {
  55                priv->sgIF = 124;
  56                mode = "I";
  57        } else if (params->std & V4L2_STD_DK) {
  58                priv->sgIF = 124;
  59                mode = "DK";
  60        } else if (params->std & V4L2_STD_SECAM_L) {
  61                priv->sgIF = 124;
  62                mode = "L";
  63        } else if (params->std & V4L2_STD_SECAM_LC) {
  64                priv->sgIF = 20;
  65                mode = "LC";
  66        } else {
  67                priv->sgIF = 124;
  68                mode = "xx";
  69        }
  70
  71        if (params->mode == V4L2_TUNER_RADIO) {
  72                priv->sgIF = 88; /* if frequency is 5.5 MHz */
  73                dprintk("setting tda827x to radio FM\n");
  74        } else
  75                dprintk("setting tda827x to system %s\n", mode);
  76}
  77
  78
  79/* ------------------------------------------------------------------ */
  80
  81struct tda827x_data {
  82        u32 lomax;
  83        u8  spd;
  84        u8  bs;
  85        u8  bp;
  86        u8  cp;
  87        u8  gc3;
  88        u8 div1p5;
  89};
  90
  91static const struct tda827x_data tda827x_table[] = {
  92        { .lomax =  62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
  93        { .lomax =  66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
  94        { .lomax =  76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
  95        { .lomax =  84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
  96        { .lomax =  93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
  97        { .lomax =  98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
  98        { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
  99        { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
 100        { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
 101        { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
 102        { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
 103        { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
 104        { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
 105        { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
 106        { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
 107        { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
 108        { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
 109        { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
 110        { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
 111        { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
 112        { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
 113        { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
 114        { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
 115        { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
 116        { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
 117        { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
 118        { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
 119        { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
 120        { .lomax =         0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
 121};
 122
 123static int tuner_transfer(struct dvb_frontend *fe,
 124                          struct i2c_msg *msg,
 125                          const int size)
 126{
 127        int rc;
 128        struct tda827x_priv *priv = fe->tuner_priv;
 129
 130        if (fe->ops.i2c_gate_ctrl)
 131                fe->ops.i2c_gate_ctrl(fe, 1);
 132        rc = i2c_transfer(priv->i2c_adap, msg, size);
 133        if (fe->ops.i2c_gate_ctrl)
 134                fe->ops.i2c_gate_ctrl(fe, 0);
 135
 136        if (rc >= 0 && rc != size)
 137                return -EIO;
 138
 139        return rc;
 140}
 141
 142static int tda827xo_set_params(struct dvb_frontend *fe)
 143{
 144        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 145        struct tda827x_priv *priv = fe->tuner_priv;
 146        u8 buf[14];
 147        int rc;
 148
 149        struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 150                               .buf = buf, .len = sizeof(buf) };
 151        int i, tuner_freq, if_freq;
 152        u32 N;
 153
 154        dprintk("%s:\n", __func__);
 155        if (c->bandwidth_hz == 0) {
 156                if_freq = 5000000;
 157        } else if (c->bandwidth_hz <= 6000000) {
 158                if_freq = 4000000;
 159        } else if (c->bandwidth_hz <= 7000000) {
 160                if_freq = 4500000;
 161        } else {        /* 8 MHz */
 162                if_freq = 5000000;
 163        }
 164        tuner_freq = c->frequency;
 165
 166        i = 0;
 167        while (tda827x_table[i].lomax < tuner_freq) {
 168                if (tda827x_table[i + 1].lomax == 0)
 169                        break;
 170                i++;
 171        }
 172
 173        tuner_freq += if_freq;
 174
 175        N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
 176        buf[0] = 0;
 177        buf[1] = (N>>8) | 0x40;
 178        buf[2] = N & 0xff;
 179        buf[3] = 0;
 180        buf[4] = 0x52;
 181        buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
 182                                (tda827x_table[i].bs << 3) +
 183                                tda827x_table[i].bp;
 184        buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
 185        buf[7] = 0xbf;
 186        buf[8] = 0x2a;
 187        buf[9] = 0x05;
 188        buf[10] = 0xff;
 189        buf[11] = 0x00;
 190        buf[12] = 0x00;
 191        buf[13] = 0x40;
 192
 193        msg.len = 14;
 194        rc = tuner_transfer(fe, &msg, 1);
 195        if (rc < 0)
 196                goto err;
 197
 198        msleep(500);
 199        /* correct CP value */
 200        buf[0] = 0x30;
 201        buf[1] = 0x50 + tda827x_table[i].cp;
 202        msg.len = 2;
 203
 204        rc = tuner_transfer(fe, &msg, 1);
 205        if (rc < 0)
 206                goto err;
 207
 208        priv->frequency = c->frequency;
 209        priv->bandwidth = c->bandwidth_hz;
 210
 211        return 0;
 212
 213err:
 214        printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
 215               __func__, priv->i2c_addr << 1);
 216        return rc;
 217}
 218
 219static int tda827xo_sleep(struct dvb_frontend *fe)
 220{
 221        struct tda827x_priv *priv = fe->tuner_priv;
 222        static u8 buf[] = { 0x30, 0xd0 };
 223        struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 224                               .buf = buf, .len = sizeof(buf) };
 225
 226        dprintk("%s:\n", __func__);
 227        tuner_transfer(fe, &msg, 1);
 228
 229        if (priv->cfg && priv->cfg->sleep)
 230                priv->cfg->sleep(fe);
 231
 232        return 0;
 233}
 234
 235/* ------------------------------------------------------------------ */
 236
 237static int tda827xo_set_analog_params(struct dvb_frontend *fe,
 238                                      struct analog_parameters *params)
 239{
 240        unsigned char tuner_reg[8];
 241        unsigned char reg2[2];
 242        u32 N;
 243        int i;
 244        struct tda827x_priv *priv = fe->tuner_priv;
 245        struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
 246        unsigned int freq = params->frequency;
 247
 248        tda827x_set_std(fe, params);
 249
 250        if (params->mode == V4L2_TUNER_RADIO)
 251                freq = freq / 1000;
 252
 253        N = freq + priv->sgIF;
 254
 255        i = 0;
 256        while (tda827x_table[i].lomax < N * 62500) {
 257                if (tda827x_table[i + 1].lomax == 0)
 258                        break;
 259                i++;
 260        }
 261
 262        N = N << tda827x_table[i].spd;
 263
 264        tuner_reg[0] = 0;
 265        tuner_reg[1] = (unsigned char)(N>>8);
 266        tuner_reg[2] = (unsigned char) N;
 267        tuner_reg[3] = 0x40;
 268        tuner_reg[4] = 0x52 + (priv->lpsel << 5);
 269        tuner_reg[5] = (tda827x_table[i].spd    << 6) +
 270                       (tda827x_table[i].div1p5 << 5) +
 271                       (tda827x_table[i].bs     << 3) + tda827x_table[i].bp;
 272        tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
 273        tuner_reg[7] = 0x8f;
 274
 275        msg.buf = tuner_reg;
 276        msg.len = 8;
 277        tuner_transfer(fe, &msg, 1);
 278
 279        msg.buf = reg2;
 280        msg.len = 2;
 281        reg2[0] = 0x80;
 282        reg2[1] = 0;
 283        tuner_transfer(fe, &msg, 1);
 284
 285        reg2[0] = 0x60;
 286        reg2[1] = 0xbf;
 287        tuner_transfer(fe, &msg, 1);
 288
 289        reg2[0] = 0x30;
 290        reg2[1] = tuner_reg[4] + 0x80;
 291        tuner_transfer(fe, &msg, 1);
 292
 293        msleep(1);
 294        reg2[0] = 0x30;
 295        reg2[1] = tuner_reg[4] + 4;
 296        tuner_transfer(fe, &msg, 1);
 297
 298        msleep(1);
 299        reg2[0] = 0x30;
 300        reg2[1] = tuner_reg[4];
 301        tuner_transfer(fe, &msg, 1);
 302
 303        msleep(550);
 304        reg2[0] = 0x30;
 305        reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
 306        tuner_transfer(fe, &msg, 1);
 307
 308        reg2[0] = 0x60;
 309        reg2[1] = 0x3f;
 310        tuner_transfer(fe, &msg, 1);
 311
 312        reg2[0] = 0x80;
 313        reg2[1] = 0x08;   /* Vsync en */
 314        tuner_transfer(fe, &msg, 1);
 315
 316        priv->frequency = params->frequency;
 317
 318        return 0;
 319}
 320
 321static void tda827xo_agcf(struct dvb_frontend *fe)
 322{
 323        struct tda827x_priv *priv = fe->tuner_priv;
 324        unsigned char data[] = { 0x80, 0x0c };
 325        struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 326                               .buf = data, .len = 2};
 327
 328        tuner_transfer(fe, &msg, 1);
 329}
 330
 331/* ------------------------------------------------------------------ */
 332
 333struct tda827xa_data {
 334        u32 lomax;
 335        u8  svco;
 336        u8  spd;
 337        u8  scr;
 338        u8  sbs;
 339        u8  gc3;
 340};
 341
 342static struct tda827xa_data tda827xa_dvbt[] = {
 343        { .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
 344        { .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
 345        { .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
 346        { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
 347        { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
 348        { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
 349        { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
 350        { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
 351        { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
 352        { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
 353        { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
 354        { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
 355        { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
 356        { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
 357        { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
 358        { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
 359        { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
 360        { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
 361        { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
 362        { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
 363        { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
 364        { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
 365        { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
 366        { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
 367        { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
 368        { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
 369        { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
 370};
 371
 372static struct tda827xa_data tda827xa_dvbc[] = {
 373        { .lomax =  50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
 374        { .lomax =  58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
 375        { .lomax =  69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
 376        { .lomax =  83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
 377        { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
 378        { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
 379        { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
 380        { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
 381        { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
 382        { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
 383        { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
 384        { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
 385        { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
 386        { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
 387        { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
 388        { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
 389        { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
 390        { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
 391        { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
 392        { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
 393        { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
 394        { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
 395        { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
 396        { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
 397        { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
 398        { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
 399        { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
 400};
 401
 402static struct tda827xa_data tda827xa_analog[] = {
 403        { .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
 404        { .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
 405        { .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
 406        { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
 407        { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
 408        { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
 409        { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
 410        { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
 411        { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
 412        { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
 413        { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
 414        { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
 415        { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
 416        { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
 417        { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
 418        { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
 419        { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
 420        { .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
 421        { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
 422        { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
 423        { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
 424        { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
 425        { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
 426        { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
 427        { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
 428        { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
 429};
 430
 431static int tda827xa_sleep(struct dvb_frontend *fe)
 432{
 433        struct tda827x_priv *priv = fe->tuner_priv;
 434        static u8 buf[] = { 0x30, 0x90 };
 435        struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 436                               .buf = buf, .len = sizeof(buf) };
 437
 438        dprintk("%s:\n", __func__);
 439
 440        tuner_transfer(fe, &msg, 1);
 441
 442        if (priv->cfg && priv->cfg->sleep)
 443                priv->cfg->sleep(fe);
 444
 445        return 0;
 446}
 447
 448static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
 449                              struct analog_parameters *params)
 450{
 451        struct tda827x_priv *priv = fe->tuner_priv;
 452        unsigned char buf[] = {0x22, 0x01};
 453        int arg;
 454        int gp_func;
 455        struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) };
 456
 457        if (NULL == priv->cfg) {
 458                dprintk("tda827x_config not defined, cannot set LNA gain!\n");
 459                return;
 460        }
 461        msg.addr = priv->cfg->switch_addr;
 462        if (priv->cfg->config) {
 463                if (high)
 464                        dprintk("setting LNA to high gain\n");
 465                else
 466                        dprintk("setting LNA to low gain\n");
 467        }
 468        switch (priv->cfg->config) {
 469        case TDA8290_LNA_OFF: /* no LNA */
 470                break;
 471        case TDA8290_LNA_GP0_HIGH_ON: /* switch is GPIO 0 of tda8290 */
 472        case TDA8290_LNA_GP0_HIGH_OFF:
 473                if (params == NULL) {
 474                        gp_func = 0;
 475                        arg  = 0;
 476                } else {
 477                        /* turn Vsync on */
 478                        gp_func = 1;
 479                        if (params->std & V4L2_STD_MN)
 480                                arg = 1;
 481                        else
 482                                arg = 0;
 483                }
 484                if (fe->callback)
 485                        fe->callback(priv->i2c_adap->algo_data,
 486                                     DVB_FRONTEND_COMPONENT_TUNER,
 487                                     gp_func, arg);
 488                buf[1] = high ? 0 : 1;
 489                if (priv->cfg->config == TDA8290_LNA_GP0_HIGH_OFF)
 490                        buf[1] = high ? 1 : 0;
 491                tuner_transfer(fe, &msg, 1);
 492                break;
 493        case TDA8290_LNA_ON_BRIDGE: /* switch with GPIO of saa713x */
 494                if (fe->callback)
 495                        fe->callback(priv->i2c_adap->algo_data,
 496                                     DVB_FRONTEND_COMPONENT_TUNER, 0, high);
 497                break;
 498        }
 499}
 500
 501static int tda827xa_set_params(struct dvb_frontend *fe)
 502{
 503        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 504        struct tda827x_priv *priv = fe->tuner_priv;
 505        struct tda827xa_data *frequency_map = tda827xa_dvbt;
 506        u8 buf[11];
 507
 508        struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 509                               .buf = buf, .len = sizeof(buf) };
 510
 511        int i, tuner_freq, if_freq, rc;
 512        u32 N;
 513
 514        dprintk("%s:\n", __func__);
 515
 516        tda827xa_lna_gain(fe, 1, NULL);
 517        msleep(20);
 518
 519        if (c->bandwidth_hz == 0) {
 520                if_freq = 5000000;
 521        } else if (c->bandwidth_hz <= 6000000) {
 522                if_freq = 4000000;
 523        } else if (c->bandwidth_hz <= 7000000) {
 524                if_freq = 4500000;
 525        } else {        /* 8 MHz */
 526                if_freq = 5000000;
 527        }
 528        tuner_freq = c->frequency;
 529
 530        switch (c->delivery_system) {
 531        case SYS_DVBC_ANNEX_A:
 532        case SYS_DVBC_ANNEX_C:
 533                dprintk("%s select tda827xa_dvbc\n", __func__);
 534                frequency_map = tda827xa_dvbc;
 535                break;
 536        default:
 537                break;
 538        }
 539
 540        i = 0;
 541        while (frequency_map[i].lomax < tuner_freq) {
 542                if (frequency_map[i + 1].lomax == 0)
 543                        break;
 544                i++;
 545        }
 546
 547        tuner_freq += if_freq;
 548
 549        N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
 550        buf[0] = 0;            // subaddress
 551        buf[1] = N >> 8;
 552        buf[2] = N & 0xff;
 553        buf[3] = 0;
 554        buf[4] = 0x16;
 555        buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
 556                        frequency_map[i].sbs;
 557        buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
 558        buf[7] = 0x1c;
 559        buf[8] = 0x06;
 560        buf[9] = 0x24;
 561        buf[10] = 0x00;
 562        msg.len = 11;
 563        rc = tuner_transfer(fe, &msg, 1);
 564        if (rc < 0)
 565                goto err;
 566
 567        buf[0] = 0x90;
 568        buf[1] = 0xff;
 569        buf[2] = 0x60;
 570        buf[3] = 0x00;
 571        buf[4] = 0x59;  // lpsel, for 6MHz + 2
 572        msg.len = 5;
 573        rc = tuner_transfer(fe, &msg, 1);
 574        if (rc < 0)
 575                goto err;
 576
 577        buf[0] = 0xa0;
 578        buf[1] = 0x40;
 579        msg.len = 2;
 580        rc = tuner_transfer(fe, &msg, 1);
 581        if (rc < 0)
 582                goto err;
 583
 584        msleep(11);
 585        msg.flags = I2C_M_RD;
 586        rc = tuner_transfer(fe, &msg, 1);
 587        if (rc < 0)
 588                goto err;
 589        msg.flags = 0;
 590
 591        buf[1] >>= 4;
 592        dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
 593        if ((buf[1]) < 2) {
 594                tda827xa_lna_gain(fe, 0, NULL);
 595                buf[0] = 0x60;
 596                buf[1] = 0x0c;
 597                rc = tuner_transfer(fe, &msg, 1);
 598                if (rc < 0)
 599                        goto err;
 600        }
 601
 602        buf[0] = 0xc0;
 603        buf[1] = 0x99;    // lpsel, for 6MHz + 2
 604        rc = tuner_transfer(fe, &msg, 1);
 605        if (rc < 0)
 606                goto err;
 607
 608        buf[0] = 0x60;
 609        buf[1] = 0x3c;
 610        rc = tuner_transfer(fe, &msg, 1);
 611        if (rc < 0)
 612                goto err;
 613
 614        /* correct CP value */
 615        buf[0] = 0x30;
 616        buf[1] = 0x10 + frequency_map[i].scr;
 617        rc = tuner_transfer(fe, &msg, 1);
 618        if (rc < 0)
 619                goto err;
 620
 621        msleep(163);
 622        buf[0] = 0xc0;
 623        buf[1] = 0x39;  // lpsel, for 6MHz + 2
 624        rc = tuner_transfer(fe, &msg, 1);
 625        if (rc < 0)
 626                goto err;
 627
 628        msleep(3);
 629        /* freeze AGC1 */
 630        buf[0] = 0x50;
 631        buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
 632        rc = tuner_transfer(fe, &msg, 1);
 633        if (rc < 0)
 634                goto err;
 635
 636        priv->frequency = c->frequency;
 637        priv->bandwidth = c->bandwidth_hz;
 638
 639        return 0;
 640
 641err:
 642        printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
 643               __func__, priv->i2c_addr << 1);
 644        return rc;
 645}
 646
 647
 648static int tda827xa_set_analog_params(struct dvb_frontend *fe,
 649                                      struct analog_parameters *params)
 650{
 651        unsigned char tuner_reg[11];
 652        u32 N;
 653        int i;
 654        struct tda827x_priv *priv = fe->tuner_priv;
 655        struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 656                               .buf = tuner_reg, .len = sizeof(tuner_reg) };
 657        unsigned int freq = params->frequency;
 658
 659        tda827x_set_std(fe, params);
 660
 661        tda827xa_lna_gain(fe, 1, params);
 662        msleep(10);
 663
 664        if (params->mode == V4L2_TUNER_RADIO)
 665                freq = freq / 1000;
 666
 667        N = freq + priv->sgIF;
 668
 669        i = 0;
 670        while (tda827xa_analog[i].lomax < N * 62500) {
 671                if (tda827xa_analog[i + 1].lomax == 0)
 672                        break;
 673                i++;
 674        }
 675
 676        N = N << tda827xa_analog[i].spd;
 677
 678        tuner_reg[0] = 0;
 679        tuner_reg[1] = (unsigned char)(N>>8);
 680        tuner_reg[2] = (unsigned char) N;
 681        tuner_reg[3] = 0;
 682        tuner_reg[4] = 0x16;
 683        tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
 684                       (tda827xa_analog[i].svco << 3) +
 685                        tda827xa_analog[i].sbs;
 686        tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
 687        tuner_reg[7] = 0x1c;
 688        tuner_reg[8] = 4;
 689        tuner_reg[9] = 0x20;
 690        tuner_reg[10] = 0x00;
 691        msg.len = 11;
 692        tuner_transfer(fe, &msg, 1);
 693
 694        tuner_reg[0] = 0x90;
 695        tuner_reg[1] = 0xff;
 696        tuner_reg[2] = 0xe0;
 697        tuner_reg[3] = 0;
 698        tuner_reg[4] = 0x99 + (priv->lpsel << 1);
 699        msg.len = 5;
 700        tuner_transfer(fe, &msg, 1);
 701
 702        tuner_reg[0] = 0xa0;
 703        tuner_reg[1] = 0xc0;
 704        msg.len = 2;
 705        tuner_transfer(fe, &msg, 1);
 706
 707        tuner_reg[0] = 0x30;
 708        tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
 709        tuner_transfer(fe, &msg, 1);
 710
 711        msg.flags = I2C_M_RD;
 712        tuner_transfer(fe, &msg, 1);
 713        msg.flags = 0;
 714        tuner_reg[1] >>= 4;
 715        dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
 716        if (tuner_reg[1] < 1)
 717                tda827xa_lna_gain(fe, 0, params);
 718
 719        msleep(100);
 720        tuner_reg[0] = 0x60;
 721        tuner_reg[1] = 0x3c;
 722        tuner_transfer(fe, &msg, 1);
 723
 724        msleep(163);
 725        tuner_reg[0] = 0x50;
 726        tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
 727        tuner_transfer(fe, &msg, 1);
 728
 729        tuner_reg[0] = 0x80;
 730        tuner_reg[1] = 0x28;
 731        tuner_transfer(fe, &msg, 1);
 732
 733        tuner_reg[0] = 0xb0;
 734        tuner_reg[1] = 0x01;
 735        tuner_transfer(fe, &msg, 1);
 736
 737        tuner_reg[0] = 0xc0;
 738        tuner_reg[1] = 0x19 + (priv->lpsel << 1);
 739        tuner_transfer(fe, &msg, 1);
 740
 741        priv->frequency = params->frequency;
 742
 743        return 0;
 744}
 745
 746static void tda827xa_agcf(struct dvb_frontend *fe)
 747{
 748        struct tda827x_priv *priv = fe->tuner_priv;
 749        unsigned char data[] = {0x80, 0x2c};
 750        struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
 751                              .buf = data, .len = 2};
 752        tuner_transfer(fe, &msg, 1);
 753}
 754
 755/* ------------------------------------------------------------------ */
 756
 757static void tda827x_release(struct dvb_frontend *fe)
 758{
 759        kfree(fe->tuner_priv);
 760        fe->tuner_priv = NULL;
 761}
 762
 763static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 764{
 765        struct tda827x_priv *priv = fe->tuner_priv;
 766        *frequency = priv->frequency;
 767        return 0;
 768}
 769
 770static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 771{
 772        struct tda827x_priv *priv = fe->tuner_priv;
 773        *bandwidth = priv->bandwidth;
 774        return 0;
 775}
 776
 777static int tda827x_init(struct dvb_frontend *fe)
 778{
 779        struct tda827x_priv *priv = fe->tuner_priv;
 780        dprintk("%s:\n", __func__);
 781        if (priv->cfg && priv->cfg->init)
 782                priv->cfg->init(fe);
 783
 784        return 0;
 785}
 786
 787static int tda827x_probe_version(struct dvb_frontend *fe);
 788
 789static int tda827x_initial_init(struct dvb_frontend *fe)
 790{
 791        int ret;
 792        ret = tda827x_probe_version(fe);
 793        if (ret)
 794                return ret;
 795        return fe->ops.tuner_ops.init(fe);
 796}
 797
 798static int tda827x_initial_sleep(struct dvb_frontend *fe)
 799{
 800        int ret;
 801        ret = tda827x_probe_version(fe);
 802        if (ret)
 803                return ret;
 804        return fe->ops.tuner_ops.sleep(fe);
 805}
 806
 807static const struct dvb_tuner_ops tda827xo_tuner_ops = {
 808        .info = {
 809                .name = "Philips TDA827X",
 810                .frequency_min_hz  =  55 * MHz,
 811                .frequency_max_hz  = 860 * MHz,
 812                .frequency_step_hz = 250 * kHz
 813        },
 814        .release = tda827x_release,
 815        .init = tda827x_initial_init,
 816        .sleep = tda827x_initial_sleep,
 817        .set_params = tda827xo_set_params,
 818        .set_analog_params = tda827xo_set_analog_params,
 819        .get_frequency = tda827x_get_frequency,
 820        .get_bandwidth = tda827x_get_bandwidth,
 821};
 822
 823static const struct dvb_tuner_ops tda827xa_tuner_ops = {
 824        .info = {
 825                .name = "Philips TDA827XA",
 826                .frequency_min_hz  =  44 * MHz,
 827                .frequency_max_hz  = 906 * MHz,
 828                .frequency_step_hz = 62500
 829        },
 830        .release = tda827x_release,
 831        .init = tda827x_init,
 832        .sleep = tda827xa_sleep,
 833        .set_params = tda827xa_set_params,
 834        .set_analog_params = tda827xa_set_analog_params,
 835        .get_frequency = tda827x_get_frequency,
 836        .get_bandwidth = tda827x_get_bandwidth,
 837};
 838
 839static int tda827x_probe_version(struct dvb_frontend *fe)
 840{
 841        u8 data;
 842        int rc;
 843        struct tda827x_priv *priv = fe->tuner_priv;
 844        struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
 845                               .buf = &data, .len = 1 };
 846
 847        rc = tuner_transfer(fe, &msg, 1);
 848
 849        if (rc < 0) {
 850                printk("%s: could not read from tuner at addr: 0x%02x\n",
 851                       __func__, msg.addr << 1);
 852                return rc;
 853        }
 854        if ((data & 0x3c) == 0) {
 855                dprintk("tda827x tuner found\n");
 856                fe->ops.tuner_ops.init  = tda827x_init;
 857                fe->ops.tuner_ops.sleep = tda827xo_sleep;
 858                if (priv->cfg)
 859                        priv->cfg->agcf = tda827xo_agcf;
 860        } else {
 861                dprintk("tda827xa tuner found\n");
 862                memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
 863                if (priv->cfg)
 864                        priv->cfg->agcf = tda827xa_agcf;
 865        }
 866        return 0;
 867}
 868
 869struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
 870                                    struct i2c_adapter *i2c,
 871                                    struct tda827x_config *cfg)
 872{
 873        struct tda827x_priv *priv = NULL;
 874
 875        dprintk("%s:\n", __func__);
 876        priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
 877        if (priv == NULL)
 878                return NULL;
 879
 880        priv->i2c_addr = addr;
 881        priv->i2c_adap = i2c;
 882        priv->cfg = cfg;
 883        memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
 884        fe->tuner_priv = priv;
 885
 886        dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
 887
 888        return fe;
 889}
 890EXPORT_SYMBOL_GPL(tda827x_attach);
 891
 892MODULE_DESCRIPTION("DVB TDA827x driver");
 893MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
 894MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
 895MODULE_LICENSE("GPL");
 896