root/drivers/media/tuners/tda827x.c

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

DEFINITIONS

This source file includes following definitions.
  1. tda827x_set_std
  2. tuner_transfer
  3. tda827xo_set_params
  4. tda827xo_sleep
  5. tda827xo_set_analog_params
  6. tda827xo_agcf
  7. tda827xa_sleep
  8. tda827xa_lna_gain
  9. tda827xa_set_params
  10. tda827xa_set_analog_params
  11. tda827xa_agcf
  12. tda827x_release
  13. tda827x_get_frequency
  14. tda827x_get_bandwidth
  15. tda827x_init
  16. tda827x_initial_init
  17. tda827x_initial_sleep
  18. tda827x_probe_version
  19. tda827x_attach

   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 
  16 static int debug;
  17 module_param(debug, int, 0644);
  18 MODULE_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 
  25 struct 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 
  37 static 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 
  81 struct 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 
  91 static 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 
 123 static 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 
 142 static 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 
 213 err:
 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 
 219 static 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 
 237 static 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 
 321 static 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 
 333 struct tda827xa_data {
 334         u32 lomax;
 335         u8  svco;
 336         u8  spd;
 337         u8  scr;
 338         u8  sbs;
 339         u8  gc3;
 340 };
 341 
 342 static 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 
 372 static 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 
 402 static 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 
 431 static 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 
 448 static 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 
 501 static 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 
 641 err:
 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 
 648 static 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 
 746 static 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 
 757 static void tda827x_release(struct dvb_frontend *fe)
 758 {
 759         kfree(fe->tuner_priv);
 760         fe->tuner_priv = NULL;
 761 }
 762 
 763 static 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 
 770 static 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 
 777 static 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 
 787 static int tda827x_probe_version(struct dvb_frontend *fe);
 788 
 789 static 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 
 798 static 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 
 807 static 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 
 823 static 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 
 839 static 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 
 869 struct 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 }
 890 EXPORT_SYMBOL_GPL(tda827x_attach);
 891 
 892 MODULE_DESCRIPTION("DVB TDA827x driver");
 893 MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
 894 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
 895 MODULE_LICENSE("GPL");

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