root/drivers/media/tuners/fc0013.c

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

DEFINITIONS

This source file includes following definitions.
  1. fc0013_writereg
  2. fc0013_readreg
  3. fc0013_release
  4. fc0013_init
  5. fc0013_sleep
  6. fc0013_rc_cal_add
  7. fc0013_rc_cal_reset
  8. fc0013_set_vhf_track
  9. fc0013_set_params
  10. fc0013_get_frequency
  11. fc0013_get_if_frequency
  12. fc0013_get_bandwidth
  13. fc0013_get_rf_strength
  14. fc0013_attach

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Fitipower FC0013 tuner driver
   4  *
   5  * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
   6  * partially based on driver code from Fitipower
   7  * Copyright (C) 2010 Fitipower Integrated Technology Inc
   8  */
   9 
  10 #include "fc0013.h"
  11 #include "fc0013-priv.h"
  12 
  13 static int fc0013_writereg(struct fc0013_priv *priv, u8 reg, u8 val)
  14 {
  15         u8 buf[2] = {reg, val};
  16         struct i2c_msg msg = {
  17                 .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
  18         };
  19 
  20         if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
  21                 err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
  22                 return -EREMOTEIO;
  23         }
  24         return 0;
  25 }
  26 
  27 static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val)
  28 {
  29         struct i2c_msg msg[2] = {
  30                 { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
  31                 { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
  32         };
  33 
  34         if (i2c_transfer(priv->i2c, msg, 2) != 2) {
  35                 err("I2C read reg failed, reg: %02x", reg);
  36                 return -EREMOTEIO;
  37         }
  38         return 0;
  39 }
  40 
  41 static void fc0013_release(struct dvb_frontend *fe)
  42 {
  43         kfree(fe->tuner_priv);
  44         fe->tuner_priv = NULL;
  45 }
  46 
  47 static int fc0013_init(struct dvb_frontend *fe)
  48 {
  49         struct fc0013_priv *priv = fe->tuner_priv;
  50         int i, ret = 0;
  51         unsigned char reg[] = {
  52                 0x00,   /* reg. 0x00: dummy */
  53                 0x09,   /* reg. 0x01 */
  54                 0x16,   /* reg. 0x02 */
  55                 0x00,   /* reg. 0x03 */
  56                 0x00,   /* reg. 0x04 */
  57                 0x17,   /* reg. 0x05 */
  58                 0x02,   /* reg. 0x06 */
  59                 0x0a,   /* reg. 0x07: CHECK */
  60                 0xff,   /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
  61                            Loop Bw 1/8 */
  62                 0x6f,   /* reg. 0x09: enable LoopThrough */
  63                 0xb8,   /* reg. 0x0a: Disable LO Test Buffer */
  64                 0x82,   /* reg. 0x0b: CHECK */
  65                 0xfc,   /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
  66                 0x01,   /* reg. 0x0d: AGC Not Forcing & LNA Forcing, may need 0x02 */
  67                 0x00,   /* reg. 0x0e */
  68                 0x00,   /* reg. 0x0f */
  69                 0x00,   /* reg. 0x10 */
  70                 0x00,   /* reg. 0x11 */
  71                 0x00,   /* reg. 0x12 */
  72                 0x00,   /* reg. 0x13 */
  73                 0x50,   /* reg. 0x14: DVB-t High Gain, UHF.
  74                            Middle Gain: 0x48, Low Gain: 0x40 */
  75                 0x01,   /* reg. 0x15 */
  76         };
  77 
  78         switch (priv->xtal_freq) {
  79         case FC_XTAL_27_MHZ:
  80         case FC_XTAL_28_8_MHZ:
  81                 reg[0x07] |= 0x20;
  82                 break;
  83         case FC_XTAL_36_MHZ:
  84         default:
  85                 break;
  86         }
  87 
  88         if (priv->dual_master)
  89                 reg[0x0c] |= 0x02;
  90 
  91         if (fe->ops.i2c_gate_ctrl)
  92                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
  93 
  94         for (i = 1; i < sizeof(reg); i++) {
  95                 ret = fc0013_writereg(priv, i, reg[i]);
  96                 if (ret)
  97                         break;
  98         }
  99 
 100         if (fe->ops.i2c_gate_ctrl)
 101                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
 102 
 103         if (ret)
 104                 err("fc0013_writereg failed: %d", ret);
 105 
 106         return ret;
 107 }
 108 
 109 static int fc0013_sleep(struct dvb_frontend *fe)
 110 {
 111         /* nothing to do here */
 112         return 0;
 113 }
 114 
 115 int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
 116 {
 117         struct fc0013_priv *priv = fe->tuner_priv;
 118         int ret;
 119         u8 rc_cal;
 120         int val;
 121 
 122         if (fe->ops.i2c_gate_ctrl)
 123                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
 124 
 125         /* push rc_cal value, get rc_cal value */
 126         ret = fc0013_writereg(priv, 0x10, 0x00);
 127         if (ret)
 128                 goto error_out;
 129 
 130         /* get rc_cal value */
 131         ret = fc0013_readreg(priv, 0x10, &rc_cal);
 132         if (ret)
 133                 goto error_out;
 134 
 135         rc_cal &= 0x0f;
 136 
 137         val = (int)rc_cal + rc_val;
 138 
 139         /* forcing rc_cal */
 140         ret = fc0013_writereg(priv, 0x0d, 0x11);
 141         if (ret)
 142                 goto error_out;
 143 
 144         /* modify rc_cal value */
 145         if (val > 15)
 146                 ret = fc0013_writereg(priv, 0x10, 0x0f);
 147         else if (val < 0)
 148                 ret = fc0013_writereg(priv, 0x10, 0x00);
 149         else
 150                 ret = fc0013_writereg(priv, 0x10, (u8)val);
 151 
 152 error_out:
 153         if (fe->ops.i2c_gate_ctrl)
 154                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
 155 
 156         return ret;
 157 }
 158 EXPORT_SYMBOL(fc0013_rc_cal_add);
 159 
 160 int fc0013_rc_cal_reset(struct dvb_frontend *fe)
 161 {
 162         struct fc0013_priv *priv = fe->tuner_priv;
 163         int ret;
 164 
 165         if (fe->ops.i2c_gate_ctrl)
 166                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
 167 
 168         ret = fc0013_writereg(priv, 0x0d, 0x01);
 169         if (!ret)
 170                 ret = fc0013_writereg(priv, 0x10, 0x00);
 171 
 172         if (fe->ops.i2c_gate_ctrl)
 173                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
 174 
 175         return ret;
 176 }
 177 EXPORT_SYMBOL(fc0013_rc_cal_reset);
 178 
 179 static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq)
 180 {
 181         int ret;
 182         u8 tmp;
 183 
 184         ret = fc0013_readreg(priv, 0x1d, &tmp);
 185         if (ret)
 186                 goto error_out;
 187         tmp &= 0xe3;
 188         if (freq <= 177500) {           /* VHF Track: 7 */
 189                 ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
 190         } else if (freq <= 184500) {    /* VHF Track: 6 */
 191                 ret = fc0013_writereg(priv, 0x1d, tmp | 0x18);
 192         } else if (freq <= 191500) {    /* VHF Track: 5 */
 193                 ret = fc0013_writereg(priv, 0x1d, tmp | 0x14);
 194         } else if (freq <= 198500) {    /* VHF Track: 4 */
 195                 ret = fc0013_writereg(priv, 0x1d, tmp | 0x10);
 196         } else if (freq <= 205500) {    /* VHF Track: 3 */
 197                 ret = fc0013_writereg(priv, 0x1d, tmp | 0x0c);
 198         } else if (freq <= 219500) {    /* VHF Track: 2 */
 199                 ret = fc0013_writereg(priv, 0x1d, tmp | 0x08);
 200         } else if (freq < 300000) {     /* VHF Track: 1 */
 201                 ret = fc0013_writereg(priv, 0x1d, tmp | 0x04);
 202         } else {                        /* UHF and GPS */
 203                 ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
 204         }
 205 error_out:
 206         return ret;
 207 }
 208 
 209 static int fc0013_set_params(struct dvb_frontend *fe)
 210 {
 211         struct fc0013_priv *priv = fe->tuner_priv;
 212         int i, ret = 0;
 213         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 214         u32 freq = p->frequency / 1000;
 215         u32 delsys = p->delivery_system;
 216         unsigned char reg[7], am, pm, multi, tmp;
 217         unsigned long f_vco;
 218         unsigned short xtal_freq_khz_2, xin, xdiv;
 219         bool vco_select = false;
 220 
 221         if (fe->callback) {
 222                 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
 223                         FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
 224                 if (ret)
 225                         goto exit;
 226         }
 227 
 228         switch (priv->xtal_freq) {
 229         case FC_XTAL_27_MHZ:
 230                 xtal_freq_khz_2 = 27000 / 2;
 231                 break;
 232         case FC_XTAL_36_MHZ:
 233                 xtal_freq_khz_2 = 36000 / 2;
 234                 break;
 235         case FC_XTAL_28_8_MHZ:
 236         default:
 237                 xtal_freq_khz_2 = 28800 / 2;
 238                 break;
 239         }
 240 
 241         if (fe->ops.i2c_gate_ctrl)
 242                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
 243 
 244         /* set VHF track */
 245         ret = fc0013_set_vhf_track(priv, freq);
 246         if (ret)
 247                 goto exit;
 248 
 249         if (freq < 300000) {
 250                 /* enable VHF filter */
 251                 ret = fc0013_readreg(priv, 0x07, &tmp);
 252                 if (ret)
 253                         goto exit;
 254                 ret = fc0013_writereg(priv, 0x07, tmp | 0x10);
 255                 if (ret)
 256                         goto exit;
 257 
 258                 /* disable UHF & disable GPS */
 259                 ret = fc0013_readreg(priv, 0x14, &tmp);
 260                 if (ret)
 261                         goto exit;
 262                 ret = fc0013_writereg(priv, 0x14, tmp & 0x1f);
 263                 if (ret)
 264                         goto exit;
 265         } else if (freq <= 862000) {
 266                 /* disable VHF filter */
 267                 ret = fc0013_readreg(priv, 0x07, &tmp);
 268                 if (ret)
 269                         goto exit;
 270                 ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
 271                 if (ret)
 272                         goto exit;
 273 
 274                 /* enable UHF & disable GPS */
 275                 ret = fc0013_readreg(priv, 0x14, &tmp);
 276                 if (ret)
 277                         goto exit;
 278                 ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x40);
 279                 if (ret)
 280                         goto exit;
 281         } else {
 282                 /* disable VHF filter */
 283                 ret = fc0013_readreg(priv, 0x07, &tmp);
 284                 if (ret)
 285                         goto exit;
 286                 ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
 287                 if (ret)
 288                         goto exit;
 289 
 290                 /* disable UHF & enable GPS */
 291                 ret = fc0013_readreg(priv, 0x14, &tmp);
 292                 if (ret)
 293                         goto exit;
 294                 ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x20);
 295                 if (ret)
 296                         goto exit;
 297         }
 298 
 299         /* select frequency divider and the frequency of VCO */
 300         if (freq < 37084) {             /* freq * 96 < 3560000 */
 301                 multi = 96;
 302                 reg[5] = 0x82;
 303                 reg[6] = 0x00;
 304         } else if (freq < 55625) {      /* freq * 64 < 3560000 */
 305                 multi = 64;
 306                 reg[5] = 0x02;
 307                 reg[6] = 0x02;
 308         } else if (freq < 74167) {      /* freq * 48 < 3560000 */
 309                 multi = 48;
 310                 reg[5] = 0x42;
 311                 reg[6] = 0x00;
 312         } else if (freq < 111250) {     /* freq * 32 < 3560000 */
 313                 multi = 32;
 314                 reg[5] = 0x82;
 315                 reg[6] = 0x02;
 316         } else if (freq < 148334) {     /* freq * 24 < 3560000 */
 317                 multi = 24;
 318                 reg[5] = 0x22;
 319                 reg[6] = 0x00;
 320         } else if (freq < 222500) {     /* freq * 16 < 3560000 */
 321                 multi = 16;
 322                 reg[5] = 0x42;
 323                 reg[6] = 0x02;
 324         } else if (freq < 296667) {     /* freq * 12 < 3560000 */
 325                 multi = 12;
 326                 reg[5] = 0x12;
 327                 reg[6] = 0x00;
 328         } else if (freq < 445000) {     /* freq * 8 < 3560000 */
 329                 multi = 8;
 330                 reg[5] = 0x22;
 331                 reg[6] = 0x02;
 332         } else if (freq < 593334) {     /* freq * 6 < 3560000 */
 333                 multi = 6;
 334                 reg[5] = 0x0a;
 335                 reg[6] = 0x00;
 336         } else if (freq < 950000) {     /* freq * 4 < 3800000 */
 337                 multi = 4;
 338                 reg[5] = 0x12;
 339                 reg[6] = 0x02;
 340         } else {
 341                 multi = 2;
 342                 reg[5] = 0x0a;
 343                 reg[6] = 0x02;
 344         }
 345 
 346         f_vco = freq * multi;
 347 
 348         if (f_vco >= 3060000) {
 349                 reg[6] |= 0x08;
 350                 vco_select = true;
 351         }
 352 
 353         if (freq >= 45000) {
 354                 /* From divided value (XDIV) determined the FA and FP value */
 355                 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
 356                 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
 357                         xdiv++;
 358 
 359                 pm = (unsigned char)(xdiv / 8);
 360                 am = (unsigned char)(xdiv - (8 * pm));
 361 
 362                 if (am < 2) {
 363                         reg[1] = am + 8;
 364                         reg[2] = pm - 1;
 365                 } else {
 366                         reg[1] = am;
 367                         reg[2] = pm;
 368                 }
 369         } else {
 370                 /* fix for frequency less than 45 MHz */
 371                 reg[1] = 0x06;
 372                 reg[2] = 0x11;
 373         }
 374 
 375         /* fix clock out */
 376         reg[6] |= 0x20;
 377 
 378         /* From VCO frequency determines the XIN ( fractional part of Delta
 379            Sigma PLL) and divided value (XDIV) */
 380         xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
 381         xin = (xin << 15) / xtal_freq_khz_2;
 382         if (xin >= 16384)
 383                 xin += 32768;
 384 
 385         reg[3] = xin >> 8;
 386         reg[4] = xin & 0xff;
 387 
 388         if (delsys == SYS_DVBT) {
 389                 reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
 390                 switch (p->bandwidth_hz) {
 391                 case 6000000:
 392                         reg[6] |= 0x80;
 393                         break;
 394                 case 7000000:
 395                         reg[6] |= 0x40;
 396                         break;
 397                 case 8000000:
 398                 default:
 399                         break;
 400                 }
 401         } else {
 402                 err("%s: modulation type not supported!", __func__);
 403                 return -EINVAL;
 404         }
 405 
 406         /* modified for Realtek demod */
 407         reg[5] |= 0x07;
 408 
 409         for (i = 1; i <= 6; i++) {
 410                 ret = fc0013_writereg(priv, i, reg[i]);
 411                 if (ret)
 412                         goto exit;
 413         }
 414 
 415         ret = fc0013_readreg(priv, 0x11, &tmp);
 416         if (ret)
 417                 goto exit;
 418         if (multi == 64)
 419                 ret = fc0013_writereg(priv, 0x11, tmp | 0x04);
 420         else
 421                 ret = fc0013_writereg(priv, 0x11, tmp & 0xfb);
 422         if (ret)
 423                 goto exit;
 424 
 425         /* VCO Calibration */
 426         ret = fc0013_writereg(priv, 0x0e, 0x80);
 427         if (!ret)
 428                 ret = fc0013_writereg(priv, 0x0e, 0x00);
 429 
 430         /* VCO Re-Calibration if needed */
 431         if (!ret)
 432                 ret = fc0013_writereg(priv, 0x0e, 0x00);
 433 
 434         if (!ret) {
 435                 msleep(10);
 436                 ret = fc0013_readreg(priv, 0x0e, &tmp);
 437         }
 438         if (ret)
 439                 goto exit;
 440 
 441         /* vco selection */
 442         tmp &= 0x3f;
 443 
 444         if (vco_select) {
 445                 if (tmp > 0x3c) {
 446                         reg[6] &= ~0x08;
 447                         ret = fc0013_writereg(priv, 0x06, reg[6]);
 448                         if (!ret)
 449                                 ret = fc0013_writereg(priv, 0x0e, 0x80);
 450                         if (!ret)
 451                                 ret = fc0013_writereg(priv, 0x0e, 0x00);
 452                 }
 453         } else {
 454                 if (tmp < 0x02) {
 455                         reg[6] |= 0x08;
 456                         ret = fc0013_writereg(priv, 0x06, reg[6]);
 457                         if (!ret)
 458                                 ret = fc0013_writereg(priv, 0x0e, 0x80);
 459                         if (!ret)
 460                                 ret = fc0013_writereg(priv, 0x0e, 0x00);
 461                 }
 462         }
 463 
 464         priv->frequency = p->frequency;
 465         priv->bandwidth = p->bandwidth_hz;
 466 
 467 exit:
 468         if (fe->ops.i2c_gate_ctrl)
 469                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
 470         if (ret)
 471                 warn("%s: failed: %d", __func__, ret);
 472         return ret;
 473 }
 474 
 475 static int fc0013_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 476 {
 477         struct fc0013_priv *priv = fe->tuner_priv;
 478         *frequency = priv->frequency;
 479         return 0;
 480 }
 481 
 482 static int fc0013_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
 483 {
 484         /* always ? */
 485         *frequency = 0;
 486         return 0;
 487 }
 488 
 489 static int fc0013_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 490 {
 491         struct fc0013_priv *priv = fe->tuner_priv;
 492         *bandwidth = priv->bandwidth;
 493         return 0;
 494 }
 495 
 496 #define INPUT_ADC_LEVEL -8
 497 
 498 static int fc0013_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
 499 {
 500         struct fc0013_priv *priv = fe->tuner_priv;
 501         int ret;
 502         unsigned char tmp;
 503         int int_temp, lna_gain, int_lna, tot_agc_gain, power;
 504         static const int fc0013_lna_gain_table[] = {
 505                 /* low gain */
 506                 -63, -58, -99, -73,
 507                 -63, -65, -54, -60,
 508                 /* middle gain */
 509                  71,  70,  68,  67,
 510                  65,  63,  61,  58,
 511                 /* high gain */
 512                 197, 191, 188, 186,
 513                 184, 182, 181, 179,
 514         };
 515 
 516         if (fe->ops.i2c_gate_ctrl)
 517                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
 518 
 519         ret = fc0013_writereg(priv, 0x13, 0x00);
 520         if (ret)
 521                 goto err;
 522 
 523         ret = fc0013_readreg(priv, 0x13, &tmp);
 524         if (ret)
 525                 goto err;
 526         int_temp = tmp;
 527 
 528         ret = fc0013_readreg(priv, 0x14, &tmp);
 529         if (ret)
 530                 goto err;
 531         lna_gain = tmp & 0x1f;
 532 
 533         if (fe->ops.i2c_gate_ctrl)
 534                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
 535 
 536         if (lna_gain < ARRAY_SIZE(fc0013_lna_gain_table)) {
 537                 int_lna = fc0013_lna_gain_table[lna_gain];
 538                 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
 539                                 (int_temp & 0x1f)) * 2;
 540                 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
 541 
 542                 if (power >= 45)
 543                         *strength = 255;        /* 100% */
 544                 else if (power < -95)
 545                         *strength = 0;
 546                 else
 547                         *strength = (power + 95) * 255 / 140;
 548 
 549                 *strength |= *strength << 8;
 550         } else {
 551                 ret = -1;
 552         }
 553 
 554         goto exit;
 555 
 556 err:
 557         if (fe->ops.i2c_gate_ctrl)
 558                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
 559 exit:
 560         if (ret)
 561                 warn("%s: failed: %d", __func__, ret);
 562         return ret;
 563 }
 564 
 565 static const struct dvb_tuner_ops fc0013_tuner_ops = {
 566         .info = {
 567                 .name             = "Fitipower FC0013",
 568 
 569                 .frequency_min_hz =   37 * MHz, /* estimate */
 570                 .frequency_max_hz = 1680 * MHz, /* CHECK */
 571         },
 572 
 573         .release        = fc0013_release,
 574 
 575         .init           = fc0013_init,
 576         .sleep          = fc0013_sleep,
 577 
 578         .set_params     = fc0013_set_params,
 579 
 580         .get_frequency  = fc0013_get_frequency,
 581         .get_if_frequency = fc0013_get_if_frequency,
 582         .get_bandwidth  = fc0013_get_bandwidth,
 583 
 584         .get_rf_strength = fc0013_get_rf_strength,
 585 };
 586 
 587 struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
 588         struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
 589         enum fc001x_xtal_freq xtal_freq)
 590 {
 591         struct fc0013_priv *priv = NULL;
 592 
 593         priv = kzalloc(sizeof(struct fc0013_priv), GFP_KERNEL);
 594         if (priv == NULL)
 595                 return NULL;
 596 
 597         priv->i2c = i2c;
 598         priv->dual_master = dual_master;
 599         priv->addr = i2c_address;
 600         priv->xtal_freq = xtal_freq;
 601 
 602         info("Fitipower FC0013 successfully attached.");
 603 
 604         fe->tuner_priv = priv;
 605 
 606         memcpy(&fe->ops.tuner_ops, &fc0013_tuner_ops,
 607                 sizeof(struct dvb_tuner_ops));
 608 
 609         return fe;
 610 }
 611 EXPORT_SYMBOL(fc0013_attach);
 612 
 613 MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver");
 614 MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
 615 MODULE_LICENSE("GPL");
 616 MODULE_VERSION("0.2");

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